fix(core): fix ui flashing (#7056)

This commit is contained in:
EYHN
2024-05-27 08:05:20 +00:00
parent 306cf2ae6f
commit b356ddbe6e
33 changed files with 545 additions and 404 deletions

View File

@@ -16,7 +16,14 @@ import type {
PropsWithChildren,
RefObject,
} from 'react';
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
memo,
useCallback,
useLayoutEffect,
useMemo,
useRef,
useState,
} from 'react';
import type { View } from '../../entities/view';
import { WorkbenchService } from '../../services/workbench';
@@ -57,7 +64,7 @@ export const SplitViewPanel = memo(function SplitViewPanel({
const isDragging = dndIsDragging || indicatorPressed;
const isActive = activeView === view;
useEffect(() => {
useLayoutEffect(() => {
if (ref.current) {
setSlots?.(slots => ({ ...slots, [view.id]: ref }));
}

View File

@@ -15,7 +15,7 @@ import {
import { useService } from '@toeverything/infra';
import clsx from 'clsx';
import type { HTMLAttributes, RefObject } from 'react';
import { useCallback, useRef, useState } from 'react';
import { useCallback, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import type { View } from '../../entities/view';
@@ -52,11 +52,18 @@ export const SplitView = ({
const workbench = useService(WorkbenchService).workbench;
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: {
distance: 0,
},
})
useSensor(
PointerSensor,
useMemo(
/* avoid re-rendering */
() => ({
activationConstraint: {
distance: 0,
},
}),
[]
)
)
);
const onResizing = useCallback(

View File

@@ -1,5 +1,5 @@
import { FrameworkScope, useLiveData } from '@toeverything/infra';
import { lazy as reactLazy, useEffect, useMemo } from 'react';
import { lazy as reactLazy, useLayoutEffect, useMemo } from 'react';
import {
createMemoryRouter,
RouterProvider,
@@ -34,7 +34,7 @@ export const ViewRoot = ({ view }: { view: View }) => {
const location = useLiveData(view.location$);
useEffect(() => {
useLayoutEffect(() => {
viewRouter.navigate(location).catch(err => {
console.error('navigate error', err);
});

View File

@@ -1,5 +1,5 @@
import { useLiveData, useService } from '@toeverything/infra';
import { useCallback, useEffect, useRef } from 'react';
import { memo, useCallback, useEffect, useRef } from 'react';
import { useLocation } from 'react-router-dom';
import type { View } from '../entities/view';
@@ -14,7 +14,7 @@ const useAdapter = environment.isDesktop
? useBindWorkbenchToDesktopRouter
: useBindWorkbenchToBrowserRouter;
export const WorkbenchRoot = () => {
export const WorkbenchRoot = memo(() => {
const workbench = useService(WorkbenchService).workbench;
// for debugging
@@ -50,7 +50,9 @@ export const WorkbenchRoot = () => {
onMove={onMove}
/>
);
};
});
WorkbenchRoot.displayName = 'memo(WorkbenchRoot)';
const WorkbenchView = ({ view, index }: { view: View; index: number }) => {
const workbench = useService(WorkbenchService).workbench;

View File

@@ -24,6 +24,7 @@ import {
type WorkspaceProfileInfo,
} from '@toeverything/infra';
import { effect, globalBlockSuiteSchema, Service } from '@toeverything/infra';
import { isEqual } from 'lodash-es';
import { nanoid } from 'nanoid';
import { EMPTY, map, mergeMap } from 'rxjs';
import { applyUpdate, encodeStateAsUpdate } from 'yjs';
@@ -148,11 +149,16 @@ export class CloudWorkspaceFlavourProviderService
mergeMap(data => {
if (data) {
const { accountId, workspaces } = data;
const sorted = workspaces.sort((a, b) => {
return a.id.localeCompare(b.id);
});
this.globalState.set(
CLOUD_WORKSPACES_CACHE_KEY + accountId,
workspaces
sorted
);
this.workspaces$.next(workspaces);
if (!isEqual(this.workspaces$.value, sorted)) {
this.workspaces$.next(sorted);
}
} else {
this.workspaces$.next([]);
}

View File

@@ -22,13 +22,15 @@ export class CloudBlobStorage implements BlobStorage {
? key
: `/api/workspaces/${this.workspaceId}/blobs/${key}`;
return fetch(getBaseUrl() + suffix).then(async res => {
if (!res.ok) {
// status not in the range 200-299
return null;
return fetch(getBaseUrl() + suffix, { cache: 'default' }).then(
async res => {
if (!res.ok) {
// status not in the range 200-299
return null;
}
return bufferToBlob(await res.arrayBuffer());
}
return bufferToBlob(await res.arrayBuffer());
});
);
}
async set(key: string, value: Blob) {

View File

@@ -9,6 +9,7 @@ import type {
WorkspaceProfileInfo,
} from '@toeverything/infra';
import { globalBlockSuiteSchema, LiveData, Service } from '@toeverything/infra';
import { isEqual } from 'lodash-es';
import { nanoid } from 'nanoid';
import { Observable } from 'rxjs';
import { applyUpdate, encodeStateAsUpdate } from 'yjs';
@@ -96,12 +97,14 @@ export class LocalWorkspaceFlavourProvider
}
workspaces$ = LiveData.from(
new Observable<WorkspaceMetadata[]>(subscriber => {
let last: WorkspaceMetadata[] | null = null;
const emit = () => {
subscriber.next(
JSON.parse(
localStorage.getItem(LOCAL_WORKSPACE_LOCAL_STORAGE_KEY) ?? '[]'
).map((id: string) => ({ id, flavour: WorkspaceFlavour.LOCAL }))
);
const value = JSON.parse(
localStorage.getItem(LOCAL_WORKSPACE_LOCAL_STORAGE_KEY) ?? '[]'
).map((id: string) => ({ id, flavour: WorkspaceFlavour.LOCAL }));
if (isEqual(last, value)) return;
subscriber.next(value);
last = value;
};
emit();