mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-15 15:10:31 -08:00
feat: Move new user helps to Guide page
This commit is contained in:
parent
aefd9dcd88
commit
b790f7b97c
12 changed files with 95 additions and 25 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import AccountTreeIcon from '@material-ui/icons/AccountTree';
|
||||
import InfoIcon from '@material-ui/icons/Info';
|
||||
import { PageType } from '@services/pages/interface';
|
||||
|
||||
export function getBuildInPageIcon(pageType: PageType): JSX.Element {
|
||||
|
|
@ -10,5 +11,9 @@ export function getBuildInPageIcon(pageType: PageType): JSX.Element {
|
|||
case PageType.workflow: {
|
||||
return <AccountTreeIcon />;
|
||||
}
|
||||
case PageType.guide: {
|
||||
return <InfoIcon />;
|
||||
}
|
||||
}
|
||||
// don't return null here. If you get `Function lacks ending return statement and return type does not include 'undefined'.ts(2366)`, you must forget to provide an icon for a newly added page type here.
|
||||
}
|
||||
|
|
|
|||
44
src/pages/Guide/index.tsx
Normal file
44
src/pages/Guide/index.tsx
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
||||
/* eslint-disable @typescript-eslint/promise-function-async */
|
||||
import { Typography } from '@material-ui/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { usePreferenceObservable } from '@services/preferences/hooks';
|
||||
import { useWorkspacesListObservable } from '@services/workspaces/hooks';
|
||||
import { useState } from 'react';
|
||||
import { Languages } from '../Preferences/sections/Languages';
|
||||
import { TiddlyWiki } from '../Preferences/sections/TiddlyWiki';
|
||||
import { NewUserMessage } from './NewUserMessage';
|
||||
import { useAutoCreateFirstWorkspace } from './useAutoCreateFirstWorkspace';
|
||||
|
||||
const InnerContentRoot = styled.div`
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
export function Guide(): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
const workspacesList = useWorkspacesListObservable();
|
||||
const [wikiCreationMessage, wikiCreationMessageSetter] = useState('');
|
||||
useAutoCreateFirstWorkspace(workspacesList, wikiCreationMessageSetter);
|
||||
const preferences = usePreferenceObservable();
|
||||
return (
|
||||
<>
|
||||
<InnerContentRoot>
|
||||
{wikiCreationMessage && <Typography color='textSecondary'>{wikiCreationMessage}</Typography>}
|
||||
{preferences !== undefined && Array.isArray(workspacesList) && workspacesList.length === 0 && (
|
||||
<NewUserMessage sidebar={preferences.sidebar} themeSource={preferences.themeSource} />
|
||||
)}
|
||||
</InnerContentRoot>
|
||||
<Languages languageSelectorOnly />
|
||||
<TiddlyWiki />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ export function useAutoCreateFirstWorkspace(workspacesList: IWorkspaceWithMetada
|
|||
if (DEFAULT_WIKI_FOLDER === undefined || DEFAULT_FIRST_WIKI_PATH === undefined) return;
|
||||
if (workspacesList?.length === 0) {
|
||||
createdSetter(true);
|
||||
void onSubmit();
|
||||
void onSubmit()
|
||||
}
|
||||
}, [workspacesList?.length, created, createdSetter, onSubmit, DEFAULT_WIKI_FOLDER, DEFAULT_FIRST_WIKI_PATH]);
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ import { WindowNames } from '@services/windows/WindowProperties';
|
|||
import FindInPage from '../../components/FindInPage';
|
||||
import { SideBar } from '../../components/Sidebar';
|
||||
import { WikiBackground } from '../WikiBackground';
|
||||
import { Guide } from '../Guide';
|
||||
|
||||
const Workflow = lazy(() => import('../Workflow'));
|
||||
|
||||
|
|
@ -78,11 +79,10 @@ export default function Main(): JSX.Element {
|
|||
<FindInPage />
|
||||
<Switch>
|
||||
<Route path={`/${WindowNames.main}/${PageType.wiki}/:id/`} component={WikiBackground} />
|
||||
<Route path={`/${WindowNames.main}/${PageType.guide}/:id/`} component={Guide} />
|
||||
<Route path={`/${WindowNames.main}/${PageType.workflow}/:id/`} component={Workflow} />
|
||||
<Route path={`/${WindowNames.main}`} component={WikiBackground} />
|
||||
<Route>
|
||||
<div>{t('Loading')}(Main)</div>
|
||||
</Route>
|
||||
<Route path={`/${WindowNames.main}`} component={Guide} />
|
||||
<Route component={Guide} />
|
||||
</Switch>
|
||||
</ContentRoot>
|
||||
</Root>
|
||||
|
|
|
|||
|
|
@ -4,14 +4,10 @@ import { Typography } from '@material-ui/core';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { usePreferenceObservable } from '@services/preferences/hooks';
|
||||
import { useWorkspacesListObservable } from '@services/workspaces/hooks';
|
||||
import { useState } from 'react';
|
||||
import { useAutoCreateFirstWorkspace } from '../Main/useAutoCreateFirstWorkspace';
|
||||
import { Languages } from '../Preferences/sections/Languages';
|
||||
import { TiddlyWiki } from '../Preferences/sections/TiddlyWiki';
|
||||
import { useAutoCreateFirstWorkspace } from '../Guide/useAutoCreateFirstWorkspace';
|
||||
import { ViewLoadErrorMessages, WikiErrorMessages } from './ErrorMessage';
|
||||
import { NewUserMessage } from './NewUserMessage';
|
||||
|
||||
const InnerContentRoot = styled.div`
|
||||
flex: 1;
|
||||
|
|
@ -37,10 +33,6 @@ export function WikiBackground(): JSX.Element {
|
|||
activeWorkspaceMetadata?.isLoading === false;
|
||||
const [wikiCreationMessage, wikiCreationMessageSetter] = useState('');
|
||||
useAutoCreateFirstWorkspace(workspacesList, wikiCreationMessageSetter);
|
||||
const preferences = usePreferenceObservable();
|
||||
if (preferences === undefined) return <div>{t('Loading')}</div>;
|
||||
|
||||
const { sidebar, themeSource } = preferences;
|
||||
return (
|
||||
<>
|
||||
<InnerContentRoot>
|
||||
|
|
@ -50,10 +42,7 @@ export function WikiBackground(): JSX.Element {
|
|||
)}
|
||||
{Array.isArray(workspacesList) && workspacesList.length > 0 && activeWorkspaceMetadata?.isLoading === true && <Typography color='textSecondary'>{t('Loading')}</Typography>}
|
||||
{wikiCreationMessage && <Typography color='textSecondary'>{wikiCreationMessage}</Typography>}
|
||||
{Array.isArray(workspacesList) && workspacesList.length === 0 && <NewUserMessage sidebar={sidebar} themeSource={themeSource} />}
|
||||
</InnerContentRoot>
|
||||
<Languages languageSelectorOnly />
|
||||
<TiddlyWiki />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable @typescript-eslint/promise-function-async */
|
||||
import { WindowNames } from '@services/windows/WindowProperties';
|
||||
import { t } from 'i18next';
|
||||
import { lazy, useEffect } from 'react';
|
||||
import { Route, Switch, useLocation } from 'wouter';
|
||||
|
||||
|
|
@ -26,9 +25,7 @@ export function Pages(): JSX.Element {
|
|||
<Route path={`/${WindowNames.preferences}`} component={DialogPreferences} />
|
||||
<Route path={`/${WindowNames.spellcheck}`} component={SpellcheckLanguages} />
|
||||
<Route path={`/${WindowNames.main}/:any*/:any*`} component={Main} />
|
||||
<Route>
|
||||
<div>{t('Loading')}(index)</div>
|
||||
</Route>
|
||||
<Route component={Main} />
|
||||
</Switch>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,21 @@
|
|||
import { PageType } from './interface';
|
||||
import { IPage, PageType } from './interface';
|
||||
|
||||
export const defaultBuildInPages = {
|
||||
/**
|
||||
* Add React component route for build-in pages in `src/pages/Main/index.tsx`
|
||||
*/
|
||||
export const defaultBuildInPages: Record<string, IPage> = {
|
||||
workflow: {
|
||||
type: PageType.workflow,
|
||||
id: PageType.workflow,
|
||||
active: false,
|
||||
hide: false,
|
||||
order: 0,
|
||||
},
|
||||
guide: {
|
||||
type: PageType.guide,
|
||||
id: PageType.guide,
|
||||
active: false,
|
||||
hide: false,
|
||||
order: 0,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,5 +9,8 @@ export function getBuildInPageName(pageType: PageType, t: TFunction) {
|
|||
case PageType.workflow: {
|
||||
return t('Workflow.Title');
|
||||
}
|
||||
case PageType.guide: {
|
||||
return t('WorkspaceSelector.Guide');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,11 +38,17 @@ export class Pages implements IPagesService {
|
|||
* load pages in sync, and ensure it is an Object
|
||||
*/
|
||||
private getInitPagesForCache(): Record<string, IPage> {
|
||||
const pagesFromDisk = settings.getSync(`pages`) ?? defaultBuildInPages;
|
||||
const pagesFromDisk = settings.getSync(`pages`) ?? {};
|
||||
const loadedPages = typeof pagesFromDisk === 'object' && !Array.isArray(pagesFromDisk)
|
||||
? pickBy(pagesFromDisk, (value) => value !== null) as unknown as Record<string, IPage>
|
||||
: {};
|
||||
return loadedPages;
|
||||
return this.sanitizePageSettings(loadedPages);
|
||||
}
|
||||
|
||||
private sanitizePageSettings(pages: Record<string, IPage>): Record<string, IPage> {
|
||||
// assign newly added default page setting to old user config, if user config missing a key (id of newly added build-in page)
|
||||
const sanitizedPages = { ...defaultBuildInPages, ...pages };
|
||||
return sanitizedPages;
|
||||
}
|
||||
|
||||
public async setActivePage(id: string | PageType, oldActivePageID: string | PageType | undefined): Promise<void> {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,25 @@ import { ProxyPropertyType } from 'electron-ipc-cat/common';
|
|||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
export enum PageType {
|
||||
/**
|
||||
* Default empty page, have some user guide and new user settings.
|
||||
*/
|
||||
guide = 'guide',
|
||||
/**
|
||||
* All "workspaces". It is hard to merge workspace concept with page concept, because will need to migrate all user data. So we leave them to be still workspace, but also call them wiki pages. And in event listeners about wiki page, we redirect them to call workspace methods.
|
||||
*/
|
||||
wiki = 'wiki',
|
||||
/**
|
||||
* AI workflow
|
||||
*/
|
||||
workflow = 'workflow',
|
||||
}
|
||||
export interface IPage {
|
||||
active: boolean;
|
||||
/**
|
||||
* User can hide a page's button from sidebar if they don't want to see it.
|
||||
*/
|
||||
hide: boolean;
|
||||
/**
|
||||
* Wiki's workspaceID, or just be build-in page's type.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -397,6 +397,7 @@ export class Workspace implements IWorkspaceService {
|
|||
}
|
||||
// switch from page to workspace, clear active page to switch to WikiBackground page
|
||||
const activePage = this.pagesService.getActivePageSync();
|
||||
// instead of switch to a wiki workspace, we simply clear active page, because wiki page logic is not implemented yet, we are still using workspace logic.
|
||||
await this.pagesService.clearActivePage(activePage?.id);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue