Anchor revert

This commit is contained in:
ilia tapazukk 2023-04-20 14:01:15 +00:00 committed by Igor
parent ae32a0c4e4
commit dab4bcd41e
6 changed files with 42 additions and 55 deletions

View File

@ -90,7 +90,6 @@ export const FullArticle = (props: ArticleProps) => {
}) })
const commentsRef: { current: HTMLDivElement } = { current: null } const commentsRef: { current: HTMLDivElement } = { current: null }
const scrollToComments = () => { const scrollToComments = () => {
window.scrollTo({ window.scrollTo({
top: commentsRef.current.offsetTop - 96, top: commentsRef.current.offsetTop - 96,
@ -98,12 +97,20 @@ export const FullArticle = (props: ArticleProps) => {
behavior: 'smooth' behavior: 'smooth'
}) })
} }
const { searchParams } = useRouter()
createEffect(() => { createEffect(() => {
if (props.scrollToComments) { if (props.scrollToComments) {
scrollToComments() scrollToComments()
} }
}) })
const { changeSearchParam } = useRouter()
createEffect(() => {
if (searchParams()?.scrollTo === 'comments' && commentsRef.current) {
scrollToComments()
changeSearchParam('scrollTo', null)
}
})
const { const {
actions: { loadReactionsBy } actions: { loadReactionsBy }

View File

@ -12,6 +12,8 @@ import stylesHeader from '../Nav/Header.module.scss'
import { getDescription } from '../../utils/meta' import { getDescription } from '../../utils/meta'
import { FeedArticlePopup } from './FeedArticlePopup' import { FeedArticlePopup } from './FeedArticlePopup'
import { useLocalize } from '../../context/localize' import { useLocalize } from '../../context/localize'
import { openPage } from '@nanostores/router'
import { router, useRouter } from '../../stores/router'
interface ArticleCardProps { interface ArticleCardProps {
settings?: { settings?: {
@ -35,6 +37,7 @@ interface ArticleCardProps {
isBeside?: boolean isBeside?: boolean
} }
article: Shout article: Shout
scrollTo: 'comments'
} }
const getTitleAndSubtitle = (article: Shout): { title: string; subtitle: string } => { const getTitleAndSubtitle = (article: Shout): { title: string; subtitle: string } => {
@ -75,6 +78,13 @@ export const ArticleCard = (props: ArticleCardProps) => {
const { cover, layout, slug, authors, stat, body } = props.article const { cover, layout, slug, authors, stat, body } = props.article
const { changeSearchParam } = useRouter()
const scrollToComments = (event) => {
event.preventDefault()
openPage(router, 'article', { slug: slug })
changeSearchParam('scrollTo', 'comments')
}
return ( return (
<section <section
class={clsx(styles.shoutCard, `${props.settings?.additionalClass || ''}`)} class={clsx(styles.shoutCard, `${props.settings?.additionalClass || ''}`)}
@ -172,7 +182,7 @@ export const ArticleCard = (props: ArticleCardProps) => {
</div> </div>
<div class={clsx(styles.shoutCardDetailsItem, styles.shoutCardComments)}> <div class={clsx(styles.shoutCardDetailsItem, styles.shoutCardComments)}>
<a href={`/${slug + '#comments'}`}> <a href="#" onClick={(event) => scrollToComments(event)}>
<Icon name="comment" class={clsx(styles.icon, styles.feedControlIcon)} /> <Icon name="comment" class={clsx(styles.icon, styles.feedControlIcon)} />
{stat?.commented || t('Add comment')} {stat?.commented || t('Add comment')}
</a> </a>

View File

@ -80,7 +80,8 @@ export const Header = (props: Props) => {
}) })
}) })
const scrollToComments = (value) => { const scrollToComments = (event, value) => {
event.preventDefault()
props.scrollToComments(value) props.scrollToComments(value)
} }
@ -110,7 +111,6 @@ export const Header = (props: Props) => {
<Show when={props.title}> <Show when={props.title}>
<div class={styles.articleHeader}>{props.title}</div> <div class={styles.articleHeader}>{props.title}</div>
</Show> </Show>
<ul <ul
class={clsx(styles.mainNavigation, 'col text-xl inline-flex')} class={clsx(styles.mainNavigation, 'col text-xl inline-flex')}
classList={{ fixed: fixed() }} classList={{ fixed: fixed() }}
@ -144,7 +144,7 @@ export const Header = (props: Props) => {
containerCssClass={styles.control} containerCssClass={styles.control}
trigger={<Icon name="share-outline" class={styles.icon} />} trigger={<Icon name="share-outline" class={styles.icon} />}
/> />
<div onClick={() => scrollToComments(true)} class={styles.control}> <div onClick={(event) => scrollToComments(event, true)} class={styles.control}>
<Icon name="comments-outline" class={styles.icon} /> <Icon name="comments-outline" class={styles.icon} />
</div> </div>
<a href={getPagePath(router, 'create')} class={styles.control}> <a href={getPagePath(router, 'create')} class={styles.control}>

View File

@ -35,24 +35,12 @@ const LOAD_MORE_PAGE_SIZE = 9
export const AuthorView = (props: AuthorProps) => { export const AuthorView = (props: AuthorProps) => {
const { t } = useLocalize() const { t } = useLocalize()
const { sortedArticles } = useArticlesStore({ const { sortedArticles } = useArticlesStore({ shouts: props.shouts })
shouts: props.shouts
})
const { authorEntities } = useAuthorsStore({ authors: [props.author] })
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
const author = createMemo(() => authorEntities()[props.authorSlug])
const [followers, setFollowers] = createSignal<Author[]>([])
onMount(async () => {
try {
const authorSubscribers = await apiClient.getAuthorFollowers({ slug: props.author.slug })
setFollowers(authorSubscribers)
} catch (error) {
console.log('[getAuthorSubscribers]', error)
}
})
const { searchParams, changeSearchParam } = useRouter<AuthorPageSearchParams>() const { searchParams, changeSearchParam } = useRouter<AuthorPageSearchParams>()
const { authorEntities } = useAuthorsStore({ authors: [props.author] })
const author = authorEntities()[props.authorSlug]
const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false)
const [followers, setFollowers] = createSignal<Author[]>([])
onMount(() => { onMount(() => {
if (!searchParams().by) { if (!searchParams().by) {
@ -63,7 +51,7 @@ export const AuthorView = (props: AuthorProps) => {
const loadMore = async () => { const loadMore = async () => {
saveScrollPosition() saveScrollPosition()
const { hasMore } = await loadShouts({ const { hasMore } = await loadShouts({
filters: { author: author().slug }, filters: { author: props.authorSlug },
limit: LOAD_MORE_PAGE_SIZE, limit: LOAD_MORE_PAGE_SIZE,
offset: sortedArticles().length offset: sortedArticles().length
}) })
@ -73,7 +61,7 @@ export const AuthorView = (props: AuthorProps) => {
onMount(async () => { onMount(async () => {
if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) { if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) {
loadMore() await loadMore()
} }
}) })
@ -91,6 +79,16 @@ export const AuthorView = (props: AuthorProps) => {
) )
const [commented, setCommented] = createSignal([]) const [commented, setCommented] = createSignal([])
onMount(async () => {
try {
const authorSubscribers = await apiClient.getAuthorFollowers({ slug: props.authorSlug })
setFollowers(authorSubscribers)
} catch (error) {
console.log('[getAuthorSubscribers]', error)
}
})
createEffect(async () => { createEffect(async () => {
if (searchParams().by === 'commented') { if (searchParams().by === 'commented') {
try { try {
@ -107,7 +105,7 @@ export const AuthorView = (props: AuthorProps) => {
return ( return (
<div class="author-page"> <div class="author-page">
<div class="wide-container"> <div class="wide-container">
<AuthorFull author={author()} /> <AuthorFull author={author} />
<div class="row group__controls"> <div class="row group__controls">
<div class="col-md-16"> <div class="col-md-16">
<ul class="view-switcher"> <ul class="view-switcher">
@ -197,9 +195,7 @@ export const AuthorView = (props: AuthorProps) => {
> >
<Match when={searchParams().by === 'about'}> <Match when={searchParams().by === 'about'}>
<div class="wide-container"> <div class="wide-container">
<Show when={author().bio}> <p>{author.bio}</p>
<p>{author().bio}</p>
</Show>
</div> </div>
</Match> </Match>
<Match when={searchParams().by === 'commented'}> <Match when={searchParams().by === 'commented'}>

View File

@ -2,7 +2,6 @@ import type { Accessor } from 'solid-js'
import { createRouter, createSearchParams } from '@nanostores/router' import { createRouter, createSearchParams } from '@nanostores/router'
import { isServer } from 'solid-js/web' import { isServer } from 'solid-js/web'
import { useStore } from '@nanostores/solid' import { useStore } from '@nanostores/solid'
import { getPageLoadManagerPromise } from '../utils/pageLoadManager'
export const ROUTES = { export const ROUTES = {
home: '/', home: '/',
@ -103,33 +102,9 @@ const handleClientRouteLinkClick = async (event) => {
top: 0, top: 0,
left: 0 left: 0
}) })
return return
} }
await getPageLoadManagerPromise()
const images = document.querySelectorAll('img')
let imagesLoaded = 0
const imageLoadEventHandler = () => {
imagesLoaded++
if (imagesLoaded === images.length) {
scrollToHash(url.hash) scrollToHash(url.hash)
images.forEach((image) => image.removeEventListener('load', imageLoadEventHandler))
images.forEach((image) => image.removeEventListener('error', imageLoadEventHandler))
}
}
images.forEach((image) => {
if (image.complete) {
imagesLoaded++
}
image.addEventListener('load', imageLoadEventHandler)
image.addEventListener('error', imageLoadEventHandler)
})
} }
export const initRouter = (pathname: string, search: Record<string, string>) => { export const initRouter = (pathname: string, search: Record<string, string>) => {

View File

@ -2,7 +2,6 @@ import type { FollowingEntity } from '../../graphql/types.gen'
import { apiClient } from '../../utils/apiClient' import { apiClient } from '../../utils/apiClient'
export const follow = async ({ what, slug }: { what: FollowingEntity; slug: string }) => { export const follow = async ({ what, slug }: { what: FollowingEntity; slug: string }) => {
console.log('!!! follow:')
await apiClient.follow({ what, slug }) await apiClient.follow({ what, slug })
} }
export const unfollow = async ({ what, slug }: { what: FollowingEntity; slug: string }) => { export const unfollow = async ({ what, slug }: { what: FollowingEntity; slug: string }) => {