From bc52dcc6536f790ab23025a4441f27ea0001a216 Mon Sep 17 00:00:00 2001 From: Untone Date: Tue, 25 Jun 2024 14:25:20 +0300 Subject: [PATCH] tsc-ok --- src/app.tsx | 12 +- src/components/App.tsx | 142 ---------- .../Editor/TopicSelect/TopicSelect.scss | 9 - src/context/ui.tsx | 14 +- src/graphql/client/chat.ts | 74 ------ src/graphql/client/core.ts | 244 ------------------ src/graphql/client/notifier.ts | 32 --- src/graphql/createGraphQLClient.ts | 20 -- src/graphql/error.ts | 16 -- tests/basic-routes.spec.ts | 2 +- tsconfig.json | 3 +- 11 files changed, 21 insertions(+), 547 deletions(-) delete mode 100644 src/components/App.tsx delete mode 100644 src/components/Editor/TopicSelect/TopicSelect.scss delete mode 100644 src/graphql/client/chat.ts delete mode 100644 src/graphql/client/core.ts delete mode 100644 src/graphql/client/notifier.ts delete mode 100644 src/graphql/createGraphQLClient.ts delete mode 100644 src/graphql/error.ts diff --git a/src/app.tsx b/src/app.tsx index 26600d5f..b0fbc956 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,10 +1,11 @@ -import { MetaProvider } from '@solidjs/meta' +import { Meta, MetaProvider } from '@solidjs/meta' import { Router } from '@solidjs/router' import { FileRoutes } from '@solidjs/start/router' import { type JSX, Suspense } from 'solid-js' import { Loading } from './components/_shared/Loading' import { PageLayout } from './components/_shared/PageLayout' +import { EditorProvider } from './context/editor' import { FeedProvider } from './context/feed' import { GraphQLClientProvider } from './context/graphql' import { LocalizeProvider, useLocalize } from './context/localize' @@ -22,10 +23,13 @@ export const Providers = (props: { children?: JSX.Element }) => { + - }> - {props.children} - + + }> + {props.children} + + diff --git a/src/components/App.tsx b/src/components/App.tsx deleted file mode 100644 index 00b5dfa9..00000000 --- a/src/components/App.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import type { PageProps, RootSearchParams } from '../pages/types' - -import { Component, createEffect, createMemo } from 'solid-js' -import { Dynamic } from 'solid-js/web' -import { Meta, MetaProvider } from '../context/meta' - -import { ConfirmProvider } from '../context/confirm' -import { ConnectProvider } from '../context/connect' -import { EditorProvider } from '../context/editor' -import { FollowingProvider } from '../context/following' -import { InboxProvider } from '../context/inbox' -import { LocalizeProvider } from '../context/localize' -import { MediaQueryProvider } from '../context/mediaQuery' -import { NotificationsProvider } from '../context/notifications' -import { SeenProvider } from '../context/seen' -import { SessionProvider } from '../context/session' -import { SnackbarProvider } from '../context/snackbar' -import { TopicsProvider } from '../context/topics' -import { DiscussionRulesPage } from '../pages/about/discussionRules.page' -import { DogmaPage } from '../pages/about/dogma.page' -import { GuidePage } from '../pages/about/guide.page' -import { HelpPage } from '../pages/about/help.page' -import { ManifestPage } from '../pages/about/manifest.page' -import { PartnersPage } from '../pages/about/partners.page' -import { PrinciplesPage } from '../pages/about/principles.page' -import { ProjectsPage } from '../pages/about/projects.page' -import { TermsOfUsePage } from '../pages/about/termsOfUse.page' -import { ThanksPage } from '../pages/about/thanks.page' -import { AllAuthorsPage } from '../pages/allAuthors.page' -import { AllTopicsPage } from '../pages/allTopics.page' -import { ArticlePage } from '../pages/article.page' -import { AuthorPage } from '../pages/author.page' -import { ConnectPage } from '../pages/connect.page' -import { CreatePage } from '../pages/create.page' -import { DraftsPage } from '../pages/drafts.page' -import { EditPage } from '../pages/edit.page' -import { ExpoPage } from '../pages/expo/expo.page' -import { FeedPage } from '../pages/feed.page' -import { FourOuFourPage } from '../pages/fourOuFour.page' -import { InboxPage } from '../pages/inbox.page' -import { HomePage } from '../pages/index.page' -import { ProfileSecurityPage } from '../pages/profile/profileSecurity.page' -import { ProfileSettingsPage } from '../pages/profile/profileSettings.page' -import { ProfileSubscriptionsPage } from '../pages/profile/profileSubscriptions.page' -import { SearchPage } from '../pages/search.page' -import { TopicPage } from '../pages/topic.page' -import { ROUTES, useRouter } from '../stores/router' -import { MODALS, showModal } from '../stores/ui' - -const pagesMap: Record> = { - author: AuthorPage, - authorComments: AuthorPage, - authorAbout: AuthorPage, - inbox: InboxPage, - expo: ExpoPage, - connect: ConnectPage, - create: CreatePage, - edit: EditPage, - editSettings: EditPage, - drafts: DraftsPage, - home: HomePage, - topics: AllTopicsPage, - topic: TopicPage, - authors: AllAuthorsPage, - feed: FeedPage, - feedMy: FeedPage, - feedNotifications: FeedPage, - feedBookmarks: FeedPage, - feedCollaborations: FeedPage, - feedDiscussions: FeedPage, - article: ArticlePage, - search: SearchPage, - discussionRules: DiscussionRulesPage, - dogma: DogmaPage, - guide: GuidePage, - help: HelpPage, - manifest: ManifestPage, - projects: ProjectsPage, - partners: PartnersPage, - principles: PrinciplesPage, - termsOfUse: TermsOfUsePage, - thanks: ThanksPage, - profileSettings: ProfileSettingsPage, - profileSecurity: ProfileSecurityPage, - profileSubscriptions: ProfileSubscriptionsPage, - fourOuFour: FourOuFourPage, -} - -type Props = PageProps & { is404: boolean } - -export const App = (props: Props) => { - const { page, searchParams } = useRouter() - const is404 = createMemo(() => props.is404) - - createEffect(() => { - const modal = MODALS[searchParams().m] - if (modal) { - showModal(modal) - } - }) - - const pageComponent = createMemo(() => { - const result = pagesMap[page()?.route || 'home'] - - if (is404() || !result || page()?.path === '/404') { - return FourOuFourPage - } - - return result - }) - - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) -} diff --git a/src/components/Editor/TopicSelect/TopicSelect.scss b/src/components/Editor/TopicSelect/TopicSelect.scss deleted file mode 100644 index 831880a5..00000000 --- a/src/components/Editor/TopicSelect/TopicSelect.scss +++ /dev/null @@ -1,9 +0,0 @@ -.TopicSelect .solid-select-list { - background: #fff; - position: relative; - z-index: 13; -} - -.TopicSelect .solid-select-option[data-disabled='true'] { - display: none; -} diff --git a/src/context/ui.tsx b/src/context/ui.tsx index f115efeb..4e8a82b6 100644 --- a/src/context/ui.tsx +++ b/src/context/ui.tsx @@ -183,13 +183,19 @@ export const UIProvider = (props: { children: JSX.Element }) => { setModal('') } + const [searchParams] = useSearchParams() + createEffect( on( - modal, - (m) => { - if (m) showModal(m) + [modal, () => searchParams?.m || ''], + ([m1, m2]) => { + const m = m1 || m2 || '' + setModal((_) => m as ModalType) + if (m) { + showModal(m as ModalType) + } }, - {}, + { defer: true }, ), ) diff --git a/src/graphql/client/chat.ts b/src/graphql/client/chat.ts deleted file mode 100644 index c00fd705..00000000 --- a/src/graphql/client/chat.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { chatApiUrl } from '../../utils/config' -// inbox -import { createGraphQLClient } from '../createGraphQLClient' -import createChat from '../mutation/chat/chat-create' -import deleteChat from '../mutation/chat/chat-delete' -import markAsRead from '../mutation/chat/chat-mark-as-read' -import createChatMessage from '../mutation/chat/chat-message-create' -import deleteChatMessage from '../mutation/chat/chat-message-delete' -import updateChatMessage from '../mutation/chat/chat-message-update' -import updateChat from '../mutation/chat/chat-update' -import chatMessagesLoadBy from '../query/chat/chat-messages-load-by' -import myChats from '../query/chat/chats-load' -import { - Chat, - MutationCreate_ChatArgs, - MutationCreate_MessageArgs, - MutationDelete_ChatArgs, - MutationDelete_MessageArgs, - MutationMark_As_ReadArgs, - MutationUpdate_ChatArgs, - MutationUpdate_MessageArgs, - QueryLoad_ChatsArgs, - QueryLoad_Messages_ByArgs, -} from '../schema/chat.gen' - -export const inboxClient = { - private: null, - connect: (token: string) => (inboxClient.private = createGraphQLClient(chatApiUrl, token)), - - loadChats: async (options: QueryLoad_ChatsArgs): Promise => { - const resp = await inboxClient.private.query(myChats, options).toPromise() - return resp.data.load_chats.chats - }, - - createChat: async (options: MutationCreate_ChatArgs) => { - const resp = await inboxClient.private.mutation(createChat, options).toPromise() - return resp.data.create_chat - }, - - markAsRead: async (options: MutationMark_As_ReadArgs) => { - const resp = await inboxClient.private.mutation(markAsRead, options).toPromise() - return resp.data.mark_as_read - }, - - updateChat: async (options: MutationUpdate_ChatArgs) => { - const resp = await inboxClient.private.mutation(updateChat, options).toPromise() - return resp.data.update_chat - }, - - deleteChat: async (options: MutationDelete_ChatArgs) => { - const resp = await inboxClient.private.mutation(deleteChat, options).toPromise() - return resp.data.delete_chat - }, - - createMessage: async (options: MutationCreate_MessageArgs) => { - const resp = await inboxClient.private.mutation(createChatMessage, options).toPromise() - return resp.data.create_message.message - }, - - updateMessage: async (options: MutationUpdate_MessageArgs) => { - const resp = await inboxClient.private.mutation(updateChatMessage, options).toPromise() - return resp.data.update_message.message - }, - - deleteMessage: async (options: MutationDelete_MessageArgs) => { - const resp = await inboxClient.private.mutation(deleteChatMessage, options).toPromise() - return resp.data.delete_message - }, - - loadChatMessages: async (options: QueryLoad_Messages_ByArgs) => { - const resp = await inboxClient.private.query(chatMessagesLoadBy, options).toPromise() - return resp.data.load_messages_by.messages - }, -} diff --git a/src/graphql/client/core.ts b/src/graphql/client/core.ts deleted file mode 100644 index 2512b771..00000000 --- a/src/graphql/client/core.ts +++ /dev/null @@ -1,244 +0,0 @@ -import type { - Author, - CommonResult, - FollowingEntity, - LoadShoutsOptions, - MutationDelete_ShoutArgs, - ProfileInput, - QueryGet_Topic_FollowersArgs, - QueryLoad_Authors_ByArgs, - QueryLoad_Shouts_Random_TopArgs, - QueryLoad_Shouts_SearchArgs, - ReactionBy, - ReactionInput, - Shout, - ShoutInput, - Topic, -} from '../schema/core.gen' - -import { coreApiUrl } from '../../utils/config' -import { createGraphQLClient } from '../createGraphQLClient' -import createArticle from '../mutation/core/article-create' -import deleteShout from '../mutation/core/article-delete' -import updateArticle from '../mutation/core/article-update' -import rateAuthor from '../mutation/core/author-rate' -import updateAuthor from '../mutation/core/author-update' -import followMutation from '../mutation/core/follow' -import reactionCreate from '../mutation/core/reaction-create' -import reactionDestroy from '../mutation/core/reaction-destroy' -import reactionUpdate from '../mutation/core/reaction-update' -import unfollowMutation from '../mutation/core/unfollow' -import shoutLoad from '../query/core/article-load' -import getMyShout from '../query/core/article-my' -import shoutsLoadBy from '../query/core/articles-load-by' -import draftsLoad from '../query/core/articles-load-drafts' -import myFeed from '../query/core/articles-load-feed' -import loadShoutsTopRandom from '../query/core/articles-load-random-top' -import articlesLoadRandomTopic from '../query/core/articles-load-random-topic' -import shoutsLoadSearch from '../query/core/articles-load-search' -import loadShoutsUnrated from '../query/core/articles-load-unrated' -import authorBy from '../query/core/author-by' -import authorFollowers from '../query/core/author-followers' -import authorFollows from '../query/core/author-follows' -import authorsAll from '../query/core/authors-all' -import authorsLoadBy from '../query/core/authors-load-by' -import reactionsLoadBy from '../query/core/reactions-load-by' -import topicBySlug from '../query/core/topic-by-slug' -import topicFollowers from '../query/core/topic-followers' -import topicsAll from '../query/core/topics-all' -import topicsRandomQuery from '../query/core/topics-random' - -const publicGraphQLClient = createGraphQLClient(coreApiUrl) - -export const apiClient = { - private: null, - connect: (token: string) => { - // NOTE: use it after token appears - apiClient.private = createGraphQLClient(coreApiUrl, token) - }, - - getRandomTopShouts: async (params: QueryLoad_Shouts_Random_TopArgs) => { - const response = await publicGraphQLClient.query(loadShoutsTopRandom, params).toPromise() - if (!response.data) console.error('[graphql.core] load_shouts_random_top failed', response) - - return response.data.load_shouts_random_top - }, - - getUnratedShouts: async (limit = 50, offset = 0) => { - const response = await apiClient.private.query(loadShoutsUnrated, { limit, offset }).toPromise() - if (!response.data) console.error('[graphql.core] load_shouts_unrated', response) - - return response.data.load_shouts_unrated - }, - - rateAuthor: async ({ rated_slug, value }: { rated_slug: string; value: number }) => { - const response = await apiClient.private.mutation(rateAuthor, { rated_slug, value }).toPromise() - if (!response.data) console.error('[graphql.client.core] get_topics_random failed', response) - - return response.data.rate_author - }, - - getRandomTopics: async ({ amount }: { amount: number }) => { - const response = await publicGraphQLClient.query(topicsRandomQuery, { amount }).toPromise() - if (!response.data) console.error('[graphql.client.core] get_topics_random failed', response) - - return response.data.get_topics_random - }, - - getRandomTopicShouts: async (limit: number): Promise => { - const resp = await publicGraphQLClient.query(articlesLoadRandomTopic, { limit }).toPromise() - if (!resp.data) console.error('[graphql.client.core] load_shouts_random_topic', resp) - return resp.data.load_shouts_random_topic - }, - - follow: async ({ what, slug }: { what: FollowingEntity; slug: string }) => { - const response = await apiClient.private.mutation(followMutation, { what, slug }).toPromise() - return response.data.follow - }, - - unfollow: async ({ what, slug }: { what: FollowingEntity; slug: string }) => { - const response = await apiClient.private.mutation(unfollowMutation, { what, slug }).toPromise() - return response.data.unfollow - }, - - getAllTopics: async () => { - const response = await publicGraphQLClient.query(topicsAll, {}).toPromise() - if (!response.data) console.error('[graphql.client.core] get_topics_all', response) - - return response.data.get_topics_all - }, - - getAllAuthors: async () => { - const response = await publicGraphQLClient.query(authorsAll, {}).toPromise() - if (!response.data) console.error('[graphql.client.core] getAllAuthors', response) - - return response.data.get_authors_all - }, - - getAuthor: async (params: { slug?: string; author_id?: number }): Promise => { - const response = await publicGraphQLClient.query(authorBy, params).toPromise() - return response.data.get_author - }, - - getAuthorFollowers: async ({ slug }: { slug: string }): Promise => { - const response = await publicGraphQLClient.query(authorFollowers, { slug }).toPromise() - return response.data.get_author_followers - }, - - getTopicFollowers: async ({ slug }: QueryGet_Topic_FollowersArgs): Promise => { - const response = await publicGraphQLClient.query(topicFollowers, { slug }).toPromise() - return response.data.get_topic_followers - }, - - getAuthorFollows: async (params: { - slug?: string - author_id?: number - user?: string - }): Promise => { - const response = await publicGraphQLClient.query(authorFollows, params).toPromise() - return response.data.get_author_follows - }, - - updateAuthor: async (input: ProfileInput) => { - const response = await apiClient.private.mutation(updateAuthor, { profile: input }).toPromise() - return response.data.update_author - }, - - getTopic: async ({ slug }: { slug: string }): Promise => { - const response = await publicGraphQLClient.query(topicBySlug, { slug }).toPromise() - return response.data.get_topic - }, - - createArticle: async ({ article }: { article: ShoutInput }): Promise => { - const response = await apiClient.private.mutation(createArticle, { shout: article }).toPromise() - return response.data.create_shout.shout - }, - - updateArticle: async ({ - shout_id, - shout_input, - publish, - }: { - shout_id: number - shout_input?: ShoutInput - publish: boolean - }): Promise => { - const response = await apiClient.private - .mutation(updateArticle, { shout_id, shout_input, publish }) - .toPromise() - console.debug('[graphql.client.core] updateArticle:', response.data) - return response.data.update_shout - }, - - deleteShout: async (params: MutationDelete_ShoutArgs): Promise => { - const response = await apiClient.private.mutation(deleteShout, params).toPromise() - console.debug('[graphql.client.core] deleteShout:', response) - }, - - getDrafts: async (): Promise => { - const response = await apiClient.private.query(draftsLoad, {}).toPromise() - console.debug('[graphql.client.core] getDrafts:', response) - return response.data.get_shouts_drafts - }, - createReaction: async (input: ReactionInput) => { - const response = await apiClient.private.mutation(reactionCreate, { reaction: input }).toPromise() - console.debug('[graphql.client.core] createReaction:', response) - return response.data.create_reaction - }, - destroyReaction: async (reaction_id: number) => { - const response = await apiClient.private.mutation(reactionDestroy, { reaction_id }).toPromise() - console.debug('[graphql.client.core] destroyReaction:', response) - return response.data.delete_reaction - }, - updateReaction: async (reaction: ReactionInput) => { - const response = await apiClient.private.mutation(reactionUpdate, { reaction }).toPromise() - console.debug('[graphql.client.core] updateReaction:', response) - return response.data.update_reaction - }, - loadAuthorsBy: async (args: QueryLoad_Authors_ByArgs) => { - const resp = await publicGraphQLClient.query(authorsLoadBy, args).toPromise() - console.debug('[graphql.client.core] authorsLoadBy:', resp) - return resp.data.load_authors_by - }, - - getShoutBySlug: async (slug: string) => { - const resp = await publicGraphQLClient.query(shoutLoad, { slug }).toPromise() - return resp.data.get_shout - }, - - getMyShout: async (shout_id: number) => { - await apiClient.private - const resp = await apiClient.private.query(getMyShout, { shout_id }).toPromise() - if (resp.error) console.error(resp) - - return resp.data.get_my_shout - }, - - getShouts: async (options: LoadShoutsOptions) => { - const resp = await publicGraphQLClient.query(shoutsLoadBy, { options }).toPromise() - if (resp.error) console.error(resp) - - return resp.data?.load_shouts_by - }, - - getShoutsSearch: async ({ text, limit, offset }: QueryLoad_Shouts_SearchArgs) => { - const resp = await publicGraphQLClient.query(shoutsLoadSearch, { text, limit, offset }).toPromise() - if (resp.error) console.error(resp) - - return resp.data.load_shouts_search - }, - - getMyFeed: async (options: LoadShoutsOptions) => { - const resp = await apiClient.private.query(myFeed, { options }).toPromise() - if (resp.error) console.error(resp) - - return resp.data.load_shouts_feed - }, - - getReactionsBy: async ({ by, limit, offset }: { by: ReactionBy; limit?: number; offset?: number }) => { - const resp = await publicGraphQLClient - .query(reactionsLoadBy, { by, limit: limit ?? 1000, offset: offset ?? 0 }) - .toPromise() - return resp.data.load_reactions_by - }, -} diff --git a/src/graphql/client/notifier.ts b/src/graphql/client/notifier.ts deleted file mode 100644 index 6592849f..00000000 --- a/src/graphql/client/notifier.ts +++ /dev/null @@ -1,32 +0,0 @@ -import markSeenMutation from '../mutation/notifier/mark-seen' -import markSeenAfterMutation from '../mutation/notifier/mark-seen-after' -import markThreadSeenMutation from '../mutation/notifier/mark-seen-thread' -import loadNotifications from '../query/notifier/notifications-load' -import { - MutationNotifications_Seen_AfterArgs, - NotificationsResult, - QueryLoad_NotificationsArgs, -} from '../schema/core.gen' -import { apiClient } from './core' - -export const notifierClient = { - private: apiClient.private, - getNotifications: async (params: QueryLoad_NotificationsArgs): Promise => { - const resp = await notifierClient.private.query(loadNotifications, params).toPromise() - return resp.data?.load_notifications - }, - - markSeen: async (notification_id: number): Promise => { - // call when notification is clicked - await notifierClient.private.mutation(markSeenMutation, { notification_id }).toPromise() - }, - - markSeenAfter: async (options: MutationNotifications_Seen_AfterArgs): Promise => { - // call when 'mark all as seen' cliecked - await notifierClient.private.mutation(markSeenAfterMutation, options).toPromise() - }, - markSeenThread: async (thread: string): Promise => { - // call when notification group is clicked - await notifierClient.private.mutation(markThreadSeenMutation, { thread }).toPromise() - }, -} diff --git a/src/graphql/createGraphQLClient.ts b/src/graphql/createGraphQLClient.ts deleted file mode 100644 index 89b0d620..00000000 --- a/src/graphql/createGraphQLClient.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ClientOptions, Exchange, createClient, fetchExchange } from '@urql/core' -import { devtoolsExchange } from '@urql/devtools' - -import { isDev } from '../utils/config' - -const exchanges: Exchange[] = [fetchExchange] - -if (isDev) { - exchanges.unshift(devtoolsExchange) -} - -export const createGraphQLClient = (url: string, token = '') => { - const options: ClientOptions = { - url, - requestPolicy: 'cache-and-network', - fetchOptions: () => (token ? { headers: { Authorization: token } } : {}), - exchanges, - } - return createClient(options) -} diff --git a/src/graphql/error.ts b/src/graphql/error.ts deleted file mode 100644 index 4b522b6f..00000000 --- a/src/graphql/error.ts +++ /dev/null @@ -1,16 +0,0 @@ -type ApiErrorCode = - | 'unknown' - | 'email_not_confirmed' - | 'user_not_found' - | 'user_already_exists' - | 'token_expired' - | 'token_invalid' - -export class ApiError extends Error { - code: ApiErrorCode - - constructor(code: ApiErrorCode, message?: string) { - super(message) - this.code = code - } -} diff --git a/tests/basic-routes.spec.ts b/tests/basic-routes.spec.ts index b904fbef..b096368b 100644 --- a/tests/basic-routes.spec.ts +++ b/tests/basic-routes.spec.ts @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test' const baseHost = process.env.BASE_HOST || 'https://localhost:3000' -const pagesTitles = { +const pagesTitles: {[key:string]: RegExp } = { '/': /Дискурс/, '/feed': /Лента/, '/create': /Выберите тип публикации/, diff --git a/tsconfig.json b/tsconfig.json index e75d7943..b762d5cb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,5 +21,6 @@ "~/*": ["./src/*"], "@/*": ["./public/*"] } - } + }, + "exclude": ["./src/pages"] }