scroll to anchor fixes, profile comments link fix

This commit is contained in:
bniwredyc 2023-04-03 14:55:00 +02:00
parent 7c1a51f638
commit 3549e57506
6 changed files with 65 additions and 104 deletions

View File

@ -108,7 +108,7 @@ export const CommentsTree = (props: Props) => {
return (
<>
<div class={styles.commentsHeaderWrapper}>
<h2 id="comments" class={styles.commentsHeader}>
<h2 class={styles.commentsHeader}>
{t('Comments')} {comments().length.toString() || ''}
<Show when={newReactions().length > 0}>
<span class={styles.newReactions}>&nbsp;+{newReactions().length}</span>
@ -161,7 +161,7 @@ export const CommentsTree = (props: Props) => {
</ul>
<ShowIfAuthenticated
fallback={
<div class={styles.signInMessage} id="comments">
<div class={styles.signInMessage}>
{t('To write a comment, you must')}{' '}
<a href="?modal=auth&mode=register" class={styles.link}>
{t('sign up')}

View File

@ -66,19 +66,6 @@ export const FullArticle = (props: ArticleProps) => {
props.article.topics[0]
)
onMount(() => {
const windowHash = window.location.hash
if (windowHash?.length > 0) {
const comments = document.querySelector(windowHash)
if (comments) {
window.scrollTo({
top: comments.getBoundingClientRect().top,
behavior: 'smooth'
})
}
}
})
onMount(async () => {
await loadReactionsBy({
by: { shout: props.article.slug }
@ -105,20 +92,6 @@ export const FullArticle = (props: ArticleProps) => {
actions: { loadReactionsBy }
} = useReactions()
let commentsRef: HTMLDivElement | undefined
const scrollToComments = () => {
if (!isReactionsLoaded()) {
return
}
commentsRef.scrollIntoView({ behavior: 'smooth' })
}
const { searchParams } = useRouter()
createEffect(() => {
if (searchParams()?.scrollTo === 'comments') {
scrollToComments()
}
})
return (
<>
<Title>{props.article.title}</Title>
@ -276,7 +249,7 @@ export const FullArticle = (props: ArticleProps) => {
)}
</For>
</div>
<div>
<div id="comments">
<Show when={isReactionsLoaded()}>
<CommentsTree
shoutId={props.article.id}

View File

@ -12,12 +12,7 @@ import stylesHeader from '../Nav/Header.module.scss'
import { getDescription } from '../../utils/meta'
import { FeedArticlePopup } from './FeedArticlePopup'
import { useLocalize } from '../../context/localize'
import { openPage } from '@nanostores/router'
import { router, useRouter } from '../../stores/router'
type ArticleSearchParams = {
scrollTo: 'comments'
}
interface ArticleCardProps {
settings?: {
noicon?: boolean
@ -80,12 +75,6 @@ export const ArticleCard = (props: ArticleCardProps) => {
const { cover, layout, slug, authors, stat, body } = props.article
const { changeSearchParam } = useRouter<ArticleSearchParams>()
const scrollToComments = () => {
openPage(router, 'article', { slug: slug })
changeSearchParam('scrollTo', 'comments')
}
return (
<section
class={clsx(styles.shoutCard, `${props.settings?.additionalClass || ''}`)}
@ -184,10 +173,10 @@ export const ArticleCard = (props: ArticleCardProps) => {
</div>
<div class={clsx(styles.shoutCardDetailsItem, styles.shoutCardComments)}>
<button type="button" onClick={scrollToComments}>
<a href={`/${slug + '#comments'}`}>
<Icon name="comment" class={clsx(styles.icon, styles.feedControlIcon)} />
{stat?.commented || t('Add comment')}
</button>
</a>
</div>
</div>

View File

@ -2,10 +2,9 @@ import { useSession } from '../../context/session'
import type { PopupProps } from '../_shared/Popup'
import { Popup } from '../_shared/Popup'
import styles from '../_shared/Popup/Popup.module.scss'
import { getPagePath, openPage } from '@nanostores/router'
import { router, useRouter } from '../../stores/router'
import { getPagePath } from '@nanostores/router'
import { router } from '../../stores/router'
import { useLocalize } from '../../context/localize'
import type { AuthorPageSearchParams } from '../Views/Author'
type ProfilePopupProps = Omit<PopupProps, 'children'>
@ -16,12 +15,6 @@ export const ProfilePopup = (props: ProfilePopupProps) => {
} = useSession()
const { t } = useLocalize()
const { changeSearchParam } = useRouter<AuthorPageSearchParams>()
const openAuthorComments = () => {
openPage(router, 'author', { slug: userSlug() })
changeSearchParam('by', 'commented')
}
return (
<Popup {...props} horizontalAnchor="right" variant="bordered">
@ -36,13 +29,7 @@ export const ProfilePopup = (props: ProfilePopupProps) => {
<a href="#">{t('Subscriptions')}</a>
</li>
<li>
<a
href="#"
onClick={(event) => {
event.preventDefault()
openAuthorComments()
}}
>
<a href={`${getPagePath(router, 'author', { slug: userSlug() })}/?by=commented`}>
{t('Comments')}
</a>
</li>

View File

@ -54,7 +54,11 @@ export const AuthorView = (props: AuthorProps) => {
const { searchParams, changeSearchParam } = useRouter<AuthorPageSearchParams>()
changeSearchParam('by', 'rating')
onMount(() => {
if (!searchParams().by) {
changeSearchParam('by', 'rating')
}
})
const loadMore = async () => {
saveScrollPosition()

View File

@ -40,9 +40,8 @@ const routerStore = createRouter(ROUTES, {
export const router = routerStore
const handleClientRouteLinkClick = (event) => {
const link = event.target.closest('a')
if (
const checkOpenOnClient = (link: HTMLAnchorElement, event) => {
return (
link &&
event.button === 0 &&
link.target !== '_blank' &&
@ -52,48 +51,58 @@ const handleClientRouteLinkClick = (event) => {
!event.ctrlKey &&
!event.shiftKey &&
!event.altKey
) {
const url = new URL(link.href)
if (url.origin === location.origin) {
event.preventDefault()
)
}
if (url.pathname) {
routerStore.open(url.pathname)
}
const handleClientRouteLinkClick = (event) => {
const link = event.target.closest('a')
if (url.search) {
const params = Object.fromEntries(new URLSearchParams(url.search))
searchParamsStore.open(params)
}
if (url.hash) {
let selector = url.hash
if (/^#\d+/.test(selector)) {
// id="1" fix
// https://stackoverflow.com/questions/20306204/using-queryselector-with-ids-that-are-numbers
selector = `[id="${selector.replace('#', '')}"]`
}
const anchor = document.querySelector(selector)
const headerOffset = 80 // 100px for header
const elementPosition = anchor ? anchor.getBoundingClientRect().top : 0
const newScrollTop = elementPosition + window.scrollY - headerOffset
window.scrollTo({
top: newScrollTop,
behavior: 'smooth'
})
return
}
window.scrollTo({
top: 0,
left: 0
})
}
if (!checkOpenOnClient(link, event)) {
return
}
const url = new URL(link.href)
if (url.origin !== location.origin) {
return
}
event.preventDefault()
if (url.pathname) {
routerStore.open(url.pathname)
}
if (url.search) {
const params = Object.fromEntries(new URLSearchParams(url.search))
searchParamsStore.open(params)
}
if (url.hash) {
let selector = url.hash
if (/^#\d+/.test(selector)) {
// id="1" fix
// https://stackoverflow.com/questions/20306204/using-queryselector-with-ids-that-are-numbers
selector = `[id="${selector.replace('#', '')}"]`
}
const anchor = document.querySelector(selector)
const headerOffset = 80 // 100px for header
const elementPosition = anchor ? anchor.getBoundingClientRect().top : 0
const newScrollTop = elementPosition + window.scrollY - headerOffset
window.scrollTo({
top: newScrollTop,
behavior: 'smooth'
})
return
}
window.scrollTo({
top: 0,
left: 0
})
}
export const initRouter = (pathname: string, search: Record<string, string>) => {
@ -134,7 +143,6 @@ export const useRouter = <TSearchParams extends Record<string, string> = Record<
return {
page,
searchParams,
changeSearchParam,
handleClientRouteLinkClick
changeSearchParam
}
}