From 28f52ba745053759514c3b335c6a2a47c0bb0ccc Mon Sep 17 00:00:00 2001 From: tonyrewin Date: Sun, 13 Nov 2022 12:25:31 +0300 Subject: [PATCH] refactoring-wpi --- astro.config.ts | 8 +- package.json | 2 +- pnpm-lock.yaml | 14 +- public/icons/audio.svg | 4 + public/icons/literature.svg | 1 + src/components/Pages/LayoutShoutsPage.tsx | 12 +- src/components/Views/FeedSettings.tsx | 2 +- src/components/Views/LayoutView.tsx | 39 ++-- src/graphql/query/layout-recent.ts | 40 ++++ src/graphql/query/layout-top-month.ts | 40 ++++ .../{articles-for-layout.ts => layout-top.ts} | 4 +- src/main.astro | 2 +- src/pages/404.astro | 6 +- src/pages/[...slug].astro | 6 +- src/pages/about/discussion-rules.astro | 6 +- src/pages/about/dogma.astro | 6 +- src/pages/about/guide.astro | 6 +- src/pages/about/help.astro | 6 +- src/pages/about/manifest.astro | 6 +- src/pages/about/partners.astro | 6 +- src/pages/about/principles.astro | 6 +- src/pages/about/projects.astro | 6 +- src/pages/about/terms-of-use.astro | 6 +- src/pages/about/thanks.astro | 6 +- src/pages/author/[slug]/index.astro | 6 +- src/pages/authors.astro | 6 +- src/pages/connect.astro | 6 +- src/pages/create.astro | 6 +- src/pages/expo/[...layout].astro | 6 +- src/pages/feed/index.astro | 6 +- src/pages/feed/settings.astro | 12 + src/pages/feed/settings.astro.bak | 13 -- src/pages/inbox.astro | 6 +- src/pages/index.astro | 6 +- src/pages/search.astro | 6 +- src/pages/topic/[slug].astro | 6 +- src/pages/topics.astro | 6 +- src/stores/zine/layouts.ts | 211 +++++------------- src/utils/apiClient.ts | 25 ++- 39 files changed, 283 insertions(+), 284 deletions(-) create mode 100644 public/icons/audio.svg create mode 100644 public/icons/literature.svg create mode 100644 src/graphql/query/layout-recent.ts create mode 100644 src/graphql/query/layout-top-month.ts rename src/graphql/query/{articles-for-layout.ts => layout-top.ts} (78%) create mode 100644 src/pages/feed/settings.astro delete mode 100644 src/pages/feed/settings.astro.bak diff --git a/astro.config.ts b/astro.config.ts index 60927b97..cf758735 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -2,7 +2,7 @@ import { defineConfig, AstroUserConfig } from 'astro/config' import vercel from '@astrojs/vercel/serverless' import solidJs from '@astrojs/solid-js' import type { CSSOptions } from 'vite' -import { generateScopedNameDefault } from 'postcss-modules/build/scoping' +import defaultGenerateScopedName from 'postcss-modules/build/generateScopedName' import { isDev } from './src/utils/config' import { visualizer } from 'rollup-plugin-visualizer' @@ -16,7 +16,7 @@ const getDevCssClassPrefix = (filename: string): string => { } const devGenerateScopedName = (name: string, filename: string, css: string) => - getDevCssClassPrefix(filename) + '_' + generateScopedNameDefault(name, filename, css) + getDevCssClassPrefix(filename) + '_' + defaultGenerateScopedName(name, filename, css) const css: CSSOptions = { preprocessorOptions: { @@ -25,7 +25,7 @@ const css: CSSOptions = { } }, modules: { - generateScopedName: isDev ? devGenerateScopedName : generateScopedNameDefault, + generateScopedName: isDev ? devGenerateScopedName : defaultGenerateScopedName, localsConvention: null } } @@ -67,7 +67,7 @@ const astroConfig: AstroUserConfig = { } */ }, - external: ['@aws-sdk/clients/s3'] + external: [] } }, css diff --git a/package.json b/package.json index 75b2477a..8c00866d 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "nanostores": "^0.7.0", "orderedmap": "^2.1.0", "postcss": "^8.4.19", - "postcss-modules": "^6.0.0", + "postcss-modules": "5.0.0", "prettier": "^2.7.1", "prettier-eslint": "^15.0.1", "prosemirror-commands": "^1.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d299a3f6..d0514ee4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,7 +63,7 @@ specifiers: nanostores: ^0.7.0 orderedmap: ^2.1.0 postcss: ^8.4.19 - postcss-modules: ^6.0.0 + postcss-modules: 5.0.0 prettier: ^2.7.1 prettier-eslint: ^15.0.1 prosemirror-commands: ^1.3.1 @@ -173,7 +173,7 @@ devDependencies: nanostores: 0.7.0 orderedmap: 2.1.0 postcss: 8.4.19 - postcss-modules: 6.0.0_postcss@8.4.19 + postcss-modules: 5.0.0_postcss@8.4.19 prettier: 2.7.1 prettier-eslint: 15.0.1 prosemirror-commands: 1.3.1 @@ -6087,6 +6087,10 @@ packages: safer-buffer: 2.1.2 dev: true + /icss-replace-symbols/1.1.0: + resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} + dev: true + /icss-utils/5.1.0_postcss@8.4.19: resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} @@ -8577,13 +8581,13 @@ packages: postcss: 8.4.19 dev: true - /postcss-modules/6.0.0_postcss@8.4.19: - resolution: {integrity: sha512-7DGfnlyi/ju82BRzTIjWS5C4Tafmzl3R79YP/PASiocj+aa6yYphHhhKUOEoXQToId5rgyFgJ88+ccOUydjBXQ==} + /postcss-modules/5.0.0_postcss@8.4.19: + resolution: {integrity: sha512-rGvpTDOM3//3Ysn3Xtvhzaj8ab984wKCpP02TEF559tLbUjNay3RQDpPxb7BREmfBtJm3/1WbQOZ7fSXwYLZ/w==} peerDependencies: postcss: ^8.0.0 dependencies: generic-names: 4.0.0 - icss-utils: 5.1.0_postcss@8.4.19 + icss-replace-symbols: 1.1.0 lodash.camelcase: 4.3.0 postcss: 8.4.19 postcss-modules-extract-imports: 3.0.0_postcss@8.4.19 diff --git a/public/icons/audio.svg b/public/icons/audio.svg new file mode 100644 index 00000000..87621cb9 --- /dev/null +++ b/public/icons/audio.svg @@ -0,0 +1,4 @@ + + + diff --git a/public/icons/literature.svg b/public/icons/literature.svg new file mode 100644 index 00000000..ccf3f9d0 --- /dev/null +++ b/public/icons/literature.svg @@ -0,0 +1 @@ + diff --git a/src/components/Pages/LayoutShoutsPage.tsx b/src/components/Pages/LayoutShoutsPage.tsx index f85128ee..fca3481a 100644 --- a/src/components/Pages/LayoutShoutsPage.tsx +++ b/src/components/Pages/LayoutShoutsPage.tsx @@ -1,10 +1,10 @@ import { PageWrap } from '../Wraps/PageWrap' -import { LayoutView } from '../Views/LayoutView' +import { LayoutType, LayoutView } from '../Views/LayoutView' import type { PageProps } from '../types' import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' import { resetSortedArticles } from '../../stores/zine/articles' import { useRouter } from '../../stores/router' -import { loadLayoutShouts } from '../../stores/zine/layouts' +import { loadRecentLayoutShouts } from '../../stores/zine/layouts' import { Loading } from '../Loading' const PER_PAGE = 50 @@ -12,7 +12,7 @@ const PER_PAGE = 50 export const LayoutShoutsPage = (props: PageProps) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.shouts)) - const layout = createMemo(() => { + const layout = createMemo(() => { const { page: getPage } = useRouter() const page = getPage() @@ -21,7 +21,7 @@ export const LayoutShoutsPage = (props: PageProps) => { throw new Error('ts guard') } - return page.params.layout + return page.params.layout as LayoutType }) onMount(async () => { @@ -29,7 +29,7 @@ export const LayoutShoutsPage = (props: PageProps) => { return } - await loadLayoutShouts({ layout: layout(), amount: PER_PAGE, offset: 0 }) + await loadRecentLayoutShouts({ layout: layout(), amount: PER_PAGE, offset: 0 }) setIsLoaded(true) }) @@ -39,7 +39,7 @@ export const LayoutShoutsPage = (props: PageProps) => { return ( }> - + ) diff --git a/src/components/Views/FeedSettings.tsx b/src/components/Views/FeedSettings.tsx index bbd31b72..b25c165d 100644 --- a/src/components/Views/FeedSettings.tsx +++ b/src/components/Views/FeedSettings.tsx @@ -6,7 +6,7 @@ import { handleClientRouteLinkClick } from '../../stores/router' // by: '' | 'topics' | 'authors' | 'reacted' // } -export const FeedSettingsView = () => { +export const FeedSettingsView = (_props) => { return (

