diff --git a/astro.config.ts b/astro.config.ts index 472928ed..d0c2d3ec 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -43,34 +43,34 @@ const astroConfig: AstroUserConfig = { // eslint-disable-next-line sonarjs/cognitive-complexity manualChunks(id) { if (id.includes('node_modules')) { - let chunkid = 'vendor' - if (id.includes('solid')) { - chunkid = 'solid' - } - if (id.includes('acorn')) { - chunkid = 'acorn' - } - if (id.includes('simple-peer')) { - chunkid = 'simple-peer' - } - if (id.includes('prosemirror')) { - chunkid = 'prosemirror' - } - if (id.includes('markdown') || id.includes('mdurl')) { - chunkid = 'markdown' - } - if (id.includes('swiper')) { - chunkid = 'swiper' - } - if ( - id.includes('yjs') || - id.includes('y-prosemirror') || - id.includes('y-protocols') || - id.includes('y-webrtc') - ) { - chunkid = 'yjs' - } - return chunkid + // FIXME: doesn't work in production + // if (id.includes('solid')) { + // chunkid = 'solid' + // } + // if (id.includes('acorn')) { + // chunkid = 'acorn' + // } + // if (id.includes('simple-peer')) { + // chunkid = 'simple-peer' + // } + // if (id.includes('prosemirror')) { + // chunkid = 'prosemirror' + // } + // if (id.includes('markdown') || id.includes('mdurl')) { + // chunkid = 'markdown' + // } + // if (id.includes('swiper')) { + // chunkid = 'swiper' + // } + // if ( + // id.includes('yjs') || + // id.includes('y-prosemirror') || + // id.includes('y-protocols') || + // id.includes('y-webrtc') + // ) { + // chunkid = 'yjs' + // } + return 'vendor' } } }, diff --git a/public/icons/arrows-rotate.svg b/public/icons/arrows-rotate.svg new file mode 100644 index 00000000..4fc42bf3 --- /dev/null +++ b/public/icons/arrows-rotate.svg @@ -0,0 +1,5 @@ + + + diff --git a/src/components/Article/FullArticle.tsx b/src/components/Article/FullArticle.tsx index a499adc4..512cdac9 100644 --- a/src/components/Article/FullArticle.tsx +++ b/src/components/Article/FullArticle.tsx @@ -37,7 +37,6 @@ const formatDate = (date: Date) => { } export const FullArticle = (props: ArticleProps) => { - const body = createMemo(() => props.article.body.toString().trim()) const { session } = useAuthStore() onMount(() => { @@ -93,9 +92,16 @@ export const FullArticle = (props: ArticleProps) => {
-
- -
+ +
+ } + > + + +
+
diff --git a/src/components/Loading.module.scss b/src/components/Loading.module.scss new file mode 100644 index 00000000..de09f09b --- /dev/null +++ b/src/components/Loading.module.scss @@ -0,0 +1,27 @@ +.container { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} + +.icon { + animation-name: spin; + width: 64px; + height: 64px; + background-image: url(/icons/arrows-rotate.svg); + background-repeat: no-repeat; + animation-duration: 2s; + animation-iteration-count: infinite; + animation-timing-function: linear; +} diff --git a/src/components/Loading.tsx b/src/components/Loading.tsx new file mode 100644 index 00000000..252c0f52 --- /dev/null +++ b/src/components/Loading.tsx @@ -0,0 +1,9 @@ +import styles from './Loading.module.scss' + +export const Loading = () => { + return ( +
+
+
+ ) +} diff --git a/src/components/Nav/AuthModal.tsx b/src/components/Nav/AuthModal.tsx index 9f1729ba..e26ad6b2 100644 --- a/src/components/Nav/AuthModal.tsx +++ b/src/components/Nav/AuthModal.tsx @@ -9,6 +9,7 @@ import { useAuthStore, signIn, register } from '../../stores/auth' import { useValidator } from '../../utils/validators' import { baseUrl } from '../../graphql/publicGraphQLClient' import { ApiError } from '../../utils/apiClient' +import { handleClientRouteLinkClick } from '../../stores/router' type AuthMode = 'sign-in' | 'sign-up' | 'forget' | 'reset' | 'resend' | 'password' @@ -30,9 +31,16 @@ const titles = { // const isProperEmail = (email) => email && email.length > 5 && email.includes('@') && email.includes('.') +// 3rd party provider auth handler +const oauth = (provider: string): void => { + const popup = window.open(`${baseUrl}/oauth/${provider}`, provider, 'width=740, height=420') + popup?.focus() + hideModal() +} + // FIXME !!! // eslint-disable-next-line sonarjs/cognitive-complexity -export default (props: { code?: string; mode?: string }) => { +export default (props: { code?: string; mode?: AuthMode }) => { const { session } = useAuthStore() const [handshaking] = createSignal(false) const { getModal } = useModalStore() @@ -45,13 +53,6 @@ export default (props: { code?: string; mode?: string }) => { let passElement: HTMLInputElement | undefined let codeElement: HTMLInputElement | undefined - // 3rd party provider auth handler - const oauth = (provider: string): void => { - const popup = window.open(`${baseUrl}/oauth/${provider}`, provider, 'width=740, height=420') - popup?.focus() - hideModal() - } - // FIXME: restore logic // const usedEmails = {} // const checkEmailAsync = async (email: string) => { @@ -179,9 +180,15 @@ export default (props: { code?: string; mode?: string }) => { {t('New stories every day and even more!')}

- {t('By signing up you agree with our')} - - {' ' + t('terms of use')} + {t('By signing up you agree with our')}{' '} + { + hideModal() + handleClientRouteLinkClick(event) + }} + > + {t('terms of use')} , {t('personal data usage and email notifications')}.

