From a433bfcd2b15cb6c02c0f01779072c4d9fff4f9b Mon Sep 17 00:00:00 2001 From: robonau <30987265+Robonau@users.noreply.github.com> Date: Thu, 1 Feb 2024 01:06:49 +0000 Subject: [PATCH 1/4] more sorts in library --- schema.graphql | 26 +++++++++++++++++ src/gql/Queries.gql | 8 +++++- src/lib/generated.ts | 38 +++++++++++++++++++++++-- src/lib/simpleStores.ts | 6 ++-- src/routes/(app)/(library)/+page.svelte | 15 ++++++++-- 5 files changed, 86 insertions(+), 7 deletions(-) diff --git a/schema.graphql b/schema.graphql index 4c561e3b..d9eb5beb 100644 --- a/schema.graphql +++ b/schema.graphql @@ -456,6 +456,11 @@ type PartialSettingsType implements Settings { excludeNotStarted: Boolean excludeUnreadChapters: Boolean extensionRepos: [String!] + flareSolverrEnabled: Boolean + flareSolverrSessionName: String + flareSolverrSessionTtl: Int + flareSolverrTimeout: Int + flareSolverrUrl: String globalUpdateInterval: Float gqlDebugLogsEnabled: Boolean initialOpenInBrowserEnabled: Boolean @@ -566,6 +571,11 @@ type SettingsType implements Settings { excludeNotStarted: Boolean! excludeUnreadChapters: Boolean! extensionRepos: [String!]! + flareSolverrEnabled: Boolean! + flareSolverrSessionName: String! + flareSolverrSessionTtl: Int! + flareSolverrTimeout: Int! + flareSolverrUrl: String! globalUpdateInterval: Float! gqlDebugLogsEnabled: Boolean! initialOpenInBrowserEnabled: Boolean! @@ -683,6 +693,10 @@ type TrackSearchType { trackingUrl: String! tracker: TrackerType! } +type TrackStatusType { + name: String! + value: Int! +} type TrackerEdge implements Edge { cursor: Cursor! node: TrackerType! @@ -699,6 +713,8 @@ type TrackerType { id: Int! isLoggedIn: Boolean! name: String! + scores: [String!]! + statuses: [TrackStatusType!]! trackRecords: TrackRecordNodeList! } type TriStateFilter { @@ -849,6 +865,11 @@ interface Settings { excludeNotStarted: Boolean excludeUnreadChapters: Boolean extensionRepos: [String!] + flareSolverrEnabled: Boolean + flareSolverrSessionName: String + flareSolverrSessionTtl: Int + flareSolverrTimeout: Int + flareSolverrUrl: String globalUpdateInterval: Float gqlDebugLogsEnabled: Boolean initialOpenInBrowserEnabled: Boolean @@ -1377,6 +1398,11 @@ input PartialSettingsTypeInput { excludeNotStarted: Boolean excludeUnreadChapters: Boolean extensionRepos: [String!] + flareSolverrEnabled: Boolean + flareSolverrSessionName: String + flareSolverrSessionTtl: Int + flareSolverrTimeout: Int + flareSolverrUrl: String globalUpdateInterval: Float gqlDebugLogsEnabled: Boolean initialOpenInBrowserEnabled: Boolean diff --git a/src/gql/Queries.gql b/src/gql/Queries.gql index e2dd2507..0a917cbb 100644 --- a/src/gql/Queries.gql +++ b/src/gql/Queries.gql @@ -25,7 +25,13 @@ query category($id: Int!) { thumbnailUrl unreadCount downloadCount - lastReadChapter { + latestFetchedChapter { + fetchedAt + } + latestUploadedChapter { + uploadDate + } + latestReadChapter { lastReadAt } chapters { diff --git a/src/lib/generated.ts b/src/lib/generated.ts index 4d18618d..40a7299e 100644 --- a/src/lib/generated.ts +++ b/src/lib/generated.ts @@ -1380,6 +1380,11 @@ export type PartialSettingsType = Settings & { excludeNotStarted?: Maybe; excludeUnreadChapters?: Maybe; extensionRepos?: Maybe>; + flareSolverrEnabled?: Maybe; + flareSolverrSessionName?: Maybe; + flareSolverrSessionTtl?: Maybe; + flareSolverrTimeout?: Maybe; + flareSolverrUrl?: Maybe; globalUpdateInterval?: Maybe; gqlDebugLogsEnabled?: Maybe; initialOpenInBrowserEnabled?: Maybe; @@ -1417,6 +1422,11 @@ export type PartialSettingsTypeInput = { excludeNotStarted?: InputMaybe; excludeUnreadChapters?: InputMaybe; extensionRepos?: InputMaybe>; + flareSolverrEnabled?: InputMaybe; + flareSolverrSessionName?: InputMaybe; + flareSolverrSessionTtl?: InputMaybe; + flareSolverrTimeout?: InputMaybe; + flareSolverrUrl?: InputMaybe; globalUpdateInterval?: InputMaybe; gqlDebugLogsEnabled?: InputMaybe; initialOpenInBrowserEnabled?: InputMaybe; @@ -1757,6 +1767,11 @@ export type Settings = { excludeNotStarted?: Maybe; excludeUnreadChapters?: Maybe; extensionRepos?: Maybe>; + flareSolverrEnabled?: Maybe; + flareSolverrSessionName?: Maybe; + flareSolverrSessionTtl?: Maybe; + flareSolverrTimeout?: Maybe; + flareSolverrUrl?: Maybe; globalUpdateInterval?: Maybe; gqlDebugLogsEnabled?: Maybe; initialOpenInBrowserEnabled?: Maybe; @@ -1795,6 +1810,11 @@ export type SettingsType = Settings & { excludeNotStarted: Scalars['Boolean']['output']; excludeUnreadChapters: Scalars['Boolean']['output']; extensionRepos: Array; + flareSolverrEnabled: Scalars['Boolean']['output']; + flareSolverrSessionName: Scalars['String']['output']; + flareSolverrSessionTtl: Scalars['Int']['output']; + flareSolverrTimeout: Scalars['Int']['output']; + flareSolverrUrl: Scalars['String']['output']; globalUpdateInterval: Scalars['Float']['output']; gqlDebugLogsEnabled: Scalars['Boolean']['output']; initialOpenInBrowserEnabled: Scalars['Boolean']['output']; @@ -2081,6 +2101,12 @@ export type TrackSearchType = { trackingUrl: Scalars['String']['output']; }; +export type TrackStatusType = { + __typename?: 'TrackStatusType'; + name: Scalars['String']['output']; + value: Scalars['Int']['output']; +}; + export type TrackerConditionInput = { icon?: InputMaybe; id?: InputMaybe; @@ -2115,6 +2141,8 @@ export type TrackerType = { id: Scalars['Int']['output']; isLoggedIn: Scalars['Boolean']['output']; name: Scalars['String']['output']; + scores: Array; + statuses: Array; trackRecords: TrackRecordNodeList; }; @@ -2777,7 +2805,7 @@ export type CategoryQueryVariables = Exact<{ }>; -export type CategoryQuery = { __typename?: 'Query', category: { __typename?: 'CategoryType', mangas: { __typename?: 'MangaNodeList', nodes: Array<{ __typename?: 'MangaType', id: number, title: string, inLibrary: boolean, thumbnailUrl?: string | null, unreadCount: number, downloadCount: number, lastReadChapter?: { __typename?: 'ChapterType', lastReadAt: any } | null, chapters: { __typename?: 'ChapterNodeList', totalCount: number } }> } } }; +export type CategoryQuery = { __typename?: 'Query', category: { __typename?: 'CategoryType', mangas: { __typename?: 'MangaNodeList', nodes: Array<{ __typename?: 'MangaType', id: number, title: string, inLibrary: boolean, thumbnailUrl?: string | null, unreadCount: number, downloadCount: number, latestFetchedChapter?: { __typename?: 'ChapterType', fetchedAt: any } | null, latestUploadedChapter?: { __typename?: 'ChapterType', uploadDate: any } | null, latestReadChapter?: { __typename?: 'ChapterType', lastReadAt: any } | null, chapters: { __typename?: 'ChapterNodeList', totalCount: number } }> } } }; export type GetMangaQueryVariables = Exact<{ id: Scalars['Int']['input']; @@ -3525,7 +3553,13 @@ export const CategoryDoc = gql` thumbnailUrl unreadCount downloadCount - lastReadChapter { + latestFetchedChapter { + fetchedAt + } + latestUploadedChapter { + uploadDate + } + latestReadChapter { lastReadAt } chapters { diff --git a/src/lib/simpleStores.ts b/src/lib/simpleStores.ts index a408c8e4..ab571301 100644 --- a/src/lib/simpleStores.ts +++ b/src/lib/simpleStores.ts @@ -77,8 +77,10 @@ type mangaMeta = typeof mangaMetaDefaults; export enum sort { Unread = 'Unread', Alphabetical = 'Alphabetical', - 'Last Read' = 'Last Read', - ID = 'ID' + ID = 'ID', + 'Latest Read' = 'Latest Read', + 'Latest Fetched' = 'Latest Fetched', + 'Latest Uploaded' = 'Latest Uploaded' } export enum display { diff --git a/src/routes/(app)/(library)/+page.svelte b/src/routes/(app)/(library)/+page.svelte index 8d8c7b04..a12bb515 100644 --- a/src/routes/(app)/(library)/+page.svelte +++ b/src/routes/(app)/(library)/+page.svelte @@ -118,9 +118,20 @@ case sort.Alphabetical: tru = a.title > b.title; break; - case sort['Last Read']: - tru = a.lastReadChapter?.lastReadAt > b.lastReadChapter?.lastReadAt; + case sort['Latest Read']: + tru = + parseInt(a.latestReadChapter?.lastReadAt ?? 0) > + parseInt(b.latestReadChapter?.lastReadAt ?? 0); break; + case sort['Latest Fetched']: + tru = + parseInt(a.latestFetchedChapter?.fetchedAt ?? 0) > + parseInt(b.latestFetchedChapter?.fetchedAt ?? 0); + break; + case sort['Latest Uploaded']: + tru = + parseInt(a.latestUploadedChapter?.uploadDate ?? 0) > + parseInt(b.latestUploadedChapter?.uploadDate ?? 0); } if ($Meta.Asc) tru = !tru; From 1ce2fbce24d9f1a0e0b40e8b823681bd1404e099 Mon Sep 17 00:00:00 2001 From: robonau <30987265+Robonau@users.noreply.github.com> Date: Thu, 1 Feb 2024 03:53:22 +0000 Subject: [PATCH 2/4] server settings --- src/gql/Mutations.gql | 46 ++ src/gql/Queries.gql | 44 ++ src/lib/generated.ts | 160 +++++++ src/lib/util.ts | 31 +- src/routes/(app)/settings/+page.svelte | 7 + src/routes/(app)/settings/server/+page.svelte | 404 ++++++++++++++++++ .../settings/server/components/Select.svelte | 23 + .../components/extensionReposModal.svelte | 59 +++ .../settings/server/components/number.svelte | 43 ++ .../settings/server/components/text.svelte | 35 ++ .../settings/server/components/toggle.svelte | 32 ++ 11 files changed, 883 insertions(+), 1 deletion(-) create mode 100644 src/routes/(app)/settings/server/+page.svelte create mode 100644 src/routes/(app)/settings/server/components/Select.svelte create mode 100644 src/routes/(app)/settings/server/components/extensionReposModal.svelte create mode 100644 src/routes/(app)/settings/server/components/number.svelte create mode 100644 src/routes/(app)/settings/server/components/text.svelte create mode 100644 src/routes/(app)/settings/server/components/toggle.svelte diff --git a/src/gql/Mutations.gql b/src/gql/Mutations.gql index 398a058c..c5b3e851 100644 --- a/src/gql/Mutations.gql +++ b/src/gql/Mutations.gql @@ -503,3 +503,49 @@ mutation updateTrack($input: UpdateTrackInput!) { } } } + +mutation setServerSettings($settings: PartialSettingsTypeInput = {}) { + setSettings(input: { settings: $settings }) { + settings { + autoDownloadAheadLimit + autoDownloadNewChapters + backupInterval + backupPath + backupTTL + backupTime + basicAuthEnabled + basicAuthPassword + basicAuthUsername + debugLogsEnabled + downloadAsCbz + downloadsPath + electronPath + excludeCompleted + excludeNotStarted + excludeEntryWithUnreadChapters + excludeUnreadChapters + flareSolverrEnabled + extensionRepos + flareSolverrSessionName + flareSolverrSessionTtl + flareSolverrTimeout + flareSolverrUrl + globalUpdateInterval + gqlDebugLogsEnabled + initialOpenInBrowserEnabled + ip + localSourcePath + maxSourcesInParallel + port + socksProxyEnabled + socksProxyHost + socksProxyPort + systemTrayEnabled + updateMangas + webUIChannel + webUIFlavor + webUIInterface + webUIUpdateCheckInterval + } + } +} diff --git a/src/gql/Queries.gql b/src/gql/Queries.gql index 0a917cbb..9958adbd 100644 --- a/src/gql/Queries.gql +++ b/src/gql/Queries.gql @@ -418,3 +418,47 @@ query trackRecords { } } } + +query serverSettings { + settings { + autoDownloadAheadLimit + autoDownloadNewChapters + backupInterval + backupPath + backupTTL + backupTime + basicAuthEnabled + basicAuthPassword + basicAuthUsername + debugLogsEnabled + downloadAsCbz + downloadsPath + electronPath + excludeCompleted + excludeEntryWithUnreadChapters + excludeNotStarted + extensionRepos + excludeUnreadChapters + flareSolverrEnabled + flareSolverrSessionName + flareSolverrSessionTtl + flareSolverrTimeout + flareSolverrUrl + globalUpdateInterval + gqlDebugLogsEnabled + initialOpenInBrowserEnabled + ip + localSourcePath + maxSourcesInParallel + port + socksProxyEnabled + socksProxyHost + socksProxyPort + systemTrayEnabled + updateMangas + webUIChannel + webUIFlavor + webUIInterface + webUIUpdateCheckInterval + } +} diff --git a/src/lib/generated.ts b/src/lib/generated.ts index 40a7299e..dff4ed4b 100644 --- a/src/lib/generated.ts +++ b/src/lib/generated.ts @@ -2793,6 +2793,13 @@ export type UpdateTrackMutationVariables = Exact<{ export type UpdateTrackMutation = { __typename?: 'Mutation', updateTrack: { __typename?: 'UpdateTrackPayload', trackRecord?: { __typename?: 'TrackRecordType', id: number, mangaId: number, remoteId: any, remoteUrl: string, title: string, trackerId: number } | null } }; +export type SetServerSettingsMutationVariables = Exact<{ + settings?: InputMaybe; +}>; + + +export type SetServerSettingsMutation = { __typename?: 'Mutation', setSettings: { __typename?: 'SetSettingsPayload', settings: { __typename?: 'SettingsType', autoDownloadAheadLimit: number, autoDownloadNewChapters: boolean, backupInterval: number, backupPath: string, backupTTL: number, backupTime: string, basicAuthEnabled: boolean, basicAuthPassword: string, basicAuthUsername: string, debugLogsEnabled: boolean, downloadAsCbz: boolean, downloadsPath: string, electronPath: string, excludeCompleted: boolean, excludeNotStarted: boolean, excludeEntryWithUnreadChapters: boolean, excludeUnreadChapters: boolean, flareSolverrEnabled: boolean, extensionRepos: Array, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrTimeout: number, flareSolverrUrl: string, globalUpdateInterval: number, gqlDebugLogsEnabled: boolean, initialOpenInBrowserEnabled: boolean, ip: string, localSourcePath: string, maxSourcesInParallel: number, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, systemTrayEnabled: boolean, updateMangas: boolean, webUIChannel: WebUiChannel, webUIFlavor: WebUiFlavor, webUIInterface: WebUiInterface, webUIUpdateCheckInterval: number } } }; + export type CategoriesQueryVariables = Exact<{ notEqualTo?: InputMaybe; }>; @@ -2943,6 +2950,11 @@ export type TrackRecordsQueryVariables = Exact<{ [key: string]: never; }>; export type TrackRecordsQuery = { __typename?: 'Query', trackRecords: { __typename?: 'TrackRecordNodeList', nodes: Array<{ __typename?: 'TrackRecordType', id: number, mangaId: number, remoteId: any, remoteUrl: string, title: string, trackerId: number }> } }; +export type ServerSettingsQueryVariables = Exact<{ [key: string]: never; }>; + + +export type ServerSettingsQuery = { __typename?: 'Query', settings: { __typename?: 'SettingsType', autoDownloadAheadLimit: number, autoDownloadNewChapters: boolean, backupInterval: number, backupPath: string, backupTTL: number, backupTime: string, basicAuthEnabled: boolean, basicAuthPassword: string, basicAuthUsername: string, debugLogsEnabled: boolean, downloadAsCbz: boolean, downloadsPath: string, electronPath: string, excludeCompleted: boolean, excludeEntryWithUnreadChapters: boolean, excludeNotStarted: boolean, extensionRepos: Array, excludeUnreadChapters: boolean, flareSolverrEnabled: boolean, flareSolverrSessionName: string, flareSolverrSessionTtl: number, flareSolverrTimeout: number, flareSolverrUrl: string, globalUpdateInterval: number, gqlDebugLogsEnabled: boolean, initialOpenInBrowserEnabled: boolean, ip: string, localSourcePath: string, maxSourcesInParallel: number, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, systemTrayEnabled: boolean, updateMangas: boolean, webUIChannel: WebUiChannel, webUIFlavor: WebUiFlavor, webUIInterface: WebUiInterface, webUIUpdateCheckInterval: number } }; + export type DownloadChangedSubscriptionVariables = Exact<{ [key: string]: never; }>; @@ -3533,6 +3545,53 @@ export const UpdateTrackDoc = gql` } } ${TrackRecordTypeFragmentFragmentDoc}`; +export const SetServerSettingsDoc = gql` + mutation setServerSettings($settings: PartialSettingsTypeInput = {}) { + setSettings(input: {settings: $settings}) { + settings { + autoDownloadAheadLimit + autoDownloadNewChapters + backupInterval + backupPath + backupTTL + backupTime + basicAuthEnabled + basicAuthPassword + basicAuthUsername + debugLogsEnabled + downloadAsCbz + downloadsPath + electronPath + excludeCompleted + excludeNotStarted + excludeEntryWithUnreadChapters + excludeUnreadChapters + flareSolverrEnabled + extensionRepos + flareSolverrSessionName + flareSolverrSessionTtl + flareSolverrTimeout + flareSolverrUrl + globalUpdateInterval + gqlDebugLogsEnabled + initialOpenInBrowserEnabled + ip + localSourcePath + maxSourcesInParallel + port + socksProxyEnabled + socksProxyHost + socksProxyPort + systemTrayEnabled + updateMangas + webUIChannel + webUIFlavor + webUIInterface + webUIUpdateCheckInterval + } + } +} + `; export const CategoriesDoc = gql` query categories($notEqualTo: Int = null) { categories(filter: {id: {notEqualTo: $notEqualTo}}) { @@ -3954,6 +4013,51 @@ export const TrackRecordsDoc = gql` } } ${TrackRecordTypeFragmentFragmentDoc}`; +export const ServerSettingsDoc = gql` + query serverSettings { + settings { + autoDownloadAheadLimit + autoDownloadNewChapters + backupInterval + backupPath + backupTTL + backupTime + basicAuthEnabled + basicAuthPassword + basicAuthUsername + debugLogsEnabled + downloadAsCbz + downloadsPath + electronPath + excludeCompleted + excludeEntryWithUnreadChapters + excludeNotStarted + extensionRepos + excludeUnreadChapters + flareSolverrEnabled + flareSolverrSessionName + flareSolverrSessionTtl + flareSolverrTimeout + flareSolverrUrl + globalUpdateInterval + gqlDebugLogsEnabled + initialOpenInBrowserEnabled + ip + localSourcePath + maxSourcesInParallel + port + socksProxyEnabled + socksProxyHost + socksProxyPort + systemTrayEnabled + updateMangas + webUIChannel + webUIFlavor + webUIInterface + webUIUpdateCheckInterval + } +} + `; export const DownloadChangedDoc = gql` subscription downloadChanged { downloadChanged { @@ -4460,6 +4564,18 @@ export const updateTrack = ( }); return m; } +export const setServerSettings = ( + options: Omit< + MutationOptions, + "mutation" + > + ) => { + const m = client.mutate({ + mutation: SetServerSettingsDoc, + ...options, + }); + return m; + } export const categories = ( options: Omit< WatchQueryOptions, @@ -5428,6 +5544,50 @@ export const trackRecords = ( return client.query({query: TrackRecordsDoc, ...options}) } +export const serverSettings = ( + options: Omit< + WatchQueryOptions, + "query" + > + ): Readable< + ApolloQueryResult & { + query: ObservableQuery< + ServerSettingsQuery, + ServerSettingsQueryVariables + >; + } + > => { + const q = client.watchQuery({ + query: ServerSettingsDoc, + ...options, + }); + var result = readable< + ApolloQueryResult & { + query: ObservableQuery< + ServerSettingsQuery, + ServerSettingsQueryVariables + >; + } + >( + { data: {} as any, loading: true, error: undefined, networkStatus: 1, query: q }, + (set) => { + q.subscribe((v: any) => { + set({ ...v, query: q }); + }); + } + ); + return result; + } + + export const AsyncserverSettings = ( + options: Omit< + QueryOptions, + "query" + > + ) => { + return client.query({query: ServerSettingsDoc, ...options}) + } + export const downloadChanged = ( options: Omit, "query"> ) => { diff --git a/src/lib/util.ts b/src/lib/util.ts index 509849f4..9291840d 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -12,7 +12,11 @@ import { type BindTrackMutation, type UpdateTrackMutation, type GetMangaQuery, - GetMangaDoc + GetMangaDoc, + type SetServerSettingsMutation, + ServerSettingsDoc, + setServerSettings, + type PartialSettingsTypeInput } from './generated'; import type { FetchResult } from '@apollo/client/link/core'; @@ -217,6 +221,12 @@ export type PartialBy = Omit & Partial>; export function enumKeys(e: E): (keyof E)[] { return Object.keys(e) as (keyof E)[]; } +export function enumValues(e: E): E[keyof E][] { + return Object.values(e) as E[keyof E][]; +} +export function enumEntries(e: E): [keyof E, E[keyof E]][] { + return Object.entries(e) as [keyof E, E[keyof E]][]; +} export function groupBy( list: T[], @@ -290,3 +300,22 @@ export function bindTrackUpdater( data: { manga: mga } }); } + +export function setServerSettingsUpdater( + cache: ApolloCache, + { data }: FetchResult +) { + if (!data) return; + const settings = data.setSettings.settings; + cache.writeQuery({ + query: ServerSettingsDoc, + data: { settings } + }); +} + +export function setSettings(settings: PartialSettingsTypeInput) { + ErrorHelp( + 'failed to set server settings', + setServerSettings({ variables: { settings }, update: setServerSettingsUpdater }) + ); +} diff --git a/src/routes/(app)/settings/+page.svelte b/src/routes/(app)/settings/+page.svelte index fbc6cbb1..4391a99c 100644 --- a/src/routes/(app)/settings/+page.svelte +++ b/src/routes/(app)/settings/+page.svelte @@ -141,3 +141,10 @@
Cache
+ + +
Server Settings
+
diff --git a/src/routes/(app)/settings/server/+page.svelte b/src/routes/(app)/settings/server/+page.svelte new file mode 100644 index 00000000..39995d17 --- /dev/null +++ b/src/routes/(app)/settings/server/+page.svelte @@ -0,0 +1,404 @@ + + + +{#if $settingsData.error} + {JSON.stringify($settingsData.error)} +{:else if $settingsData.errors} + {JSON.stringify($settingsData.errors)} +{:else if $settingsData.loading} + Loading... +{:else if $settingsData.data} + {@const settings = $settingsData.data.settings} +
+ + setSettings({ autoDownloadAheadLimit })} + /> + + setSettings({ autoDownloadNewChapters })} + /> + + setSettings({ backupInterval })} + /> + + setSettings({ backupPath })} + /> + + setSettings({ backupTTL })} + /> + + { + if (/^([01][0-9]|2[0-3]):([0-5][0-9])$/.test(backupTime)) { + setSettings({ backupTime }); + return; + } + errortoast('Time validation failed', 'Backup Time must be in format HH:MM'); + backupTime = settings.backupTime; + }} + /> + + setSettings({ basicAuthEnabled })} + /> + + setSettings({ basicAuthPassword })} + type="password" + /> + + setSettings({ basicAuthUsername })} + /> + + setSettings({ debugLogsEnabled })} + /> + + setSettings({ downloadAsCbz })} + /> + + setSettings({ downloadsPath })} + /> + + setSettings({ electronPath })} + /> + + setSettings({ excludeCompleted })} + /> + + setSettings({ excludeEntryWithUnreadChapters })} + /> + + setSettings({ excludeNotStarted })} + /> + + + + setSettings({ excludeUnreadChapters })} + /> + + setSettings({ flareSolverrEnabled })} + /> + + setSettings({ flareSolverrSessionName })} + /> + + setSettings({ flareSolverrSessionTtl })} + /> + + setSettings({ flareSolverrTimeout })} + /> + + setSettings({ flareSolverrUrl })} + /> + + setSettings({ globalUpdateInterval })} + /> + + setSettings({ gqlDebugLogsEnabled })} + /> + + setSettings({ initialOpenInBrowserEnabled })} + /> + + { + if (/^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/.test(ip)) { + setSettings({ ip }); + return; + } + errortoast('Time validation failed', 'Backup Time must be in format HH:MM'); + ip = settings.ip; + }} + /> + + setSettings({ localSourcePath })} + /> + + setSettings({ maxSourcesInParallel })} + /> + + { + if (port < 65535 && port > 0) { + setSettings({ port }); + return; + } + errortoast('Port validation failed', 'Port must be between 0 and 65535'); + port = settings.port; + }} + /> + + setSettings({ socksProxyEnabled })} + /> + + setSettings({ socksProxyHost })} + /> + + { + if (value < 65535 && value > 0) { + setSettings({ socksProxyPort: value.toString() }); + return; + } + errortoast( + 'socksProxyPort validation failed', + 'socksProxyPort must be between 0 and 65535' + ); + reset(parseInt(settings.socksProxyPort)); + }} + /> + + setSettings({ systemTrayEnabled })} + /> + + setSettings({ updateMangas })} + /> + + setSettings({ webUIFlavor })} + /> + + + {#each options as option} + + {/each} + +
+ diff --git a/src/routes/(app)/settings/server/components/extensionReposModal.svelte b/src/routes/(app)/settings/server/components/extensionReposModal.svelte new file mode 100644 index 00000000..14c5ae9c --- /dev/null +++ b/src/routes/(app)/settings/server/components/extensionReposModal.svelte @@ -0,0 +1,59 @@ + + + +{#if $modalStore[0]} +
+

Extension Repos

+
+
+
+ + +
+
+ {#each repos as value} +
+
+ {value} +
+ +
+ {/each} +
+
+
+
+
+{/if} diff --git a/src/routes/(app)/settings/server/components/number.svelte b/src/routes/(app)/settings/server/components/number.svelte new file mode 100644 index 00000000..74f15d24 --- /dev/null +++ b/src/routes/(app)/settings/server/components/number.svelte @@ -0,0 +1,43 @@ + + + + diff --git a/src/routes/(app)/settings/server/components/text.svelte b/src/routes/(app)/settings/server/components/text.svelte new file mode 100644 index 00000000..4a95ceee --- /dev/null +++ b/src/routes/(app)/settings/server/components/text.svelte @@ -0,0 +1,35 @@ + + + + diff --git a/src/routes/(app)/settings/server/components/toggle.svelte b/src/routes/(app)/settings/server/components/toggle.svelte new file mode 100644 index 00000000..9effe037 --- /dev/null +++ b/src/routes/(app)/settings/server/components/toggle.svelte @@ -0,0 +1,32 @@ + + + + From d2520637347e5cb51b81297a93d22071b7394ca9 Mon Sep 17 00:00:00 2001 From: robonau <30987265+Robonau@users.noreply.github.com> Date: Thu, 1 Feb 2024 03:57:32 +0000 Subject: [PATCH 3/4] quick number change --- src/routes/(app)/settings/server/+page.svelte | 16 +++++++------- .../settings/server/components/number.svelte | 21 ++----------------- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/src/routes/(app)/settings/server/+page.svelte b/src/routes/(app)/settings/server/+page.svelte index 39995d17..34bb40ec 100644 --- a/src/routes/(app)/settings/server/+page.svelte +++ b/src/routes/(app)/settings/server/+page.svelte @@ -344,20 +344,20 @@ on:change={() => setSettings({ socksProxyHost })} /> - { - if (value < 65535 && value > 0) { - setSettings({ socksProxyPort: value.toString() }); + bind:value={socksProxyPort} + on:change={() => { + const int = parseInt(socksProxyPort); + if (!isNaN(int) && int < 65535 && int > 0) { + setSettings({ socksProxyPort }); return; } errortoast( 'socksProxyPort validation failed', - 'socksProxyPort must be between 0 and 65535' + 'socksProxyPort must be a number between 0 and 65535' ); - reset(parseInt(settings.socksProxyPort)); + socksProxyPort = settings.socksProxyPort; }} /> diff --git a/src/routes/(app)/settings/server/components/number.svelte b/src/routes/(app)/settings/server/components/number.svelte index 74f15d24..39962732 100644 --- a/src/routes/(app)/settings/server/components/number.svelte +++ b/src/routes/(app)/settings/server/components/number.svelte @@ -9,31 +9,14 @@ export let value: number; export let max: number; export let title: string; - import { createEventDispatcher } from 'svelte'; - type Event = { - change: { - value: number; - reset: (def: number) => void; - }; - }; - function reset(def: number) { - value = def; - } - const dispatch = createEventDispatcher();