diff --git a/packages/frontend/apps/android/src/app.tsx b/packages/frontend/apps/android/src/app.tsx
index 452494e203..269d79b5d5 100644
--- a/packages/frontend/apps/android/src/app.tsx
+++ b/packages/frontend/apps/android/src/app.tsx
@@ -1,6 +1,6 @@
-import { AppFallback } from '@affine/core/components/affine/app-container';
import { AffineContext } from '@affine/core/components/context';
import { Telemetry } from '@affine/core/components/telemetry';
+import { AppFallback } from '@affine/core/mobile/components';
import { configureMobileModules } from '@affine/core/mobile/modules';
import { router } from '@affine/core/mobile/router';
import { configureCommonModules } from '@affine/core/modules';
diff --git a/packages/frontend/apps/ios/src/app.tsx b/packages/frontend/apps/ios/src/app.tsx
index dffbc5dafc..eb3ef91e1b 100644
--- a/packages/frontend/apps/ios/src/app.tsx
+++ b/packages/frontend/apps/ios/src/app.tsx
@@ -1,6 +1,6 @@
-import { AppFallback } from '@affine/core/components/affine/app-container';
import { AffineContext } from '@affine/core/components/context';
import { Telemetry } from '@affine/core/components/telemetry';
+import { AppFallback } from '@affine/core/mobile/components';
import { configureMobileModules } from '@affine/core/mobile/modules';
import { router } from '@affine/core/mobile/router';
import { configureCommonModules } from '@affine/core/modules';
diff --git a/packages/frontend/apps/mobile/src/app.tsx b/packages/frontend/apps/mobile/src/app.tsx
index 416fcf327b..762907f13a 100644
--- a/packages/frontend/apps/mobile/src/app.tsx
+++ b/packages/frontend/apps/mobile/src/app.tsx
@@ -1,6 +1,6 @@
-import { AppFallback } from '@affine/core/components/affine/app-container';
import { AffineContext } from '@affine/core/components/context';
import { Telemetry } from '@affine/core/components/telemetry';
+import { AppFallback } from '@affine/core/mobile/components';
import { configureMobileModules } from '@affine/core/mobile/modules';
import { router } from '@affine/core/mobile/router';
import { configureCommonModules } from '@affine/core/modules';
diff --git a/packages/frontend/core/src/mobile/components/index.ts b/packages/frontend/core/src/mobile/components/index.ts
index 92f35011f7..d7197cd78b 100644
--- a/packages/frontend/core/src/mobile/components/index.ts
+++ b/packages/frontend/core/src/mobile/components/index.ts
@@ -5,5 +5,6 @@ export * from './rename';
export * from './search-input';
export * from './search-result';
export * from './selector';
+export * from './skeletons';
export * from './user-plan-tag';
export * from './workspace-selector';
diff --git a/packages/frontend/core/src/mobile/components/skeletons/app-fallback.tsx b/packages/frontend/core/src/mobile/components/skeletons/app-fallback.tsx
new file mode 100644
index 0000000000..273115aac3
--- /dev/null
+++ b/packages/frontend/core/src/mobile/components/skeletons/app-fallback.tsx
@@ -0,0 +1,85 @@
+import { SafeArea, Skeleton } from '@affine/component';
+
+import { WorkspaceSelector } from '../workspace-selector';
+
+const SectionTitleFallback = () => {
+ return (
+
+
+
+ );
+};
+const sectionRows = [127, 238, 191, 102];
+
+const Section = () => {
+ return (
+
+
+
+ {sectionRows.map((width, i) => {
+ return (
+
+
+
+
+ );
+ })}
+
+
+ );
+};
+
+export const AppFallback = () => {
+ return (
+
+ {/* setting */}
+
+
+
+ {/* workspace card */}
+
+
+
+ {/* search */}
+
+
+
+ {/* recent */}
+
+
+ {[1, 2, 3].map(i => (
+
+ ))}
+
+
+
+
+ );
+};
diff --git a/packages/frontend/core/src/mobile/components/skeletons/index.tsx b/packages/frontend/core/src/mobile/components/skeletons/index.tsx
new file mode 100644
index 0000000000..cc9deefffd
--- /dev/null
+++ b/packages/frontend/core/src/mobile/components/skeletons/index.tsx
@@ -0,0 +1 @@
+export * from './app-fallback';
diff --git a/packages/frontend/core/src/mobile/components/workspace-selector/current-card.tsx b/packages/frontend/core/src/mobile/components/workspace-selector/current-card.tsx
index fe32b35b7e..515af7de59 100644
--- a/packages/frontend/core/src/mobile/components/workspace-selector/current-card.tsx
+++ b/packages/frontend/core/src/mobile/components/workspace-selector/current-card.tsx
@@ -1,8 +1,9 @@
+import { Avatar } from '@affine/component';
import { WorkspaceAvatar } from '@affine/component/workspace-avatar';
import { useWorkspaceInfo } from '@affine/core/components/hooks/use-workspace-info';
import { UNTITLED_WORKSPACE_NAME } from '@affine/env/constant';
import { ArrowDownSmallIcon } from '@blocksuite/icons/rc';
-import { useService, WorkspaceService } from '@toeverything/infra';
+import { useServiceOptional, WorkspaceService } from '@toeverything/infra';
import clsx from 'clsx';
import { forwardRef, type HTMLAttributes } from 'react';
@@ -15,8 +16,8 @@ export const CurrentWorkspaceCard = forwardRef<
HTMLDivElement,
CurrentWorkspaceCardProps
>(function CurrentWorkspaceCard({ onClick, className, ...attrs }, ref) {
- const currentWorkspace = useService(WorkspaceService).workspace;
- const info = useWorkspaceInfo(currentWorkspace.meta);
+ const currentWorkspace = useServiceOptional(WorkspaceService)?.workspace;
+ const info = useWorkspaceInfo(currentWorkspace?.meta);
const name = info?.name ?? UNTITLED_WORKSPACE_NAME;
return (
@@ -26,15 +27,19 @@ export const CurrentWorkspaceCard = forwardRef<
className={clsx(card, className)}
{...attrs}
>
-
+ {currentWorkspace ? (
+
+ ) : (
+
+ )}
{name}
diff --git a/packages/frontend/core/src/mobile/components/workspace-selector/index.tsx b/packages/frontend/core/src/mobile/components/workspace-selector/index.tsx
index 4da2a274e3..23f07a7bed 100644
--- a/packages/frontend/core/src/mobile/components/workspace-selector/index.tsx
+++ b/packages/frontend/core/src/mobile/components/workspace-selector/index.tsx
@@ -1,6 +1,6 @@
import { MobileMenu } from '@affine/component';
import { track } from '@affine/track';
-import { useService, WorkspacesService } from '@toeverything/infra';
+import { useServiceOptional, WorkspacesService } from '@toeverything/infra';
import { useCallback, useEffect, useState } from 'react';
import { CurrentWorkspaceCard } from './current-card';
@@ -8,7 +8,7 @@ import { SelectorMenu } from './menu';
export const WorkspaceSelector = () => {
const [open, setOpen] = useState(false);
- const workspaceManager = useService(WorkspacesService);
+ const workspaceManager = useServiceOptional(WorkspacesService);
const openMenu = useCallback(() => {
track.$.navigationPanel.workspaceList.open();
@@ -20,7 +20,7 @@ export const WorkspaceSelector = () => {
// revalidate workspace list when open workspace list
useEffect(() => {
- if (open) workspaceManager.list.revalidate();
+ if (open) workspaceManager?.list.revalidate();
}, [workspaceManager, open]);
return (
diff --git a/packages/frontend/core/src/mobile/pages/workspace/layout.tsx b/packages/frontend/core/src/mobile/pages/workspace/layout.tsx
index 6d10c284c1..16750c6264 100644
--- a/packages/frontend/core/src/mobile/pages/workspace/layout.tsx
+++ b/packages/frontend/core/src/mobile/pages/workspace/layout.tsx
@@ -1,5 +1,4 @@
import { AffineErrorBoundary } from '@affine/core/components/affine/affine-error-boundary';
-import { AppFallback } from '@affine/core/components/affine/app-container';
import { WorkspaceLayoutProviders } from '@affine/core/components/layouts/workspace-layout';
import { SWRConfigProvider } from '@affine/core/components/providers/swr-config-provider';
import type { Workspace, WorkspaceMetadata } from '@toeverything/infra';
@@ -17,6 +16,7 @@ import {
useState,
} from 'react';
+import { AppFallback } from '../../components';
import { MobileCurrentWorkspaceModals } from '../../provider/model-provider';
// TODO(@forehalo): reuse the global context with [core/electron]