Feature/settings support custom extension repos (#539)
* [Codegen] Support custom extension repos * [VersionMapping] Require server version "r1444" for preview
This commit is contained in:
@@ -22,6 +22,7 @@ import { makeToast } from '@/components/util/Toast.tsx';
|
||||
interface IProps {
|
||||
extension: PartialExtension;
|
||||
handleUpdate: () => void;
|
||||
usesCustomRepos: boolean;
|
||||
}
|
||||
|
||||
enum ExtensionAction {
|
||||
@@ -91,8 +92,9 @@ export function ExtensionCard(props: IProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const {
|
||||
extension: { name, lang, versionName, isInstalled, hasUpdate, isObsolete, pkgName, iconUrl, isNsfw },
|
||||
extension: { name, lang, versionName, isInstalled, hasUpdate, isObsolete, pkgName, iconUrl, isNsfw, repo },
|
||||
handleUpdate,
|
||||
usesCustomRepos,
|
||||
} = props;
|
||||
const [installedState, setInstalledState] = useState<InstalledStates>(
|
||||
getInstalledState(isInstalled, isObsolete, hasUpdate),
|
||||
@@ -184,6 +186,11 @@ export function ExtensionCard(props: IProps) {
|
||||
</Typography>
|
||||
)}
|
||||
</Typography>
|
||||
{usesCustomRepos && (
|
||||
<Typography variant="caption" display="block">
|
||||
{repo}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
|
||||
131
src/components/settings/MutableListSetting.tsx
Normal file
131
src/components/settings/MutableListSetting.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Button, Dialog, DialogTitle, ListItemButton, ListItemText, Stack, Tooltip } from '@mui/material';
|
||||
import { useEffect, useState } from 'react';
|
||||
import DialogContent from '@mui/material/DialogContent';
|
||||
import DialogActions from '@mui/material/DialogActions';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import List from '@mui/material/List';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import DialogContentText from '@mui/material/DialogContentText';
|
||||
import { TextSetting, TextSettingProps } from '@/components/settings/TextSetting.tsx';
|
||||
|
||||
const MutableListItem = ({
|
||||
handleDelete,
|
||||
...textSettingProps
|
||||
}: Omit<TextSettingProps, 'isPassword' | 'disabled'> & { handleDelete: () => void }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Stack direction="row">
|
||||
<TextSetting {...textSettingProps} dialogTitle="" />
|
||||
<Tooltip title={t('chapter.action.download.delete.label.action')}>
|
||||
<IconButton size="large" onClick={handleDelete}>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export const MutableListSetting = ({
|
||||
settingName,
|
||||
description,
|
||||
values,
|
||||
handleChange,
|
||||
addItemButtonTitle,
|
||||
}: {
|
||||
settingName: string;
|
||||
description?: string;
|
||||
values?: string[];
|
||||
handleChange: (values: string[]) => void;
|
||||
addItemButtonTitle?: string;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
const [dialogValues, setDialogValues] = useState(values ?? []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!values) {
|
||||
return;
|
||||
}
|
||||
|
||||
setDialogValues(values);
|
||||
}, [values]);
|
||||
|
||||
const closeDialog = (resetValue: boolean = true) => {
|
||||
if (resetValue) {
|
||||
setDialogValues(values ?? []);
|
||||
}
|
||||
|
||||
setIsDialogOpen(false);
|
||||
};
|
||||
|
||||
const updateSetting = (index: number, newValue: string | undefined) => {
|
||||
const deleteValue = newValue === undefined;
|
||||
if (deleteValue) {
|
||||
setDialogValues(dialogValues.toSpliced(index, 1));
|
||||
return;
|
||||
}
|
||||
|
||||
setDialogValues(dialogValues.toSpliced(index, 1, newValue.trim()));
|
||||
};
|
||||
|
||||
const saveChanges = () => {
|
||||
closeDialog();
|
||||
handleChange(dialogValues.filter((dialogValue) => dialogValue !== ''));
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ListItemButton onClick={() => setIsDialogOpen(true)}>
|
||||
<ListItemText
|
||||
primary={settingName}
|
||||
secondary={values?.length ? values?.join(', ') : description}
|
||||
secondaryTypographyProps={{ style: { display: 'flex', flexDirection: 'column' } }}
|
||||
/>
|
||||
</ListItemButton>
|
||||
|
||||
<Dialog open={isDialogOpen} onClose={() => closeDialog()} fullWidth>
|
||||
<DialogTitle>{settingName}</DialogTitle>
|
||||
{!!description && (
|
||||
<DialogContent>
|
||||
<DialogContentText sx={{ paddingBottom: '10px' }}>{description}</DialogContentText>
|
||||
</DialogContent>
|
||||
)}
|
||||
<DialogContent dividers sx={{ maxHeight: '300px' }}>
|
||||
<List>
|
||||
{dialogValues.map((dialogValue, index) => (
|
||||
<MutableListItem
|
||||
settingName={dialogValue === '' ? t('global.label.placeholder') : ''}
|
||||
placeholder="https://github.com/MY_ACCOUNT/MY_REPO/tree/repo"
|
||||
handleChange={(newValue: string) => updateSetting(index, newValue)}
|
||||
handleDelete={() => updateSetting(index, undefined)}
|
||||
value={dialogValue}
|
||||
/>
|
||||
))}
|
||||
</List>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Stack sx={{ width: '100%' }} direction="row" justifyContent="space-between">
|
||||
<Button onClick={() => updateSetting(dialogValues.length, '')}>
|
||||
{addItemButtonTitle ?? t('global.button.add')}
|
||||
</Button>
|
||||
<Stack direction="row">
|
||||
<Button onClick={() => closeDialog()}>{t('global.button.cancel')}</Button>
|
||||
<Button onClick={() => saveChanges()}>{t('global.button.ok')}</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -17,23 +17,27 @@ import DialogContentText from '@mui/material/DialogContentText';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import { Visibility, VisibilityOff } from '@mui/icons-material';
|
||||
|
||||
export const TextSetting = ({
|
||||
settingName,
|
||||
dialogDescription,
|
||||
value,
|
||||
handleChange,
|
||||
isPassword = false,
|
||||
placeholder = '',
|
||||
disabled = false,
|
||||
}: {
|
||||
export type TextSettingProps = {
|
||||
settingName: string;
|
||||
dialogTitle?: string;
|
||||
dialogDescription?: string;
|
||||
value?: string;
|
||||
handleChange: (value: string) => void;
|
||||
isPassword?: boolean;
|
||||
placeholder?: string;
|
||||
disabled?: boolean;
|
||||
}) => {
|
||||
};
|
||||
|
||||
export const TextSetting = ({
|
||||
settingName,
|
||||
dialogTitle = settingName,
|
||||
dialogDescription,
|
||||
value,
|
||||
handleChange,
|
||||
isPassword = false,
|
||||
placeholder = '',
|
||||
disabled = false,
|
||||
}: TextSettingProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
@@ -70,13 +74,15 @@ export const TextSetting = ({
|
||||
<ListItemText
|
||||
primary={settingName}
|
||||
secondary={isPassword ? value?.replace(/./g, '*') : value ?? t('global.label.loading')}
|
||||
secondaryTypographyProps={{ style: { display: 'flex', flexDirection: 'column' } }}
|
||||
secondaryTypographyProps={{
|
||||
sx: { display: 'flex', flexDirection: 'column', wordWrap: 'break-word' },
|
||||
}}
|
||||
/>
|
||||
</ListItemButton>
|
||||
|
||||
<Dialog open={isDialogOpen} onClose={() => closeDialog()} fullWidth>
|
||||
<DialogContent>
|
||||
<DialogTitle sx={{ paddingLeft: 0 }}>{settingName}</DialogTitle>
|
||||
<DialogTitle sx={{ paddingLeft: 0 }}>{dialogTitle}</DialogTitle>
|
||||
{!!dialogDescription && (
|
||||
<DialogContentText sx={{ paddingBottom: '10px' }}>{dialogDescription}</DialogContentText>
|
||||
)}
|
||||
|
||||
@@ -233,6 +233,23 @@
|
||||
"all": "All",
|
||||
"other": "Other"
|
||||
},
|
||||
"settings": {
|
||||
"repositories": {
|
||||
"custom": {
|
||||
"dialog": {
|
||||
"action": {
|
||||
"button": {
|
||||
"add": "Add repository"
|
||||
}
|
||||
}
|
||||
},
|
||||
"label": {
|
||||
"description": "Add custom repositories from which extensions can be installed",
|
||||
"title": "Custom repositories"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
"label": {
|
||||
"installed": "Installed",
|
||||
@@ -247,6 +264,7 @@
|
||||
},
|
||||
"global": {
|
||||
"button": {
|
||||
"add": "Add",
|
||||
"browse": "Browse",
|
||||
"cancel": "Cancel",
|
||||
"clear": "Clear",
|
||||
@@ -326,6 +344,7 @@
|
||||
"none": "None",
|
||||
"other": "Other",
|
||||
"password": "Password",
|
||||
"placeholder": "Placeholder",
|
||||
"sort": "Sort",
|
||||
"unknown": "Unknown",
|
||||
"username": "Username"
|
||||
|
||||
@@ -302,6 +302,7 @@ export const UPDATER_MANGA_FIELDS = gql`
|
||||
export const FULL_EXTENSION_FIELDS = gql`
|
||||
fragment FULL_EXTENSION_FIELDS on ExtensionType {
|
||||
apkName
|
||||
repo
|
||||
hasUpdate
|
||||
iconUrl
|
||||
isInstalled
|
||||
@@ -473,6 +474,9 @@ export const SERVER_SETTINGS = gql`
|
||||
excludeEntryWithUnreadChapters
|
||||
autoDownloadAheadLimit
|
||||
|
||||
# extensions
|
||||
extensionRepos
|
||||
|
||||
# requests
|
||||
maxSourcesInParallel
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ export type ExtensionNodeListFieldPolicy = {
|
||||
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
totalCount?: FieldPolicy<any> | FieldReadFunction<any>
|
||||
};
|
||||
export type ExtensionTypeKeySpecifier = ('apkName' | 'hasUpdate' | 'iconUrl' | 'isInstalled' | 'isNsfw' | 'isObsolete' | 'lang' | 'name' | 'pkgName' | 'source' | 'versionCode' | 'versionName' | ExtensionTypeKeySpecifier)[];
|
||||
export type ExtensionTypeKeySpecifier = ('apkName' | 'hasUpdate' | 'iconUrl' | 'isInstalled' | 'isNsfw' | 'isObsolete' | 'lang' | 'name' | 'pkgName' | 'repo' | 'source' | 'versionCode' | 'versionName' | ExtensionTypeKeySpecifier)[];
|
||||
export type ExtensionTypeFieldPolicy = {
|
||||
apkName?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
hasUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
@@ -265,6 +265,7 @@ export type ExtensionTypeFieldPolicy = {
|
||||
lang?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
name?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
pkgName?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
repo?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
source?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
versionCode?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
versionName?: FieldPolicy<any> | FieldReadFunction<any>
|
||||
@@ -356,7 +357,7 @@ export type MangaNodeListFieldPolicy = {
|
||||
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
totalCount?: FieldPolicy<any> | FieldReadFunction<any>
|
||||
};
|
||||
export type MangaTypeKeySpecifier = ('age' | 'artist' | 'author' | 'categories' | 'chapters' | 'chaptersAge' | 'chaptersLastFetchedAt' | 'description' | 'downloadCount' | 'genre' | 'id' | 'inLibrary' | 'inLibraryAt' | 'initialized' | 'lastFetchedAt' | 'lastReadChapter' | 'meta' | 'realUrl' | 'source' | 'sourceId' | 'status' | 'thumbnailUrl' | 'title' | 'unreadCount' | 'url' | MangaTypeKeySpecifier)[];
|
||||
export type MangaTypeKeySpecifier = ('age' | 'artist' | 'author' | 'categories' | 'chapters' | 'chaptersAge' | 'chaptersLastFetchedAt' | 'description' | 'downloadCount' | 'genre' | 'id' | 'inLibrary' | 'inLibraryAt' | 'initialized' | 'lastFetchedAt' | 'lastReadChapter' | 'meta' | 'realUrl' | 'source' | 'sourceId' | 'status' | 'thumbnailUrl' | 'title' | 'unreadCount' | 'updateStrategy' | 'url' | MangaTypeKeySpecifier)[];
|
||||
export type MangaTypeFieldPolicy = {
|
||||
age?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
artist?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
@@ -382,6 +383,7 @@ export type MangaTypeFieldPolicy = {
|
||||
thumbnailUrl?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
title?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
unreadCount?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
updateStrategy?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
url?: FieldPolicy<any> | FieldReadFunction<any>
|
||||
};
|
||||
export type MetaEdgeKeySpecifier = ('cursor' | 'node' | MetaEdgeKeySpecifier)[];
|
||||
@@ -473,7 +475,7 @@ export type PageInfoFieldPolicy = {
|
||||
hasPreviousPage?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
startCursor?: FieldPolicy<any> | FieldReadFunction<any>
|
||||
};
|
||||
export type PartialSettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadNewChapters' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPort' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | PartialSettingsTypeKeySpecifier)[];
|
||||
export type PartialSettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadNewChapters' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPort' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | PartialSettingsTypeKeySpecifier)[];
|
||||
export type PartialSettingsTypeFieldPolicy = {
|
||||
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
@@ -492,6 +494,7 @@ export type PartialSettingsTypeFieldPolicy = {
|
||||
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
extensionRepos?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
@@ -585,7 +588,7 @@ export type SetSettingsPayloadFieldPolicy = {
|
||||
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
settings?: FieldPolicy<any> | FieldReadFunction<any>
|
||||
};
|
||||
export type SettingsKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadNewChapters' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPort' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsKeySpecifier)[];
|
||||
export type SettingsKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadNewChapters' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPort' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsKeySpecifier)[];
|
||||
export type SettingsFieldPolicy = {
|
||||
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
@@ -604,6 +607,7 @@ export type SettingsFieldPolicy = {
|
||||
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
extensionRepos?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
@@ -621,7 +625,7 @@ export type SettingsFieldPolicy = {
|
||||
webUIInterface?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
webUIUpdateCheckInterval?: FieldPolicy<any> | FieldReadFunction<any>
|
||||
};
|
||||
export type SettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadNewChapters' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPort' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsTypeKeySpecifier)[];
|
||||
export type SettingsTypeKeySpecifier = ('autoDownloadAheadLimit' | 'autoDownloadNewChapters' | 'backupInterval' | 'backupPath' | 'backupTTL' | 'backupTime' | 'basicAuthEnabled' | 'basicAuthPassword' | 'basicAuthUsername' | 'debugLogsEnabled' | 'downloadAsCbz' | 'downloadsPath' | 'electronPath' | 'excludeCompleted' | 'excludeEntryWithUnreadChapters' | 'excludeNotStarted' | 'excludeUnreadChapters' | 'extensionRepos' | 'globalUpdateInterval' | 'gqlDebugLogsEnabled' | 'initialOpenInBrowserEnabled' | 'ip' | 'localSourcePath' | 'maxSourcesInParallel' | 'port' | 'socksProxyEnabled' | 'socksProxyHost' | 'socksProxyPort' | 'systemTrayEnabled' | 'updateMangas' | 'webUIChannel' | 'webUIFlavor' | 'webUIInterface' | 'webUIUpdateCheckInterval' | SettingsTypeKeySpecifier)[];
|
||||
export type SettingsTypeFieldPolicy = {
|
||||
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
@@ -640,6 +644,7 @@ export type SettingsTypeFieldPolicy = {
|
||||
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
extensionRepos?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||
|
||||
@@ -511,6 +511,7 @@ export type ExtensionConditionInput = {
|
||||
lang?: InputMaybe<Scalars['String']['input']>;
|
||||
name?: InputMaybe<Scalars['String']['input']>;
|
||||
pkgName?: InputMaybe<Scalars['String']['input']>;
|
||||
repo?: InputMaybe<Scalars['String']['input']>;
|
||||
versionCode?: InputMaybe<Scalars['Int']['input']>;
|
||||
versionName?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
@@ -534,6 +535,7 @@ export type ExtensionFilterInput = {
|
||||
not?: InputMaybe<ExtensionFilterInput>;
|
||||
or?: InputMaybe<Array<ExtensionFilterInput>>;
|
||||
pkgName?: InputMaybe<StringFilterInput>;
|
||||
repo?: InputMaybe<StringFilterInput>;
|
||||
versionCode?: InputMaybe<IntFilterInput>;
|
||||
versionName?: InputMaybe<StringFilterInput>;
|
||||
};
|
||||
@@ -563,6 +565,7 @@ export type ExtensionType = {
|
||||
lang: Scalars['String']['output'];
|
||||
name: Scalars['String']['output'];
|
||||
pkgName: Scalars['String']['output'];
|
||||
repo?: Maybe<Scalars['String']['output']>;
|
||||
source: SourceNodeList;
|
||||
versionCode: Scalars['Int']['output'];
|
||||
versionName: Scalars['String']['output'];
|
||||
@@ -880,6 +883,7 @@ export type MangaType = {
|
||||
thumbnailUrl?: Maybe<Scalars['String']['output']>;
|
||||
title: Scalars['String']['output'];
|
||||
unreadCount: Scalars['Int']['output'];
|
||||
updateStrategy: UpdateStrategy;
|
||||
url: Scalars['String']['output'];
|
||||
};
|
||||
|
||||
@@ -1263,6 +1267,7 @@ export type PartialSettingsType = Settings & {
|
||||
excludeEntryWithUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
||||
excludeNotStarted?: Maybe<Scalars['Boolean']['output']>;
|
||||
excludeUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
||||
extensionRepos?: Maybe<Array<Scalars['String']['output']>>;
|
||||
globalUpdateInterval?: Maybe<Scalars['Float']['output']>;
|
||||
gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>;
|
||||
initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>;
|
||||
@@ -1299,6 +1304,7 @@ export type PartialSettingsTypeInput = {
|
||||
excludeEntryWithUnreadChapters?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
excludeNotStarted?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
excludeUnreadChapters?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
extensionRepos?: InputMaybe<Array<Scalars['String']['input']>>;
|
||||
globalUpdateInterval?: InputMaybe<Scalars['Float']['input']>;
|
||||
gqlDebugLogsEnabled?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
initialOpenInBrowserEnabled?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
@@ -1583,6 +1589,7 @@ export type Settings = {
|
||||
excludeEntryWithUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
||||
excludeNotStarted?: Maybe<Scalars['Boolean']['output']>;
|
||||
excludeUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
||||
extensionRepos?: Maybe<Array<Scalars['String']['output']>>;
|
||||
globalUpdateInterval?: Maybe<Scalars['Float']['output']>;
|
||||
gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>;
|
||||
initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>;
|
||||
@@ -1620,6 +1627,7 @@ export type SettingsType = Settings & {
|
||||
excludeEntryWithUnreadChapters: Scalars['Boolean']['output'];
|
||||
excludeNotStarted: Scalars['Boolean']['output'];
|
||||
excludeUnreadChapters: Scalars['Boolean']['output'];
|
||||
extensionRepos: Array<Scalars['String']['output']>;
|
||||
globalUpdateInterval: Scalars['Float']['output'];
|
||||
gqlDebugLogsEnabled: Scalars['Boolean']['output'];
|
||||
initialOpenInBrowserEnabled: Scalars['Boolean']['output'];
|
||||
@@ -1918,7 +1926,7 @@ export type UpdateExtensionPatchInput = {
|
||||
export type UpdateExtensionPayload = {
|
||||
__typename?: 'UpdateExtensionPayload';
|
||||
clientMutationId?: Maybe<Scalars['String']['output']>;
|
||||
extension: ExtensionType;
|
||||
extension?: Maybe<ExtensionType>;
|
||||
};
|
||||
|
||||
export type UpdateExtensionsInput = {
|
||||
@@ -2052,6 +2060,11 @@ export type UpdateStopPayload = {
|
||||
clientMutationId?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export enum UpdateStrategy {
|
||||
AlwaysUpdate = 'ALWAYS_UPDATE',
|
||||
OnlyFetchOnce = 'ONLY_FETCH_ONCE'
|
||||
}
|
||||
|
||||
export type ValidateBackupInput = {
|
||||
backup: Scalars['Upload']['input'];
|
||||
};
|
||||
@@ -2135,7 +2148,7 @@ export type FullMangaFieldsFragment = { __typename?: 'MangaType', unreadCount: n
|
||||
|
||||
export type UpdaterMangaFieldsFragment = { __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null };
|
||||
|
||||
export type FullExtensionFieldsFragment = { __typename?: 'ExtensionType', apkName: string, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string };
|
||||
export type FullExtensionFieldsFragment = { __typename?: 'ExtensionType', apkName: string, repo?: string | null, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string };
|
||||
|
||||
export type FullDownloadStatusFragment = { __typename?: 'DownloadStatus', state: DownloaderState, queue: Array<{ __typename?: 'DownloadType', progress: number, state: DownloadState, tries: number, chapter: { __typename?: 'ChapterType', id: number, name: string, sourceOrder: number, isDownloaded: boolean, manga: { __typename?: 'MangaType', id: number, title: string, downloadCount: number } } }> };
|
||||
|
||||
@@ -2151,7 +2164,7 @@ export type WebuiUpdateInfoFragment = { __typename?: 'WebUIUpdateInfo', channel:
|
||||
|
||||
export type WebuiUpdateStatusFragment = { __typename?: 'WebUIUpdateStatus', progress: number, state: UpdateState, info: { __typename?: 'WebUIUpdateInfo', channel: string, tag: string } };
|
||||
|
||||
export type ServerSettingsFragment = { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string };
|
||||
export type ServerSettingsFragment = { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, extensionRepos: Array<string>, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string };
|
||||
|
||||
export type CreateBackupMutationVariables = Exact<{
|
||||
input: CreateBackupInput;
|
||||
@@ -2362,28 +2375,28 @@ export type GetExtensionsFetchMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetExtensionsFetchMutation = { __typename?: 'Mutation', fetchExtensions: { __typename?: 'FetchExtensionsPayload', clientMutationId?: string | null, extensions: Array<{ __typename?: 'ExtensionType', apkName: string, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string }> } };
|
||||
export type GetExtensionsFetchMutation = { __typename?: 'Mutation', fetchExtensions: { __typename?: 'FetchExtensionsPayload', clientMutationId?: string | null, extensions: Array<{ __typename?: 'ExtensionType', apkName: string, repo?: string | null, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string }> } };
|
||||
|
||||
export type UpdateExtensionMutationVariables = Exact<{
|
||||
input: UpdateExtensionInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateExtensionMutation = { __typename?: 'Mutation', updateExtension: { __typename?: 'UpdateExtensionPayload', clientMutationId?: string | null, extension: { __typename?: 'ExtensionType', pkgName: string, apkName: string, versionName: string, versionCode: number, isInstalled: boolean, isObsolete: boolean, hasUpdate: boolean } } };
|
||||
export type UpdateExtensionMutation = { __typename?: 'Mutation', updateExtension: { __typename?: 'UpdateExtensionPayload', clientMutationId?: string | null, extension?: { __typename?: 'ExtensionType', pkgName: string, apkName: string, repo?: string | null, versionName: string, versionCode: number, isInstalled: boolean, isObsolete: boolean, hasUpdate: boolean } | null } };
|
||||
|
||||
export type UpdateExtensionsMutationVariables = Exact<{
|
||||
input: UpdateExtensionsInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateExtensionsMutation = { __typename?: 'Mutation', updateExtensions: { __typename?: 'UpdateExtensionsPayload', clientMutationId?: string | null, extensions: Array<{ __typename?: 'ExtensionType', pkgName: string, apkName: string, versionName: string, versionCode: number, isInstalled: boolean, isObsolete: boolean, hasUpdate: boolean }> } };
|
||||
export type UpdateExtensionsMutation = { __typename?: 'Mutation', updateExtensions: { __typename?: 'UpdateExtensionsPayload', clientMutationId?: string | null, extensions: Array<{ __typename?: 'ExtensionType', pkgName: string, apkName: string, repo?: string | null, versionName: string, versionCode: number, isInstalled: boolean, isObsolete: boolean, hasUpdate: boolean }> } };
|
||||
|
||||
export type InstallExternalExtensionMutationVariables = Exact<{
|
||||
file: Scalars['Upload']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type InstallExternalExtensionMutation = { __typename?: 'Mutation', installExternalExtension: { __typename?: 'InstallExternalExtensionPayload', clientMutationId?: string | null, extension: { __typename?: 'ExtensionType', apkName: string, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string } } };
|
||||
export type InstallExternalExtensionMutation = { __typename?: 'Mutation', installExternalExtension: { __typename?: 'InstallExternalExtensionPayload', clientMutationId?: string | null, extension: { __typename?: 'ExtensionType', apkName: string, repo?: string | null, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string } } };
|
||||
|
||||
export type DeleteGlobalMetadataMutationVariables = Exact<{
|
||||
input: DeleteGlobalMetaInput;
|
||||
@@ -2472,14 +2485,14 @@ export type ResetServerSettingsMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type ResetServerSettingsMutation = { __typename?: 'Mutation', resetSettings: { __typename?: 'ResetSettingsPayload', clientMutationId?: string | null, settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string } } };
|
||||
export type ResetServerSettingsMutation = { __typename?: 'Mutation', resetSettings: { __typename?: 'ResetSettingsPayload', clientMutationId?: string | null, settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, extensionRepos: Array<string>, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string } } };
|
||||
|
||||
export type UpdateServerSettingsMutationVariables = Exact<{
|
||||
input: SetSettingsInput;
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateServerSettingsMutation = { __typename?: 'Mutation', setSettings: { __typename?: 'SetSettingsPayload', clientMutationId?: string | null, settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string } } };
|
||||
export type UpdateServerSettingsMutation = { __typename?: 'Mutation', setSettings: { __typename?: 'SetSettingsPayload', clientMutationId?: string | null, settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, extensionRepos: Array<string>, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string } } };
|
||||
|
||||
export type GetSourceMangasFetchMutationVariables = Exact<{
|
||||
input: FetchSourceMangaInput;
|
||||
@@ -2601,7 +2614,7 @@ export type GetExtensionQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetExtensionQuery = { __typename?: 'Query', extension: { __typename?: 'ExtensionType', apkName: string, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string } };
|
||||
export type GetExtensionQuery = { __typename?: 'Query', extension: { __typename?: 'ExtensionType', apkName: string, repo?: string | null, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string } };
|
||||
|
||||
export type GetExtensionsQueryVariables = Exact<{
|
||||
after?: InputMaybe<Scalars['Cursor']['input']>;
|
||||
@@ -2616,7 +2629,7 @@ export type GetExtensionsQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetExtensionsQuery = { __typename?: 'Query', extensions: { __typename?: 'ExtensionNodeList', totalCount: number, nodes: Array<{ __typename?: 'ExtensionType', apkName: string, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string }>, pageInfo: { __typename?: 'PageInfo', endCursor?: any | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: any | null } } };
|
||||
export type GetExtensionsQuery = { __typename?: 'Query', extensions: { __typename?: 'ExtensionNodeList', totalCount: number, nodes: Array<{ __typename?: 'ExtensionType', apkName: string, repo?: string | null, hasUpdate: boolean, iconUrl: string, isInstalled: boolean, isNsfw: boolean, isObsolete: boolean, lang: string, name: string, pkgName: string, versionCode: number, versionName: string }>, pageInfo: { __typename?: 'PageInfo', endCursor?: any | null, hasNextPage: boolean, hasPreviousPage: boolean, startCursor?: any | null } } };
|
||||
|
||||
export type GetGlobalMetadataQueryVariables = Exact<{
|
||||
key: Scalars['String']['input'];
|
||||
@@ -2685,7 +2698,7 @@ export type GetWebuiUpdateStatusQuery = { __typename?: 'Query', getWebUIUpdateSt
|
||||
export type GetServerSettingsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetServerSettingsQuery = { __typename?: 'Query', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string } };
|
||||
export type GetServerSettingsQuery = { __typename?: 'Query', settings: { __typename?: 'SettingsType', ip: string, port: number, socksProxyEnabled: boolean, socksProxyHost: string, socksProxyPort: string, webUIFlavor: WebUiFlavor, initialOpenInBrowserEnabled: boolean, webUIInterface: WebUiInterface, electronPath: string, webUIChannel: WebUiChannel, webUIUpdateCheckInterval: number, downloadAsCbz: boolean, downloadsPath: string, autoDownloadNewChapters: boolean, excludeEntryWithUnreadChapters: boolean, autoDownloadAheadLimit: number, extensionRepos: Array<string>, maxSourcesInParallel: number, excludeUnreadChapters: boolean, excludeNotStarted: boolean, excludeCompleted: boolean, globalUpdateInterval: number, updateMangas: boolean, basicAuthEnabled: boolean, basicAuthUsername: string, basicAuthPassword: string, debugLogsEnabled: boolean, gqlDebugLogsEnabled: boolean, systemTrayEnabled: boolean, backupPath: string, backupTime: string, backupInterval: number, backupTTL: number, localSourcePath: string } };
|
||||
|
||||
export type GetSourceQueryVariables = Exact<{
|
||||
id: Scalars['LongString']['input'];
|
||||
|
||||
@@ -29,6 +29,7 @@ export const UPDATE_EXTENSION = gql`
|
||||
extension {
|
||||
pkgName
|
||||
apkName
|
||||
repo
|
||||
versionName
|
||||
versionCode
|
||||
isInstalled
|
||||
@@ -46,6 +47,7 @@ export const UPDATE_EXTENSIONS = gql`
|
||||
extensions {
|
||||
pkgName
|
||||
apkName
|
||||
repo
|
||||
versionName
|
||||
versionCode
|
||||
isInstalled
|
||||
|
||||
@@ -1026,7 +1026,7 @@ export class RequestManager {
|
||||
...cachedExtensions.data.fetchExtensions,
|
||||
extensions: cachedExtensions.data.fetchExtensions.extensions.map((extension) => {
|
||||
const isUpdatedExtension =
|
||||
extension.apkName === response.data?.updateExtension.extension.apkName;
|
||||
extension.apkName === response.data?.updateExtension.extension?.apkName;
|
||||
if (!isUpdatedExtension) {
|
||||
return extension;
|
||||
}
|
||||
|
||||
@@ -98,6 +98,9 @@ export function Extensions() {
|
||||
const theme = useTheme();
|
||||
const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));
|
||||
|
||||
const { data: serverSettingsData } = requestManager.useGetServerSettings();
|
||||
const usesCustomRepos = !!serverSettingsData?.settings.extensionRepos.length;
|
||||
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const { setTitle, setAction } = useContext(NavBarContext);
|
||||
const [shownLangs, setShownLangs] = useLocalStorage<string[]>('shownExtensionLangs', extensionDefaultLangs());
|
||||
@@ -255,7 +258,11 @@ export function Extensions() {
|
||||
|
||||
return (
|
||||
<StyledGroupItemWrapper key={item.apkName} isLastItem={index === visibleExtensions.length - 1}>
|
||||
<ExtensionCard extension={item} handleUpdate={handleExtensionUpdate} />
|
||||
<ExtensionCard
|
||||
extension={item}
|
||||
handleUpdate={handleExtensionUpdate}
|
||||
usesCustomRepos={usesCustomRepos}
|
||||
/>
|
||||
</StyledGroupItemWrapper>
|
||||
);
|
||||
}}
|
||||
|
||||
@@ -16,6 +16,7 @@ import { useLocalStorage } from '@/util/useLocalStorage.tsx';
|
||||
import { TextSetting } from '@/components/settings/TextSetting.tsx';
|
||||
import { ServerSettings as GqlServerSettings } from '@/typings.ts';
|
||||
import { NumberSetting } from '@/components/settings/NumberSetting.tsx';
|
||||
import { MutableListSetting } from '@/components/settings/MutableListSetting.tsx';
|
||||
|
||||
type ServerSettingsType = Pick<
|
||||
GqlServerSettings,
|
||||
@@ -32,6 +33,7 @@ type ServerSettingsType = Pick<
|
||||
| 'basicAuthPassword'
|
||||
| 'maxSourcesInParallel'
|
||||
| 'localSourcePath'
|
||||
| 'extensionRepos'
|
||||
>;
|
||||
|
||||
const extractDownloadSettings = (settings: GqlServerSettings): ServerSettingsType => ({
|
||||
@@ -48,6 +50,7 @@ const extractDownloadSettings = (settings: GqlServerSettings): ServerSettingsTyp
|
||||
basicAuthPassword: settings.basicAuthPassword,
|
||||
maxSourcesInParallel: settings.maxSourcesInParallel,
|
||||
localSourcePath: settings.localSourcePath,
|
||||
extensionRepos: settings.extensionRepos,
|
||||
});
|
||||
|
||||
export const ServerSettings = () => {
|
||||
@@ -120,6 +123,21 @@ export const ServerSettings = () => {
|
||||
handleUpdate={(parallelSources) => updateSetting('maxSourcesInParallel', parallelSources)}
|
||||
/>
|
||||
</List>
|
||||
<List
|
||||
subheader={
|
||||
<ListSubheader component="div" id="server-settings-extension-repos">
|
||||
{t('extension.title')}
|
||||
</ListSubheader>
|
||||
}
|
||||
>
|
||||
<MutableListSetting
|
||||
settingName={t('extension.settings.repositories.custom.label.title')}
|
||||
description={t('extension.settings.repositories.custom.label.description')}
|
||||
handleChange={(repos) => updateSetting('extensionRepos', repos)}
|
||||
values={serverSettings?.extensionRepos}
|
||||
addItemButtonTitle={t('extension.settings.repositories.custom.dialog.action.button.add')}
|
||||
/>
|
||||
</List>
|
||||
<List
|
||||
subheader={
|
||||
<ListSubheader component="div" id="server-settings-requests">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[
|
||||
{
|
||||
"uiVersion": "PREVIEW",
|
||||
"serverVersion": "r1438"
|
||||
"serverVersion": "r1444"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user