From 829e523d366703caf6f2e4e367d4fc62be1d5580 Mon Sep 17 00:00:00 2001 From: Tony <454794+tonyrewin@users.noreply.github.com> Date: Fri, 2 Feb 2024 20:29:53 +0300 Subject: [PATCH] Hotfix/featured (#391) add: Shout.featured_at remove: Shout.visibility --- src/components/Article/FullArticle.tsx | 2 +- .../Feed/ArticleCard/ArticleCard.tsx | 8 +++----- .../Nav/SearchModal/SearchModal.tsx | 6 ------ src/components/Views/Edit.tsx | 8 ++++---- src/components/Views/Expo/Expo.tsx | 2 +- src/components/Views/Feed/Feed.tsx | 19 +++++++++++++------ src/components/Views/Home.tsx | 4 ++-- src/context/editor.tsx | 8 ++++---- src/context/following.tsx | 2 +- src/graphql/query/core/article-load.ts | 2 +- src/graphql/query/core/articles-load-by.ts | 1 + .../query/core/articles-load-drafts.ts | 1 + src/graphql/query/core/articles-load-feed.ts | 1 + .../query/core/articles-load-followed.ts | 1 + .../query/core/articles-load-random-top.ts | 1 + .../query/core/articles-load-random-topic.ts | 1 + .../query/core/articles-load-unrated.ts | 1 + src/pages/author.page.server.ts | 2 +- src/pages/author.page.tsx | 2 +- src/pages/feed.page.tsx | 2 +- src/pages/index.page.server.ts | 2 +- src/pages/index.page.tsx | 2 +- src/pages/topic.page.server.ts | 2 +- src/pages/topic.page.tsx | 2 +- src/stores/zine/articles.ts | 10 +++++----- src/stores/zine/layouts.ts | 2 +- src/utils/sortby.ts | 4 ++++ 27 files changed, 54 insertions(+), 44 deletions(-) diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index c7977bb5..cbf7281b 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -80,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 diff --git a/src/components/Feed/ArticleCard/ArticleCard.tsx b/src/components/Feed/ArticleCard/ArticleCard.tsx index d2c15c13..a14aa66c 100644 --- a/src/components/Feed/ArticleCard/ArticleCard.tsx +++ b/src/components/Feed/ArticleCard/ArticleCard.tsx @@ -94,11 +94,9 @@ export const ArticleCard = (props: ArticleCardProps) => { 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/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/context/editor.tsx b/src/context/editor.tsx index 41975d52..83992474 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/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)[],