diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index c04615a0..cbf7281b 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -29,6 +29,7 @@ import { VideoPlayer } from '../_shared/VideoPlayer' import { AuthorBadge } from '../Author/AuthorBadge' import { CardTopic } from '../Feed/CardTopic' import { FeedArticlePopup } from '../Feed/FeedArticlePopup' +import { Modal } from '../Nav/Modal' import { TableOfContents } from '../TableOfContents' import { AudioHeader } from './AudioHeader' @@ -79,7 +80,7 @@ export const FullArticle = (props: Props) => { actions: { requireAuthentication }, } = useSession() - const formattedDate = createMemo(() => formatDate(new Date(props.article.created_at * 1000))) + const formattedDate = createMemo(() => formatDate(new Date(props.article.published_at * 1000))) const mainTopic = createMemo(() => { const main_topic_slug = props.article.topics.length > 0 ? props.article.main_topic : null @@ -308,6 +309,8 @@ export const FullArticle = (props: Props) => { const aspectRatio = width / height iframe.style.width = `${containerWidth}px` iframe.style.height = `${Math.round(containerWidth / aspectRatio) + 40}px` + } else { + iframe.style.height = `${containerWidth}px` } }) } @@ -618,7 +621,9 @@ export const FullArticle = (props: Props) => { - + + + { const mainTopicTitle = mainTopicSlug && lang() === 'en' ? mainTopicSlug.replace(/-/, ' ') : mainTopic?.title || '' - const formattedDate = createMemo(() => { - let r = '' - if (props.article.created_at) r = formatDate(new Date(props.article.created_at * 1000)) - return r - }) + const formattedDate = createMemo(() => + props.article.published_at ? formatDate(new Date(props.article.published_at * 1000)) : '', + ) const { title, subtitle } = getTitleAndSubtitle(props.article) diff --git a/src/components/Nav/AuthModal/AuthModal.module.scss b/src/components/Nav/AuthModal/AuthModal.module.scss index d9b7daaa..f589c677 100644 --- a/src/components/Nav/AuthModal/AuthModal.module.scss +++ b/src/components/Nav/AuthModal/AuthModal.module.scss @@ -188,11 +188,10 @@ line-height: 16px; margin-top: 0.3em; - /* Red/500 */ - color: #d00820; + color: var(--danger-color); a { - color: #d00820; + color: var(--danger-color); border-color: #d00820; &:hover { diff --git a/src/components/Nav/AuthModal/ForgotPasswordForm.tsx b/src/components/Nav/AuthModal/ForgotPasswordForm.tsx index 4e147d92..493bd64a 100644 --- a/src/components/Nav/AuthModal/ForgotPasswordForm.tsx +++ b/src/components/Nav/AuthModal/ForgotPasswordForm.tsx @@ -1,11 +1,11 @@ import type { AuthModalSearchParams } from './types' +import { ApiResponse, ForgotPasswordResponse } from '@authorizerdev/authorizer-js' import { clsx } from 'clsx' import { createSignal, JSX, Show } from 'solid-js' import { useLocalize } from '../../../context/localize' import { useSession } from '../../../context/session' -// import { ApiError } from '../../../graphql/error' import { useRouter } from '../../../stores/router' import { validateEmail } from '../../../utils/validateEmail' @@ -29,16 +29,14 @@ export const ForgotPasswordForm = () => { const { actions: { forgotPassword }, } = useSession() - const [submitError, setSubmitError] = createSignal('') const [isSubmitting, setIsSubmitting] = createSignal(false) const [validationErrors, setValidationErrors] = createSignal({}) - const [isUserNotFount, setIsUserNotFound] = createSignal(false) + const [isUserNotFound, setIsUserNotFound] = createSignal(false) const authFormRef: { current: HTMLFormElement } = { current: null } const [message, setMessage] = createSignal('') const handleSubmit = async (event: Event) => { event.preventDefault() - setSubmitError('') setIsUserNotFound(false) const newValidationErrors: ValidationErrors = {} @@ -66,15 +64,8 @@ export const ForgotPasswordForm = () => { redirect_uri: window.location.origin, }) console.debug('[ForgotPasswordForm] authorizer response:', data) - setMessage(data.message) - - console.warn(errors) - if (errors.some((e) => e.cause === 'user_not_found')) { + if (errors && errors.some((error) => error.message.includes('bad user credentials'))) { setIsUserNotFound(true) - return - } else { - const errorText = errors.map((e) => e.message).join(' ') // FIXME - setSubmitError(errorText) } } catch (error) { console.error(error) @@ -111,37 +102,27 @@ export const ForgotPasswordForm = () => { /> {t('Email')} + + + {t("We can't find you, check email or")}{' '} + + changeSearchParams({ + mode: 'login', + }) + } + > + {t('register')} + + + + + {validationErrors().email} + - - - - {submitError()} - - - - - - - {t("We can't find you, check email or")}{' '} - { - event.preventDefault() - changeSearchParams({ - mode: 'register', - }) - }} - > - {t('register')} - - - {validationErrors().email} - - - - - + { setIsSubmitting(true) try { - await signIn({ email: email(), password: password() }) - + const { errors } = await signIn({ email: email(), password: password() }) + if (errors?.length > 0) { + if (errors.some((error) => error.message.includes('bad user credentials'))) { + setValidationErrors((prev) => ({ + ...prev, + password: t('Something went wrong, check email and password'), + })) + } else { + setSubmitError(t('Error')) + } + return + } hideModal() - showSnackbar({ body: t('Welcome!') }) } catch (error) { console.error(error) - if (error instanceof ApiError) { - if (error.code === 'email_not_confirmed') { - setSubmitError(t('Please, confirm email')) - setIsEmailNotConfirmed(true) - - return - } - if (error.code === 'user_not_found') { - setSubmitError(t('Something went wrong, check email and password')) - - return - } - } setSubmitError(error.message) } finally { setIsSubmitting(false) @@ -170,6 +166,11 @@ export const LoginForm = () => { handlePasswordInput(value)} /> + + + {validationErrors().password} + + diff --git a/src/components/Nav/AuthModal/RegisterForm.tsx b/src/components/Nav/AuthModal/RegisterForm.tsx index 24d1477d..f5706525 100644 --- a/src/components/Nav/AuthModal/RegisterForm.tsx +++ b/src/components/Nav/AuthModal/RegisterForm.tsx @@ -6,7 +6,6 @@ import { Show, createSignal } from 'solid-js' import { useLocalize } from '../../../context/localize' import { useSession } from '../../../context/session' -// import { ApiError } from '../../../graphql/error' import { checkEmail, useEmailChecks } from '../../../stores/emailChecks' import { useRouter } from '../../../stores/router' import { hideModal } from '../../../stores/ui' @@ -113,34 +112,30 @@ export const RegisterForm = () => { confirm_password: password(), redirect_uri: window.location.origin, } - await signUp(opts) - + const { errors } = await signUp(opts) + if (errors && errors.some((error) => error.message.includes('has already signed up'))) { + setValidationErrors((prev) => ({ + ...prev, + email: ( + <> + {t('User with this email already exists')},{' '} + + changeSearchParams({ + mode: 'login', + }) + } + > + {t('sign in')} + + > + ), + })) + } setIsSuccess(true) } catch (error) { console.error(error) - if (error) { - if (error.message.includes('has already signed up')) { - setValidationErrors((errors) => ({ - ...errors, - email: ( - <> - {t('User with this email already exists')},{' '} - - changeSearchParams({ - mode: 'login', - }) - } - > - {t('sign in')} - - > - ), - })) - } - console.error(error) - } } finally { setIsSubmitting(false) } diff --git a/src/components/Nav/SearchModal/SearchModal.tsx b/src/components/Nav/SearchModal/SearchModal.tsx index 5e3ddaca..9fdb03df 100644 --- a/src/components/Nav/SearchModal/SearchModal.tsx +++ b/src/components/Nav/SearchModal/SearchModal.tsx @@ -29,13 +29,7 @@ const getSearchCoincidences = ({ str, intersection }: { str: string; intersectio const prepareSearchResults = (list: Shout[], searchValue: string) => list.sort(byScore()).map((article, index) => ({ ...article, - body: article.body, - cover: article.cover, - created_at: article.created_at, id: index, - slug: article.slug, - authors: article.authors, - topics: article.topics, title: article.title ? getSearchCoincidences({ str: article.title, diff --git a/src/components/Views/Edit.tsx b/src/components/Views/Edit.tsx index 4110971f..e3779df8 100644 --- a/src/components/Views/Edit.tsx +++ b/src/components/Views/Edit.tsx @@ -5,7 +5,7 @@ import { createStore } from 'solid-js/store' import { ShoutForm, useEditorContext } from '../../context/editor' import { useLocalize } from '../../context/localize' -import { ShoutVisibility, type Shout, type Topic } from '../../graphql/schema/core.gen' +import { type Shout, type Topic } from '../../graphql/schema/core.gen' import { LayoutType, MediaItem } from '../../pages/types' import { useRouter } from '../../stores/router' import { clone } from '../../utils/clone' @@ -182,10 +182,10 @@ export const EditView = (props: Props) => { const hasChanges = !deepEqual(form, prevForm) if (hasChanges) { setSaving(true) - if (props.shout?.visibility === ShoutVisibility.Authors) { - await saveDraft(form) - } else { + if (props.shout?.published_at) { saveDraftToLocalStorage(form) + } else { + await saveDraft(form) } setPrevForm(clone(form)) setTimeout(() => { diff --git a/src/components/Views/Expo/Expo.tsx b/src/components/Views/Expo/Expo.tsx index 604cc50b..acd67f83 100644 --- a/src/components/Views/Expo/Expo.tsx +++ b/src/components/Views/Expo/Expo.tsx @@ -45,7 +45,7 @@ export const Expo = (props: Props) => { }) const getLoadShoutsFilters = (additionalFilters: LoadShoutsFilters = {}): LoadShoutsFilters => { - const filters = { published: true, ...additionalFilters } + const filters = { featured: true, ...additionalFilters } if (!filters.layouts) filters.layouts = [] if (props.layout) { diff --git a/src/components/Views/Feed/Feed.tsx b/src/components/Views/Feed/Feed.tsx index 5bd73f71..07c46e50 100644 --- a/src/components/Views/Feed/Feed.tsx +++ b/src/components/Views/Feed/Feed.tsx @@ -1,5 +1,3 @@ -import type { Author, LoadShoutsOptions, Reaction, Shout } from '../../../graphql/schema/core.gen' - import { getPagePath } from '@nanostores/router' import { Meta } from '@solidjs/meta' import { clsx } from 'clsx' @@ -9,6 +7,12 @@ import { useLocalize } from '../../../context/localize' import { useReactions } from '../../../context/reactions' import { useSession } from '../../../context/session' import { apiClient } from '../../../graphql/client/core' +import { + type Author, + type LoadShoutsOptions, + type Reaction, + type Shout, +} from '../../../graphql/schema/core.gen' import { router, useRouter } from '../../../stores/router' import { showModal } from '../../../stores/ui' import { useArticlesStore, resetSortedArticles } from '../../../stores/zine/articles' @@ -35,7 +39,7 @@ export const FEED_PAGE_SIZE = 20 const UNRATED_ARTICLES_COUNT = 5 type FeedPeriod = 'week' | 'month' | 'year' -type VisibilityMode = 'all' | 'community' | 'public' +type VisibilityMode = 'all' | 'community' | 'featured' type PeriodItem = { value: FeedPeriod @@ -96,7 +100,7 @@ export const FeedView = (props: Props) => { const { t } = useLocalize() const monthPeriod: PeriodItem = { value: 'month', title: t('This month') } - const visibilityAll = { value: 'public', title: t('All') } + const visibilityAll = { value: 'featured', title: t('All') } const periods: PeriodItem[] = [ { value: 'week', title: t('This week') }, @@ -106,7 +110,7 @@ export const FeedView = (props: Props) => { const visibilities: VisibilityItem[] = [ { value: 'community', title: t('All') }, - { value: 'public', title: t('Published') }, + { value: 'featured', title: t('Published') }, ] const { page, searchParams, changeSearchParams } = useRouter() @@ -190,7 +194,10 @@ export const FeedView = (props: Props) => { if (visibilityMode === 'all') { options.filters = { ...options.filters } } else if (visibilityMode) { - options.filters = { ...options.filters, published: visibilityMode === 'public' } + options.filters = { + ...options.filters, + featured: visibilityMode === 'featured', + } } if (searchParams().by && searchParams().by !== 'publish_date') { diff --git a/src/components/Views/Home.tsx b/src/components/Views/Home.tsx index dfcb0d6b..ac1d3b2b 100644 --- a/src/components/Views/Home.tsx +++ b/src/components/Views/Home.tsx @@ -60,7 +60,7 @@ export const HomeView = (props: Props) => { loadTopMonthArticles() if (sortedArticles().length < PRERENDERED_ARTICLES_COUNT + CLIENT_LOAD_ARTICLES_COUNT) { const { hasMore } = await loadShouts({ - filters: { published: true }, + filters: { featured: true }, limit: CLIENT_LOAD_ARTICLES_COUNT, offset: sortedArticles().length, }) @@ -80,7 +80,7 @@ export const HomeView = (props: Props) => { saveScrollPosition() const { hasMore } = await loadShouts({ - filters: { published: true }, + filters: { featured: true }, limit: LOAD_MORE_PAGE_SIZE, offset: sortedArticles().length, }) diff --git a/src/components/_shared/InviteMembers/InviteMembers.tsx b/src/components/_shared/InviteMembers/InviteMembers.tsx index 87979810..a1563d0e 100644 --- a/src/components/_shared/InviteMembers/InviteMembers.tsx +++ b/src/components/_shared/InviteMembers/InviteMembers.tsx @@ -111,7 +111,7 @@ export const InviteMembers = (props: Props) => { } return ( - + <> {props.title || t('Invite collaborators')} @@ -182,6 +182,6 @@ export const InviteMembers = (props: Props) => { /> - + > ) } diff --git a/src/context/editor.tsx b/src/context/editor.tsx index 6d7c550b..02958b2d 100644 --- a/src/context/editor.tsx +++ b/src/context/editor.tsx @@ -6,7 +6,7 @@ import { Accessor, createContext, createSignal, useContext } from 'solid-js' import { createStore, SetStoreFunction } from 'solid-js/store' import { apiClient } from '../graphql/client/core' -import { ShoutVisibility, Topic, TopicInput } from '../graphql/schema/core.gen' +import { Topic, TopicInput } from '../graphql/schema/core.gen' import { router, useRouter } from '../stores/router' import { slugify } from '../utils/slugify' @@ -158,10 +158,10 @@ export const EditorProvider = (props: { children: JSX.Element }) => { const shout = await updateShout(formToSave, { publish: false }) removeDraftFromLocalStorage(formToSave.shoutId) - if (shout.visibility === ShoutVisibility.Authors) { - openPage(router, 'drafts') - } else { + if (shout.published_at) { openPage(router, 'article', { slug: shout.slug }) + } else { + openPage(router, 'drafts') } } catch (error) { console.error('[saveShout]', error) diff --git a/src/context/following.tsx b/src/context/following.tsx index c826740b..9b87b140 100644 --- a/src/context/following.tsx +++ b/src/context/following.tsx @@ -1,4 +1,4 @@ -import { createEffect, createSignal, createContext, Accessor, useContext, JSX, onMount } from 'solid-js' +import { createEffect, createSignal, createContext, Accessor, useContext, JSX } from 'solid-js' import { createStore } from 'solid-js/store' import { apiClient } from '../graphql/client/core' diff --git a/src/context/session.tsx b/src/context/session.tsx index c2b8b8f7..61ab704e 100644 --- a/src/context/session.tsx +++ b/src/context/session.tsx @@ -59,8 +59,8 @@ export type SessionContextType = { callback: (() => Promise) | (() => void), modalSource: AuthModalSource, ) => void - signUp: (params: SignupInput) => Promise - signIn: (params: LoginInput) => Promise + signUp: (params: SignupInput) => Promise<{ data: AuthToken; errors: Error[] }> + signIn: (params: LoginInput) => Promise<{ data: AuthToken; errors: Error[] }> signOut: () => Promise oauth: (provider: string) => Promise forgotPassword: ( @@ -273,16 +273,20 @@ export const SessionProvider = (props: { }) // authorizer api proxy methods + const authenticate = async (authFunction, params) => { + const resp = await authFunction(params) + console.debug('[context.session] authenticate:', resp) + if (resp?.data && !resp.errors) { + setSession(resp.data) + } + return { data: resp?.data, errors: resp?.errors } + } const signUp = async (params: SignupInput) => { - const authResult: ApiResponse = await authorizer().signup(params) - if (authResult?.data) setSession(authResult.data) - if (authResult?.errors) console.error(authResult.errors) + return authenticate(authorizer().signup, params) } const signIn = async (params: LoginInput) => { - const authResult: ApiResponse = await authorizer().login(params) - if (authResult?.data) setSession(authResult.data) - if (authResult?.errors) console.error(authResult.errors) + return authenticate(authorizer().login, params) } const signOut = async () => { diff --git a/src/graphql/client/chat.ts b/src/graphql/client/chat.ts index 2f637fe3..42c5be97 100644 --- a/src/graphql/client/chat.ts +++ b/src/graphql/client/chat.ts @@ -28,7 +28,6 @@ export const inboxClient = { loadChats: async (options: QueryLoad_ChatsArgs): Promise => { const resp = await inboxClient.private.query(myChats, options).toPromise() - console.log('!!! resp:', resp) return resp.data.load_chats.chats }, diff --git a/src/graphql/query/core/article-load.ts b/src/graphql/query/core/article-load.ts index 066b7fb5..f6965dcb 100644 --- a/src/graphql/query/core/article-load.ts +++ b/src/graphql/query/core/article-load.ts @@ -7,7 +7,6 @@ export default gql` title lead description - visibility subtitle slug layout @@ -45,6 +44,7 @@ export default gql` created_at updated_at published_at + featured_at stat { viewed diff --git a/src/graphql/query/core/articles-load-by.ts b/src/graphql/query/core/articles-load-by.ts index a6a117ee..1dd14296 100644 --- a/src/graphql/query/core/articles-load-by.ts +++ b/src/graphql/query/core/articles-load-by.ts @@ -34,6 +34,7 @@ export default gql` } created_at published_at + featured_at stat { viewed diff --git a/src/graphql/query/core/articles-load-drafts.ts b/src/graphql/query/core/articles-load-drafts.ts index 7b2e4c01..af33cf9a 100644 --- a/src/graphql/query/core/articles-load-drafts.ts +++ b/src/graphql/query/core/articles-load-drafts.ts @@ -32,6 +32,7 @@ export default gql` } created_at published_at + featured_at stat { viewed diff --git a/src/graphql/query/core/articles-load-feed.ts b/src/graphql/query/core/articles-load-feed.ts index bc48b7cd..fe827259 100644 --- a/src/graphql/query/core/articles-load-feed.ts +++ b/src/graphql/query/core/articles-load-feed.ts @@ -26,6 +26,7 @@ export default gql` } created_at published_at + featured_at stat { viewed diff --git a/src/graphql/query/core/articles-load-followed.ts b/src/graphql/query/core/articles-load-followed.ts index 2eb0f193..07a18468 100644 --- a/src/graphql/query/core/articles-load-followed.ts +++ b/src/graphql/query/core/articles-load-followed.ts @@ -29,6 +29,7 @@ export default gql` } created_at published_at + featured_at stat { viewed diff --git a/src/graphql/query/core/articles-load-random-top.ts b/src/graphql/query/core/articles-load-random-top.ts index f7f9b8cc..3edbc8bd 100644 --- a/src/graphql/query/core/articles-load-random-top.ts +++ b/src/graphql/query/core/articles-load-random-top.ts @@ -34,6 +34,7 @@ export default gql` } created_at published_at + featured_at stat { viewed diff --git a/src/graphql/query/core/articles-load-random-topic.ts b/src/graphql/query/core/articles-load-random-topic.ts index e0b820c3..099895a6 100644 --- a/src/graphql/query/core/articles-load-random-topic.ts +++ b/src/graphql/query/core/articles-load-random-topic.ts @@ -50,6 +50,7 @@ export default gql` } created_at published_at + featured_at stat { viewed diff --git a/src/graphql/query/core/articles-load-unrated.ts b/src/graphql/query/core/articles-load-unrated.ts index fd0a2823..a305c8f0 100644 --- a/src/graphql/query/core/articles-load-unrated.ts +++ b/src/graphql/query/core/articles-load-unrated.ts @@ -35,6 +35,7 @@ export default gql` } created_at published_at + featured_at stat { viewed diff --git a/src/pages/author.page.server.ts b/src/pages/author.page.server.ts index 41cd96ed..405298e2 100644 --- a/src/pages/author.page.server.ts +++ b/src/pages/author.page.server.ts @@ -16,7 +16,7 @@ export const onBeforeRender = async (pageContext: PageContext) => { } const authorShouts = await apiClient.getShouts({ - filters: { author: slug, published: false }, + filters: { author: slug, featured: false }, limit: PRERENDERED_ARTICLES_COUNT, }) const pageProps: PageProps = { author, authorShouts, seo: { title: author.name } } diff --git a/src/pages/author.page.tsx b/src/pages/author.page.tsx index d2adfb2e..6b06342b 100644 --- a/src/pages/author.page.tsx +++ b/src/pages/author.page.tsx @@ -21,7 +21,7 @@ export const AuthorPage = (props: PageProps) => { const preload = () => { return Promise.all([ loadShouts({ - filters: { author: slug(), published: false }, + filters: { author: slug(), featured: false }, limit: PRERENDERED_ARTICLES_COUNT, }), loadAuthor({ slug: slug() }), diff --git a/src/pages/feed.page.tsx b/src/pages/feed.page.tsx index aa29649c..5e654b26 100644 --- a/src/pages/feed.page.tsx +++ b/src/pages/feed.page.tsx @@ -13,7 +13,7 @@ const handleFeedLoadShouts = (options: LoadShoutsOptions) => { return loadShouts({ ...options, filters: { - published: false, + featured: false, ...options.filters, }, }) diff --git a/src/pages/index.page.server.ts b/src/pages/index.page.server.ts index 19c909f9..c523d1f5 100644 --- a/src/pages/index.page.server.ts +++ b/src/pages/index.page.server.ts @@ -6,7 +6,7 @@ import { apiClient } from '../graphql/client/core' export const onBeforeRender = async (_pageContext: PageContext) => { const homeShouts = await apiClient.getShouts({ - filters: { published: true }, + filters: { featured: true }, limit: PRERENDERED_ARTICLES_COUNT, }) diff --git a/src/pages/index.page.tsx b/src/pages/index.page.tsx index f1f08406..feceee68 100644 --- a/src/pages/index.page.tsx +++ b/src/pages/index.page.tsx @@ -20,7 +20,7 @@ export const HomePage = (props: PageProps) => { } await Promise.all([ - loadShouts({ filters: { published: true }, limit: PRERENDERED_ARTICLES_COUNT }), + loadShouts({ filters: { featured: true }, limit: PRERENDERED_ARTICLES_COUNT }), loadRandomTopics({ amount: RANDOM_TOPICS_COUNT }), ]) diff --git a/src/pages/topic.page.server.ts b/src/pages/topic.page.server.ts index a14c24cf..7b73745d 100644 --- a/src/pages/topic.page.server.ts +++ b/src/pages/topic.page.server.ts @@ -16,7 +16,7 @@ export const onBeforeRender = async (pageContext: PageContext) => { } const topicShouts = await apiClient.getShouts({ - filters: { topic: topic.slug, published: true }, + filters: { topic: topic.slug, featured: true }, limit: PRERENDERED_ARTICLES_COUNT, }) diff --git a/src/pages/topic.page.tsx b/src/pages/topic.page.tsx index 641fb210..3e1204b1 100644 --- a/src/pages/topic.page.tsx +++ b/src/pages/topic.page.tsx @@ -21,7 +21,7 @@ export const TopicPage = (props: PageProps) => { const preload = () => Promise.all([ loadShouts({ - filters: { topic: slug(), published: true }, + filters: { topic: slug(), featured: true }, limit: PRERENDERED_ARTICLES_COUNT, offset: 0, }), diff --git a/src/stores/zine/articles.ts b/src/stores/zine/articles.ts index f7cb9ae6..c126000d 100644 --- a/src/stores/zine/articles.ts +++ b/src/stores/zine/articles.ts @@ -131,7 +131,7 @@ export const loadShouts = async ( ): Promise<{ hasMore: boolean; newShouts: Shout[] }> => { options.limit += 1 const newShouts = await apiClient.getShouts(options) - const hasMore = newShouts ?? newShouts.length === options.limit + 1 + const hasMore = newShouts?.length === options.limit + 1 if (hasMore) { newShouts.splice(-1) @@ -148,7 +148,7 @@ export const loadMyFeed = async ( ): Promise<{ hasMore: boolean; newShouts: Shout[] }> => { options.limit += 1 const newShouts = await apiClient.getMyFeed(options) - const hasMore = newShouts ?? newShouts.length === options.limit + 1 + const hasMore = newShouts?.length === options.limit + 1 if (hasMore) { newShouts.splice(-1) @@ -165,7 +165,7 @@ export const loadShoutsSearch = async ( ): Promise<{ hasMore: boolean; newShouts: Shout[] }> => { options.limit += 1 const newShouts = await apiClient.getShoutsSearch(options) - const hasMore = newShouts ?? newShouts.length === options.limit + 1 + const hasMore = newShouts?.length === options.limit + 1 if (hasMore) { newShouts.splice(-1) @@ -193,7 +193,7 @@ export const loadTopMonthArticles = async (): Promise => { const after = Math.floor(daysago / 1000) const options: LoadShoutsOptions = { filters: { - published: true, + featured: true, after, }, order_by: 'likes_stat', @@ -208,7 +208,7 @@ const TOP_ARTICLES_COUNT = 10 export const loadTopArticles = async (): Promise => { const options: LoadShoutsOptions = { - filters: { published: true }, + filters: { featured: true }, order_by: 'likes_stat', limit: TOP_ARTICLES_COUNT, } diff --git a/src/stores/zine/layouts.ts b/src/stores/zine/layouts.ts index f31d1e84..218f0255 100644 --- a/src/stores/zine/layouts.ts +++ b/src/stores/zine/layouts.ts @@ -29,7 +29,7 @@ export const resetSortedLayoutShouts = () => { export const loadLayoutShoutsBy = async (options: LoadShoutsOptions): Promise<{ hasMore: boolean }> => { options.limit += 1 const newLayoutShouts = await apiClient.getShouts(options) - const hasMore = newLayoutShouts.length === options.limit + 1 + const hasMore = newLayoutShouts?.length === options.limit + 1 if (hasMore) { newLayoutShouts.splice(-1) diff --git a/src/utils/sortby.ts b/src/utils/sortby.ts index f6d88df6..d8906991 100644 --- a/src/utils/sortby.ts +++ b/src/utils/sortby.ts @@ -6,6 +6,10 @@ export const byCreated = (a: Shout | Reaction, b: Shout | Reaction) => { return a?.created_at - b?.created_at } +export const byPublished = (a: Shout, b: Shout) => { + return a.published_at - b.published_at +} + export const byLength = ( a: (Shout | Reaction | Topic | Author)[], b: (Shout | Reaction | Topic | Author)[],