feat: init affine blob storage (#2045)

This commit is contained in:
Himself65
2023-04-20 03:23:41 -05:00
committed by GitHub
parent c08c587efb
commit 63f7b2556e
25 changed files with 828 additions and 448 deletions

View File

@@ -1,4 +1,3 @@
import { getLoginStorage } from '@affine/workspace/affine/login';
import type { AffinePublicWorkspace } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
@@ -14,10 +13,9 @@ function createPublicWorkspace(
): AffinePublicWorkspace {
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
workspaceId,
(k: string) =>
// fixme: token could be expired
({ api: `api/workspace`, token: getLoginStorage()?.token }[k]),
WorkspaceFlavour.AFFINE,
{
workspaceApis: affineApis,
cachePrefix: WorkspaceFlavour.PUBLIC + (singlePage ? '-single-page' : ''),
}
);

View File

@@ -1,3 +1,4 @@
import { WorkspaceFlavour } from '@affine/workspace/type';
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
import type { EditorContainer } from '@blocksuite/editor';
import type { Page } from '@blocksuite/store';
@@ -9,7 +10,7 @@ import { BlockSuiteEditor } from '../../blocksuite/block-suite-editor';
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
'test',
_ => undefined,
WorkspaceFlavour.LOCAL,
{
idGenerator: Generator.AutoIncrement,
}

View File

@@ -1,41 +1,50 @@
import type { BlobStorage } from '@blocksuite/store';
import { useEffect, useState } from 'react';
import type { BlobManager } from '@blocksuite/store';
import { useEffect, useMemo, useRef, useState } from 'react';
import type { BlockSuiteWorkspace } from '../shared';
export function useWorkspaceBlob(
blockSuiteWorkspace: BlockSuiteWorkspace
): BlobStorage | null {
const [blobStorage, setBlobStorage] = useState<BlobStorage | null>(null);
useEffect(() => {
blockSuiteWorkspace.blobs.then(blobStorage => {
setBlobStorage(blobStorage);
});
}, [blockSuiteWorkspace]);
return blobStorage;
): BlobManager {
return useMemo(() => blockSuiteWorkspace.blobs, [blockSuiteWorkspace.blobs]);
}
export function useWorkspaceBlobImage(
key: string | null,
blockSuiteWorkspace: BlockSuiteWorkspace
) {
const blobStorage = useWorkspaceBlob(blockSuiteWorkspace);
const [imageURL, setImageURL] = useState<string | null>(null);
const blobManager = useWorkspaceBlob(blockSuiteWorkspace);
const [blob, setBlob] = useState<Blob | null>(null);
useEffect(() => {
const controller = new AbortController();
if (key === null) {
setImageURL(null);
setBlob(null);
return;
}
blobStorage?.get(key).then(blob => {
blobManager?.get(key).then(blob => {
if (controller.signal.aborted) {
return;
}
setImageURL(blob);
if (blob) {
setBlob(blob);
}
});
return () => {
controller.abort();
};
}, [blobStorage, key]);
return imageURL;
}, [blobManager, key]);
const [url, setUrl] = useState<string | null>(null);
const ref = useRef<string | null>(null);
useEffect(() => {
if (ref.current) {
URL.revokeObjectURL(ref.current);
}
if (blob) {
const url = URL.createObjectURL(blob);
setUrl(url);
ref.current = url;
}
}, [blob]);
return url;
}

View File

@@ -43,7 +43,7 @@ export function useAppHelper() {
async (name: string): Promise<string> => {
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
nanoid(),
_ => undefined
WorkspaceFlavour.LOCAL
);
blockSuiteWorkspace.meta.setName(name);
const id = await LocalPlugin.CRUD.create(blockSuiteWorkspace);

View File

@@ -2,6 +2,7 @@ import { Button } from '@affine/component';
import { DebugLogger } from '@affine/debug';
import { createBroadCastChannelProvider } from '@affine/workspace/providers';
import type { BroadCastChannelProvider } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
import { nanoid } from '@blocksuite/store';
import { Typography } from '@mui/material';
@@ -22,10 +23,7 @@ declare global {
const BroadcastPage: React.FC = () => {
const blockSuiteWorkspace = useMemo(
() =>
createEmptyBlockSuiteWorkspace(
'broadcast-test',
(_: string) => undefined
),
createEmptyBlockSuiteWorkspace('broadcast-test', WorkspaceFlavour.LOCAL),
[]
);
const [provider, setProvider] = useState<BroadCastChannelProvider | null>(

View File

@@ -1,4 +1,3 @@
import { getLoginStorage } from '@affine/workspace/affine/login';
import { rootStore } from '@affine/workspace/atom';
import type { AffineWorkspace } from '@affine/workspace/type';
import { WorkspaceFlavour } from '@affine/workspace/type';
@@ -66,9 +65,10 @@ export const fetcher = async (
return workspaces.map(workspace => {
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
workspace.id,
(k: string) =>
// fixme: token could be expired
({ api: '/api/workspace', token: getLoginStorage()?.token }[k])
WorkspaceFlavour.AFFINE,
{
workspaceApis: affineApis,
}
);
const remWorkspace: AffineWorkspace = {
...workspace,

View File

@@ -51,12 +51,10 @@ const getPersistenceAllWorkspace = () => {
...items.map((item: z.infer<typeof schema>) => {
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
item.id,
(k: string) =>
// fixme: token could be expired
({
api: prefixUrl + 'api/workspace',
token: getLoginStorage()?.token,
}[k])
WorkspaceFlavour.AFFINE,
{
workspaceApis: affineApis,
}
);
const affineWorkspace: AffineWorkspace = {
...item,
@@ -116,19 +114,15 @@ export const AffinePlugin: WorkspacePlugin<WorkspaceFlavour.AFFINE> = {
const newWorkspaceId = id;
await new Promise(resolve => setTimeout(resolve, 1000));
const blobs = await blockSuiteWorkspace.blobs;
if (blobs) {
const ids = await blobs.blobs;
for (const id of ids) {
const url = await blobs.get(id);
if (url) {
const blob = await fetch(url).then(res => res.blob());
await affineApis.uploadBlob(
newWorkspaceId,
await blob.arrayBuffer(),
blob.type
);
}
const blobManager = blockSuiteWorkspace.blobs;
for (const id of await blobManager.list()) {
const blob = await blobManager.get(id);
if (blob) {
await affineApis.uploadBlob(
newWorkspaceId,
await blob.arrayBuffer(),
blob.type
);
}
}
@@ -182,9 +176,10 @@ export const AffinePlugin: WorkspacePlugin<WorkspaceFlavour.AFFINE> = {
return workspaces.map(workspace => {
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
workspace.id,
(k: string) =>
// fixme: token could be expired
({ api: '/api/workspace', token: getLoginStorage()?.token }[k])
WorkspaceFlavour.AFFINE,
{
workspaceApis: affineApis,
}
);
const dump = workspaces.map(workspace => {
return {

View File

@@ -29,7 +29,7 @@ export const LocalPlugin: WorkspacePlugin<WorkspaceFlavour.LOCAL> = {
'app:init': () => {
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
nanoid(),
(_: string) => undefined
WorkspaceFlavour.LOCAL
);
blockSuiteWorkspace.meta.setName(DEFAULT_WORKSPACE_NAME);
const page = blockSuiteWorkspace.createPage(DEFAULT_HELLO_WORLD_PAGE_ID);