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 {
|
interface IProps {
|
||||||
extension: PartialExtension;
|
extension: PartialExtension;
|
||||||
handleUpdate: () => void;
|
handleUpdate: () => void;
|
||||||
|
usesCustomRepos: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ExtensionAction {
|
enum ExtensionAction {
|
||||||
@@ -91,8 +92,9 @@ export function ExtensionCard(props: IProps) {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
extension: { name, lang, versionName, isInstalled, hasUpdate, isObsolete, pkgName, iconUrl, isNsfw },
|
extension: { name, lang, versionName, isInstalled, hasUpdate, isObsolete, pkgName, iconUrl, isNsfw, repo },
|
||||||
handleUpdate,
|
handleUpdate,
|
||||||
|
usesCustomRepos,
|
||||||
} = props;
|
} = props;
|
||||||
const [installedState, setInstalledState] = useState<InstalledStates>(
|
const [installedState, setInstalledState] = useState<InstalledStates>(
|
||||||
getInstalledState(isInstalled, isObsolete, hasUpdate),
|
getInstalledState(isInstalled, isObsolete, hasUpdate),
|
||||||
@@ -184,6 +186,11 @@ export function ExtensionCard(props: IProps) {
|
|||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
{usesCustomRepos && (
|
||||||
|
<Typography variant="caption" display="block">
|
||||||
|
{repo}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</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 IconButton from '@mui/material/IconButton';
|
||||||
import { Visibility, VisibilityOff } from '@mui/icons-material';
|
import { Visibility, VisibilityOff } from '@mui/icons-material';
|
||||||
|
|
||||||
export const TextSetting = ({
|
export type TextSettingProps = {
|
||||||
settingName,
|
|
||||||
dialogDescription,
|
|
||||||
value,
|
|
||||||
handleChange,
|
|
||||||
isPassword = false,
|
|
||||||
placeholder = '',
|
|
||||||
disabled = false,
|
|
||||||
}: {
|
|
||||||
settingName: string;
|
settingName: string;
|
||||||
|
dialogTitle?: string;
|
||||||
dialogDescription?: string;
|
dialogDescription?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
handleChange: (value: string) => void;
|
handleChange: (value: string) => void;
|
||||||
isPassword?: boolean;
|
isPassword?: boolean;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
}) => {
|
};
|
||||||
|
|
||||||
|
export const TextSetting = ({
|
||||||
|
settingName,
|
||||||
|
dialogTitle = settingName,
|
||||||
|
dialogDescription,
|
||||||
|
value,
|
||||||
|
handleChange,
|
||||||
|
isPassword = false,
|
||||||
|
placeholder = '',
|
||||||
|
disabled = false,
|
||||||
|
}: TextSettingProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||||
@@ -70,13 +74,15 @@ export const TextSetting = ({
|
|||||||
<ListItemText
|
<ListItemText
|
||||||
primary={settingName}
|
primary={settingName}
|
||||||
secondary={isPassword ? value?.replace(/./g, '*') : value ?? t('global.label.loading')}
|
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>
|
</ListItemButton>
|
||||||
|
|
||||||
<Dialog open={isDialogOpen} onClose={() => closeDialog()} fullWidth>
|
<Dialog open={isDialogOpen} onClose={() => closeDialog()} fullWidth>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogTitle sx={{ paddingLeft: 0 }}>{settingName}</DialogTitle>
|
<DialogTitle sx={{ paddingLeft: 0 }}>{dialogTitle}</DialogTitle>
|
||||||
{!!dialogDescription && (
|
{!!dialogDescription && (
|
||||||
<DialogContentText sx={{ paddingBottom: '10px' }}>{dialogDescription}</DialogContentText>
|
<DialogContentText sx={{ paddingBottom: '10px' }}>{dialogDescription}</DialogContentText>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -233,6 +233,23 @@
|
|||||||
"all": "All",
|
"all": "All",
|
||||||
"other": "Other"
|
"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": {
|
"state": {
|
||||||
"label": {
|
"label": {
|
||||||
"installed": "Installed",
|
"installed": "Installed",
|
||||||
@@ -247,6 +264,7 @@
|
|||||||
},
|
},
|
||||||
"global": {
|
"global": {
|
||||||
"button": {
|
"button": {
|
||||||
|
"add": "Add",
|
||||||
"browse": "Browse",
|
"browse": "Browse",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
@@ -326,6 +344,7 @@
|
|||||||
"none": "None",
|
"none": "None",
|
||||||
"other": "Other",
|
"other": "Other",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
|
"placeholder": "Placeholder",
|
||||||
"sort": "Sort",
|
"sort": "Sort",
|
||||||
"unknown": "Unknown",
|
"unknown": "Unknown",
|
||||||
"username": "Username"
|
"username": "Username"
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ export const UPDATER_MANGA_FIELDS = gql`
|
|||||||
export const FULL_EXTENSION_FIELDS = gql`
|
export const FULL_EXTENSION_FIELDS = gql`
|
||||||
fragment FULL_EXTENSION_FIELDS on ExtensionType {
|
fragment FULL_EXTENSION_FIELDS on ExtensionType {
|
||||||
apkName
|
apkName
|
||||||
|
repo
|
||||||
hasUpdate
|
hasUpdate
|
||||||
iconUrl
|
iconUrl
|
||||||
isInstalled
|
isInstalled
|
||||||
@@ -473,6 +474,9 @@ export const SERVER_SETTINGS = gql`
|
|||||||
excludeEntryWithUnreadChapters
|
excludeEntryWithUnreadChapters
|
||||||
autoDownloadAheadLimit
|
autoDownloadAheadLimit
|
||||||
|
|
||||||
|
# extensions
|
||||||
|
extensionRepos
|
||||||
|
|
||||||
# requests
|
# requests
|
||||||
maxSourcesInParallel
|
maxSourcesInParallel
|
||||||
|
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ export type ExtensionNodeListFieldPolicy = {
|
|||||||
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
totalCount?: 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 = {
|
export type ExtensionTypeFieldPolicy = {
|
||||||
apkName?: FieldPolicy<any> | FieldReadFunction<any>,
|
apkName?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
hasUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
|
hasUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
@@ -265,6 +265,7 @@ export type ExtensionTypeFieldPolicy = {
|
|||||||
lang?: FieldPolicy<any> | FieldReadFunction<any>,
|
lang?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
name?: FieldPolicy<any> | FieldReadFunction<any>,
|
name?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
pkgName?: FieldPolicy<any> | FieldReadFunction<any>,
|
pkgName?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
|
repo?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
source?: FieldPolicy<any> | FieldReadFunction<any>,
|
source?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
versionCode?: FieldPolicy<any> | FieldReadFunction<any>,
|
versionCode?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
versionName?: FieldPolicy<any> | FieldReadFunction<any>
|
versionName?: FieldPolicy<any> | FieldReadFunction<any>
|
||||||
@@ -356,7 +357,7 @@ export type MangaNodeListFieldPolicy = {
|
|||||||
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
totalCount?: 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 = {
|
export type MangaTypeFieldPolicy = {
|
||||||
age?: FieldPolicy<any> | FieldReadFunction<any>,
|
age?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
artist?: FieldPolicy<any> | FieldReadFunction<any>,
|
artist?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
@@ -382,6 +383,7 @@ export type MangaTypeFieldPolicy = {
|
|||||||
thumbnailUrl?: FieldPolicy<any> | FieldReadFunction<any>,
|
thumbnailUrl?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
title?: FieldPolicy<any> | FieldReadFunction<any>,
|
title?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
unreadCount?: FieldPolicy<any> | FieldReadFunction<any>,
|
unreadCount?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
|
updateStrategy?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
url?: FieldPolicy<any> | FieldReadFunction<any>
|
url?: FieldPolicy<any> | FieldReadFunction<any>
|
||||||
};
|
};
|
||||||
export type MetaEdgeKeySpecifier = ('cursor' | 'node' | MetaEdgeKeySpecifier)[];
|
export type MetaEdgeKeySpecifier = ('cursor' | 'node' | MetaEdgeKeySpecifier)[];
|
||||||
@@ -473,7 +475,7 @@ export type PageInfoFieldPolicy = {
|
|||||||
hasPreviousPage?: FieldPolicy<any> | FieldReadFunction<any>,
|
hasPreviousPage?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
startCursor?: 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 = {
|
export type PartialSettingsTypeFieldPolicy = {
|
||||||
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
@@ -492,6 +494,7 @@ export type PartialSettingsTypeFieldPolicy = {
|
|||||||
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
|
extensionRepos?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
@@ -585,7 +588,7 @@ export type SetSettingsPayloadFieldPolicy = {
|
|||||||
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>,
|
clientMutationId?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
settings?: 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 = {
|
export type SettingsFieldPolicy = {
|
||||||
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
@@ -604,6 +607,7 @@ export type SettingsFieldPolicy = {
|
|||||||
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
|
extensionRepos?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
@@ -621,7 +625,7 @@ export type SettingsFieldPolicy = {
|
|||||||
webUIInterface?: FieldPolicy<any> | FieldReadFunction<any>,
|
webUIInterface?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
webUIUpdateCheckInterval?: 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 = {
|
export type SettingsTypeFieldPolicy = {
|
||||||
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
autoDownloadAheadLimit?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
autoDownloadNewChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
@@ -640,6 +644,7 @@ export type SettingsTypeFieldPolicy = {
|
|||||||
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeEntryWithUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeNotStarted?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
excludeUnreadChapters?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
|
extensionRepos?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
globalUpdateInterval?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
gqlDebugLogsEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
initialOpenInBrowserEnabled?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
|
|||||||
@@ -511,6 +511,7 @@ export type ExtensionConditionInput = {
|
|||||||
lang?: InputMaybe<Scalars['String']['input']>;
|
lang?: InputMaybe<Scalars['String']['input']>;
|
||||||
name?: InputMaybe<Scalars['String']['input']>;
|
name?: InputMaybe<Scalars['String']['input']>;
|
||||||
pkgName?: InputMaybe<Scalars['String']['input']>;
|
pkgName?: InputMaybe<Scalars['String']['input']>;
|
||||||
|
repo?: InputMaybe<Scalars['String']['input']>;
|
||||||
versionCode?: InputMaybe<Scalars['Int']['input']>;
|
versionCode?: InputMaybe<Scalars['Int']['input']>;
|
||||||
versionName?: InputMaybe<Scalars['String']['input']>;
|
versionName?: InputMaybe<Scalars['String']['input']>;
|
||||||
};
|
};
|
||||||
@@ -534,6 +535,7 @@ export type ExtensionFilterInput = {
|
|||||||
not?: InputMaybe<ExtensionFilterInput>;
|
not?: InputMaybe<ExtensionFilterInput>;
|
||||||
or?: InputMaybe<Array<ExtensionFilterInput>>;
|
or?: InputMaybe<Array<ExtensionFilterInput>>;
|
||||||
pkgName?: InputMaybe<StringFilterInput>;
|
pkgName?: InputMaybe<StringFilterInput>;
|
||||||
|
repo?: InputMaybe<StringFilterInput>;
|
||||||
versionCode?: InputMaybe<IntFilterInput>;
|
versionCode?: InputMaybe<IntFilterInput>;
|
||||||
versionName?: InputMaybe<StringFilterInput>;
|
versionName?: InputMaybe<StringFilterInput>;
|
||||||
};
|
};
|
||||||
@@ -563,6 +565,7 @@ export type ExtensionType = {
|
|||||||
lang: Scalars['String']['output'];
|
lang: Scalars['String']['output'];
|
||||||
name: Scalars['String']['output'];
|
name: Scalars['String']['output'];
|
||||||
pkgName: Scalars['String']['output'];
|
pkgName: Scalars['String']['output'];
|
||||||
|
repo?: Maybe<Scalars['String']['output']>;
|
||||||
source: SourceNodeList;
|
source: SourceNodeList;
|
||||||
versionCode: Scalars['Int']['output'];
|
versionCode: Scalars['Int']['output'];
|
||||||
versionName: Scalars['String']['output'];
|
versionName: Scalars['String']['output'];
|
||||||
@@ -880,6 +883,7 @@ export type MangaType = {
|
|||||||
thumbnailUrl?: Maybe<Scalars['String']['output']>;
|
thumbnailUrl?: Maybe<Scalars['String']['output']>;
|
||||||
title: Scalars['String']['output'];
|
title: Scalars['String']['output'];
|
||||||
unreadCount: Scalars['Int']['output'];
|
unreadCount: Scalars['Int']['output'];
|
||||||
|
updateStrategy: UpdateStrategy;
|
||||||
url: Scalars['String']['output'];
|
url: Scalars['String']['output'];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1263,6 +1267,7 @@ export type PartialSettingsType = Settings & {
|
|||||||
excludeEntryWithUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
excludeEntryWithUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
||||||
excludeNotStarted?: Maybe<Scalars['Boolean']['output']>;
|
excludeNotStarted?: Maybe<Scalars['Boolean']['output']>;
|
||||||
excludeUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
excludeUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
||||||
|
extensionRepos?: Maybe<Array<Scalars['String']['output']>>;
|
||||||
globalUpdateInterval?: Maybe<Scalars['Float']['output']>;
|
globalUpdateInterval?: Maybe<Scalars['Float']['output']>;
|
||||||
gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>;
|
gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>;
|
||||||
initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>;
|
initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>;
|
||||||
@@ -1299,6 +1304,7 @@ export type PartialSettingsTypeInput = {
|
|||||||
excludeEntryWithUnreadChapters?: InputMaybe<Scalars['Boolean']['input']>;
|
excludeEntryWithUnreadChapters?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
excludeNotStarted?: InputMaybe<Scalars['Boolean']['input']>;
|
excludeNotStarted?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
excludeUnreadChapters?: InputMaybe<Scalars['Boolean']['input']>;
|
excludeUnreadChapters?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
|
extensionRepos?: InputMaybe<Array<Scalars['String']['input']>>;
|
||||||
globalUpdateInterval?: InputMaybe<Scalars['Float']['input']>;
|
globalUpdateInterval?: InputMaybe<Scalars['Float']['input']>;
|
||||||
gqlDebugLogsEnabled?: InputMaybe<Scalars['Boolean']['input']>;
|
gqlDebugLogsEnabled?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
initialOpenInBrowserEnabled?: InputMaybe<Scalars['Boolean']['input']>;
|
initialOpenInBrowserEnabled?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
@@ -1583,6 +1589,7 @@ export type Settings = {
|
|||||||
excludeEntryWithUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
excludeEntryWithUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
||||||
excludeNotStarted?: Maybe<Scalars['Boolean']['output']>;
|
excludeNotStarted?: Maybe<Scalars['Boolean']['output']>;
|
||||||
excludeUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
excludeUnreadChapters?: Maybe<Scalars['Boolean']['output']>;
|
||||||
|
extensionRepos?: Maybe<Array<Scalars['String']['output']>>;
|
||||||
globalUpdateInterval?: Maybe<Scalars['Float']['output']>;
|
globalUpdateInterval?: Maybe<Scalars['Float']['output']>;
|
||||||
gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>;
|
gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>;
|
||||||
initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>;
|
initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>;
|
||||||
@@ -1620,6 +1627,7 @@ export type SettingsType = Settings & {
|
|||||||
excludeEntryWithUnreadChapters: Scalars['Boolean']['output'];
|
excludeEntryWithUnreadChapters: Scalars['Boolean']['output'];
|
||||||
excludeNotStarted: Scalars['Boolean']['output'];
|
excludeNotStarted: Scalars['Boolean']['output'];
|
||||||
excludeUnreadChapters: Scalars['Boolean']['output'];
|
excludeUnreadChapters: Scalars['Boolean']['output'];
|
||||||
|
extensionRepos: Array<Scalars['String']['output']>;
|
||||||
globalUpdateInterval: Scalars['Float']['output'];
|
globalUpdateInterval: Scalars['Float']['output'];
|
||||||
gqlDebugLogsEnabled: Scalars['Boolean']['output'];
|
gqlDebugLogsEnabled: Scalars['Boolean']['output'];
|
||||||
initialOpenInBrowserEnabled: Scalars['Boolean']['output'];
|
initialOpenInBrowserEnabled: Scalars['Boolean']['output'];
|
||||||
@@ -1918,7 +1926,7 @@ export type UpdateExtensionPatchInput = {
|
|||||||
export type UpdateExtensionPayload = {
|
export type UpdateExtensionPayload = {
|
||||||
__typename?: 'UpdateExtensionPayload';
|
__typename?: 'UpdateExtensionPayload';
|
||||||
clientMutationId?: Maybe<Scalars['String']['output']>;
|
clientMutationId?: Maybe<Scalars['String']['output']>;
|
||||||
extension: ExtensionType;
|
extension?: Maybe<ExtensionType>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UpdateExtensionsInput = {
|
export type UpdateExtensionsInput = {
|
||||||
@@ -2052,6 +2060,11 @@ export type UpdateStopPayload = {
|
|||||||
clientMutationId?: Maybe<Scalars['String']['output']>;
|
clientMutationId?: Maybe<Scalars['String']['output']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export enum UpdateStrategy {
|
||||||
|
AlwaysUpdate = 'ALWAYS_UPDATE',
|
||||||
|
OnlyFetchOnce = 'ONLY_FETCH_ONCE'
|
||||||
|
}
|
||||||
|
|
||||||
export type ValidateBackupInput = {
|
export type ValidateBackupInput = {
|
||||||
backup: Scalars['Upload']['input'];
|
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 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 } } }> };
|
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 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<{
|
export type CreateBackupMutationVariables = Exact<{
|
||||||
input: CreateBackupInput;
|
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<{
|
export type UpdateExtensionMutationVariables = Exact<{
|
||||||
input: UpdateExtensionInput;
|
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<{
|
export type UpdateExtensionsMutationVariables = Exact<{
|
||||||
input: UpdateExtensionsInput;
|
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<{
|
export type InstallExternalExtensionMutationVariables = Exact<{
|
||||||
file: Scalars['Upload']['input'];
|
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<{
|
export type DeleteGlobalMetadataMutationVariables = Exact<{
|
||||||
input: DeleteGlobalMetaInput;
|
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<{
|
export type UpdateServerSettingsMutationVariables = Exact<{
|
||||||
input: SetSettingsInput;
|
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<{
|
export type GetSourceMangasFetchMutationVariables = Exact<{
|
||||||
input: FetchSourceMangaInput;
|
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<{
|
export type GetExtensionsQueryVariables = Exact<{
|
||||||
after?: InputMaybe<Scalars['Cursor']['input']>;
|
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<{
|
export type GetGlobalMetadataQueryVariables = Exact<{
|
||||||
key: Scalars['String']['input'];
|
key: Scalars['String']['input'];
|
||||||
@@ -2685,7 +2698,7 @@ export type GetWebuiUpdateStatusQuery = { __typename?: 'Query', getWebUIUpdateSt
|
|||||||
export type GetServerSettingsQueryVariables = Exact<{ [key: string]: never; }>;
|
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<{
|
export type GetSourceQueryVariables = Exact<{
|
||||||
id: Scalars['LongString']['input'];
|
id: Scalars['LongString']['input'];
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export const UPDATE_EXTENSION = gql`
|
|||||||
extension {
|
extension {
|
||||||
pkgName
|
pkgName
|
||||||
apkName
|
apkName
|
||||||
|
repo
|
||||||
versionName
|
versionName
|
||||||
versionCode
|
versionCode
|
||||||
isInstalled
|
isInstalled
|
||||||
@@ -46,6 +47,7 @@ export const UPDATE_EXTENSIONS = gql`
|
|||||||
extensions {
|
extensions {
|
||||||
pkgName
|
pkgName
|
||||||
apkName
|
apkName
|
||||||
|
repo
|
||||||
versionName
|
versionName
|
||||||
versionCode
|
versionCode
|
||||||
isInstalled
|
isInstalled
|
||||||
|
|||||||
@@ -1026,7 +1026,7 @@ export class RequestManager {
|
|||||||
...cachedExtensions.data.fetchExtensions,
|
...cachedExtensions.data.fetchExtensions,
|
||||||
extensions: cachedExtensions.data.fetchExtensions.extensions.map((extension) => {
|
extensions: cachedExtensions.data.fetchExtensions.extensions.map((extension) => {
|
||||||
const isUpdatedExtension =
|
const isUpdatedExtension =
|
||||||
extension.apkName === response.data?.updateExtension.extension.apkName;
|
extension.apkName === response.data?.updateExtension.extension?.apkName;
|
||||||
if (!isUpdatedExtension) {
|
if (!isUpdatedExtension) {
|
||||||
return extension;
|
return extension;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ export function Extensions() {
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));
|
const isMobileWidth = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
|
const { data: serverSettingsData } = requestManager.useGetServerSettings();
|
||||||
|
const usesCustomRepos = !!serverSettingsData?.settings.extensionRepos.length;
|
||||||
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const { setTitle, setAction } = useContext(NavBarContext);
|
const { setTitle, setAction } = useContext(NavBarContext);
|
||||||
const [shownLangs, setShownLangs] = useLocalStorage<string[]>('shownExtensionLangs', extensionDefaultLangs());
|
const [shownLangs, setShownLangs] = useLocalStorage<string[]>('shownExtensionLangs', extensionDefaultLangs());
|
||||||
@@ -255,7 +258,11 @@ export function Extensions() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledGroupItemWrapper key={item.apkName} isLastItem={index === visibleExtensions.length - 1}>
|
<StyledGroupItemWrapper key={item.apkName} isLastItem={index === visibleExtensions.length - 1}>
|
||||||
<ExtensionCard extension={item} handleUpdate={handleExtensionUpdate} />
|
<ExtensionCard
|
||||||
|
extension={item}
|
||||||
|
handleUpdate={handleExtensionUpdate}
|
||||||
|
usesCustomRepos={usesCustomRepos}
|
||||||
|
/>
|
||||||
</StyledGroupItemWrapper>
|
</StyledGroupItemWrapper>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { useLocalStorage } from '@/util/useLocalStorage.tsx';
|
|||||||
import { TextSetting } from '@/components/settings/TextSetting.tsx';
|
import { TextSetting } from '@/components/settings/TextSetting.tsx';
|
||||||
import { ServerSettings as GqlServerSettings } from '@/typings.ts';
|
import { ServerSettings as GqlServerSettings } from '@/typings.ts';
|
||||||
import { NumberSetting } from '@/components/settings/NumberSetting.tsx';
|
import { NumberSetting } from '@/components/settings/NumberSetting.tsx';
|
||||||
|
import { MutableListSetting } from '@/components/settings/MutableListSetting.tsx';
|
||||||
|
|
||||||
type ServerSettingsType = Pick<
|
type ServerSettingsType = Pick<
|
||||||
GqlServerSettings,
|
GqlServerSettings,
|
||||||
@@ -32,6 +33,7 @@ type ServerSettingsType = Pick<
|
|||||||
| 'basicAuthPassword'
|
| 'basicAuthPassword'
|
||||||
| 'maxSourcesInParallel'
|
| 'maxSourcesInParallel'
|
||||||
| 'localSourcePath'
|
| 'localSourcePath'
|
||||||
|
| 'extensionRepos'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
const extractDownloadSettings = (settings: GqlServerSettings): ServerSettingsType => ({
|
const extractDownloadSettings = (settings: GqlServerSettings): ServerSettingsType => ({
|
||||||
@@ -48,6 +50,7 @@ const extractDownloadSettings = (settings: GqlServerSettings): ServerSettingsTyp
|
|||||||
basicAuthPassword: settings.basicAuthPassword,
|
basicAuthPassword: settings.basicAuthPassword,
|
||||||
maxSourcesInParallel: settings.maxSourcesInParallel,
|
maxSourcesInParallel: settings.maxSourcesInParallel,
|
||||||
localSourcePath: settings.localSourcePath,
|
localSourcePath: settings.localSourcePath,
|
||||||
|
extensionRepos: settings.extensionRepos,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const ServerSettings = () => {
|
export const ServerSettings = () => {
|
||||||
@@ -120,6 +123,21 @@ export const ServerSettings = () => {
|
|||||||
handleUpdate={(parallelSources) => updateSetting('maxSourcesInParallel', parallelSources)}
|
handleUpdate={(parallelSources) => updateSetting('maxSourcesInParallel', parallelSources)}
|
||||||
/>
|
/>
|
||||||
</List>
|
</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
|
<List
|
||||||
subheader={
|
subheader={
|
||||||
<ListSubheader component="div" id="server-settings-requests">
|
<ListSubheader component="div" id="server-settings-requests">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"uiVersion": "PREVIEW",
|
"uiVersion": "PREVIEW",
|
||||||
"serverVersion": "r1438"
|
"serverVersion": "r1444"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user