feat(core): mode in query string (#7904)

This commit is contained in:
EYHN
2024-08-16 10:59:43 +00:00
parent 83716c2fd9
commit c822594882
16 changed files with 174 additions and 29 deletions

View File

@@ -81,6 +81,7 @@
"mixpanel-browser": "^2.49.0",
"nanoid": "^5.0.7",
"next-themes": "^0.3.0",
"query-string": "^9.1.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-error-boundary": "^4.0.13",

View File

@@ -1,5 +1,7 @@
import { Entity, LiveData } from '@toeverything/infra';
import type { Location, To } from 'history';
import { isEqual } from 'lodash-es';
import queryString from 'query-string';
import { Observable } from 'rxjs';
import { createNavigableHistory } from '../../../utils/navigable-history';
@@ -77,6 +79,52 @@ export class View extends Entity<{
icon$ = new LiveData(this.props.icon ?? 'allDocs');
queryString$<T extends Record<string, unknown>>({
parseNumbers = true,
}: { parseNumbers?: boolean } = {}) {
return this.location$.map(
location =>
queryString.parse(location.search, {
parseBooleans: true,
parseNumbers: parseNumbers,
}) as Partial<T>
);
}
updateQueryString<T extends Record<string, unknown>>(
patch: Partial<T>,
{
forceUpdate,
parseNumbers,
replace,
}: {
forceUpdate?: boolean;
parseNumbers?: boolean;
replace?: boolean;
} = {}
) {
const oldQueryStrings = queryString.parse(location.search, {
parseBooleans: true,
parseNumbers: parseNumbers,
});
const newQueryStrings = { ...oldQueryStrings, ...patch };
if (forceUpdate || !isEqual(oldQueryStrings, newQueryStrings)) {
const search = queryString.stringify(newQueryStrings);
const newState = {
...this.history.location,
search,
};
if (replace) {
this.history.replace(newState);
} else {
this.history.push(newState);
}
}
}
push(path: To) {
this.history.push(path);
}

View File

@@ -10,7 +10,7 @@ import type { Editor } from '@affine/core/modules/editor';
import { EditorService, EditorsService } from '@affine/core/modules/editor';
import { RecentDocsService } from '@affine/core/modules/quicksearch';
import { ViewService } from '@affine/core/modules/workbench/services/view';
import type { PageRootService } from '@blocksuite/blocks';
import type { DocMode, PageRootService } from '@blocksuite/blocks';
import {
BookmarkBlockService,
customImageProxyMiddleware,
@@ -330,9 +330,25 @@ export const DetailPage = ({ pageId }: { pageId: string }): ReactElement => {
const docRecordList = docsService.list;
const docListReady = useLiveData(docRecordList.isReady$);
const docRecord = useLiveData(docRecordList.doc$(pageId));
const viewService = useService(ViewService);
const queryString = useLiveData(
viewService.view.queryString$<{
mode?: string;
}>()
);
const queryStringMode =
queryString.mode && ['edgeless', 'page'].includes(queryString.mode)
? (queryString.mode as DocMode)
: null;
// We only read the querystring mode when entering, so use useState here.
const [initialQueryStringMode] = useState(() => queryStringMode);
const [doc, setDoc] = useState<Doc | null>(null);
const [editor, setEditor] = useState<Editor | null>(null);
const editorMode = useLiveData(editor?.mode$);
useLayoutEffect(() => {
if (!docRecord) {
@@ -351,12 +367,26 @@ export const DetailPage = ({ pageId }: { pageId: string }): ReactElement => {
}
const editor = doc.scope
.get(EditorsService)
.createEditor(doc.getPrimaryMode() || 'page');
.createEditor(initialQueryStringMode || doc.getPrimaryMode() || 'page');
setEditor(editor);
return () => {
editor.dispose();
};
}, [doc]);
}, [doc, initialQueryStringMode]);
// update editor mode to queryString
useEffect(() => {
if (editorMode) {
viewService.view.updateQueryString(
{
mode: editorMode,
},
{
replace: true,
}
);
}
}, [editorMode, viewService.view]);
// set sync engine priority target
useEffect(() => {

View File

@@ -310,6 +310,7 @@ export enum ErrorNames {
MAILER_SERVICE_IS_NOT_CONFIGURED = 'MAILER_SERVICE_IS_NOT_CONFIGURED',
MEMBER_QUOTA_EXCEEDED = 'MEMBER_QUOTA_EXCEEDED',
MISSING_OAUTH_QUERY_PARAMETER = 'MISSING_OAUTH_QUERY_PARAMETER',
NOT_FOUND = 'NOT_FOUND',
NOT_IN_WORKSPACE = 'NOT_IN_WORKSPACE',
NO_COPILOT_PROVIDER_AVAILABLE = 'NO_COPILOT_PROVIDER_AVAILABLE',
OAUTH_ACCOUNT_ALREADY_CONNECTED = 'OAUTH_ACCOUNT_ALREADY_CONNECTED',