diff --git a/features/stepDefinitions/electron.ts b/features/stepDefinitions/electron.ts index 4bdaaee2..a65f2980 100644 --- a/features/stepDefinitions/electron.ts +++ b/features/stepDefinitions/electron.ts @@ -1,30 +1,30 @@ /* eslint-disable @typescript-eslint/no-unused-expressions */ -import { setWorldConstructor, Given, Then } from '@cucumber/cucumber'; +import { Given, setWorldConstructor, Then } from '@cucumber/cucumber'; import { delay } from 'bluebird'; import { expect } from 'chai'; import { TidGiWorld } from '../supports/world'; setWorldConstructor(TidGiWorld); -Given('the app is launched', async function (this: TidGiWorld) { +Given('the app is launched', async function(this: TidGiWorld) { await delay(100); await this.start(); const windowCount = await this.app?.client?.getWindowCount(); expect(windowCount).equal(1); }); -Then('the element {string} is on the page', async function (this: TidGiWorld, elementSelector: string) { +Then('the element {string} is on the page', async function(this: TidGiWorld, elementSelector: string) { const result = await this.getElement(elementSelector); expect(result).to.not.be.undefined; this.updateContext({ previousElement: result }); }); -Then('click on this element', async function (this: TidGiWorld) { +Then('click on this element', async function(this: TidGiWorld) { expect(this.context?.previousElement).to.not.be.undefined; if (this.context?.previousElement !== undefined) { await this.context.previousElement.click(); } }); -Then('click on {string} element', async function (this: TidGiWorld, elementSelector: string) { +Then('click on {string} element', async function(this: TidGiWorld, elementSelector: string) { const result = await this.getElement(elementSelector); expect(result).to.not.be.undefined; if (result !== undefined) { @@ -32,7 +32,7 @@ Then('click on {string} element', async function (this: TidGiWorld, elementSelec await result.click(); } }); -Then('{string} window show up', async function (this: TidGiWorld, windowName: string) { +Then('{string} window show up', async function(this: TidGiWorld, windowName: string) { // await delay(1000); const windowCount = await this.app?.client?.getWindowCount(); expect(windowCount).equal(2); diff --git a/features/supports/after.ts b/features/supports/after.ts index 9259406d..b4c944b2 100644 --- a/features/supports/after.ts +++ b/features/supports/after.ts @@ -1,17 +1,17 @@ import { After, Before } from '@cucumber/cucumber'; import fs from 'fs-extra'; -import { DEFAULT_WIKI_FOLDER } from '../../src/constants/paths'; import { SETTINGS_FOLDER } from '../../src/constants/appPaths'; +import { DEFAULT_WIKI_FOLDER } from '../../src/constants/paths'; import { TidGiWorld } from './world'; -Before(async function () { +Before(async function() { // clear setting folder await fs.remove(SETTINGS_FOLDER); await fs.remove(DEFAULT_WIKI_FOLDER); }); -After(async function (this: TidGiWorld, testCase) { +After(async function(this: TidGiWorld, testCase) { // print logs if test failed // if (this.app !== undefined && testCase.result?.status === Status.FAILED) { // console.log('main:\n---\n'); diff --git a/forge.config.js b/forge.config.js index ea4ed519..2290ac77 100644 --- a/forge.config.js +++ b/forge.config.js @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/restrict-template-expressions */ const packageJson = require('./package.json'); -const beforeAsar = require('./scripts/beforeAsar') +const beforeAsar = require('./scripts/beforeAsar'); const { version, description } = packageJson; @@ -91,7 +91,7 @@ const config = { An unhandled rejection has occurred inside Forge: [object Object] */ - { + { name: '@reforged/maker-appimage', platforms: ['linux'], config: { diff --git a/scripts/beforeAsar.js b/scripts/beforeAsar.js index 08ee5266..f192f0ff 100644 --- a/scripts/beforeAsar.js +++ b/scripts/beforeAsar.js @@ -15,7 +15,6 @@ const fs = require('fs-extra'); const util = require('util'); /** - * * @param {*} buildPath /var/folders/qj/7j0zx32d0l75zmnrl1w3m3b80000gn/T/electron-packager/darwin-x64/TidGi-darwin-x64/Electron.app/Contents/Resources/app * @param {*} electronVersion 12.0.6 * @param {*} platform darwin diff --git a/src/components/FindInPage.tsx b/src/components/FindInPage.tsx index 97c3eec1..b58fb999 100644 --- a/src/components/FindInPage.tsx +++ b/src/components/FindInPage.tsx @@ -1,9 +1,9 @@ -import React, { useState, useCallback, useEffect, useRef } from 'react'; -import { useTranslation } from 'react-i18next'; -import styled from 'styled-components'; import Button from '@material-ui/core/Button'; import TextField from '@material-ui/core/TextField'; import Typography from '@material-ui/core/Typography'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; const Root = styled.div` display: flex; @@ -66,11 +66,11 @@ export default function FindInPage(): JSX.Element | null { return ( - + {activeMatch} - / + / {matches} - {t('Menu.FindMatches')} + {t('Menu.FindMatches')}
@@ -79,7 +79,7 @@ export default function FindInPage(): JSX.Element | null { inputRef={inputReference} placeholder={t('Menu.Find')} value={text} - margin="dense" + margin='dense' onChange={(event: React.ChangeEvent) => { const value = event.target.value; if (typeof value !== 'string') return; @@ -119,41 +119,45 @@ export default function FindInPage(): JSX.Element | null { />
diff --git a/src/components/PopUpMenuItem.tsx b/src/components/PopUpMenuItem.tsx index d2feab11..4ebb64ea 100644 --- a/src/components/PopUpMenuItem.tsx +++ b/src/components/PopUpMenuItem.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ -import React from 'react'; import Menu from '@material-ui/core/Menu'; +import React from 'react'; interface Props { buttonElement: React.ReactElement; diff --git a/src/components/RestartSnackbar.tsx b/src/components/RestartSnackbar.tsx index 67a47011..3cf960d2 100644 --- a/src/components/RestartSnackbar.tsx +++ b/src/components/RestartSnackbar.tsx @@ -1,9 +1,9 @@ -import React, { useCallback, useState } from 'react'; -import styled, { keyframes } from 'styled-components'; -import { Snackbar, Button, IconButton, Tooltip } from '@material-ui/core'; +import { Button, IconButton, Snackbar, Tooltip } from '@material-ui/core'; import { Close as CloseIcon } from '@material-ui/icons'; -import { useTranslation } from 'react-i18next'; import useDebouncedCallback from 'beautiful-react-hooks/useDebouncedCallback'; +import React, { useCallback, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import styled, { keyframes } from 'styled-components'; const progressAnimation = keyframes` from { @@ -65,7 +65,7 @@ export function useRestartSnackbar(waitBeforeCountDown = 1000, waitBeforeRestart return [ requestRestartCountDown, -
+
+ color='secondary' + size='small' + onClick={handleCloseAndRestart} + > {t('Dialog.RestartNow')} {t('Dialog.Later')}}> - - + + diff --git a/src/components/RootStyle.tsx b/src/components/RootStyle.tsx index 7b38c71a..392fcca1 100644 --- a/src/components/RootStyle.tsx +++ b/src/components/RootStyle.tsx @@ -4,20 +4,20 @@ export const RootStyle = styled.div` .Mui-selected, .Mui-checked { ${({ theme }) => - theme.palette.mode === 'dark' - ? css` + theme.palette.mode === 'dark' + ? css` color: ${theme.palette.primary.light} !important; ` - : ''}; + : ''}; } .Mui-disabled { ${({ theme }) => - theme.palette.mode === 'dark' - ? css` + theme.palette.mode === 'dark' + ? css` color: ${theme.palette.primary.dark} !important; -webkit-text-fill-color: ${theme.palette.primary.light}; ` - : ''}; + : ''}; } label, diff --git a/src/components/StorageService/SearchGithubRepo.tsx b/src/components/StorageService/SearchGithubRepo.tsx index 09f36c68..9b2d7aba 100644 --- a/src/components/StorageService/SearchGithubRepo.tsx +++ b/src/components/StorageService/SearchGithubRepo.tsx @@ -1,14 +1,14 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ -import Promise from 'bluebird'; -import React, { useState, useEffect, useMemo, useCallback } from 'react'; -import styled from 'styled-components'; -import { useQuery, useMutation, GraphQLClient, ClientContext } from 'graphql-hooks'; -import { trim } from 'lodash'; -import { useTranslation } from 'react-i18next'; import useDebouncedCallback from 'beautiful-react-hooks/useDebouncedCallback'; +import Promise from 'bluebird'; +import { ClientContext, GraphQLClient, useMutation, useQuery } from 'graphql-hooks'; +import { trim } from 'lodash'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; -import { TextField, LinearProgress, List, ListItem, ListItemIcon, ListItemText, Button } from '@material-ui/core'; -import { Folder as FolderIcon, Cached as CachedIcon, CreateNewFolder as CreateNewFolderIcon } from '@material-ui/icons'; +import { Button, LinearProgress, List, ListItem, ListItemIcon, ListItemText, TextField } from '@material-ui/core'; +import { Cached as CachedIcon, CreateNewFolder as CreateNewFolderIcon, Folder as FolderIcon } from '@material-ui/icons'; import { GITHUB_GRAPHQL_API } from '@/constants/auth'; import { useUserInfoObservable } from '@services/auth/hooks'; @@ -80,7 +80,7 @@ export default function SearchGithubRepo(props: Props): JSX.Element { [], ); useEffect(() => { - graphqlClient.setHeader('Authorization', accessToken !== undefined ? `Bearer ${accessToken}` : ''); + graphqlClient.setHeader('Authorization', accessToken === undefined ? '' : `Bearer ${accessToken}`); }, [accessToken, graphqlClient]); if (githubUsername === '' || githubUsername === undefined || accessToken === '' || accessToken === undefined) { @@ -132,7 +132,9 @@ function SearchGithubRepoResultList({ const timeoutHandle = setTimeout(async () => { await refetchDebounced(); }, 100); - return () => clearTimeout(timeoutHandle); + return () => { + clearTimeout(timeoutHandle); + }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [githubUsername, accessToken]); // try refetch on error @@ -143,7 +145,9 @@ function SearchGithubRepoResultList({ await refetchDebounced(); retryIntervalSetter(retryInterval * 10); }, retryInterval); - return () => clearTimeout(timeoutHandle); + return () => { + clearTimeout(timeoutHandle); + }; } return () => {}; // eslint-disable-next-line react-hooks/exhaustive-deps @@ -189,11 +193,18 @@ function SearchGithubRepoResultList({ value={githubRepoSearchString} helperText={helperText} /> - {(loading || isCreatingRepo) && } + {(loading || isCreatingRepo) && } - + {repoList.map(({ name, url }) => ( - onSelectRepo(url, name)} selected={trim(githubWikiUrl) === trim(url)}> + { + onSelectRepo(url, name); + }} + selected={trim(githubWikiUrl) === trim(url)} + > @@ -220,20 +231,19 @@ function SearchGithubRepoResultList({ isCreatingRepoSetter(false); githubWikiUrlSetter(wikiUrlToCreate); }} - selected={isCreateNewRepo}> + selected={isCreateNewRepo} + > )} {repoList.length === 0 && ( - } onClick={async () => await refetchDebounced()}> + } onClick={async () => await refetchDebounced()}> {t('AddWorkspace.Reload')} )} diff --git a/src/components/TokenForm/GitTokenForm.tsx b/src/components/TokenForm/GitTokenForm.tsx index 2f4a5d05..3de5c3e8 100644 --- a/src/components/TokenForm/GitTokenForm.tsx +++ b/src/components/TokenForm/GitTokenForm.tsx @@ -1,12 +1,12 @@ -import styled from 'styled-components'; import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; -import { TextField, Button } from '@material-ui/core'; +import { Button, TextField } from '@material-ui/core'; -import { SupportedStorageServices } from '@services/types'; import { useUserInfoObservable } from '@services/auth/hooks'; -import { useAuth } from './gitTokenHooks'; import { getServiceBranchTypes, getServiceEmailTypes, getServiceTokenTypes, getServiceUserNameTypes } from '@services/auth/interface'; +import { SupportedStorageServices } from '@services/types'; +import { useAuth } from './gitTokenHooks'; const AuthingLoginButton = styled(Button)` width: 100%; diff --git a/src/components/TokenForm/gitTokenHooks.ts b/src/components/TokenForm/gitTokenHooks.ts index ee2201d5..096760f2 100644 --- a/src/components/TokenForm/gitTokenHooks.ts +++ b/src/components/TokenForm/gitTokenHooks.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ -import { useCallback, useMemo } from 'react'; -import { AuthenticationClient } from 'authing-js-sdk'; +import { APP_DOMAIN, APP_ID } from '@/constants/auth'; import { SupportedStorageServices } from '@services/types'; -import { APP_ID, APP_DOMAIN } from '@/constants/auth'; +import { AuthenticationClient } from 'authing-js-sdk'; +import { useCallback, useMemo } from 'react'; export function useAuth(storageService: SupportedStorageServices): [() => Promise, () => Promise] { const authing = useMemo( @@ -42,7 +42,9 @@ export function useAuth(storageService: SupportedStorageServices): [() => Promis } } }, - onError: (code, message) => onFailure(new Error(message + String(code))), + onError: (code, message) => { + onFailure(new Error(message + String(code))); + }, }); } catch (error) { onFailure(error as Error); diff --git a/src/components/TokenForm/index.tsx b/src/components/TokenForm/index.tsx index fa8ffe61..a83e574e 100644 --- a/src/components/TokenForm/index.tsx +++ b/src/components/TokenForm/index.tsx @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ -import React, { useEffect, useState } from 'react'; -import styled, { DefaultTheme, keyframes } from 'styled-components'; -import { Tab as TabRaw, ListItemText as ListItemTextRaw } from '@material-ui/core'; -import { TabPanel as TabPanelRaw, TabContext, TabList as TabListRaw } from '@material-ui/lab'; +import { ListItemText as ListItemTextRaw, 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 { GitTokenForm } from './GitTokenForm'; @@ -45,7 +45,8 @@ const TabsContainer = styled.div` min-width: 160px; } `; -const backgroundColorShift = ({ theme }: { theme: DefaultTheme }) => keyframes` +const backgroundColorShift = ({ theme }: { theme: DefaultTheme }) => + keyframes` from {background-color: ${theme.palette.background.default};} to {background-color: ${theme.palette.background.default};} `; @@ -85,14 +86,17 @@ export function TokenForm({ storageProvider, storageProviderSetter }: Props): JS currentTabSetter(newValue as SupportedStorageServices)} - orientation="vertical" - variant="scrollable" + onChange={(_event, newValue) => { + currentTabSetter(newValue as SupportedStorageServices); + }} + orientation='vertical' + variant='scrollable' value={currentTab} - aria-label="Vertical tabs example"> - - - + aria-label='Vertical tabs example' + > + + + diff --git a/src/components/WorkspaceIconAndSelector/SortableWorkspaceSelector.tsx b/src/components/WorkspaceIconAndSelector/SortableWorkspaceSelector.tsx index ea65be88..3bc4cb04 100644 --- a/src/components/WorkspaceIconAndSelector/SortableWorkspaceSelector.tsx +++ b/src/components/WorkspaceIconAndSelector/SortableWorkspaceSelector.tsx @@ -1,10 +1,10 @@ -import { useCallback, MouseEvent, useState } from 'react'; -import { useTranslation } from 'react-i18next'; import { useSortable } from '@dnd-kit/sortable'; import { CSS } from '@dnd-kit/utilities'; -import { WorkspaceSelector } from './WorkspaceSelector'; -import { IWorkspace } from '@services/workspaces/interface'; import { getWorkspaceMenuTemplate, openWorkspaceTagTiddler } from '@services/workspaces/getWorkspaceMenuTemplate'; +import { IWorkspace } from '@services/workspaces/interface'; +import { MouseEvent, useCallback, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { WorkspaceSelector } from './WorkspaceSelector'; import defaultIcon from '@/images/default-icon.png'; diff --git a/src/components/WorkspaceIconAndSelector/SortableWorkspaceSelectorList.tsx b/src/components/WorkspaceIconAndSelector/SortableWorkspaceSelectorList.tsx index 589d187e..37be8006 100644 --- a/src/components/WorkspaceIconAndSelector/SortableWorkspaceSelectorList.tsx +++ b/src/components/WorkspaceIconAndSelector/SortableWorkspaceSelectorList.tsx @@ -1,6 +1,6 @@ -import { DndContext, useSensor, useSensors, PointerSensor } from '@dnd-kit/core'; -import { SortableContext, arrayMove, verticalListSortingStrategy } from '@dnd-kit/sortable'; +import { DndContext, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'; import { restrictToVerticalAxis } from '@dnd-kit/modifiers'; +import { arrayMove, SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable'; import { IWorkspace, IWorkspaceWithMetadata } from '@services/workspaces/interface'; import { SortableWorkspaceSelector } from './SortableWorkspaceSelector'; @@ -38,7 +38,8 @@ export function SortableWorkspaceSelectorList({ workspacesList, sidebarShortcutH }); await window.service.workspace.setWorkspaces(newWorkspaces); - }}> + }} + > {workspacesList .sort((a, b) => a.order - b.order) diff --git a/src/components/WorkspaceIconAndSelector/WorkspaceSelector.tsx b/src/components/WorkspaceIconAndSelector/WorkspaceSelector.tsx index 281c2961..fad39400 100644 --- a/src/components/WorkspaceIconAndSelector/WorkspaceSelector.tsx +++ b/src/components/WorkspaceIconAndSelector/WorkspaceSelector.tsx @@ -1,11 +1,11 @@ -import Promise from 'bluebird'; -import React, { useState, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; import BadgeRaw from '@material-ui/core/Badge'; +import Promise from 'bluebird'; +import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import styled, { css, keyframes } from 'styled-components'; -import defaultIcon from '../../images/default-icon.png'; import { getAssetsFileUrl } from '@/helpers/url'; +import defaultIcon from '../../images/default-icon.png'; Promise.config({ cancellation: true }); @@ -28,21 +28,21 @@ const Root = styled.div<{ active?: boolean; hibernated?: boolean; workspaceClick border: 0; border-color: transparent; ${({ hibernated }) => - hibernated === true && - css` + hibernated === true && + css` opacity: 0.4; `} ${({ active }) => - active === true && - css` + active === true && + css` opacity: 1; `} box-sizing: border-box; border-left: ${({ workspaceCount }) => (workspaceCount > 1 ? '3px' : '0')} solid ${({ active, theme }) => (active === true ? theme.palette.text.primary : 'transparent')}; ${({ workspaceClickedLoading }) => - workspaceClickedLoading === true && - css` + workspaceClickedLoading === true && + css` &:hover { cursor: wait; } @@ -69,15 +69,15 @@ const Avatar = styled.div` text-transform: uppercase; overflow: hidden; ${({ large }) => - large === true && - css` + large === true && + css` height: 44px; width: 44px; line-height: 44px; `} ${({ transparent }) => - transparent === true && - css` + transparent === true && + css` background: transparent; border: none; border-radius: 0; @@ -91,9 +91,9 @@ const Avatar = styled.div` color: ${({ theme }) => theme.palette.common.black}; } ${({ addAvatar }: IAvatarProps) => - addAvatar - ? '' - : css` + addAvatar + ? '' + : css` background-color: transparent; `} `; @@ -102,8 +102,8 @@ const AvatarPicture = styled.img<{ large?: boolean }>` height: calc(36px - 2px); width: calc(36px - 2px); ${({ large }) => - large === true && - css` + large === true && + css` height: 44px; width: 44px; `} @@ -119,8 +119,8 @@ const ShortcutText = styled.p<{ active?: boolean }>` word-break: break-all; text-align: center; ${({ active }) => - active === true && - css` + active === true && + css` text-decoration: underline; text-underline-offset: 0.2em; `} @@ -172,28 +172,32 @@ export function WorkspaceSelector({ active={active} onClick={workspaceClickedLoading ? () => {} : onClick} workspaceClickedLoading={workspaceClickedLoading} - workspaceCount={workspaceCount}> - + workspaceCount={workspaceCount} + > + {!hideSideBarIcon && ( - {id === 'add' ? ( - '+' - ) : id === 'guide' ? ( - '※' - ) : ( - - )} + id={id === 'add' || id === 'guide' ? 'add-workspace-button' : `workspace-avatar-${id}`} + > + {id === 'add' + ? ( + '+' + ) + : (id === 'guide' + ? ( + '※' + ) + : )} )} {(showSidebarShortcutHints || hideSideBarIcon) && ( - {id === 'add' ? t('WorkspaceSelector.Add') : id === 'guide' ? t('WorkspaceSelector.Guide') : shortWorkspaceName} + {id === 'add' ? t('WorkspaceSelector.Add') : (id === 'guide' ? t('WorkspaceSelector.Guide') : shortWorkspaceName)} )} diff --git a/src/components/WorkspaceIconAndSelector/index.ts b/src/components/WorkspaceIconAndSelector/index.ts index 58b2d18f..c3b6895a 100644 --- a/src/components/WorkspaceIconAndSelector/index.ts +++ b/src/components/WorkspaceIconAndSelector/index.ts @@ -1,3 +1,3 @@ -export * from './WorkspaceSelector'; export * from './SortableWorkspaceSelector'; export * from './SortableWorkspaceSelectorList'; +export * from './WorkspaceSelector'; diff --git a/src/components/icon/CommandPaletteSVG.tsx b/src/components/icon/CommandPaletteSVG.tsx index 046ca279..96bdf2c3 100644 --- a/src/components/icon/CommandPaletteSVG.tsx +++ b/src/components/icon/CommandPaletteSVG.tsx @@ -4,10 +4,10 @@ import { SVGContainer } from './SVGContainer'; function CommandPaletteSVG(): JSX.Element { return ( - + ); diff --git a/src/constants/appPaths.ts b/src/constants/appPaths.ts index 924da10d..ea769e27 100644 --- a/src/constants/appPaths.ts +++ b/src/constants/appPaths.ts @@ -7,7 +7,7 @@ import { sourcePath } from './paths'; export const USER_DATA_FOLDER = app.getPath('userData'); export const SETTINGS_FOLDER = isDevelopmentOrTest ? path.resolve(sourcePath, '..', developmentSettingFolderName) - : // eslint-disable-next-line @typescript-eslint/no-var-requires - path.resolve(USER_DATA_FOLDER, 'settings'); + // eslint-disable-next-line @typescript-eslint/no-var-requires + : path.resolve(USER_DATA_FOLDER, 'settings'); export const LOCAL_GIT_DIRECTORY = path.resolve(isDevelopmentOrTest ? path.join(sourcePath, '..') : process.resourcesPath, 'node_modules', 'dugite', 'git'); export const LOG_FOLDER = isDevelopmentOrTest ? path.resolve(sourcePath, '..', 'logs') : path.resolve(USER_DATA_FOLDER, 'logs'); diff --git a/src/constants/isElectronDevelopment.ts b/src/constants/isElectronDevelopment.ts index 3200e045..194c5de2 100644 --- a/src/constants/isElectronDevelopment.ts +++ b/src/constants/isElectronDevelopment.ts @@ -5,5 +5,5 @@ const electron = require('electron'); const { isPackaged } = require('electron-is-packaged'); -export const isElectronDevelopment = - !isPackaged && (process.env.NODE_ENV === 'development' || (typeof electron === 'string' || electron.app === undefined ? false : !electron.app.isPackaged)); +export const isElectronDevelopment = !isPackaged && + (process.env.NODE_ENV === 'development' || (typeof electron === 'string' || electron.app === undefined ? false : !electron.app.isPackaged)); diff --git a/src/constants/languages.ts b/src/constants/languages.ts index 0ad062f5..fdc8f790 100644 --- a/src/constants/languages.ts +++ b/src/constants/languages.ts @@ -1,6 +1,6 @@ +import { LOCALIZATION_FOLDER } from '@/constants/paths'; import fs from 'fs-extra'; import path from 'path'; -import { LOCALIZATION_FOLDER } from '@/constants/paths'; export const supportedLanguagesMap = fs.readJsonSync(path.join(LOCALIZATION_FOLDER, 'supportedLanguages.json')) as Record; export const tiddlywikiLanguagesMap = fs.readJsonSync(path.join(LOCALIZATION_FOLDER, 'tiddlywikiLanguages.json')) as Record; diff --git a/src/constants/paths.ts b/src/constants/paths.ts index f0cf2711..3fbc85e9 100644 --- a/src/constants/paths.ts +++ b/src/constants/paths.ts @@ -1,8 +1,8 @@ -import path from 'path'; import os from 'os'; +import path from 'path'; +import { isMac } from '../helpers/system'; import { isDevelopmentOrTest } from './environment'; import { developmentWikiFolderName, localizationFolderName } from './fileNames'; -import { isMac } from '../helpers/system'; /** src folder */ export const sourcePath = path.resolve(__dirname, '..'); diff --git a/src/constants/wiki.ts b/src/constants/wiki.ts index 3c68aebf..83d537ae 100644 --- a/src/constants/wiki.ts +++ b/src/constants/wiki.ts @@ -1,4 +1,4 @@ export enum WikiStateKey { - titleBarOpened = 'titleBarOpened', sideBarOpened = 'sideBarOpened', + titleBarOpened = 'titleBarOpened', } diff --git a/src/helpers/configSetting.ts b/src/helpers/configSetting.ts index 7f1f9dd0..0e2a1278 100644 --- a/src/helpers/configSetting.ts +++ b/src/helpers/configSetting.ts @@ -1,13 +1,13 @@ -import fs from 'fs-extra'; -import settings from 'electron-settings'; -import { parse as bestEffortJsonParser } from 'best-effort-json-parser'; import { SETTINGS_FOLDER } from '@/constants/appPaths'; import { logger } from '@services/libs/log'; +import { parse as bestEffortJsonParser } from 'best-effort-json-parser'; +import settings from 'electron-settings'; +import fs from 'fs-extra'; import { isWin } from './system'; export function fixSettingFileWhenError(jsonError: Error): void { logger.error('Setting file format bad: ' + jsonError.message); - const jsonContent = fs.readFileSync(settings.file(), 'utf-8'); + const jsonContent = fs.readFileSync(settings.file(), 'utf8'); logger.info('Try to fix JSON content.'); try { const repaired = bestEffortJsonParser(jsonContent) as Record; diff --git a/src/helpers/ip.ts b/src/helpers/ip.ts index 4baa6a3d..ec6c1730 100644 --- a/src/helpers/ip.ts +++ b/src/helpers/ip.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ -import { platform, type, networkInterfaces } from 'os'; import ip from 'ipaddr.js'; +import { networkInterfaces, platform, type } from 'os'; /** * Copy from https://github.com/sindresorhus/internal-ip, to fi xsilverwind/default-gateway 's bug diff --git a/src/helpers/singleInstance.ts b/src/helpers/singleInstance.ts index b543e730..d3f46bcf 100644 --- a/src/helpers/singleInstance.ts +++ b/src/helpers/singleInstance.ts @@ -1,5 +1,5 @@ -import { app } from 'electron'; import { logger } from '@services/libs/log'; +import { app } from 'electron'; const gotTheLock = app.requestSingleInstanceLock(); diff --git a/src/helpers/url.ts b/src/helpers/url.ts index edffaa04..a894852a 100644 --- a/src/helpers/url.ts +++ b/src/helpers/url.ts @@ -1,6 +1,6 @@ export function extractDomain(fullUrl: string | undefined): string | undefined { - const matches = /^([a-zA-Z\-]+):\/\/([^#/?]+)(?:[#/?]|$)/i.exec(fullUrl ?? ''); - const domain = matches !== null ? matches[1] : undefined; + const matches = /^([a-z\-]+):\/\/([^#/?]+)(?:[#/?]|$)/i.exec(fullUrl ?? ''); + const domain = matches === null ? undefined : matches[1]; // https://stackoverflow.com/a/9928725 return typeof domain === 'string' ? domain.replace(/^(www\.)/, '') : undefined; } diff --git a/src/helpers/useServiceValue.ts b/src/helpers/useServiceValue.ts index 416503a9..8655e103 100644 --- a/src/helpers/useServiceValue.ts +++ b/src/helpers/useServiceValue.ts @@ -1,6 +1,6 @@ -import { useEffect, useState, useCallback } from 'react'; -import { AsyncReturnType } from 'type-fest'; import useDebouncedCallback from 'beautiful-react-hooks/useDebouncedCallback'; +import { useCallback, useEffect, useState } from 'react'; +import { AsyncReturnType } from 'type-fest'; /** * Use value from service, especially constant value that never changes diff --git a/src/main.ts b/src/main.ts index 90d5e030..ec5683a9 100755 --- a/src/main.ts +++ b/src/main.ts @@ -1,34 +1,34 @@ +/* eslint-disable unicorn/prefer-top-level-await */ /* eslint-disable @typescript-eslint/no-misused-promises */ import { uninstall } from './helpers/installV8Cache'; import 'source-map-support/register'; import 'reflect-metadata'; import './helpers/singleInstance'; import './helpers/configSetting'; -import fs from 'fs-extra'; -import path from 'path'; -import { ipcMain, protocol, powerMonitor, app } from 'electron'; +import { app, ipcMain, powerMonitor, protocol } from 'electron'; import settings from 'electron-settings'; import unhandled from 'electron-unhandled'; +import fs from 'fs-extra'; +import path from 'path'; -import { buildLanguageMenu } from '@services/menu/buildLanguageMenu'; import { MainChannel } from '@/constants/channels'; import { isTest } from '@/constants/environment'; import { container } from '@services/container'; -import { logger } from '@services/libs/log'; import { initRendererI18NHandler } from '@services/libs/i18n'; +import { logger } from '@services/libs/log'; +import { buildLanguageMenu } from '@services/menu/buildLanguageMenu'; +import { bindServiceAndProxy } from '@services/libs/bindServiceAndProxy'; import serviceIdentifier from '@services/serviceIdentifier'; import { WindowNames } from '@services/windows/WindowProperties'; -import { bindServiceAndProxy } from '@services/libs/bindServiceAndProxy'; -import type { IPreferenceService } from './services/preferences/interface'; -import type { IWikiService } from './services/wiki/interface'; -import type { IWindowService } from './services/windows/interface'; -import type { IWorkspaceViewService } from './services/workspacesView/interface'; -import type { IUpdaterService } from '@services/updater/interface'; import { reportErrorToGithubWithTemplates } from '@services/native/reportError'; +import type { IUpdaterService } from '@services/updater/interface'; import { IWikiGitWorkspaceService } from '@services/wikiGitWorkspace/interface'; import { isLinux, isMac } from './helpers/system'; +import type { IPreferenceService } from './services/preferences/interface'; +import type { IWindowService } from './services/windows/interface'; +import type { IWorkspaceViewService } from './services/workspacesView/interface'; logger.info('App booting'); @@ -82,9 +82,10 @@ ipcMain.once(MainChannel.commonInitFinished, () => { */ const whenCommonInitFinished = async (): Promise => { if (commonInitFinished) { - return await Promise.resolve(); + await Promise.resolve(); + return; } - return await new Promise((resolve) => { + await new Promise((resolve) => { ipcMain.once(MainChannel.commonInitFinished, () => { commonInitFinished = true; resolve(); @@ -112,8 +113,8 @@ const commonInit = async (): Promise => { // if user want a menubar, we create a new window for that await Promise.all([ windowService.open(WindowNames.main), - preferenceService.get('attachToMenubar').then((attachToMenubar) => { - attachToMenubar && windowService.open(WindowNames.menuBar); + preferenceService.get('attachToMenubar').then(async (attachToMenubar) => { + attachToMenubar && await windowService.open(WindowNames.menuBar); }), ]); // perform wiki startup and git sync for each workspace @@ -160,7 +161,9 @@ app.on('ready', async () => { } await updaterService.checkForUpdates(); }) - .catch((error) => console.error(error)); + .catch((error) => { + console.error(error); + }); powerMonitor.on('shutdown', () => { app.quit(); }); diff --git a/src/pages/About.tsx b/src/pages/About.tsx index 71ad2928..8e941428 100644 --- a/src/pages/About.tsx +++ b/src/pages/About.tsx @@ -1,10 +1,10 @@ import React from 'react'; -import styled from 'styled-components'; -import { Trans, useTranslation } from 'react-i18next'; import { Helmet } from 'react-helmet'; +import { Trans, useTranslation } from 'react-i18next'; +import styled from 'styled-components'; -import { Button, DialogContent as DialogContentRaw } from '@material-ui/core'; import { usePromiseValue } from '@/helpers/useServiceValue'; +import { Button, DialogContent as DialogContentRaw } from '@material-ui/core'; import iconPath from '../../build-resources/icon.png'; const DialogContent = styled(DialogContentRaw)` @@ -81,11 +81,11 @@ export default function About(): JSX.Element { return ( -
+
{t('ContextMenu.About')} - + TidGi ({platform ?? 'Unknown Platform'}) {`Version v${appVersion ?? ' - '}.`} @@ -97,45 +97,59 @@ export default function About(): JSX.Element { - await window.service.native.open('https://github.com/tiddly-gittly/TidGi-Desktop')}> + { + await window.service.native.open('https://github.com/tiddly-gittly/TidGi-Desktop'); + }} + > Website - await window.service.native.open('https://github.com/tiddly-gittly/TidGi-Desktop/issues/new/choose')}> + { + await window.service.native.open('https://github.com/tiddly-gittly/TidGi-Desktop/issues/new/choose'); + }} + > Support - - Made with - + + Made with + - by + by await window.service.native.open('https://onetwo.ren/wiki/')} + onClick={async () => { + await window.service.native.open('https://onetwo.ren/wiki/'); + }} onKeyDown={async (event) => { if (event.key !== 'Enter') { return; } await window.service.native.open('https://onetwo.ren/wiki/'); }} - role="link" - tabIndex={0}> + role='link' + tabIndex={0} + > {t('LinOnetwo')} - && + && await window.service.native.open('https://webcatalog.app/?utm_source=tidgi_app')} + onClick={async () => { + await window.service.native.open('https://webcatalog.app/?utm_source=tidgi_app'); + }} onKeyDown={async (event) => { if (event.key !== 'Enter') { return; } await window.service.native.open('https://webcatalog.app/?utm_source=tidgi_app'); }} - role="link" - tabIndex={0}> + role='link' + tabIndex={0} + > {t('Preference.WebCatalog')} diff --git a/src/pages/AddWorkspace/CloneWikiDoneButton.tsx b/src/pages/AddWorkspace/CloneWikiDoneButton.tsx index 649b8d8a..81ef3833 100644 --- a/src/pages/AddWorkspace/CloneWikiDoneButton.tsx +++ b/src/pages/AddWorkspace/CloneWikiDoneButton.tsx @@ -1,13 +1,13 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ import { useTranslation } from 'react-i18next'; -import { Typography, LinearProgress, Snackbar } from '@material-ui/core'; +import { LinearProgress, Snackbar, Typography } from '@material-ui/core'; import Alert from '@material-ui/lab/Alert'; +import { CloseButton, ReportErrorFabButton, WikiLocation } from './FormComponents'; +import { useCloneWiki, useValidateCloneWiki } from './useCloneWiki'; import type { IWikiWorkspaceFormProps } from './useForm'; -import { useValidateCloneWiki, useCloneWiki } from './useCloneWiki'; import { useWikiCreationProgress } from './useIndicator'; -import { WikiLocation, CloseButton, ReportErrorFabButton } from './FormComponents'; export function CloneWikiDoneButton({ form, isCreateMainWorkspace, errorInWhichComponentSetter }: IWikiWorkspaceFormProps): JSX.Element { const { t } = useTranslation(); @@ -21,7 +21,7 @@ export function CloneWikiDoneButton({ form, isCreateMainWorkspace, errorInWhichC if (hasError) { return ( <> - + {wikiCreationMessage} {wikiCreationMessage !== undefined && } @@ -30,29 +30,37 @@ export function CloneWikiDoneButton({ form, isCreateMainWorkspace, errorInWhichC } return ( <> - {inProgressOrError && } - logPanelSetter(false)}> - {wikiCreationMessage} + {inProgressOrError && } + { + logPanelSetter(false); + }} + > + {wikiCreationMessage} - {isCreateMainWorkspace ? ( - - - {t('AddWorkspace.CloneWiki')} - - {form.wikiFolderLocation} - - ) : ( - - - {t('AddWorkspace.CloneWiki')} - - {form.wikiFolderLocation} - - {t('AddWorkspace.AndLinkToMainWorkspace')} - - - )} + {isCreateMainWorkspace + ? ( + + + {t('AddWorkspace.CloneWiki')} + + {form.wikiFolderLocation} + + ) + : ( + + + {t('AddWorkspace.CloneWiki')} + + {form.wikiFolderLocation} + + {t('AddWorkspace.AndLinkToMainWorkspace')} + + + )} ); } diff --git a/src/pages/AddWorkspace/CloneWikiForm.tsx b/src/pages/AddWorkspace/CloneWikiForm.tsx index ef8b35bb..51a8f9ff 100644 --- a/src/pages/AddWorkspace/CloneWikiForm.tsx +++ b/src/pages/AddWorkspace/CloneWikiForm.tsx @@ -1,20 +1,13 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ -import React, { useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; -import { Typography, MenuItem } from '@material-ui/core'; +import { MenuItem, Typography } from '@material-ui/core'; import { Folder as FolderIcon } from '@material-ui/icons'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; -import { - CreateContainer, - LocationPickerContainer, - LocationPickerInput, - LocationPickerButton, - SoftLinkToMainWikiSelect, - SubWikiTagAutoComplete, -} from './FormComponents'; +import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect, SubWikiTagAutoComplete } from './FormComponents'; -import type { IWikiWorkspaceFormProps } from './useForm'; import { useValidateCloneWiki } from './useCloneWiki'; +import type { IWikiWorkspaceFormProps } from './useForm'; export function CloneWikiForm({ form, isCreateMainWorkspace, errorInWhichComponent, errorInWhichComponentSetter }: IWikiWorkspaceFormProps): JSX.Element { const { t } = useTranslation(); @@ -24,7 +17,9 @@ export function CloneWikiForm({ form, isCreateMainWorkspace, errorInWhichCompone form.parentFolderLocationSetter(event.target.value)} + onChange={(event) => { + form.parentFolderLocationSetter(event.target.value); + }} label={t('AddWorkspace.WorkspaceParentFolder')} value={form.parentFolderLocation} /> @@ -37,8 +32,9 @@ export function CloneWikiForm({ form, isCreateMainWorkspace, errorInWhichCompone form.parentFolderLocationSetter(filePaths[0]); } }} - endIcon={}> - + endIcon={} + > + {t('AddWorkspace.Choose')} @@ -46,7 +42,9 @@ export function CloneWikiForm({ form, isCreateMainWorkspace, errorInWhichCompone form.wikiFolderNameSetter(event.target.value)} + onChange={(event) => { + form.wikiFolderNameSetter(event.target.value); + }} label={t('AddWorkspace.WorkspaceFolderNameToCreate')} helperText={`${t('AddWorkspace.CloneWiki')}${form.wikiFolderLocation ?? ''}`} value={form.wikiFolderName} @@ -57,16 +55,15 @@ export function CloneWikiForm({ form, isCreateMainWorkspace, errorInWhichCompone { const index = event.target.value as unknown as number; form.mainWikiToLinkSetter(form.mainWorkspaceList[index]); - }}> + }} + > {form.mainWorkspaceList.map((workspace, index) => ( {workspace.name} @@ -76,7 +73,9 @@ export function CloneWikiForm({ form, isCreateMainWorkspace, errorInWhichCompone fileSystemPath.tagName)} value={form.tagName} - onInputChange={(_, value) => form.tagNameSetter(value)} + onInputChange={(_, value) => { + form.tagNameSetter(value); + }} renderInput={(parameters) => ( isCreateMainWorkspaceSetter(event.target.checked)} />} + control={ + { + isCreateMainWorkspaceSetter(event.target.checked); + }} + /> + } label={label} /> - + {description} @@ -63,10 +70,17 @@ export function SyncedWikiDescription({ return ( isCreateSyncedWorkspaceSetter(event.target.checked)} />} + control={ + { + isCreateSyncedWorkspaceSetter(event.target.checked); + }} + /> + } label={label} /> - + {description} diff --git a/src/pages/AddWorkspace/ExistedWikiDoneButton.tsx b/src/pages/AddWorkspace/ExistedWikiDoneButton.tsx index 5c2c006b..e39aaf2e 100644 --- a/src/pages/AddWorkspace/ExistedWikiDoneButton.tsx +++ b/src/pages/AddWorkspace/ExistedWikiDoneButton.tsx @@ -1,12 +1,12 @@ import { useTranslation } from 'react-i18next'; -import { Typography, LinearProgress, Snackbar } from '@material-ui/core'; +import { LinearProgress, Snackbar, Typography } from '@material-ui/core'; import Alert from '@material-ui/lab/Alert'; +import { CloseButton, ReportErrorFabButton, WikiLocation } from './FormComponents'; +import { useExistedWiki, useValidateExistedWiki } from './useExistedWiki'; import type { IWikiWorkspaceFormProps } from './useForm'; -import { useValidateExistedWiki, useExistedWiki } from './useExistedWiki'; import { useWikiCreationProgress } from './useIndicator'; -import { WikiLocation, CloseButton, ReportErrorFabButton } from './FormComponents'; export function ExistedWikiDoneButton({ form, @@ -26,7 +26,7 @@ export function ExistedWikiDoneButton({ if (hasError) { return ( <> - + {wikiCreationMessage} {wikiCreationMessage !== undefined && } @@ -35,29 +35,37 @@ export function ExistedWikiDoneButton({ } return ( <> - {inProgressOrError && } - logPanelSetter(false)}> - {wikiCreationMessage} + {inProgressOrError && } + { + logPanelSetter(false); + }} + > + {wikiCreationMessage} - {isCreateMainWorkspace ? ( - - - {t('AddWorkspace.ImportWiki')} - - {form.wikiFolderLocation} - - ) : ( - - - {t('AddWorkspace.ImportWiki')} - - {form.wikiFolderLocation} - - {t('AddWorkspace.AndLinkToMainWorkspace')} - - - )} + {isCreateMainWorkspace + ? ( + + + {t('AddWorkspace.ImportWiki')} + + {form.wikiFolderLocation} + + ) + : ( + + + {t('AddWorkspace.ImportWiki')} + + {form.wikiFolderLocation} + + {t('AddWorkspace.AndLinkToMainWorkspace')} + + + )} ); } diff --git a/src/pages/AddWorkspace/ExistedWikiForm.tsx b/src/pages/AddWorkspace/ExistedWikiForm.tsx index 33b0849a..dec3a1f3 100644 --- a/src/pages/AddWorkspace/ExistedWikiForm.tsx +++ b/src/pages/AddWorkspace/ExistedWikiForm.tsx @@ -1,20 +1,13 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ +import { MenuItem, Typography } from '@material-ui/core'; +import { Folder as FolderIcon } from '@material-ui/icons'; import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { Typography, MenuItem } from '@material-ui/core'; -import { Folder as FolderIcon } from '@material-ui/icons'; -import { - CreateContainer, - LocationPickerContainer, - LocationPickerInput, - LocationPickerButton, - SoftLinkToMainWikiSelect, - SubWikiTagAutoComplete, -} from './FormComponents'; +import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect, SubWikiTagAutoComplete } from './FormComponents'; -import type { IWikiWorkspaceFormProps } from './useForm'; import { useValidateExistedWiki } from './useExistedWiki'; +import type { IWikiWorkspaceFormProps } from './useForm'; export function ExistedWikiForm({ form, @@ -73,8 +66,9 @@ export function ExistedWikiForm({ onLocationChange(filePaths[0]); } }} - endIcon={}> - + endIcon={} + > + {t('AddWorkspace.Choose')} @@ -84,16 +78,15 @@ export function ExistedWikiForm({ { const index = event.target.value as unknown as number; mainWikiToLinkSetter(mainWorkspaceList[index]); - }}> + }} + > {mainWorkspaceList.map((workspace, index) => ( {workspace.name} @@ -103,7 +96,9 @@ export function ExistedWikiForm({ fileSystemPath.tagName)} value={tagName} - onInputChange={(_, value) => tagNameSetter(value)} + onInputChange={(_, value) => { + tagNameSetter(value); + }} renderInput={(parameters) => ( - disabled === true - ? '' - : css` + disabled === true + ? '' + : css` white-space: nowrap; `} width: 100%; @@ -61,12 +61,13 @@ export function ReportErrorButton(props: { message: string }): JSX.Element { return ( @@ -85,12 +86,13 @@ export function ReportErrorFabButton(props: { message: string }): JSX.Element { return ( { const error = new Error(props.message); error.stack = 'ReportErrorButton'; void window.service.native.openNewGitHubIssue(error); - }}> + }} + > {t('Dialog.ReportBug')} diff --git a/src/pages/AddWorkspace/GitRepoUrlForm.tsx b/src/pages/AddWorkspace/GitRepoUrlForm.tsx index ecd05d4c..807d6819 100644 --- a/src/pages/AddWorkspace/GitRepoUrlForm.tsx +++ b/src/pages/AddWorkspace/GitRepoUrlForm.tsx @@ -26,7 +26,14 @@ export function GitRepoUrlForm({ return ( - gitRepoUrlSetter(event.target.value)} label={t('AddWorkspace.GitRepoUrl')} value={gitRepoUrl} /> + { + gitRepoUrlSetter(event.target.value); + }} + label={t('AddWorkspace.GitRepoUrl')} + value={gitRepoUrl} + /> {storageProvider === SupportedStorageServices.github && ( - + {wikiCreationMessage} {wikiCreationMessage !== undefined && } @@ -42,14 +42,20 @@ export function ImportHtmlWikiDoneButton({ } return ( <> - {inProgressOrError && } + {inProgressOrError && } {/* 这个好像是log面板 */} - logPanelSetter(false)}> - {wikiCreationMessage} + { + logPanelSetter(false); + }} + > + {wikiCreationMessage} - - + + {t('AddWorkspace.ImportWiki')} {form.wikiHtmlPath} diff --git a/src/pages/AddWorkspace/ImportHtmlWikiForm.tsx b/src/pages/AddWorkspace/ImportHtmlWikiForm.tsx index 37f1e5e1..e574c66b 100644 --- a/src/pages/AddWorkspace/ImportHtmlWikiForm.tsx +++ b/src/pages/AddWorkspace/ImportHtmlWikiForm.tsx @@ -1,9 +1,9 @@ -import { useTranslation } from 'react-i18next'; import { Typography } from '@material-ui/core'; import { Folder as FolderIcon } from '@material-ui/icons'; +import { useTranslation } from 'react-i18next'; import { useValidateHtmlWiki } from './useImportHtmlWiki'; -import { CreateContainer, LocationPickerContainer, LocationPickerInput, LocationPickerButton } from './FormComponents'; +import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput } from './FormComponents'; import type { IWikiWorkspaceFormProps } from './useForm'; @@ -45,8 +45,9 @@ export function ImportHtmlWikiForm({ } } }} - endIcon={}> - + endIcon={} + > + {t('AddWorkspace.Choose')} @@ -54,7 +55,9 @@ export function ImportHtmlWikiForm({ form.parentFolderLocationSetter(event.target.value)} + onChange={(event) => { + form.parentFolderLocationSetter(event.target.value); + }} label={t('AddWorkspace.WorkspaceParentFolder')} value={parentFolderLocation} /> @@ -67,8 +70,9 @@ export function ImportHtmlWikiForm({ form.parentFolderLocationSetter(filePaths[0]); } }} - endIcon={}> - + endIcon={} + > + {t('AddWorkspace.Choose')} @@ -76,7 +80,9 @@ export function ImportHtmlWikiForm({ wikiFolderNameSetter(event.target.value)} + onChange={(event) => { + wikiFolderNameSetter(event.target.value); + }} label={t('AddWorkspace.ExtractedWikiFolderName')} helperText={`${t('AddWorkspace.CreateWiki')}${wikiFolderLocation ?? ''}`} value={wikiFolderName} diff --git a/src/pages/AddWorkspace/NewWikiDoneButton.tsx b/src/pages/AddWorkspace/NewWikiDoneButton.tsx index 55b0858c..a20ffbef 100644 --- a/src/pages/AddWorkspace/NewWikiDoneButton.tsx +++ b/src/pages/AddWorkspace/NewWikiDoneButton.tsx @@ -1,13 +1,13 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ import { useTranslation } from 'react-i18next'; -import { Typography, LinearProgress, Snackbar } from '@material-ui/core'; +import { LinearProgress, Snackbar, Typography } from '@material-ui/core'; import Alert from '@material-ui/lab/Alert'; +import { CloseButton, ReportErrorFabButton, WikiLocation } from './FormComponents'; import type { IWikiWorkspaceFormProps } from './useForm'; -import { useValidateNewWiki, useNewWiki } from './useNewWiki'; import { useWikiCreationProgress } from './useIndicator'; -import { WikiLocation, CloseButton, ReportErrorFabButton } from './FormComponents'; +import { useNewWiki, useValidateNewWiki } from './useNewWiki'; export function NewWikiDoneButton({ form, @@ -27,7 +27,7 @@ export function NewWikiDoneButton({ if (hasError) { return ( <> - + {wikiCreationMessage} {wikiCreationMessage !== undefined && } @@ -36,29 +36,37 @@ export function NewWikiDoneButton({ } return ( <> - {inProgressOrError && } - logPanelSetter(false)}> - {wikiCreationMessage} + {inProgressOrError && } + { + logPanelSetter(false); + }} + > + {wikiCreationMessage} - {isCreateMainWorkspace ? ( - - - {t('AddWorkspace.CreateWiki')} - - {form.wikiFolderLocation} - - ) : ( - - - {t('AddWorkspace.CreateWiki')} - - {form.wikiFolderLocation} - - {t('AddWorkspace.AndLinkToMainWorkspace')} - - - )} + {isCreateMainWorkspace + ? ( + + + {t('AddWorkspace.CreateWiki')} + + {form.wikiFolderLocation} + + ) + : ( + + + {t('AddWorkspace.CreateWiki')} + + {form.wikiFolderLocation} + + {t('AddWorkspace.AndLinkToMainWorkspace')} + + + )} ); } diff --git a/src/pages/AddWorkspace/NewWikiForm.tsx b/src/pages/AddWorkspace/NewWikiForm.tsx index b5b74fd7..e8cc9bf3 100644 --- a/src/pages/AddWorkspace/NewWikiForm.tsx +++ b/src/pages/AddWorkspace/NewWikiForm.tsx @@ -1,16 +1,9 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ -import { useTranslation } from 'react-i18next'; -import { Typography, MenuItem } from '@material-ui/core'; +import { MenuItem, Typography } from '@material-ui/core'; import { Folder as FolderIcon } from '@material-ui/icons'; +import { useTranslation } from 'react-i18next'; -import { - CreateContainer, - LocationPickerContainer, - LocationPickerInput, - LocationPickerButton, - SoftLinkToMainWikiSelect, - SubWikiTagAutoComplete, -} from './FormComponents'; +import { CreateContainer, LocationPickerButton, LocationPickerContainer, LocationPickerInput, SoftLinkToMainWikiSelect, SubWikiTagAutoComplete } from './FormComponents'; import type { IWikiWorkspaceFormProps } from './useForm'; import { useValidateNewWiki } from './useNewWiki'; @@ -29,7 +22,9 @@ export function NewWikiForm({ form.parentFolderLocationSetter(event.target.value)} + onChange={(event) => { + form.parentFolderLocationSetter(event.target.value); + }} label={t('AddWorkspace.WorkspaceParentFolder')} value={form.parentFolderLocation} /> @@ -42,8 +37,9 @@ export function NewWikiForm({ form.parentFolderLocationSetter(filePaths[0]); } }} - endIcon={}> - + endIcon={} + > + {t('AddWorkspace.Choose')} @@ -51,7 +47,9 @@ export function NewWikiForm({ form.wikiFolderNameSetter(event.target.value)} + onChange={(event) => { + form.wikiFolderNameSetter(event.target.value); + }} label={t('AddWorkspace.WorkspaceFolderNameToCreate')} helperText={`${t('AddWorkspace.CreateWiki')}${form.wikiFolderLocation ?? ''}`} value={form.wikiFolderName} @@ -72,7 +70,8 @@ export function NewWikiForm({ onChange={(event) => { const index = event.target.value as unknown as number; form.mainWikiToLinkSetter(form.mainWorkspaceList[index]); - }}> + }} + > {form.mainWorkspaceList.map((workspace, index) => ( {workspace.name} @@ -82,7 +81,9 @@ export function NewWikiForm({ fileSystemPath.tagName)} value={form.tagName} - onInputChange={(_, value) => form.tagNameSetter(value)} + onInputChange={(_, value) => { + form.tagNameSetter(value); + }} renderInput={(parameters) => ( -
+
{t('AddWorkspace.AddWorkspace')} {wikiFolderName} - + currentTabSetter(newValue as CreateWorkspaceTabs)} - variant="scrollable" + onChange={(_event, newValue) => { + currentTabSetter(newValue as CreateWorkspaceTabs); + }} + variant='scrollable' value={currentTab} - aria-label={t('AddWorkspace.SwitchCreateNewOrOpenExisted')}> + aria-label={t('AddWorkspace.SwitchCreateNewOrOpenExisted')} + > diff --git a/src/pages/AddWorkspace/useExistedWiki.ts b/src/pages/AddWorkspace/useExistedWiki.ts index a9c3f223..6a824f46 100644 --- a/src/pages/AddWorkspace/useExistedWiki.ts +++ b/src/pages/AddWorkspace/useExistedWiki.ts @@ -74,9 +74,9 @@ export function useExistedWiki( const parentFolderLocationForExistedFolder = await window.service.native.path('dirname', form.wikiFolderLocation); if (!wikiFolderNameForExistedFolder || !parentFolderLocationForExistedFolder) { throw new Error( - `Undefined folder name: parentFolderLocationForExistedFolder: ${ + `Undefined folder name: parentFolderLocationForExistedFolder: ${parentFolderLocationForExistedFolder ?? '-'}, parentFolderLocationForExistedFolder: ${ parentFolderLocationForExistedFolder ?? '-' - }, parentFolderLocationForExistedFolder: ${parentFolderLocationForExistedFolder ?? '-'}`, + }`, ); } await window.service.wiki.ensureWikiExist(form.wikiFolderLocation, false); diff --git a/src/pages/AddWorkspace/useForm.ts b/src/pages/AddWorkspace/useForm.ts index 2c503eaf..cf843295 100644 --- a/src/pages/AddWorkspace/useForm.ts +++ b/src/pages/AddWorkspace/useForm.ts @@ -16,7 +16,9 @@ import type { INewWikiRequiredFormData } from './useNewWiki'; export function useIsCreateSyncedWorkspace(): [boolean, React.Dispatch>] { const [isCreateSyncedWorkspace, isCreateSyncedWorkspaceSetter] = useState(false); useEffect(() => { - void window.service.auth.getRandomStorageServiceUserInfo().then((result) => isCreateSyncedWorkspaceSetter(result !== undefined)); + void window.service.auth.getRandomStorageServiceUserInfo().then((result) => { + isCreateSyncedWorkspaceSetter(result !== undefined); + }); }, []); return [isCreateSyncedWorkspace, isCreateSyncedWorkspaceSetter]; } @@ -29,7 +31,9 @@ export function useWikiWorkspaceForm(options?: { fromExisted: boolean }) { const [wikiPort, wikiPortSetter] = useState(5212); useEffect(() => { // only update default port on component mount - void window.service.workspace.countWorkspaces().then((workspaceCount) => wikiPortSetter(wikiPort + workspaceCount)); + void window.service.workspace.countWorkspaces().then((workspaceCount) => { + wikiPortSetter(wikiPort + workspaceCount); + }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -79,7 +83,7 @@ export function useWikiWorkspaceForm(options?: { fromExisted: boolean }) { useEffect(() => { void (async function getDefaultExistedWikiFolderPathEffect() { const desktopPathAsDefaultExistedWikiFolderPath = await window.service.context.get('DEFAULT_WIKI_FOLDER'); - wikiFolderNameSetter(mainWorkspaceList[mainWorkspaceList.length - 1]?.wikiFolderLocation ?? 'wiki'); + wikiFolderNameSetter(mainWorkspaceList.at(-1)?.wikiFolderLocation ?? 'wiki'); parentFolderLocationSetter(desktopPathAsDefaultExistedWikiFolderPath); })(); // we only do this on component init diff --git a/src/pages/AddWorkspace/useImportHtmlWiki.ts b/src/pages/AddWorkspace/useImportHtmlWiki.ts index 053674ff..fa393c29 100644 --- a/src/pages/AddWorkspace/useImportHtmlWiki.ts +++ b/src/pages/AddWorkspace/useImportHtmlWiki.ts @@ -3,7 +3,7 @@ import { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { IErrorInWhichComponent, IWikiWorkspaceForm } from './useForm'; import { updateErrorInWhichComponentSetterByErrorMessage } from './useIndicator'; -import { useValidateNewWiki, useNewWiki } from './useNewWiki'; +import { useNewWiki, useValidateNewWiki } from './useNewWiki'; export function useValidateHtmlWiki( isCreateMainWorkspace: boolean, @@ -16,14 +16,14 @@ export function useValidateHtmlWiki( const [hasError, hasErrorSetter] = useState(false); useValidateNewWiki(isCreateMainWorkspace, isCreateSyncedWorkspace, form, errorInWhichComponentSetter); useEffect(() => { - if (!form.wikiHtmlPath) { - wikiCreationMessageSetter(`${t('AddWorkspace.NotFilled')}:${t('AddWorkspace.LocalWikiHtml')}`); - errorInWhichComponentSetter({ wikiHtmlPath: true }); - hasErrorSetter(true); - } else { + if (form.wikiHtmlPath) { wikiCreationMessageSetter(''); errorInWhichComponentSetter({}); hasErrorSetter(false); + } else { + wikiCreationMessageSetter(`${t('AddWorkspace.NotFilled')}:${t('AddWorkspace.LocalWikiHtml')}`); + errorInWhichComponentSetter({ wikiHtmlPath: true }); + hasErrorSetter(true); } }, [t, form.wikiHtmlPath, form.parentFolderLocation, form.wikiFolderName, errorInWhichComponentSetter]); diff --git a/src/pages/AddWorkspace/useIndicator.ts b/src/pages/AddWorkspace/useIndicator.ts index 7052170a..93a758ca 100644 --- a/src/pages/AddWorkspace/useIndicator.ts +++ b/src/pages/AddWorkspace/useIndicator.ts @@ -1,5 +1,5 @@ -import { useState, useEffect } from 'react'; import type { TFunction } from 'i18next'; +import { useEffect, useState } from 'react'; import { IErrorInWhichComponent } from './useForm'; export function useWikiCreationProgress( diff --git a/src/pages/AddWorkspace/useNewWiki.ts b/src/pages/AddWorkspace/useNewWiki.ts index 71c9ce66..6f7673d4 100644 --- a/src/pages/AddWorkspace/useNewWiki.ts +++ b/src/pages/AddWorkspace/useNewWiki.ts @@ -2,10 +2,10 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ import { useCallback, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { ConditionalExcept } from 'type-fest'; import { callWikiInitialization } from './useCallWikiInitialization'; import { IErrorInWhichComponent, IWikiWorkspaceForm, workspaceConfigFromForm } from './useForm'; import { updateErrorInWhichComponentSetterByErrorMessage } from './useIndicator'; -import { ConditionalExcept } from 'type-fest'; export function useValidateNewWiki( isCreateMainWorkspace: boolean, diff --git a/src/pages/EditWorkspace/index.tsx b/src/pages/EditWorkspace/index.tsx index bf9fcae7..19952df5 100644 --- a/src/pages/EditWorkspace/index.tsx +++ b/src/pages/EditWorkspace/index.tsx @@ -2,42 +2,42 @@ /* eslint-disable unicorn/no-useless-undefined */ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ /* eslint-disable unicorn/no-null */ -import React, { useCallback } from 'react'; -import styled, { css } from 'styled-components'; -import { useTranslation } from 'react-i18next'; -import { Helmet } from 'react-helmet'; import { - Tooltip, Button as ButtonRaw, - TextField as TextFieldRaw, Divider, + Link, List as ListRaw, ListItem as ListItemRaw, - ListItemText as ListItemTextRaw, ListItemSecondaryAction, - Switch, - Typography, - Link, + ListItemText as ListItemTextRaw, Paper, + Switch, + TextField as TextFieldRaw, + Tooltip, + Typography, } from '@material-ui/core'; import { Autocomplete } from '@material-ui/lab'; +import React, { useCallback } from 'react'; +import { Helmet } from 'react-helmet'; +import { useTranslation } from 'react-i18next'; +import styled, { css } from 'styled-components'; import defaultIcon from '../../images/default-icon.png'; -import type { ISubWikiPluginContent } from '@services/wiki/plugin/subWikiPlugin'; -import { WindowNames, WindowMeta } from '@services/windows/WindowProperties'; import { usePromiseValue } from '@/helpers/useServiceValue'; +import type { ISubWikiPluginContent } from '@services/wiki/plugin/subWikiPlugin'; +import { WindowMeta, WindowNames } from '@services/windows/WindowProperties'; import { useWorkspaceObservable } from '@services/workspaces/hooks'; -import { useForm } from './useForm'; import { IWorkspace } from '@services/workspaces/interface'; +import { useForm } from './useForm'; import { useRestartSnackbar } from '@/components/RestartSnackbar'; -import { defaultServerIP } from '@/constants/urls'; -import { SupportedStorageServices } from '@services/types'; -import { SyncedWikiDescription } from '../AddWorkspace/Description'; import { TokenForm } from '@/components/TokenForm'; -import { GitRepoUrlForm } from '../AddWorkspace/GitRepoUrlForm'; -import { isEqual } from 'lodash'; +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'; const Root = styled(Paper)` height: 100%; @@ -88,7 +88,7 @@ const AvatarRight = styled.div` `; /** * border: theme.palette.type === 'dark' ? 'none': '1px solid rgba(0, 0, 0, 0.12)'; - * */ + */ const Avatar = styled.div<{ transparentBackground?: boolean }>` height: 85px; width: 85px; @@ -103,14 +103,14 @@ const Avatar = styled.div<{ transparentBackground?: boolean }>` overflow: hidden; ${({ transparentBackground }) => { - if (transparentBackground === true) { - return css` + if (transparentBackground === true) { + return css` background: transparent; border: none; border-radius: 0; `; - } - }} + } +}} `; const AvatarPicture = styled.img` height: 100%; @@ -218,7 +218,7 @@ export default function EditWorkspace(): JSX.Element { const isCreateSyncedWorkspace = storageService !== SupportedStorageServices.local; return ( -
+
{RestartSnackbar} @@ -227,21 +227,25 @@ export default function EditWorkspace(): JSX.Element { </Helmet> <FlexGrow> <TextField - id="outlined-full-width" + id='outlined-full-width' label={t('EditWorkspace.Name')} helperText={t('EditWorkspace.NameDescription')} - placeholder="Optional" + placeholder='Optional' value={name} - onChange={(event) => workspaceSetter({ ...workspace, name: event.target.value })} + onChange={(event) => { + workspaceSetter({ ...workspace, name: event.target.value }); + }} /> <TextField - id="outlined-full-width" + id='outlined-full-width' label={t('EditWorkspace.Path')} helperText={t('EditWorkspace.PathDescription')} - placeholder="Optional" + placeholder='Optional' disabled value={wikiFolderLocation} - onChange={(event) => workspaceSetter({ ...workspace, wikiFolderLocation: event.target.value })} + onChange={(event) => { + workspaceSetter({ ...workspace, wikiFolderLocation: event.target.value }); + }} /> <TextField helperText={t('AddWorkspace.WorkspaceUserNameDetail')} @@ -257,17 +261,22 @@ export default function EditWorkspace(): JSX.Element { {!isSubWiki && ( <> <TextField - id="outlined-full-width" + 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' }}> + <Link + onClick={async () => { + actualIP && (await window.service.native.open(actualIP)); + }} + style={{ cursor: 'pointer' }} + > {actualIP} </Link> </span> } - placeholder="Optional" + placeholder='Optional' value={port} onChange={async (event) => { if (!Number.isNaN(Number.parseInt(event.target.value))) { @@ -282,7 +291,7 @@ export default function EditWorkspace(): JSX.Element { /> {rememberLastPageVisited && ( <TextField - id="outlined-full-width" + id='outlined-full-width' label={t('EditWorkspace.LastVisitState')} helperText={t('Preference.RememberLastVisitState')} placeholder={actualIP} @@ -312,26 +321,32 @@ export default function EditWorkspace(): JSX.Element { <AvatarFlex> <AvatarLeft> <Avatar transparentBackground={transparentBackground}> - <AvatarPicture alt="Icon" src={getValidIconPath(picturePath)} /> + <AvatarPicture alt='Icon' src={getValidIconPath(picturePath)} /> </Avatar> </AvatarLeft> <AvatarRight> - <Tooltip title={wikiPictureExtensions.join(', ')} placement="top"> + <Tooltip title={wikiPictureExtensions.join(', ')} placement='top'> <PictureButton - variant="outlined" - size="small" + variant='outlined' + size='small' onClick={async () => { const filePaths = await window.service.native.pickFile([{ name: 'Images', extensions: wikiPictureExtensions }]); if (filePaths.length > 0) { await window.service.workspace.update(workspaceID, { picturePath: filePaths[0] }); } - }}> + }} + > {t('EditWorkspace.SelectLocal')} </PictureButton> </Tooltip> - <Tooltip title={t('EditWorkspace.NoRevert') ?? ''} placement="bottom"> - <PictureButton onClick={() => workspaceSetter({ ...workspace, picturePath: null })} disabled={!picturePath}> + <Tooltip title={t('EditWorkspace.NoRevert') ?? ''} placement='bottom'> + <PictureButton + onClick={() => { + workspaceSetter({ ...workspace, picturePath: null }); + }} + disabled={!picturePath} + > {t('EditWorkspace.ResetDefaultIcon')} </PictureButton> </Tooltip> @@ -371,10 +386,12 @@ export default function EditWorkspace(): JSX.Element { <ListItemText primary={t('EditWorkspace.SyncOnInterval')} secondary={t('EditWorkspace.SyncOnIntervalDescription')} /> <ListItemSecondaryAction> <Switch - edge="end" - color="primary" + edge='end' + color='primary' checked={syncOnInterval} - onChange={(event) => workspaceSetter({ ...workspace, syncOnInterval: event.target.checked })} + onChange={(event) => { + workspaceSetter({ ...workspace, syncOnInterval: event.target.checked }); + }} /> </ListItemSecondaryAction> </ListItem> @@ -382,10 +399,12 @@ export default function EditWorkspace(): JSX.Element { <ListItemText primary={t('EditWorkspace.SyncOnStartup')} secondary={t('EditWorkspace.SyncOnStartupDescription')} /> <ListItemSecondaryAction> <Switch - edge="end" - color="primary" + edge='end' + color='primary' checked={syncOnStartup} - onChange={(event) => workspaceSetter({ ...workspace, syncOnStartup: event.target.checked })} + onChange={(event) => { + workspaceSetter({ ...workspace, syncOnStartup: event.target.checked }); + }} /> </ListItemSecondaryAction> </ListItem> @@ -401,10 +420,12 @@ export default function EditWorkspace(): JSX.Element { <ListItemText primary={t('EditWorkspace.BackupOnInterval')} secondary={t('EditWorkspace.BackupOnIntervalDescription')} /> <ListItemSecondaryAction> <Switch - edge="end" - color="primary" + edge='end' + color='primary' checked={backupOnInterval} - onChange={(event) => workspaceSetter({ ...workspace, backupOnInterval: event.target.checked })} + onChange={(event) => { + workspaceSetter({ ...workspace, backupOnInterval: event.target.checked }); + }} /> </ListItemSecondaryAction> </ListItem> @@ -418,10 +439,12 @@ export default function EditWorkspace(): JSX.Element { <ListItemText primary={t('EditWorkspace.HibernateTitle')} secondary={t('EditWorkspace.HibernateDescription')} /> <ListItemSecondaryAction> <Switch - edge="end" - color="primary" + edge='end' + color='primary' checked={hibernateWhenUnused} - onChange={(event) => workspaceSetter({ ...workspace, hibernateWhenUnused: event.target.checked })} + onChange={(event) => { + workspaceSetter({ ...workspace, hibernateWhenUnused: event.target.checked }); + }} /> </ListItemSecondaryAction> </ListItem> @@ -429,10 +452,12 @@ export default function EditWorkspace(): JSX.Element { <ListItemText primary={t('EditWorkspace.DisableNotificationTitle')} secondary={t('EditWorkspace.DisableNotification')} /> <ListItemSecondaryAction> <Switch - edge="end" - color="primary" + edge='end' + color='primary' checked={disableNotifications} - onChange={(event) => workspaceSetter({ ...workspace, disableNotifications: event.target.checked })} + onChange={(event) => { + workspaceSetter({ ...workspace, disableNotifications: event.target.checked }); + }} /> </ListItemSecondaryAction> </ListItem> @@ -440,10 +465,12 @@ export default function EditWorkspace(): JSX.Element { <ListItemText primary={t('EditWorkspace.DisableAudioTitle')} secondary={t('EditWorkspace.DisableAudio')} /> <ListItemSecondaryAction> <Switch - edge="end" - color="primary" + edge='end' + color='primary' checked={disableAudio} - onChange={(event) => workspaceSetter({ ...workspace, disableAudio: event.target.checked })} + onChange={(event) => { + workspaceSetter({ ...workspace, disableAudio: event.target.checked }); + }} /> </ListItemSecondaryAction> </ListItem> @@ -452,10 +479,10 @@ export default function EditWorkspace(): JSX.Element { </FlexGrow> {!isEqual(workspace, originalWorkspace) && ( <div> - <Button color="primary" variant="contained" disableElevation onClick={requestSaveAndRestart}> + <Button color='primary' variant='contained' disableElevation onClick={requestSaveAndRestart}> {t('EditWorkspace.Save')} </Button> - <Button variant="contained" disableElevation onClick={() => void window.remote.closeCurrentWindow()}> + <Button variant='contained' disableElevation onClick={() => void window.remote.closeCurrentWindow()}> {t('EditWorkspace.Cancel')} </Button> </div> diff --git a/src/pages/EditWorkspace/useForm.ts b/src/pages/EditWorkspace/useForm.ts index 4c2a91b2..35e0642f 100644 --- a/src/pages/EditWorkspace/useForm.ts +++ b/src/pages/EditWorkspace/useForm.ts @@ -1,6 +1,6 @@ -import usePreviousValue from 'beautiful-react-hooks/usePreviousValue'; -import { useState, useEffect, useCallback } from 'react'; import { IWorkspace } from '@services/workspaces/interface'; +import usePreviousValue from 'beautiful-react-hooks/usePreviousValue'; +import { useCallback, useEffect, useState } from 'react'; export function useForm( originalWorkspace?: IWorkspace, diff --git a/src/pages/Main/ErrorMessage.tsx b/src/pages/Main/ErrorMessage.tsx index 9867ca92..5b0d482f 100644 --- a/src/pages/Main/ErrorMessage.tsx +++ b/src/pages/Main/ErrorMessage.tsx @@ -1,11 +1,11 @@ /* eslint-disable unicorn/no-null */ +import { Accordion, AccordionDetails, AccordionSummary, Button, Typography } from '@material-ui/core'; import { useCallback } from 'react'; -import { Button, Accordion, AccordionSummary, AccordionDetails, Typography } from '@material-ui/core'; import { Trans, useTranslation } from 'react-i18next'; import styled from 'styled-components'; import { usePromiseValue } from '@/helpers/useServiceValue'; -import { IWorkspaceWithMetadata, IWorkspaceMetaData } from '@services/workspaces/interface'; +import { IWorkspaceMetaData, IWorkspaceWithMetadata } from '@services/workspaces/interface'; import { ReportErrorButton } from '../AddWorkspace/FormComponents'; const HelperTextsList = styled.ul` @@ -38,15 +38,20 @@ export function WikiErrorMessages(props: IWikiErrorMessagesProps): JSX.Element { <WikiErrorMessagesContainer> <Accordion> <AccordionSummary> - <Typography align="left" variant="h5"> + <Typography align='left' variant='h5'> {t('Error.WikiRuntimeError')} {t('ClickForDetails')} </Typography> </AccordionSummary> <AccordionDetails> - <Typography align="left" variant="body2"> + <Typography align='left' variant='body2'> {t('Error.WikiRuntimeErrorDescription')} </Typography> - <Button variant="outlined" onClick={async () => await window.service.native.open(wikiLogs.filePath, true)}> + <Button + variant='outlined' + onClick={async () => { + await window.service.native.open(wikiLogs.filePath, true); + }} + > {t('Preference.OpenLogFolder')} </Button> @@ -89,22 +94,22 @@ export function ViewLoadErrorMessages(props: IViewLoadErrorMessagesProps): JSX.E return ( <WikiErrorMessagesContainer> - <Typography align="left" variant="h5"> + <Typography align='left' variant='h5'> {t('AddWorkspace.WikiNotStarted')} </Typography> - <Typography align="left" variant="body2"> + <Typography align='left' variant='body2'> {props.activeWorkspaceMetadata.didFailLoadErrorMessage} </Typography> <br /> - <Trans t={t} i18nKey="AddWorkspace.MainPageReloadTip"> - <Typography align="left" variant="body2" component="div"> + <Trans t={t} i18nKey='AddWorkspace.MainPageReloadTip'> + <Typography align='left' variant='body2' component='div'> <> Try: <HelperTextsList> <li> Click{' '} - <b onClick={requestReload} onKeyPress={requestReload} role="button" tabIndex={0} style={{ cursor: 'pointer' }}> + <b onClick={requestReload} onKeyPress={requestReload} role='button' tabIndex={0} style={{ cursor: 'pointer' }}> Reload </b>{' '} button below or press <b>CMD_or_Ctrl + R</b> to reload the page. @@ -112,11 +117,16 @@ export function ViewLoadErrorMessages(props: IViewLoadErrorMessagesProps): JSX.E <li> Check the{' '} <b - onClick={async () => await window.service.native.open(await window.service.context.get('LOG_FOLDER'), true)} - onKeyPress={async () => await window.service.native.open(await window.service.context.get('LOG_FOLDER'), true)} - role="button" + onClick={async () => { + await window.service.native.open(await window.service.context.get('LOG_FOLDER'), true); + }} + onKeyPress={async () => { + await window.service.native.open(await window.service.context.get('LOG_FOLDER'), true); + }} + role='button' tabIndex={0} - style={{ cursor: 'pointer' }}> + style={{ cursor: 'pointer' }} + > Log Folder </b>{' '} to see what happened. @@ -128,12 +138,10 @@ export function ViewLoadErrorMessages(props: IViewLoadErrorMessagesProps): JSX.E </Trans> <ButtonGroup> - <Button variant="outlined" onClick={requestReload}> + <Button variant='outlined' onClick={requestReload}> {t('AddWorkspace.Reload')} </Button> - {typeof props.activeWorkspaceMetadata.didFailLoadErrorMessage === 'string' && ( - <ReportErrorButton message={props.activeWorkspaceMetadata.didFailLoadErrorMessage} /> - )} + {typeof props.activeWorkspaceMetadata.didFailLoadErrorMessage === 'string' && <ReportErrorButton message={props.activeWorkspaceMetadata.didFailLoadErrorMessage} />} </ButtonGroup> </WikiErrorMessagesContainer> ); diff --git a/src/pages/Main/NewUserMessage.tsx b/src/pages/Main/NewUserMessage.tsx index 448774f0..acab0f49 100644 --- a/src/pages/Main/NewUserMessage.tsx +++ b/src/pages/Main/NewUserMessage.tsx @@ -1,11 +1,11 @@ import { Trans, useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import { WindowNames } from '@services/windows/WindowProperties'; import { IPreferences } from '@services/preferences/interface'; +import { WindowNames } from '@services/windows/WindowProperties'; -import arrowWhite from '@/images/arrow-white.png'; import arrowBlack from '@/images/arrow-black.png'; +import arrowWhite from '@/images/arrow-white.png'; const Arrow = styled.div<{ image: string }>` height: 202px; @@ -64,31 +64,37 @@ export interface IProps { export function NewUserMessage(props: IProps): JSX.Element { const { t } = useTranslation(); return ( - <AddWorkspaceGuideInfoContainer onClick={async () => await window.service.window.open(WindowNames.addWorkspace)}> - {props.sidebar ? ( - <> - <Arrow image={props.themeSource === 'dark' ? arrowWhite : arrowBlack} /> - <TipWithSidebar id="new-user-tip"> - <Trans t={t} i18nKey="AddWorkspace.MainPageTipWithSidebar"> - <Tip2Text>Click</Tip2Text> - <Avatar>+</Avatar> - <Tip2Text>to get started!</Tip2Text> - </Trans> - </TipWithSidebar> - </> - ) : ( - <TipWithoutSidebar id="new-user-tip"> - <Tip2Text> - <Trans t={t} i18nKey="AddWorkspace.MainPageTipWithoutSidebar"> - <span>Click </span> - <strong>Workspaces > Add Workspace</strong> - <span>Or </span> - <strong>Click Here</strong> - <span> to get started!</span> - </Trans> - </Tip2Text> - </TipWithoutSidebar> - )} + <AddWorkspaceGuideInfoContainer + onClick={async () => { + await window.service.window.open(WindowNames.addWorkspace); + }} + > + {props.sidebar + ? ( + <> + <Arrow image={props.themeSource === 'dark' ? arrowWhite : arrowBlack} /> + <TipWithSidebar id='new-user-tip'> + <Trans t={t} i18nKey='AddWorkspace.MainPageTipWithSidebar'> + <Tip2Text>Click</Tip2Text> + <Avatar>+</Avatar> + <Tip2Text>to get started!</Tip2Text> + </Trans> + </TipWithSidebar> + </> + ) + : ( + <TipWithoutSidebar id='new-user-tip'> + <Tip2Text> + <Trans t={t} i18nKey='AddWorkspace.MainPageTipWithoutSidebar'> + <span>Click</span> + <strong>Workspaces > Add Workspace</strong> + <span>Or</span> + <strong>Click Here</strong> + <span>to get started!</span> + </Trans> + </Tip2Text> + </TipWithoutSidebar> + )} </AddWorkspaceGuideInfoContainer> ); } diff --git a/src/pages/Main/index.tsx b/src/pages/Main/index.tsx index c0e458fd..8d57df4a 100644 --- a/src/pages/Main/index.tsx +++ b/src/pages/Main/index.tsx @@ -1,34 +1,34 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ /* eslint-disable @typescript-eslint/promise-function-async */ import React, { useState } from 'react'; +import { Helmet } from 'react-helmet'; +import { useTranslation } from 'react-i18next'; import styled, { css } from 'styled-components'; import is, { isNot } from 'typescript-styled-is'; -import { useTranslation } from 'react-i18next'; -import { Helmet } from 'react-helmet'; import SimpleBar from 'simplebar-react'; import 'simplebar/dist/simplebar.min.css'; -import { Typography, Tooltip, IconButton as IconButtonRaw } from '@material-ui/core'; +import { IconButton as IconButtonRaw, Tooltip, Typography } from '@material-ui/core'; import { Settings as SettingsIcon, Upgrade as UpgradeIcon } from '@material-ui/icons'; -import { WindowNames } from '@services/windows/WindowProperties'; import { IUpdaterStatus } from '@services/updater/interface'; +import { WindowNames } from '@services/windows/WindowProperties'; import { usePromiseValue } from '@/helpers/useServiceValue'; import { useUpdaterObservable } from '@services/updater/hooks'; -import FindInPage from '../../components/FindInPage'; import { latestStableUpdateUrl } from '@/constants/urls'; +import FindInPage from '../../components/FindInPage'; -import { WorkspaceSelector, SortableWorkspaceSelectorList } from '@/components/WorkspaceIconAndSelector'; -import { useWorkspacesListObservable } from '@services/workspaces/hooks'; -import { usePreferenceObservable } from '@services/preferences/hooks'; import { CommandPaletteIcon } from '@/components/icon/CommandPaletteSVG'; +import { SortableWorkspaceSelectorList, WorkspaceSelector } from '@/components/WorkspaceIconAndSelector'; +import { usePreferenceObservable } from '@services/preferences/hooks'; +import { useWorkspacesListObservable } from '@services/workspaces/hooks'; import { Languages } from '../Preferences/sections/Languages'; import { TiddlyWiki } from '../Preferences/sections/TiddlyWiki'; +import { ViewLoadErrorMessages, WikiErrorMessages } from './ErrorMessage'; import { NewUserMessage } from './NewUserMessage'; -import { WikiErrorMessages, ViewLoadErrorMessages } from './ErrorMessage'; import { useAutoCreateFirstWorkspace } from './useAutoCreateFirstWorkspace'; const OuterRoot = styled.div` @@ -91,11 +91,11 @@ const SidebarTop = styled.div<{ titleBar?: boolean }>` flex: 1; width: 100%; ${({ titleBar }) => - titleBar === true - ? css` + titleBar === true + ? css` padding-top: 0; ` - : css` + : css` padding-top: 30px; `} `; @@ -167,13 +167,12 @@ export default function Main(): JSX.Element { if (preferences === undefined) return <div>{t('Loading')}</div>; const { sidebar, themeSource, sidebarShortcutHints, hideSideBarIcon } = preferences; - const hasError = - typeof activeWorkspaceMetadata?.didFailLoadErrorMessage === 'string' && + const hasError = typeof activeWorkspaceMetadata?.didFailLoadErrorMessage === 'string' && activeWorkspaceMetadata?.didFailLoadErrorMessage.length > 0 && activeWorkspaceMetadata?.isLoading === false; return ( <OuterRoot> - <div id="test" data-usage="For spectron automating testing" /> + <div id='test' data-usage='For spectron automating testing' /> <Helmet> <title>{t('Menu.TidGi')} @@ -181,13 +180,11 @@ export default function Main(): JSX.Element { {sidebar && ( - {workspacesList === undefined ? ( -
{t('Loading')}
- ) : ( - - )} + {workspacesList === undefined + ?
{t('Loading')}
+ : } 0 && ( <> await window.service.wiki.requestWikiSendActionMessage('open-command-palette')}> - {t('SideBar.CommandPalette')}} placement="top"> + onClick={async () => { + await window.service.wiki.requestWikiSendActionMessage('open-command-palette'); + }} + > + {t('SideBar.CommandPalette')}} placement='top'> @@ -220,19 +220,25 @@ export default function Main(): JSX.Element { )} {updaterMetaData?.status === IUpdaterStatus.updateAvailable && ( await window.service.native.open(updaterMetaData.info?.latestReleasePageUrl ?? latestStableUpdateUrl)}> - {t('SideBar.UpdateAvailable')}} placement="top"> + onClick={async () => { + await window.service.native.open(updaterMetaData.info?.latestReleasePageUrl ?? latestStableUpdateUrl); + }} + > + {t('SideBar.UpdateAvailable')}} placement='top'> )} await window.service.window.open(WindowNames.preferences)}> - {t('SideBar.Preferences')}} placement="top"> + onClick={async () => { + await window.service.window.open(WindowNames.preferences); + }} + > + {t('SideBar.Preferences')}} placement='top'> @@ -247,9 +253,9 @@ export default function Main(): JSX.Element { )} {Array.isArray(workspacesList) && workspacesList.length > 0 && activeWorkspaceMetadata?.isLoading === true && ( - {t('Loading')} + {t('Loading')} )} - {wikiCreationMessage && {wikiCreationMessage}} + {wikiCreationMessage && {wikiCreationMessage}} {Array.isArray(workspacesList) && workspacesList.length === 0 && } diff --git a/src/pages/Main/useAutoCreateFirstWorkspace.ts b/src/pages/Main/useAutoCreateFirstWorkspace.ts index 3afcee40..17dcc383 100644 --- a/src/pages/Main/useAutoCreateFirstWorkspace.ts +++ b/src/pages/Main/useAutoCreateFirstWorkspace.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/promise-function-async */ -import { useEffect, useState } from 'react'; -import { IWorkspaceWithMetadata } from '@services/workspaces/interface'; -import { INewWikiRequiredFormData, useNewWiki } from '../AddWorkspace/useNewWiki'; -import { SupportedStorageServices } from '@services/types'; -import { useWikiWorkspaceForm } from '../AddWorkspace/useForm'; import { usePromiseValue } from '@/helpers/useServiceValue'; +import { SupportedStorageServices } from '@services/types'; +import { IWorkspaceWithMetadata } from '@services/workspaces/interface'; +import { useEffect, useState } from 'react'; +import { useWikiWorkspaceForm } from '../AddWorkspace/useForm'; +import { INewWikiRequiredFormData, useNewWiki } from '../AddWorkspace/useNewWiki'; export function useAutoCreateFirstWorkspace(workspacesList: IWorkspaceWithMetadata[] | undefined, wikiCreationMessageSetter: (m: string) => void): void { const form = useWikiWorkspaceForm(); diff --git a/src/pages/Notifications/index.tsx b/src/pages/Notifications/index.tsx index 4dfe8321..1f07d46a 100644 --- a/src/pages/Notifications/index.tsx +++ b/src/pages/Notifications/index.tsx @@ -2,18 +2,18 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable unicorn/no-useless-undefined */ import React, { useState } from 'react'; -import styled from 'styled-components'; -import { useTranslation } from 'react-i18next'; import { Helmet } from 'react-helmet'; +import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; -import ListSubheader from '@material-ui/core/ListSubheader'; +import Container from '@material-ui/core/Container'; +import Divider from '@material-ui/core/Divider'; import ListRaw from '@material-ui/core/List'; import ListItem from '@material-ui/core/ListItem'; import ListItemText from '@material-ui/core/ListItemText'; -import Divider from '@material-ui/core/Divider'; -import TextField from '@material-ui/core/TextField'; +import ListSubheader from '@material-ui/core/ListSubheader'; import MenuItem from '@material-ui/core/MenuItem'; -import Container from '@material-ui/core/Container'; +import TextField from '@material-ui/core/TextField'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; @@ -23,12 +23,12 @@ import { WindowNames } from '@services/windows/WindowProperties'; import PopUpMenuItem from '@/components/PopUpMenuItem'; // https://www.sketchappsources.com/free-source/2501-iphone-app-background-sketch-freebie-resource.html -import nightBackgroundPng from '../../images/night-background.png'; -import { usePreferenceObservable } from '@services/preferences/hooks'; -import { useNotificationInfoObservable } from '@services/notifications/hooks'; -import { quickShortcuts } from './quickShortcuts'; -import { PreferenceSections } from '@services/preferences/interface'; import { formatDate } from '@services/libs/formatDate'; +import { useNotificationInfoObservable } from '@services/notifications/hooks'; +import { usePreferenceObservable } from '@services/preferences/hooks'; +import { PreferenceSections } from '@services/preferences/interface'; +import nightBackgroundPng from '../../images/night-background.png'; +import { quickShortcuts } from './quickShortcuts'; const Root = styled(Container)` width: 100%; @@ -90,7 +90,7 @@ export default function Notifications(): JSX.Element { { if (pauseNotificationsInfo === undefined) { return; @@ -114,19 +114,31 @@ export default function Notifications(): JSX.Element { <> - - + + - }> + } + > {quickShortcuts.map((shortcut) => ( - pauseNotification(shortcut.calcDate())}> + { + pauseNotification(shortcut.calcDate()); + }} + > {shortcut.name} ))} - showDateTimePickerSetter(true)}> + { + showDateTimePickerSetter(true); + }} + > Custom... @@ -147,19 +159,30 @@ export default function Notifications(): JSX.Element { } return ( - Pause notifications}> + Pause notifications}> {quickShortcuts.map((shortcut) => ( - pauseNotification(shortcut.calcDate())}> + { + pauseNotification(shortcut.calcDate()); + }} + > ))} - showDateTimePickerSetter(true)}> - + { + showDateTimePickerSetter(true); + }} + > + { await window.service.window.open(WindowNames.preferences, { gotoTab: PreferenceSections.notifications }); void window.remote.closeCurrentWindow(); @@ -172,7 +195,7 @@ export default function Notifications(): JSX.Element { return ( -
+
{t('ContextMenu.Notifications')} @@ -184,10 +207,14 @@ export default function Notifications(): JSX.Element { if (tilDate === null) return; pauseNotification(tilDate); }} - label="Custom" + label='Custom' open={showDateTimePicker} - onOpen={() => showDateTimePickerSetter(true)} - onClose={() => showDateTimePickerSetter(false)} + onOpen={() => { + showDateTimePickerSetter(true); + }} + onClose={() => { + showDateTimePickerSetter(false); + }} disablePast showTodayButton /> diff --git a/src/pages/Notifications/quickShortcuts.ts b/src/pages/Notifications/quickShortcuts.ts index 674a93cf..f4c1723b 100644 --- a/src/pages/Notifications/quickShortcuts.ts +++ b/src/pages/Notifications/quickShortcuts.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import { addMinutes, addHours, addDays, addWeeks } from 'date-fns'; +import { addDays, addHours, addMinutes, addWeeks } from 'date-fns'; export const quickShortcuts = [ { diff --git a/src/pages/Preferences/PreferenceComponents.tsx b/src/pages/Preferences/PreferenceComponents.tsx index e0f12028..6d9cae1c 100644 --- a/src/pages/Preferences/PreferenceComponents.tsx +++ b/src/pages/Preferences/PreferenceComponents.tsx @@ -1,12 +1,5 @@ +import { InputLabel as InputLabelRaw, ListItem as ListItemRaw, ListItemText as ListItemTextRaw, Paper as PaperRaw, TextField as TextFieldRaw, Typography } from '@material-ui/core'; import styled, { keyframes } from 'styled-components'; -import { - Paper as PaperRaw, - Typography, - TextField as TextFieldRaw, - ListItem as ListItemRaw, - ListItemText as ListItemTextRaw, - InputLabel as InputLabelRaw, -} from '@material-ui/core'; export const Paper = styled(PaperRaw)` margin-top: 5px; diff --git a/src/pages/Preferences/SectionsSideBar.tsx b/src/pages/Preferences/SectionsSideBar.tsx index cb7db409..ad497059 100644 --- a/src/pages/Preferences/SectionsSideBar.tsx +++ b/src/pages/Preferences/SectionsSideBar.tsx @@ -1,9 +1,9 @@ +import { Divider as DividerRaw, List, ListItem, ListItemIcon as ListItemIconRaw, ListItemText } from '@material-ui/core'; import React from 'react'; import styled, { keyframes } from 'styled-components'; -import { Divider as DividerRaw, List, ListItem, ListItemIcon as ListItemIconRaw, ListItemText } from '@material-ui/core'; -import { ISectionProps } from './useSections'; import { PreferenceSections } from '@services/preferences/interface'; +import { ISectionProps } from './useSections'; const SideBar = styled.div` position: fixed; diff --git a/src/pages/Preferences/index.tsx b/src/pages/Preferences/index.tsx index 8d2d8ac4..576544f5 100644 --- a/src/pages/Preferences/index.tsx +++ b/src/pages/Preferences/index.tsx @@ -1,27 +1,27 @@ import React, { useEffect } from 'react'; -import styled, { css } from 'styled-components'; import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; import { useRestartSnackbar } from '@/components/RestartSnackbar'; import { IPossibleWindowMeta, WindowMeta, WindowNames } from '@services/windows/WindowProperties'; -import { usePreferenceSections } from './useSections'; -import { SectionSideBar } from './SectionsSideBar'; -import { TiddlyWiki } from './sections/TiddlyWiki'; -import { Sync } from './sections/Sync'; -import { General } from './sections/General'; -import { System } from './sections/System'; -import { Notifications } from './sections/Notifications'; -import { Languages } from './sections/Languages'; -import { Downloads } from './sections/Downloads'; -import { Network } from './sections/Network'; -import { PrivacyAndSecurity } from './sections/PrivacyAndSecurity'; import { DeveloperTools } from './sections/DeveloperTools'; -import { Performance } from './sections/Performance'; -import { Updates } from './sections/Updates'; +import { Downloads } from './sections/Downloads'; import { FriendLinks } from './sections/FriendLinks'; +import { General } from './sections/General'; +import { Languages } from './sections/Languages'; import { Miscellaneous } from './sections/Miscellaneous'; +import { Network } from './sections/Network'; +import { Notifications } from './sections/Notifications'; +import { Performance } from './sections/Performance'; +import { PrivacyAndSecurity } from './sections/PrivacyAndSecurity'; +import { Sync } from './sections/Sync'; +import { System } from './sections/System'; +import { TiddlyWiki } from './sections/TiddlyWiki'; +import { Updates } from './sections/Updates'; +import { SectionSideBar } from './SectionsSideBar'; +import { usePreferenceSections } from './useSections'; const Root = styled.div` padding: 20px; @@ -47,7 +47,7 @@ export default function Preferences(): JSX.Element { return ( -
+
{RestartSnackbar} diff --git a/src/pages/Preferences/sections/DeveloperTools.tsx b/src/pages/Preferences/sections/DeveloperTools.tsx index 98407ca8..9902ee91 100644 --- a/src/pages/Preferences/sections/DeveloperTools.tsx +++ b/src/pages/Preferences/sections/DeveloperTools.tsx @@ -1,11 +1,11 @@ -import React from 'react'; -import { useTranslation } from 'react-i18next'; import { Divider, List } from '@material-ui/core'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; -import type { ISectionProps } from '../useSections'; -import { Paper, SectionTitle, ListItem, ListItemText } from '../PreferenceComponents'; import { usePromiseValue } from '@/helpers/useServiceValue'; +import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents'; +import type { ISectionProps } from '../useSections'; export function DeveloperTools(props: ISectionProps): JSX.Element { const { t } = useTranslation(); @@ -24,9 +24,7 @@ export function DeveloperTools(props: ISectionProps): JSX.Element { {t('Preference.DeveloperTools')} - {LOG_FOLDER === undefined || SETTINGS_FOLDER === undefined ? ( - {t('Loading')} - ) : ( + {LOG_FOLDER === undefined || SETTINGS_FOLDER === undefined ? {t('Loading')} : ( <> + }} + > - + + }} + > - + - await window.service.preference.resetWithConfirm()}> + { + await window.service.preference.resetWithConfirm(); + }} + > - + )} diff --git a/src/pages/Preferences/sections/Downloads.tsx b/src/pages/Preferences/sections/Downloads.tsx index 48607347..9ad772d2 100644 --- a/src/pages/Preferences/sections/Downloads.tsx +++ b/src/pages/Preferences/sections/Downloads.tsx @@ -1,11 +1,11 @@ -import React from 'react'; -import { useTranslation } from 'react-i18next'; import { Divider, List, ListItemSecondaryAction, Switch } from '@material-ui/core'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; -import type { ISectionProps } from '../useSections'; -import { Paper, SectionTitle, ListItem, ListItemText } from '../PreferenceComponents'; import { usePreferenceObservable } from '@services/preferences/hooks'; +import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents'; +import type { ISectionProps } from '../useSections'; export function Downloads(props: Required): JSX.Element { const { t } = useTranslation(); @@ -17,9 +17,7 @@ export function Downloads(props: Required): JSX.Element { {t('Preference.Downloads')} - {preference === undefined ? ( - {t('Loading')} - ) : ( + {preference === undefined ? {t('Loading')} : ( <> ): JSX.Element { .catch((error: Error) => { console.log(error); // eslint-disable-line no-console }); - }}> + }} + > - + { await window.service.preference.set('askForDownloadPath', event.target.checked); diff --git a/src/pages/Preferences/sections/FriendLinks.tsx b/src/pages/Preferences/sections/FriendLinks.tsx index a56f5fc7..1a58e27f 100644 --- a/src/pages/Preferences/sections/FriendLinks.tsx +++ b/src/pages/Preferences/sections/FriendLinks.tsx @@ -1,14 +1,14 @@ -import React from 'react'; -import styled from 'styled-components'; -import { useTranslation } from 'react-i18next'; import { Divider, List } from '@material-ui/core'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import styled from 'styled-components'; +import { ListItem, ListItemText, Paper, SectionTitle } from '../PreferenceComponents'; import type { ISectionProps } from '../useSections'; -import { Paper, SectionTitle, ListItem, ListItemText } from '../PreferenceComponents'; -import webcatalogLogo from '@/images/webcatalog-logo.svg'; import translatiumLogo from '@/images/translatium-logo.svg'; +import webcatalogLogo from '@/images/webcatalog-logo.svg'; const Logo = styled.img` height: 28px; @@ -22,19 +22,34 @@ export function FriendLinks(props: ISectionProps): JSX.Element { {t('Preference.FriendLinks')} - await window.service.native.open('https://github.com/webcatalog/webcatalog-engine')}> + { + await window.service.native.open('https://github.com/webcatalog/webcatalog-engine'); + }} + > - + - await window.service.native.open('https://webcatalogapp.com?utm_source=tidgi_app')}> + { + await window.service.native.open('https://webcatalogapp.com?utm_source=tidgi_app'); + }} + > } secondary={t('Preference.WebCatalogIntro')} /> - + - await window.service.native.open('https://translatiumapp.com?utm_source=tidgi_app')}> + { + await window.service.native.open('https://translatiumapp.com?utm_source=tidgi_app'); + }} + > } secondary={t('Preference.TranslatiumIntro')} /> - + diff --git a/src/pages/Preferences/sections/General.tsx b/src/pages/Preferences/sections/General.tsx index 2cbcacb2..200006e2 100644 --- a/src/pages/Preferences/sections/General.tsx +++ b/src/pages/Preferences/sections/General.tsx @@ -1,14 +1,14 @@ +import { Divider, List, ListItemSecondaryAction, MenuItem, Switch } from '@material-ui/core'; +import ChevronRightIcon from '@material-ui/icons/ChevronRight'; import React from 'react'; import { Trans, useTranslation } from 'react-i18next'; -import { Divider, Switch, List, ListItemSecondaryAction, MenuItem } from '@material-ui/core'; -import ChevronRightIcon from '@material-ui/icons/ChevronRight'; -import type { ISectionProps } from '../useSections'; -import { Paper, SectionTitle, ListItem, ListItemText } from '../PreferenceComponents'; -import { usePreferenceObservable } from '@services/preferences/hooks'; 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 type { ISectionProps } from '../useSections'; const getThemeString = (theme: IPreferences['themeSource']): string => { if (theme === 'light') return 'Light'; @@ -27,16 +27,14 @@ export function General(props: Required): JSX.Element { {t('Preference.General')} - {preference === undefined || platform === undefined ? ( - {t('Loading')} - ) : ( + {preference === undefined || platform === undefined ? {t('Loading')} : ( <> { await window.service.preference.set('rememberLastPageVisited', event.target.checked); @@ -47,20 +45,36 @@ export function General(props: Required): JSX.Element { - + - }> - await window.service.preference.set('themeSource', 'system')}> + } + > + { + await window.service.preference.set('themeSource', 'system'); + }} + > {t('Preference.SystemDefaultTheme')} - await window.service.preference.set('themeSource', 'light')}> + { + await window.service.preference.set('themeSource', 'light'); + }} + > {t('Preference.LightTheme')} - await window.service.preference.set('themeSource', 'dark')}> + { + await window.service.preference.set('themeSource', 'dark'); + }} + > {t('Preference.DarkTheme')} @@ -69,8 +83,8 @@ export function General(props: Required): JSX.Element { { await window.service.preference.set('sidebar', event.target.checked); @@ -83,8 +97,8 @@ export function General(props: Required): JSX.Element { { await window.service.preference.set('hideSideBarIcon', event.target.checked); @@ -97,8 +111,8 @@ export function General(props: Required): JSX.Element { { await window.service.preference.set('sidebarShortcutHints', event.target.checked); @@ -113,8 +127,8 @@ export function General(props: Required): JSX.Element { { await window.service.preference.set('titleBar', event.target.checked); @@ -134,8 +148,8 @@ export function General(props: Required): JSX.Element { { await window.service.preference.set('hideMenuBar', event.target.checked); @@ -151,8 +165,8 @@ export function General(props: Required): JSX.Element { { await window.service.preference.set('alwaysOnTop', event.target.checked); @@ -165,12 +179,12 @@ export function General(props: Required): JSX.Element { { await window.service.preference.set('attachToMenubar', event.target.checked); @@ -183,8 +197,8 @@ export function General(props: Required): JSX.Element { { await window.service.preference.set('menuBarAlwaysOnTop', event.target.checked); @@ -200,7 +214,7 @@ export function General(props: Required): JSX.Element { + Navigate between pages with 3-finger gestures. Swipe left to go back or swipe right to go forward.
To enable it, you also need to change @@ -214,8 +228,8 @@ export function General(props: Required): JSX.Element { /> { await window.service.preference.set('swipeToNavigate', event.target.checked); diff --git a/src/pages/Preferences/sections/Languages.tsx b/src/pages/Preferences/sections/Languages.tsx index c7be5dfb..72fe0109 100644 --- a/src/pages/Preferences/sections/Languages.tsx +++ b/src/pages/Preferences/sections/Languages.tsx @@ -1,13 +1,13 @@ -import { useTranslation } from 'react-i18next'; import { Divider, List, ListItemSecondaryAction, MenuItem, Select, Switch } from '@material-ui/core'; import ChevronRightIcon from '@material-ui/icons/ChevronRight'; +import { useTranslation } from 'react-i18next'; -import type { ISectionProps } from '../useSections'; -import { Paper, SectionTitle, ListItem, ListItemText, InputLabel } from '../PreferenceComponents'; -import { usePreferenceObservable } from '@services/preferences/hooks'; -import { WindowNames } from '@services/windows/WindowProperties'; 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 type { ISectionProps } from '../useSections'; export function Languages(props: Partial & { languageSelectorOnly?: boolean }): JSX.Element { const { t } = useTranslation(); @@ -24,23 +24,22 @@ export function Languages(props: Partial & { languageSelectorOnly {t('Preference.Languages')} - {preference === undefined || platform === undefined || supportedLanguagesMap === undefined || preference.language === undefined ? ( - {t('Loading')} - ) : ( + {preference === undefined || platform === undefined || supportedLanguagesMap === undefined || preference.language === undefined ? {t('Loading')} : ( <> - + {t('Preference.Languages')}