refactor: move blog related options to a accordion

This commit is contained in:
lin onetwo 2023-05-22 13:55:41 +08:00
parent 3094eb764b
commit c081711f58
22 changed files with 175 additions and 153 deletions

View file

@ -180,7 +180,8 @@
"ReadOnlyMode": "ReadOnly Mode",
"TokenAuth": "Token Authenticate",
"TokenAuthDescription": "Cannot work with read-only mode. After enabled, other ones need to bring credentials in the request header to read write the content of the wiki, preventing other people in the same LAN from accessing your notes. TidGi will automatically bring the certificate, so turning on will not affect the normal use of TidGi app, it only increases security, so it is recommended to turn it on.",
"TokenAuthAutoFillUserNameDescription": "This feature requires userName to be filled in global setting or workspace setting, if its empty, a default one will be auto filled into workspace setting, you can change it later."
"TokenAuthAutoFillUserNameDescription": "This feature requires userName to be filled in global setting or workspace setting, if its empty, a default one will be auto filled into workspace setting, you can change it later.",
"BlogOptions": "Blog Server Options"
},
"Dialog": {
"CantFindWorkspaceFolderRemoveWorkspace": "Cannot find the workspace folder that was still there before! \nThe folders that should have existed here may have been removed, or there is no wiki in this folder! \nDo you want to remove the workspace?",

View file

@ -215,7 +215,8 @@
"TokenAuth": "凭证鉴权",
"TokenAuthDescription": "无法与只读模式同时开启。开启后需要在请求中带上凭证才能读写知识库内容,防止同一局域网下其他人访问笔记。太记会自动带上凭证,因此开启后不会影响太记应用正常使用,仅增加安全性,建议开启。",
"TokenAuthAutoFillUserNameDescription": "此功能需要在全局设置或工作区设置里填写用户名,不然不会生效。若你未填,将自动在工作区设置里填一个默认值,你可自行修改。",
"TokenAuthCurrentHeader": "凭证鉴权当前请求头"
"TokenAuthCurrentHeader": "凭证鉴权当前请求头",
"BlogOptions": "博客服务器设置"
},
"Scripting": {
"ExecutingScript": "正在执行脚本"

View file

@ -0,0 +1,31 @@
import { List as ListRaw, ListItem as ListItemRaw, ListItemText as ListItemTextRaw } from '@material-ui/core';
import styled from 'styled-components';
export const List = styled(ListRaw)`
& > li > div {
padding-top: 0;
padding-bottom: 0;
}
`;
export const ListItem: typeof ListItemRaw = styled(ListItemRaw)`
svg {
color: ${({ theme }) => theme.palette.action.active};
}
p,
label {
color: ${({ theme }) => theme.palette.text.secondary};
}
div[role='button'] {
color: ${({ theme }) => theme.palette.text.primary};
}
`;
export const ListItemText: typeof ListItemTextRaw = styled(ListItemTextRaw)`
color: ${({ theme }) => theme.palette.text.primary};
input {
color: ${({ theme }) => theme.palette.text.primary};
}
p,
label {
color: ${({ theme }) => theme.palette.text.secondary};
}
`;

View file

@ -1,11 +1,12 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
import { ListItemText as ListItemTextRaw, Tab as TabRaw } from '@material-ui/core';
import { Tab as TabRaw } from '@material-ui/core';
import { TabContext, TabList as TabListRaw, TabPanel as TabPanelRaw } from '@material-ui/lab';
import { SupportedStorageServices } from '@services/types';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import styled, { DefaultTheme, keyframes } from 'styled-components';
import { ListItemText } from '../ListItem';
import { GitTokenForm } from './GitTokenForm';
const Container = styled.div`
@ -14,16 +15,6 @@ const Container = styled.div`
flex-direction: column;
background-color: ${({ theme }) => theme.palette.background.paper};
`;
export const ListItemText: typeof ListItemTextRaw = styled(ListItemTextRaw)`
color: ${({ theme }) => theme.palette.text.primary};
input {
color: ${({ theme }) => theme.palette.text.primary};
}
p,
label {
color: ${({ theme }) => theme.palette.text.secondary};
}
`;
const TabPanel = styled(TabPanelRaw)`
padding: 5px 0 !important;
padding-left: 16px !important;

View file

@ -0,0 +1,101 @@
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
import { Accordion, AccordionDetails, AccordionSummary, Divider, Link, List, ListItemSecondaryAction, Switch, TextField } from '@material-ui/core';
import { ExpandMore as ExpandMoreIcon } from '@material-ui/icons';
import { Autocomplete } from '@material-ui/lab';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { ListItem, ListItemText } from '@/components/ListItem';
import { rootTiddlers } from '@/constants/defaultTiddlerNames';
import { defaultServerIP } from '@/constants/urls';
import { IWorkspace } from '@services/workspaces/interface';
const ABlogOptionsAccordion = styled(Accordion)`
box-shadow: unset;
background-color: unset;
`;
const ABlogOptionsAccordionSummary = styled(AccordionSummary)`
padding: 0;
`;
export interface IBlogOptionsProps {
actualIP: string | undefined;
workspace: IWorkspace;
workspaceSetter: (newValue: IWorkspace, requestSaveAndRestart?: boolean | undefined) => void;
}
export function BlogOptions(props: IBlogOptionsProps) {
const { t } = useTranslation();
const { workspace, actualIP, workspaceSetter } = props;
const {
port,
tokenAuth,
readOnlyMode,
rootTiddler,
} = (workspace ?? {}) as unknown as IWorkspace;
const alreadyEnableSomeBlogOptions = readOnlyMode;
return (
<ABlogOptionsAccordion defaultExpanded={alreadyEnableSomeBlogOptions}>
<ABlogOptionsAccordionSummary expandIcon={<ExpandMoreIcon />}>{t('EditWorkspace.BlogOptions')}</ABlogOptionsAccordionSummary>
<AccordionDetails>
<List>
<ListItem disableGutters>
<TextField
id='outlined-full-width'
label={t('EditWorkspace.Port')}
helperText={
<span>
{t('EditWorkspace.URL')}{' '}
<Link
onClick={async () => {
actualIP && (await window.service.native.open(actualIP));
}}
style={{ cursor: 'pointer' }}
>
{actualIP}
</Link>
</span>
}
placeholder='Optional'
value={port}
onChange={async (event) => {
if (!Number.isNaN(Number.parseInt(event.target.value))) {
workspaceSetter({
...workspace,
port: Number(event.target.value),
homeUrl: await window.service.native.getLocalHostUrlWithActualIP(`http://${defaultServerIP}:${event.target.value}/`),
}, true);
}
}}
/>
</ListItem>
<Divider />
<ListItem disableGutters>
<ListItemText primary={t('EditWorkspace.ReadOnlyMode')} secondary={t('EditWorkspace.ReadOnlyModeDescription')} />
<ListItemSecondaryAction>
<Switch
edge='end'
color='primary'
checked={readOnlyMode}
onChange={(event) => {
workspaceSetter({ ...workspace, readOnlyMode: event.target.checked, tokenAuth: event.target.checked ? false : tokenAuth }, true);
}}
/>
</ListItemSecondaryAction>
</ListItem>
</List>
<Autocomplete
freeSolo
options={rootTiddlers}
value={rootTiddler}
defaultValue={rootTiddlers[0]}
onInputChange={(_, value) => {
workspaceSetter({ ...workspace, rootTiddler: value });
// void requestSaveAndRestart();
}}
renderInput={(parameters) => <TextField {...parameters} label={t('EditWorkspace.WikiRootTiddler')} helperText={t('EditWorkspace.WikiRootTiddlerDescription')} />}
/>
</AccordionDetails>
</ABlogOptionsAccordion>
);
}

View file

@ -2,20 +2,7 @@
/* eslint-disable unicorn/no-useless-undefined */
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
/* eslint-disable unicorn/no-null */
import {
Button as ButtonRaw,
Divider,
Link,
List as ListRaw,
ListItem as ListItemRaw,
ListItemSecondaryAction,
ListItemText as ListItemTextRaw,
Paper,
Switch,
TextField as TextFieldRaw,
Tooltip,
Typography,
} from '@material-ui/core';
import { Button as ButtonRaw, Divider, ListItemSecondaryAction, Paper, Switch, TextField as TextFieldRaw, Tooltip, Typography } from '@material-ui/core';
import { Autocomplete } from '@material-ui/lab';
import React from 'react';
import { Helmet } from 'react-helmet';
@ -30,16 +17,16 @@ import { useWorkspaceObservable } from '@services/workspaces/hooks';
import { IWorkspace } from '@services/workspaces/interface';
import { useForm } from './useForm';
import { List, ListItem, ListItemText } from '@/components/ListItem';
import { useRestartSnackbar } from '@/components/RestartSnackbar';
import { TokenForm } from '@/components/TokenForm';
import { DEFAULT_USER_NAME, getTidGiAuthHeaderWithToken } from '@/constants/auth';
import { rootTiddlers } from '@/constants/defaultTiddlerNames';
import { defaultServerIP } from '@/constants/urls';
import { useActualIp } from '@services/native/hooks';
import { SupportedStorageServices } from '@services/types';
import { isEqual } from 'lodash';
import { SyncedWikiDescription } from '../AddWorkspace/Description';
import { GitRepoUrlForm } from '../AddWorkspace/GitRepoUrlForm';
import { BlogOptions } from './blog';
const Root = styled(Paper)`
height: 100%;
@ -143,34 +130,6 @@ const Caption = styled(Typography)`
Caption.defaultProps = {
variant: 'caption',
};
const List = styled(ListRaw)`
& > li > div {
padding-top: 0;
padding-bottom: 0;
}
`;
export const ListItem: typeof ListItemRaw = styled(ListItemRaw)`
svg {
color: ${({ theme }) => theme.palette.action.active};
}
p,
label {
color: ${({ theme }) => theme.palette.text.secondary};
}
div[role='button'] {
color: ${({ theme }) => theme.palette.text.primary};
}
`;
export const ListItemText: typeof ListItemTextRaw = styled(ListItemTextRaw)`
color: ${({ theme }) => theme.palette.text.primary};
input {
color: ${({ theme }) => theme.palette.text.primary};
}
p,
label {
color: ${({ theme }) => theme.palette.text.secondary};
}
`;
const getValidIconPath = (iconPath?: string | null): string => {
if (typeof iconPath === 'string') {
@ -199,7 +158,6 @@ export default function EditWorkspace(): JSX.Element {
name,
order,
picturePath,
port,
storageService,
syncOnInterval,
syncOnStartup,
@ -209,7 +167,6 @@ export default function EditWorkspace(): JSX.Element {
userName,
lastUrl,
wikiFolderLocation,
rootTiddler,
readOnlyMode,
id,
} = (workspace ?? {}) as unknown as IWorkspace;
@ -279,49 +236,7 @@ export default function EditWorkspace(): JSX.Element {
<Divider />
{!isSubWiki && (
<>
<TextField
id='outlined-full-width'
label={t('EditWorkspace.Port')}
helperText={
<span>
{t('EditWorkspace.URL')}{' '}
<Link
onClick={async () => {
actualIP && (await window.service.native.open(actualIP));
}}
style={{ cursor: 'pointer' }}
>
{actualIP}
</Link>
</span>
}
placeholder='Optional'
value={port}
onChange={async (event) => {
if (!Number.isNaN(Number.parseInt(event.target.value))) {
workspaceSetter({
...workspace,
port: Number(event.target.value),
homeUrl: await window.service.native.getLocalHostUrlWithActualIP(`http://${defaultServerIP}:${event.target.value}/`),
}, true);
}
}}
/>
<Divider />
<List>
<ListItem disableGutters>
<ListItemText primary={t('EditWorkspace.ReadOnlyMode')} secondary={t('EditWorkspace.ReadOnlyModeDescription')} />
<ListItemSecondaryAction>
<Switch
edge='end'
color='primary'
checked={readOnlyMode}
onChange={(event) => {
workspaceSetter({ ...workspace, readOnlyMode: event.target.checked, tokenAuth: event.target.checked ? false : tokenAuth }, true);
}}
/>
</ListItemSecondaryAction>
</ListItem>
<ListItem disableGutters>
<ListItemText
primary={t('EditWorkspace.TokenAuth')}
@ -379,6 +294,7 @@ export default function EditWorkspace(): JSX.Element {
}}
/>
)}
<BlogOptions actualIP={actualIP} workspace={workspace} workspaceSetter={workspaceSetter} />
</>
)}
{isSubWiki && (
@ -392,6 +308,7 @@ export default function EditWorkspace(): JSX.Element {
renderInput={(parameters) => <TextField {...parameters} label={t('AddWorkspace.TagName')} helperText={t('AddWorkspace.TagNameHelp')} />}
/>
)}
<Divider />
<AvatarFlex>
<AvatarLeft>
<Avatar transparentBackground={transparentBackground}>
@ -504,19 +421,6 @@ export default function EditWorkspace(): JSX.Element {
</List>
</>
)}
{!isSubWiki && (
<Autocomplete
freeSolo
options={rootTiddlers}
value={rootTiddler}
defaultValue={rootTiddlers[0]}
onInputChange={(_, value) => {
workspaceSetter({ ...workspace, rootTiddler: value });
// void requestSaveAndRestart();
}}
renderInput={(parameters) => <TextField {...parameters} label={t('EditWorkspace.WikiRootTiddler')} helperText={t('EditWorkspace.WikiRootTiddlerDescription')} />}
/>
)}
{!isSubWiki && (
<List>
<Divider />

View file

@ -1,4 +1,4 @@
import { InputLabel as InputLabelRaw, ListItem as ListItemRaw, ListItemText as ListItemTextRaw, Paper as PaperRaw, TextField as TextFieldRaw, Typography } from '@material-ui/core';
import { InputLabel as InputLabelRaw, ListItem as ListItemRaw, Paper as PaperRaw, TextField as TextFieldRaw, Typography } from '@material-ui/core';
import styled, { keyframes } from 'styled-components';
export const Paper = styled(PaperRaw)`
@ -46,28 +46,6 @@ TextField.defaultProps = {
export const InputLabel: typeof InputLabelRaw = styled(InputLabelRaw)`
color: ${({ theme }) => theme.palette.text.primary};
`;
export const ListItemText: typeof ListItemTextRaw = styled(ListItemTextRaw)`
color: ${({ theme }) => theme.palette.text.primary};
input {
color: ${({ theme }) => theme.palette.text.primary};
}
p,
label {
color: ${({ theme }) => theme.palette.text.secondary};
}
`;
export const ListItem: typeof ListItemRaw = styled(ListItemRaw)`
svg {
color: ${({ theme }) => theme.palette.action.active};
}
p,
label {
color: ${({ theme }) => theme.palette.text.secondary};
}
div[role='button'] {
color: ${({ theme }) => theme.palette.text.primary};
}
`;
export const ListItemVertical: typeof ListItemRaw = styled(ListItemRaw)`
flex-direction: column;
align-items: flex-start;

View file

@ -3,8 +3,9 @@ import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ListItem, ListItemText } from '@/components/ListItem';
import { usePromiseValue } from '@/helpers/useServiceValue';
import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function DeveloperTools(props: ISectionProps): JSX.Element {

View file

@ -3,8 +3,9 @@ import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ListItem, ListItemText } from '@/components/ListItem';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function Downloads(props: Required<ISectionProps>): JSX.Element {
@ -30,7 +31,8 @@ export function Downloads(props: Required<ISectionProps>): JSX.Element {
}
})
.catch((error: Error) => {
console.log(error); // eslint-disable-line no-console
// eslint-disable-next-line security-node/detect-crlf
console.log(error);
});
}}
>

View file

@ -4,7 +4,8 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import styled from 'styled-components';
import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { ListItem, ListItemText } from '@/components/ListItem';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
import translatiumLogo from '@/images/translatium-logo.svg';

View file

@ -3,11 +3,12 @@ import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { ListItem, ListItemText } from '@/components/ListItem';
import PopUpMenuItem from '@/components/PopUpMenuItem';
import { usePromiseValue } from '@/helpers/useServiceValue';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { IPreferences } from '@services/preferences/interface';
import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
const getThemeString = (theme: IPreferences['themeSource']): string => {

View file

@ -2,11 +2,12 @@ import { Divider, List, ListItemSecondaryAction, MenuItem, Select, Switch } from
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import { useTranslation } from 'react-i18next';
import { ListItem, ListItemText } from '@/components/ListItem';
import { hunspellLanguagesMap } from '@/constants/hunspellLanguages';
import { usePromiseValue } from '@/helpers/useServiceValue';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { WindowNames } from '@services/windows/WindowProperties';
import { InputLabel, ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { InputLabel, Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function Languages(props: Partial<ISectionProps> & { languageSelectorOnly?: boolean }): JSX.Element {

View file

@ -3,7 +3,8 @@ import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { ListItem, ListItemText } from '@/components/ListItem';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
import { WindowNames } from '@services/windows/WindowProperties';

View file

@ -1,8 +1,9 @@
import { List } from '@material-ui/core';
import { useTranslation } from 'react-i18next';
import { ListItem } from '@/components/ListItem';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { ListItem, Paper, SectionTitle } from '../PreferenceComponents';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function Network(props: ISectionProps): JSX.Element {

View file

@ -5,10 +5,11 @@ import { Divider, List, ListItemSecondaryAction, Switch } from '@material-ui/cor
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import TimePicker from '@material-ui/lab/TimePicker';
import { ListItem, ListItemText } from '@/components/ListItem';
import { usePromiseValue } from '@/helpers/useServiceValue';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { WindowNames } from '@services/windows/WindowProperties';
import { Link, ListItem, ListItemText, ListItemVertical, Paper, SectionTitle, TextField, TimePickerContainer } from '../PreferenceComponents';
import { Link, ListItemVertical, Paper, SectionTitle, TextField, TimePickerContainer } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function Notifications(props: Required<ISectionProps>): JSX.Element {

View file

@ -2,8 +2,9 @@ import { Divider, List, ListItemSecondaryAction, Switch } from '@material-ui/cor
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ListItem, ListItemText } from '@/components/ListItem';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function Performance(props: Required<ISectionProps>): JSX.Element {

View file

@ -4,7 +4,8 @@ import React from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { Link, ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { Link, Paper, SectionTitle } from '../PreferenceComponents';
import { ListItem, ListItemText } from '@/components/ListItem';
import type { ISectionProps } from '../useSections';
export function PrivacyAndSecurity(props: Required<ISectionProps>): JSX.Element {

View file

@ -9,9 +9,10 @@ import { useTranslation } from 'react-i18next';
import { TokenForm } from '../../../components/TokenForm';
import { ListItem, ListItemText } from '@/components/ListItem';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { WindowNames } from '@services/windows/WindowProperties';
import { ListItem, ListItemText, Paper, SectionTitle, TextField, TimePickerContainer } from '../PreferenceComponents';
import { Paper, SectionTitle, TextField, TimePickerContainer } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function Sync(props: Required<ISectionProps>): JSX.Element {

View file

@ -3,9 +3,10 @@ import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ListItem, ListItemText } from '@/components/ListItem';
import PopUpMenuItem from '@/components/PopUpMenuItem';
import { getOpenAtLoginString, useSystemPreferenceObservable } from '@services/systemPreferences/hooks';
import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function System(props: ISectionProps): JSX.Element {

View file

@ -4,8 +4,9 @@ import { useTranslation } from 'react-i18next';
import { List } from '@material-ui/core';
import { ListItemText } from '@/components/ListItem';
import { useUserInfoObservable } from '@services/auth/hooks';
import { ListItemText, ListItemVertical, Paper, SectionTitle, TextField } from '../PreferenceComponents';
import { ListItemVertical, Paper, SectionTitle, TextField } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function TiddlyWiki(props: Partial<ISectionProps>): JSX.Element {

View file

@ -2,11 +2,12 @@ import { Divider, List, ListItemSecondaryAction, Switch } from '@material-ui/cor
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import { useTranslation } from 'react-i18next';
import { ListItem, ListItemText } from '@/components/ListItem';
import { latestStableUpdateUrl } from '@/constants/urls';
import { usePreferenceObservable } from '@services/preferences/hooks';
import { getUpdaterMessage, useUpdaterObservable } from '@services/updater/hooks';
import { IUpdaterStatus } from '@services/updater/interface';
import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents';
import { Paper, SectionTitle } from '../PreferenceComponents';
import type { ISectionProps } from '../useSections';
export function Updates(props: Required<ISectionProps>): JSX.Element {

View file

@ -59,7 +59,7 @@ export const windowDimension: Record<WindowNames, { height?: number; width?: num
height: 600,
},
[WindowNames.preferences]: {
width: 820,
width: 840,
height: 700,
},
[WindowNames.notifications]: {