mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-11-27 05:33:10 +03:00
feat(core): add toggle workspace dialog (#5312)
This commit is contained in:
parent
b9345e8d21
commit
e10609276d
@ -3,6 +3,8 @@ import { z } from 'zod';
|
||||
const _appConfigSchema = z.object({
|
||||
/** whether to show onboarding first */
|
||||
onBoarding: z.boolean().optional().default(true),
|
||||
/** whether to show change workspace guide modal */
|
||||
dismissWorkspaceGuideModal: z.boolean().optional().default(false),
|
||||
});
|
||||
export type AppConfigSchema = z.infer<typeof _appConfigSchema>;
|
||||
export const defaultAppConfig = _appConfigSchema.parse({});
|
||||
@ -20,7 +22,7 @@ interface StorageOptions<T> {
|
||||
/**
|
||||
* Storage for app configuration, stored in memory by default
|
||||
*/
|
||||
class Storage<T> {
|
||||
class Storage<T extends object> {
|
||||
private _cfg: T;
|
||||
private readonly _id = _inMemoryId++;
|
||||
private readonly _options;
|
||||
@ -67,7 +69,10 @@ class Storage<T> {
|
||||
return this._cfg;
|
||||
}
|
||||
} else {
|
||||
return this.get()[key];
|
||||
const fullConfig = this.get();
|
||||
// TODO: handle key not found, set default value
|
||||
// if (!(key in fullConfig)) {}
|
||||
return fullConfig[key];
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,26 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const title = style({
|
||||
padding: '20px 24px 8px 24px',
|
||||
fontSize: '18px',
|
||||
fontFamily: 'var(--affine-font-family)',
|
||||
fontWeight: '600',
|
||||
lineHeight: '26px',
|
||||
});
|
||||
|
||||
export const content = style({
|
||||
padding: '0px 24px',
|
||||
fontSize: '15px',
|
||||
lineHeight: '24px',
|
||||
fontWeight: 400,
|
||||
});
|
||||
|
||||
export const footer = style({
|
||||
padding: '20px 28px',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
});
|
||||
|
||||
export const gotItBtn = style({
|
||||
fontWeight: 500,
|
||||
});
|
@ -0,0 +1,74 @@
|
||||
import { Button, Modal, type ModalProps } from '@affine/component';
|
||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
||||
import { memo, useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { useAppConfigStorage } from '../../../hooks/use-app-config-storage';
|
||||
import Thumb from './assets/thumb';
|
||||
import * as styles from './workspace-guide-modal.css';
|
||||
|
||||
const contentOptions: ModalProps['contentOptions'] = {
|
||||
style: { padding: 0, overflow: 'hidden' },
|
||||
};
|
||||
const overlayOptions: ModalProps['overlayOptions'] = {
|
||||
style: {
|
||||
background:
|
||||
'linear-gradient(95deg, transparent 0px, var(--affine-background-primary-color) 400px)',
|
||||
},
|
||||
};
|
||||
|
||||
export const WorkspaceGuideModal = memo(function WorkspaceGuideModal() {
|
||||
const t = useAFFiNEI18N();
|
||||
const [dismiss, setDismiss] = useAppConfigStorage(
|
||||
'dismissWorkspaceGuideModal'
|
||||
);
|
||||
const [open, setOpen] = useState(!dismiss);
|
||||
|
||||
// blur modal background, can't use css: `backdrop-filter: blur()`,
|
||||
// because it won't behave as expected on client side (texts over transparent window are not blurred)
|
||||
useEffect(() => {
|
||||
const appDom = document.querySelector('#app') as HTMLElement;
|
||||
if (!appDom) return;
|
||||
appDom.style.filter = open ? 'blur(7px)' : 'none';
|
||||
|
||||
return () => {
|
||||
appDom.style.filter = 'none';
|
||||
};
|
||||
}, [open]);
|
||||
|
||||
const gotIt = useCallback(() => {
|
||||
setOpen(false);
|
||||
setDismiss(true);
|
||||
}, [setDismiss]);
|
||||
|
||||
const onOpenChange = useCallback((v: boolean) => {
|
||||
setOpen(v);
|
||||
// should set dismiss here ?
|
||||
// setDismiss(true)
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
withoutCloseButton
|
||||
contentOptions={contentOptions}
|
||||
overlayOptions={overlayOptions}
|
||||
open={open}
|
||||
width={400}
|
||||
onOpenChange={onOpenChange}
|
||||
>
|
||||
<Thumb />
|
||||
<div className={styles.title}>
|
||||
{t['com.affine.onboarding.workspace-guide.title']()}
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
{t['com.affine.onboarding.workspace-guide.content']()}
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
<Button type="primary" size="large" onClick={gotIt}>
|
||||
<span className={styles.gotItBtn}>
|
||||
{t['com.affine.onboarding.workspace-guide.got-it']()}
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
});
|
@ -52,6 +52,13 @@ const OnboardingModal = lazy(() =>
|
||||
default: module.OnboardingModal,
|
||||
}))
|
||||
);
|
||||
const WorkspaceGuideModal = lazy(() =>
|
||||
import('../components/affine/onboarding/workspace-guide-modal').then(
|
||||
module => ({
|
||||
default: module.WorkspaceGuideModal,
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const SignOutModal = lazy(() =>
|
||||
import('../components/affine/sign-out-modal').then(module => ({
|
||||
@ -160,6 +167,7 @@ export function CurrentWorkspaceModals() {
|
||||
<OnboardingModal />
|
||||
</Suspense>
|
||||
)}
|
||||
<WorkspaceGuideModal />
|
||||
{currentWorkspace && <Setting />}
|
||||
</>
|
||||
);
|
||||
|
@ -6,6 +6,7 @@ import { app } from 'electron';
|
||||
|
||||
import { createApplicationMenu } from './application-menu/create';
|
||||
import { buildType, overrideSession } from './config';
|
||||
import { persistentConfig } from './config-storage/persist';
|
||||
import { setupDeepLink } from './deep-link';
|
||||
import { registerEvents } from './events';
|
||||
import { registerHandlers } from './handlers';
|
||||
@ -30,6 +31,10 @@ if (require('electron-squirrel-startup')) app.quit();
|
||||
|
||||
if (process.env.SKIP_ONBOARDING) {
|
||||
launchStage.value = 'main';
|
||||
persistentConfig.set({
|
||||
onBoarding: false,
|
||||
dismissWorkspaceGuideModal: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1012,5 +1012,8 @@
|
||||
"com.affine.history.confirm-restore-modal.restore": "Restore",
|
||||
"com.affine.history.confirm-restore-modal.hint": "You are about to restore the current version of the page to the latest version available. This action will overwrite any changes made prior to the latest version.",
|
||||
"com.affine.share-page.header.present": "Present",
|
||||
"com.affine.page-operation.add-linked-page": "Add linked page"
|
||||
"com.affine.page-operation.add-linked-page": "Add linked page",
|
||||
"com.affine.onboarding.workspace-guide.title": "Start AFFiNE by creating your own Workspace here!",
|
||||
"com.affine.onboarding.workspace-guide.content": "A Workspace is your virtual space to capture, create and plan as just one person or together as a team.",
|
||||
"com.affine.onboarding.workspace-guide.got-it": "Got it!"
|
||||
}
|
||||
|
@ -34,7 +34,10 @@ type CurrentWorkspace = {
|
||||
|
||||
export const skipOnboarding = async (context: BrowserContext) => {
|
||||
await context.addInitScript(() => {
|
||||
window.localStorage.setItem('app_config', '{"onBoarding":false}');
|
||||
window.localStorage.setItem(
|
||||
'app_config',
|
||||
'{"onBoarding":false, "dismissWorkspaceGuideModal":true}'
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user