diff --git a/src/components/Nav/Header.tsx b/src/components/Nav/Header.tsx index 0d0a08f2..802db235 100644 --- a/src/components/Nav/Header.tsx +++ b/src/components/Nav/Header.tsx @@ -116,7 +116,7 @@ export const Header = (props: Props) => { > {(r) => ( -
  • +
  • {r.name} diff --git a/src/components/Pages/AllAuthorsPage.tsx b/src/components/Pages/AllAuthorsPage.tsx index 78e95682..5a6e380c 100644 --- a/src/components/Pages/AllAuthorsPage.tsx +++ b/src/components/Pages/AllAuthorsPage.tsx @@ -3,7 +3,7 @@ import { AllAuthorsView } from '../Views/AllAuthors' import type { PageProps } from '../types' import { createSignal, onMount, Show } from 'solid-js' import { loadAllAuthors } from '../../stores/zine/authors' -import { t } from '../../utils/intl' +import { Loading } from '../Loading' export const AllAuthorsPage = (props: PageProps) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.allAuthors)) @@ -19,7 +19,7 @@ export const AllAuthorsPage = (props: PageProps) => { return ( - + }> diff --git a/src/components/Pages/AllTopicsPage.tsx b/src/components/Pages/AllTopicsPage.tsx index 2e371ba6..ae5e3230 100644 --- a/src/components/Pages/AllTopicsPage.tsx +++ b/src/components/Pages/AllTopicsPage.tsx @@ -2,8 +2,8 @@ import { MainLayout } from '../Layouts/MainLayout' import { AllTopicsView } from '../Views/AllTopics' import type { PageProps } from '../types' import { createSignal, onMount, Show } from 'solid-js' -import { t } from '../../utils/intl' import { loadAllTopics } from '../../stores/zine/topics' +import { Loading } from '../Loading' export const AllTopicsPage = (props: PageProps) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.allTopics)) @@ -19,7 +19,7 @@ export const AllTopicsPage = (props: PageProps) => { return ( - + }> diff --git a/src/components/Pages/ArticlePage.tsx b/src/components/Pages/ArticlePage.tsx index cc7fb918..357c5494 100644 --- a/src/components/Pages/ArticlePage.tsx +++ b/src/components/Pages/ArticlePage.tsx @@ -3,9 +3,9 @@ import { ArticleView } from '../Views/Article' import type { PageProps } from '../types' import { loadArticle, useArticlesStore } from '../../stores/zine/articles' import { createMemo, onMount, Show } from 'solid-js' -import { t } from '../../utils/intl' import type { Shout } from '../../graphql/types.gen' import { useRouter } from '../../stores/router' +import { Loading } from '../Loading' export const ArticlePage = (props: PageProps) => { const sortedArticles = props.article ? [props.article] : [] @@ -38,7 +38,7 @@ export const ArticlePage = (props: PageProps) => { return ( - + }> diff --git a/src/components/Pages/AuthorPage.tsx b/src/components/Pages/AuthorPage.tsx index aa825fd9..1d159773 100644 --- a/src/components/Pages/AuthorPage.tsx +++ b/src/components/Pages/AuthorPage.tsx @@ -4,8 +4,8 @@ import type { PageProps } from '../types' import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' import { loadArticlesForAuthors, resetSortedArticles } from '../../stores/zine/articles' import { useRouter } from '../../stores/router' -import { t } from '../../utils/intl' import { loadAuthor } from '../../stores/zine/authors' +import { Loading } from '../Loading' export const AuthorPage = (props: PageProps) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.authorArticles) && Boolean(props.author)) @@ -37,7 +37,7 @@ export const AuthorPage = (props: PageProps) => { return ( - + }> diff --git a/src/components/Pages/FeedPage.tsx b/src/components/Pages/FeedPage.tsx index 1e015e69..13c18136 100644 --- a/src/components/Pages/FeedPage.tsx +++ b/src/components/Pages/FeedPage.tsx @@ -3,7 +3,7 @@ import { FeedView } from '../Views/Feed' import type { PageProps } from '../types' import { createSignal, onCleanup, onMount, Show } from 'solid-js' import { loadRecentArticles, resetSortedArticles } from '../../stores/zine/articles' -import { t } from '../../utils/intl' +import { Loading } from '../Loading' export const FeedPage = (props: PageProps) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.feedArticles)) @@ -22,7 +22,7 @@ export const FeedPage = (props: PageProps) => { return ( - + }> diff --git a/src/components/Pages/HomePage.tsx b/src/components/Pages/HomePage.tsx index cbfb9d10..f8430e03 100644 --- a/src/components/Pages/HomePage.tsx +++ b/src/components/Pages/HomePage.tsx @@ -2,9 +2,9 @@ import { HomeView } from '../Views/Home' import { MainLayout } from '../Layouts/MainLayout' import type { PageProps } from '../types' import { createSignal, onCleanup, onMount, Show } from 'solid-js' -import { t } from '../../utils/intl' import { loadPublishedArticles, resetSortedArticles } from '../../stores/zine/articles' import { loadRandomTopics } from '../../stores/zine/topics' +import { Loading } from '../Loading' export const HomePage = (props: PageProps) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.homeArticles) && Boolean(props.randomTopics)) @@ -24,7 +24,7 @@ export const HomePage = (props: PageProps) => { return ( - + }> diff --git a/src/components/Pages/SearchPage.tsx b/src/components/Pages/SearchPage.tsx index b7668cf9..ff636018 100644 --- a/src/components/Pages/SearchPage.tsx +++ b/src/components/Pages/SearchPage.tsx @@ -3,8 +3,8 @@ import { SearchView } from '../Views/Search' import type { PageProps } from '../types' import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' import { loadSearchResults, resetSortedArticles } from '../../stores/zine/articles' -import { t } from '../../utils/intl' import { useRouter } from '../../stores/router' +import { Loading } from '../Loading' export const SearchPage = (props: PageProps) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.searchResults)) @@ -34,7 +34,7 @@ export const SearchPage = (props: PageProps) => { return ( - + }> diff --git a/src/components/Pages/TopicPage.tsx b/src/components/Pages/TopicPage.tsx index 198be0a0..a92e1d3f 100644 --- a/src/components/Pages/TopicPage.tsx +++ b/src/components/Pages/TopicPage.tsx @@ -4,8 +4,8 @@ import type { PageProps } from '../types' import { createMemo, createSignal, onCleanup, onMount, Show } from 'solid-js' import { loadArticlesForTopics, resetSortedArticles } from '../../stores/zine/articles' import { useRouter } from '../../stores/router' -import { t } from '../../utils/intl' import { loadTopic } from '../../stores/zine/topics' +import { Loading } from '../Loading' export const TopicPage = (props: PageProps) => { const [isLoaded, setIsLoaded] = createSignal(Boolean(props.authorArticles) && Boolean(props.author)) @@ -37,7 +37,7 @@ export const TopicPage = (props: PageProps) => { return ( - + }> diff --git a/src/components/Views/Author.tsx b/src/components/Views/Author.tsx index d4afed8b..9fb5fb51 100644 --- a/src/components/Views/Author.tsx +++ b/src/components/Views/Author.tsx @@ -9,8 +9,9 @@ import { useAuthorsStore } from '../../stores/zine/authors' import { useArticlesStore } from '../../stores/zine/articles' import '../../styles/Topic.scss' -// import { useTopicsStore } from '../../stores/zine/topics' +import { useTopicsStore } from '../../stores/zine/topics' import { useRouter } from '../../stores/router' +import Beside from '../Feed/Beside' // TODO: load reactions on client type AuthorProps = { @@ -30,6 +31,7 @@ export const AuthorView = (props: AuthorProps) => { sortedArticles: props.authorArticles }) const { authorEntities } = useAuthorsStore({ authors: [props.author] }) + const { topicsByAuthor } = useTopicsStore() const author = createMemo(() => authorEntities()[props.authorSlug]) const { getSearchParams, changeSearchParam } = useRouter() @@ -54,21 +56,22 @@ export const AuthorView = (props: AuthorProps) => { {t('Recent')}
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • + {/*TODO: server sort*/} + {/*
  • */} + {/* */} + {/*
  • */} + {/*
  • */} + {/* */} + {/*
  • */} + {/*
  • */} + {/* */} + {/*
  • */}
    @@ -83,14 +86,13 @@ export const AuthorView = (props: AuthorProps) => {

    {title()}

    0}> - {/*FIXME*/} - {/**/} + diff --git a/src/components/Views/Topic.tsx b/src/components/Views/Topic.tsx index 727c31f5..2f270c24 100644 --- a/src/components/Views/Topic.tsx +++ b/src/components/Views/Topic.tsx @@ -32,14 +32,6 @@ export const TopicView = (props: TopicProps) => { const topic = createMemo(() => topicEntities()[props.topicSlug]) - /* - const slug = createMemo(() => { - let slug = props?.slug - if (props?.slug.startsWith('@')) slug = slug.replace('@', '') - return slug - }) - */ - const title = createMemo(() => { const m = getSearchParams().by if (m === 'viewed') return t('Top viewed') @@ -60,21 +52,22 @@ export const TopicView = (props: TopicProps) => { {t('Recent')} -
  • - -
  • -
  • - -
  • -
  • - -
  • + {/*TODO: server sort*/} + {/*
  • */} + {/* */} + {/*
  • */} + {/*
  • */} + {/* */} + {/*
  • */} + {/*
  • */} + {/* */} + {/*
  • */}
    @@ -108,11 +101,11 @@ export const TopicView = (props: TopicProps) => { beside={sortedArticles()[6]} wrapper={'author'} /> - - - - - + + + + +
    diff --git a/src/graphql/query/authors-all.ts b/src/graphql/query/authors-all.ts index 7afef282..4570a611 100644 --- a/src/graphql/query/authors-all.ts +++ b/src/graphql/query/authors-all.ts @@ -11,7 +11,7 @@ export default gql` communities links createdAt - wasOnlineAt + lastSeen ratings { _id: rater rater diff --git a/src/styles/app.scss b/src/styles/app.scss index 276c43dd..9123f966 100644 --- a/src/styles/app.scss +++ b/src/styles/app.scss @@ -38,6 +38,7 @@ body { &.fixed { overflow: hidden; position: fixed; + width: 100%; } } @@ -534,6 +535,7 @@ astro-island { .main-content { flex: 1 100%; padding-top: 100px; + position: relative; transition: all 1s ease; }