{t('Feed settings')}

diff --git a/src/components/Views/LayoutView.tsx b/src/components/Views/LayoutView.tsx index 389772de..6838459a 100644 --- a/src/components/Views/LayoutView.tsx +++ b/src/components/Views/LayoutView.tsx @@ -5,21 +5,18 @@ import { Row2 } from '../Feed/Row2' import { Beside } from '../Feed/Beside' import styles from '../../styles/Topic.module.scss' import { t } from '../../utils/intl' -import { useRouter } from '../../stores/router' -import { useArticlesStore } from '../../stores/zine/articles' +import { useLayoutsStore } from '../../stores/zine/layouts' import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll' import { splitToPages } from '../../utils/splitToPages' import { clsx } from 'clsx' import Slider from '../Feed/Slider' import { Row1 } from '../Feed/Row1' -import { loadLayoutShouts } from '../../stores/zine/layouts' +import { loadRecentLayoutShouts } from '../../stores/zine/layouts' -type LayoutPageSearchParams = { - layout: 'audio' | 'video' | 'image' | 'literature' -} +export type LayoutType = 'article' | 'audio' | 'video' | 'image' | 'literature' interface LayoutProps { - layout: string + layout: LayoutType shouts: Shout[] } @@ -27,34 +24,30 @@ export const PRERENDERED_ARTICLES_COUNT = 21 const LOAD_MORE_PAGE_SIZE = 9 // Row3 + Row3 + Row3 export const LayoutView = (props: LayoutProps) => { - const { searchParams, changeSearchParam } = useRouter() - + const layout = createMemo(() => props.layout) const [isLoadMoreButtonVisible, setIsLoadMoreButtonVisible] = createSignal(false) - - const { sortedArticles } = useArticlesStore({ sortedArticles: props.shouts }) - const layout = createMemo(() => props.layout) - - const loadMoreLayout = async (kind: string) => { + const { sortedLayoutShouts } = useLayoutsStore(layout(), props.shouts) + const sortedArticles = createMemo(() => sortedLayoutShouts().get(layout())) + const loadMoreLayout = async (kind: LayoutType) => { saveScrollPosition() - const { hasMore } = await loadLayoutShouts({ + const { hasMore } = await loadRecentLayoutShouts({ layout: kind, amount: LOAD_MORE_PAGE_SIZE, offset: sortedArticles().length }) setIsLoadMoreButtonVisible(hasMore) - restoreScrollPosition() } onMount(async () => { if (sortedArticles().length === PRERENDERED_ARTICLES_COUNT) { - loadMoreLayout(searchParams().layout) + loadMoreLayout(layout()) } }) const title = createMemo(() => { - const l = searchParams().layout + const l = layout() if (l === 'audio') return t('Audio') if (l === 'video') return t('Video') if (l === 'image') return t('Artworks') @@ -70,16 +63,16 @@ export const LayoutView = (props: LayoutProps) => {
@@ -129,7 +122,7 @@ export const LayoutView = (props: LayoutProps) => {

-

diff --git a/src/graphql/query/layout-recent.ts b/src/graphql/query/layout-recent.ts new file mode 100644 index 00000000..91b84957 --- /dev/null +++ b/src/graphql/query/layout-recent.ts @@ -0,0 +1,40 @@ +import { gql } from '@urql/core' + +export default gql` + query RecentShoutsForLayout($layout: String!, $amount: Int, $offset: Int) { + recentLayoutShouts(layout: $layout, amount: $amount, offset: $offset) { + _id: slug + title + subtitle + layout + slug + cover + # community + mainTopic + topics { + title + body + slug + stat { + _id: shouts + shouts + authors + followers + } + } + authors { + _id: slug + name + slug + userpic + } + createdAt + publishedAt + stat { + _id: viewed + viewed + reacted + } + } + } +` diff --git a/src/graphql/query/layout-top-month.ts b/src/graphql/query/layout-top-month.ts new file mode 100644 index 00000000..2e3100ff --- /dev/null +++ b/src/graphql/query/layout-top-month.ts @@ -0,0 +1,40 @@ +import { gql } from '@urql/core' + +export default gql` + query TopMonthShoutsForLayout($layout: String!, $amount: Int, $offset: Int) { + topMonthLayoutShouts(layout: $layout, amount: $amount, offset: $offset) { + _id: slug + title + subtitle + layout + slug + cover + # community + mainTopic + topics { + title + body + slug + stat { + _id: shouts + shouts + authors + followers + } + } + authors { + _id: slug + name + slug + userpic + } + createdAt + publishedAt + stat { + _id: viewed + viewed + reacted + } + } + } +` diff --git a/src/graphql/query/articles-for-layout.ts b/src/graphql/query/layout-top.ts similarity index 78% rename from src/graphql/query/articles-for-layout.ts rename to src/graphql/query/layout-top.ts index f5ea3c13..34da1292 100644 --- a/src/graphql/query/articles-for-layout.ts +++ b/src/graphql/query/layout-top.ts @@ -1,8 +1,8 @@ import { gql } from '@urql/core' export default gql` - query ShoutsForLayoutQuery($amount: Int, $offset: Int, $layout: String) { - shoutsByLayout(amount: $amount, offset: $offset, layout: $layout) { + query TopShoutsForLayout($layout: String!, $amount: Int, $offset: Int) { + topLayoutShouts(layout: $layout, amount: $amount, offset: $offset) { _id: slug title subtitle diff --git a/src/main.astro b/src/main.astro index a39f8e4f..63b790e0 100644 --- a/src/main.astro +++ b/src/main.astro @@ -1,5 +1,5 @@ --- -import { setLocale } from './stores/ui'; +import { setLocale } from './stores/ui' import './styles/app.scss' import { t } from './utils/intl' diff --git a/src/pages/404.astro b/src/pages/404.astro index 06d1839a..3fcad65b 100644 --- a/src/pages/404.astro +++ b/src/pages/404.astro @@ -1,5 +1,5 @@ --- -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { Root } from '../components/Root' import { initRouter } from '../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/[...slug].astro b/src/pages/[...slug].astro index d757e077..49621307 100644 --- a/src/pages/[...slug].astro +++ b/src/pages/[...slug].astro @@ -1,6 +1,6 @@ --- import { Root } from '../components/Root' -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { apiClient } from '../utils/apiClient' import { initRouter } from '../stores/router' @@ -20,6 +20,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/discussion-rules.astro b/src/pages/about/discussion-rules.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/discussion-rules.astro +++ b/src/pages/about/discussion-rules.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/dogma.astro b/src/pages/about/dogma.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/dogma.astro +++ b/src/pages/about/dogma.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/guide.astro b/src/pages/about/guide.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/guide.astro +++ b/src/pages/about/guide.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/help.astro b/src/pages/about/help.astro index 60a199ec..891e0539 100644 --- a/src/pages/about/help.astro +++ b/src/pages/about/help.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -13,6 +13,6 @@ Astro.response.headers.set( Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/manifest.astro b/src/pages/about/manifest.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/manifest.astro +++ b/src/pages/about/manifest.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/partners.astro b/src/pages/about/partners.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/partners.astro +++ b/src/pages/about/partners.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/principles.astro b/src/pages/about/principles.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/principles.astro +++ b/src/pages/about/principles.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/projects.astro b/src/pages/about/projects.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/projects.astro +++ b/src/pages/about/projects.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/terms-of-use.astro b/src/pages/about/terms-of-use.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/terms-of-use.astro +++ b/src/pages/about/terms-of-use.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/about/thanks.astro b/src/pages/about/thanks.astro index 19521c3e..c7354d08 100644 --- a/src/pages/about/thanks.astro +++ b/src/pages/about/thanks.astro @@ -1,5 +1,5 @@ --- -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { Root } from '../../components/Root' import { initRouter } from '../../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/author/[slug]/index.astro b/src/pages/author/[slug]/index.astro index d38cba66..f43de677 100644 --- a/src/pages/author/[slug]/index.astro +++ b/src/pages/author/[slug]/index.astro @@ -1,6 +1,6 @@ --- import { Root } from '../../../components/Root' -import Zine from '../../../main.astro' +import Prerendered from '../../../main.astro' import { apiClient } from '../../../utils/apiClient' import { initRouter } from '../../../stores/router' import { PRERENDERED_ARTICLES_COUNT } from '../../../components/Views/Author' @@ -15,6 +15,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/authors.astro b/src/pages/authors.astro index edf5a128..7483a581 100644 --- a/src/pages/authors.astro +++ b/src/pages/authors.astro @@ -1,6 +1,6 @@ --- import { Root } from '../components/Root' -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { apiClient } from '../utils/apiClient' import { initRouter } from '../stores/router' @@ -10,6 +10,6 @@ const { pathname, search } = Astro.url initRouter(pathname, search) --- - + - + diff --git a/src/pages/connect.astro b/src/pages/connect.astro index 06d1839a..3fcad65b 100644 --- a/src/pages/connect.astro +++ b/src/pages/connect.astro @@ -1,5 +1,5 @@ --- -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { Root } from '../components/Root' import { initRouter } from '../stores/router' @@ -9,6 +9,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/create.astro b/src/pages/create.astro index f77ecc20..b4ffc2d1 100644 --- a/src/pages/create.astro +++ b/src/pages/create.astro @@ -1,6 +1,6 @@ --- import { Root } from '../components/Root' -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { initRouter } from '../stores/router' const { pathname, search } = Astro.url @@ -8,6 +8,6 @@ initRouter(pathname, search) --- - + - + diff --git a/src/pages/expo/[...layout].astro b/src/pages/expo/[...layout].astro index 5b515ce7..aa2e67dd 100644 --- a/src/pages/expo/[...layout].astro +++ b/src/pages/expo/[...layout].astro @@ -1,6 +1,6 @@ --- import { Root } from '../../components/Root' -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { apiClient } from '../../utils/apiClient' import { initRouter } from '../../stores/router' @@ -17,7 +17,7 @@ const { pathname, search } = Astro.url initRouter(pathname, search) --- - + - + diff --git a/src/pages/feed/index.astro b/src/pages/feed/index.astro index 139a36eb..9ab066a5 100644 --- a/src/pages/feed/index.astro +++ b/src/pages/feed/index.astro @@ -1,12 +1,12 @@ --- import { Root } from '../../components/Root' -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { initRouter } from '../../stores/router' const { pathname, search } = Astro.url initRouter(pathname, search) --- - + - + diff --git a/src/pages/feed/settings.astro b/src/pages/feed/settings.astro new file mode 100644 index 00000000..98564ae8 --- /dev/null +++ b/src/pages/feed/settings.astro @@ -0,0 +1,12 @@ +--- +import Prerendered from '../../main.astro' +import { Root } from '../../components/Root' +import { initRouter } from '../../stores/router' + +const { pathname, search } = Astro.url +initRouter(pathname, search) +--- + + + + diff --git a/src/pages/feed/settings.astro.bak b/src/pages/feed/settings.astro.bak deleted file mode 100644 index 98b18912..00000000 --- a/src/pages/feed/settings.astro.bak +++ /dev/null @@ -1,13 +0,0 @@ ---- -import Zine from '../../main.astro' -import { FeedSettings } from '../../components/Views/FeedSettings' - -import { initRouter } from '../../stores/router' - -const { pathname, search } = Astro.url -initRouter(pathname, search) ---- - - - - diff --git a/src/pages/inbox.astro b/src/pages/inbox.astro index fd139a17..eeb95b82 100644 --- a/src/pages/inbox.astro +++ b/src/pages/inbox.astro @@ -1,5 +1,5 @@ --- -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { Root } from '../components/Root' import { apiClient } from '../utils/apiClient' import { initRouter } from '../stores/router' @@ -10,6 +10,6 @@ const { pathname, search } = Astro.url initRouter(pathname, search) --- - + - + diff --git a/src/pages/index.astro b/src/pages/index.astro index 8ebb57cd..d83c2c50 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,5 +1,5 @@ --- -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { Root } from '../components/Root' import { apiClient } from '../utils/apiClient' import { initRouter } from '../stores/router' @@ -14,7 +14,7 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/search.astro b/src/pages/search.astro index b9379170..4ce22e04 100644 --- a/src/pages/search.astro +++ b/src/pages/search.astro @@ -1,6 +1,6 @@ --- import { Root } from '../components/Root' -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { apiClient } from '../utils/apiClient' import { initRouter } from '../stores/router' @@ -12,6 +12,6 @@ const { pathname, search } = Astro.url initRouter(pathname, search) --- - + - + diff --git a/src/pages/topic/[slug].astro b/src/pages/topic/[slug].astro index 07d46c3a..13ba2318 100644 --- a/src/pages/topic/[slug].astro +++ b/src/pages/topic/[slug].astro @@ -1,6 +1,6 @@ --- import { Root } from '../../components/Root' -import Zine from '../../main.astro' +import Prerendered from '../../main.astro' import { apiClient } from '../../utils/apiClient' import { PRERENDERED_ARTICLES_COUNT } from '../../components/Views/Topic' @@ -16,6 +16,6 @@ initRouter(pathname, search) Astro.response.headers.set('Cache-Control', 's-maxage=1, stale-while-revalidate') --- - + - + diff --git a/src/pages/topics.astro b/src/pages/topics.astro index fe7967d0..9b115358 100644 --- a/src/pages/topics.astro +++ b/src/pages/topics.astro @@ -1,6 +1,6 @@ --- import { Root } from '../components/Root' -import Zine from '../main.astro' +import Prerendered from '../main.astro' import { apiClient } from '../utils/apiClient' import { initRouter } from '../stores/router' @@ -10,7 +10,7 @@ const { pathname, search } = Astro.url initRouter(pathname, search) --- - + - + diff --git a/src/stores/zine/layouts.ts b/src/stores/zine/layouts.ts index b19f1a33..1a0f2f17 100644 --- a/src/stores/zine/layouts.ts +++ b/src/stores/zine/layouts.ts @@ -1,196 +1,99 @@ -import type { Author, Shout, ShoutInput, Topic } from '../../graphql/types.gen' +import type { Shout } from '../../graphql/types.gen' import { apiClient } from '../../utils/apiClient' -import { addAuthorsByTopic } from './authors' -import { addTopicsByAuthor } from './topics' -import { byStat } from '../../utils/sortby' +import { useArticlesStore } from './articles' import { createSignal } from 'solid-js' -import { createLazyMemo } from '@solid-primitives/memo' +import type { LayoutType } from '../../components/Views/LayoutView' +import { byCreated } from '../../utils/sortby' -const [sortedArticles, setSortedArticles] = createSignal([]) -const [articleEntities, setArticleEntities] = createSignal<{ [articleSlug: string]: Shout }>({}) +const [sortedLayoutShouts, setSortedLayoutShouts] = createSignal>(new Map()) -const [topArticles, setTopArticles] = createSignal([]) -const [topMonthArticles, setTopMonthArticles] = createSignal([]) - -const articlesByLayout = createLazyMemo(() => { - return Object.values(articleEntities()).reduce((acc, article) => { - if (!acc[article.layout]) { - acc[article.layout] = [] - } - - acc[article.layout].push(article) - - return acc - }, {} as { [layout: string]: Shout[] }) -}) - -const topViewedArticles = createLazyMemo(() => { - const result = Object.values(articleEntities()) - result.sort(byStat('viewed')) - return result -}) - -const topCommentedArticles = createLazyMemo(() => { - const result = Object.values(articleEntities()) - result.sort(byStat('commented')) - return result -}) - -// eslint-disable-next-line sonarjs/cognitive-complexity -const addArticles = (...args: Shout[][]) => { - const allArticles = args.flatMap((articles) => articles || []) - - const newArticleEntities = allArticles.reduce((acc, article) => { - acc[article.slug] = article - return acc - }, {} as { [articleSLug: string]: Shout }) - - setArticleEntities((prevArticleEntities) => { - return { - ...prevArticleEntities, - ...newArticleEntities +const addLayoutShouts = (layout: LayoutType, shouts: Shout[]) => { + setSortedLayoutShouts((prevSorted: Map) => { + const siblings = prevSorted.get(layout) + if (Boolean(siblings)) { + const uniqued = Array.from(new Set([...siblings, ...shouts])) + prevSorted.set(layout, uniqued) } + return prevSorted }) - - const authorsByTopic = allArticles.reduce((acc, article) => { - const { authors, topics } = article - - topics.forEach((topic) => { - if (!acc[topic.slug]) { - acc[topic.slug] = [] - } - - authors.forEach((author) => { - if (!acc[topic.slug].some((a) => a.slug === author.slug)) { - acc[topic.slug].push(author) - } - }) - }) - - return acc - }, {} as { [topicSlug: string]: Author[] }) - - addAuthorsByTopic(authorsByTopic) - - const topicsByAuthor = allArticles.reduce((acc, article) => { - const { authors, topics } = article - - authors.forEach((author) => { - if (!acc[author.slug]) { - acc[author.slug] = [] - } - - topics.forEach((topic) => { - if (!acc[author.slug].some((t) => t.slug === topic.slug)) { - acc[author.slug].push(topic) - } - }) - }) - - return acc - }, {} as { [authorSlug: string]: Topic[] }) - - addTopicsByAuthor(topicsByAuthor) } -const addSortedArticles = (articles: Shout[]) => { - setSortedArticles((prevSortedArticles) => [...prevSortedArticles, ...articles]) +export const resetSortedLayoutShouts = () => { + setSortedLayoutShouts(new Map()) } -export const loadLayoutShouts = async ({ +export const loadRecentLayoutShouts = async ({ layout, amount, offset }: { - layout: string + layout: LayoutType amount: number offset?: number }): Promise<{ hasMore: boolean }> => { - const layoutShouts: Shout[] = await apiClient.getLayoutShouts({ layout, amount, offset }) - const hasMore = layoutShouts.length > amount - - if (hasMore) { - layoutShouts.splice(-1) - } - - addArticles(layoutShouts) - addSortedArticles(layoutShouts) - + const layoutShouts: Shout[] = await apiClient.getRecentLayoutShouts({ layout, amount, offset }) + const hasMore = layoutShouts.length < amount + if (hasMore) layoutShouts.splice(-1) + const sortedArticles = layoutShouts.sort(byCreated) + const { articlesByLayout } = useArticlesStore({ sortedArticles }) + addLayoutShouts(layout, articlesByLayout()[layout]) return { hasMore } } -export const resetSortedArticles = () => { - setSortedArticles([]) +export const loadTopMonthLayoutShouts = async ( + layout: LayoutType, + amount: number, + offset: number +): Promise<{ hasMore: boolean }> => { + const shouts = await apiClient.getTopMonthLayoutShouts({ layout }) + const hasMore = shouts.length < amount + if (hasMore) shouts.splice(-1) + addLayoutShouts(layout, shouts) + return { hasMore } } -export const loadTopMonthArticles = async (): Promise => { - const articles = await apiClient.getTopMonthArticles() - addArticles(articles) - setTopMonthArticles(articles) -} - -export const loadTopArticles = async (): Promise => { - const articles = await apiClient.getTopArticles() - addArticles(articles) - setTopArticles(articles) +export const loadTopLayoutShouts = async ( + layout: LayoutType, + amount, + offset +): Promise<{ hasMore: boolean }> => { + const shouts = await apiClient.getTopLayoutShouts({ layout }) + const hasMore = shouts.length < amount + if (hasMore) shouts.splice(-1) + addLayoutShouts(layout, shouts) + return { hasMore } } export const loadSearchResults = async ({ + layout, query, limit, offset }: { + layout: LayoutType query: string limit?: number offset?: number }): Promise => { - const newArticles = await apiClient.getSearchResults({ query, limit, offset }) - addArticles(newArticles) - addSortedArticles(newArticles) -} - -export const incrementView = async ({ articleSlug }: { articleSlug: string }): Promise => { - await apiClient.incrementView({ articleSlug }) -} - -export const loadArticle = async ({ slug }: { slug: string }): Promise => { - const article = await apiClient.getArticle({ slug }) - - if (!article) { - throw new Error(`Can't load article, slug: "${slug}"`) - } - - addArticles([article]) -} - -export const createArticle = async ({ article }: { article: ShoutInput }) => { - try { - await apiClient.createArticle({ article }) - } catch (error) { - console.error(error) - } + const newLayoutShouts = await apiClient.getSearchResults({ layout, query, limit, offset }) + addLayoutShouts(layout, newLayoutShouts) } type InitialState = { - sortedArticles?: Shout[] - topRatedArticles?: Shout[] - topRatedMonthArticles?: Shout[] + sortedLayoutShouts?: Shout[] + topRatedLayoutShouts?: Shout[] + topRatedMonthLayoutShouts?: Shout[] } -export const useArticlesStore = (initialState: InitialState = {}) => { - addArticles([...(initialState.sortedArticles || [])]) - - if (initialState.sortedArticles) { - setSortedArticles([...initialState.sortedArticles]) - } +export const useLayoutsStore = (layout: LayoutType, initialData: Shout[]) => { + addLayoutShouts(layout, initialData || []) return { - articleEntities, - sortedArticles, - topArticles, - topMonthArticles, - topViewedArticles, - topCommentedArticles, - articlesByLayout + addLayoutShouts, + sortedLayoutShouts, + loadSearchResults, + loadRecentLayoutShouts, + loadTopMonthLayoutShouts, + loadTopLayoutShouts } } diff --git a/src/utils/apiClient.ts b/src/utils/apiClient.ts index 7213cf58..2c41fc67 100644 --- a/src/utils/apiClient.ts +++ b/src/utils/apiClient.ts @@ -29,7 +29,10 @@ import authorsBySlugs from '../graphql/query/authors-by-slugs' import incrementView from '../graphql/mutation/increment-view' import createArticle from '../graphql/mutation/article-create' import myChats from '../graphql/query/my-chats' -import getLayout from '../graphql/query/articles-for-layout' +import getRecentByLayout from '../graphql/query/layout-recent' +import getTopByLayout from '../graphql/query/layout-top' +import getTopMonthByLayout from '../graphql/query/layout-top-month' +import type { LayoutType } from '../components/Views/LayoutView' const FEED_SIZE = 50 @@ -147,11 +150,13 @@ export const apiClient = { getSearchResults: async ({ query, limit = FEED_SIZE, - offset = 0 + offset = 0, + layout = 'literature' }: { query: string limit: number offset?: number + layout?: LayoutType }): Promise => { const response = await publicGraphQLClient .query(searchResults, { @@ -336,8 +341,18 @@ export const apiClient = { const resp = await privateGraphQLClient.query(myChats, payload).toPromise() return resp.data.myChats }, - getLayoutShouts: async ({ layout = 'article', amount = 50, offset = 0 }) => { - const resp = await publicGraphQLClient.query(getLayout, { amount, offset, layout }).toPromise() - return resp.data.shoutsByLayout + getRecentLayoutShouts: async ({ layout = 'article', amount = 50, offset = 0 }) => { + const resp = await publicGraphQLClient.query(getRecentByLayout, { amount, offset, layout }).toPromise() + return resp.data.recentLayoutShouts + }, + getTopLayoutShouts: async ({ layout = 'article', amount = 50, offset = 0 }) => { + const resp = await publicGraphQLClient.query(getTopByLayout, { amount, offset, layout }).toPromise() + return resp.data.topLayoutShouts + }, + getTopMonthLayoutShouts: async ({ layout = 'article', amount = 50, offset = 0 }) => { + const resp = await publicGraphQLClient + .query(getTopMonthByLayout, { amount, offset, layout }) + .toPromise() + return resp.data.topMonthLayoutShouts } }