fix(ios): fix mobile blob storage (#8702)
This commit is contained in:
@@ -141,26 +141,25 @@ export function configureFetchProvider(framework: Framework) {
|
|||||||
undefined,
|
undefined,
|
||||||
optionHeaders['Content-Type'] || optionHeaders['content-type']
|
optionHeaders['Content-Type'] || optionHeaders['content-type']
|
||||||
);
|
);
|
||||||
|
const accept = optionHeaders['Accept'] || optionHeaders['accept'];
|
||||||
const nativeResponse = await CapacitorHttp.request({
|
const nativeResponse = await CapacitorHttp.request({
|
||||||
url: request.url,
|
url: request.url,
|
||||||
method: method,
|
method: method,
|
||||||
data: requestData,
|
data: requestData,
|
||||||
dataType: type as any,
|
dataType: type as any,
|
||||||
responseType:
|
responseType:
|
||||||
(optionHeaders['Accept'] || optionHeaders['accept']) ===
|
accept === 'application/octet-stream' ? 'arraybuffer' : undefined,
|
||||||
'application/octet-stream'
|
|
||||||
? 'arraybuffer'
|
|
||||||
: undefined,
|
|
||||||
headers: Object.assign(Object.assign({}, headers), optionHeaders),
|
headers: Object.assign(Object.assign({}, headers), optionHeaders),
|
||||||
});
|
});
|
||||||
const contentType =
|
const contentType =
|
||||||
nativeResponse.headers['Content-Type'] ||
|
nativeResponse.headers['Content-Type'] ||
|
||||||
nativeResponse.headers['content-type'];
|
nativeResponse.headers['content-type'];
|
||||||
let data = (
|
let data =
|
||||||
contentType === null || contentType === void 0
|
accept === 'application/octet-stream'
|
||||||
|
? base64ToUint8Array(nativeResponse.data)
|
||||||
|
: contentType === null || contentType === void 0
|
||||||
? void 0
|
? void 0
|
||||||
: contentType.startsWith('application/json')
|
: contentType.startsWith('application/json')
|
||||||
)
|
|
||||||
? JSON.stringify(nativeResponse.data)
|
? JSON.stringify(nativeResponse.data)
|
||||||
: contentType === 'application/octet-stream'
|
: contentType === 'application/octet-stream'
|
||||||
? base64ToUint8Array(nativeResponse.data)
|
? base64ToUint8Array(nativeResponse.data)
|
||||||
@@ -171,7 +170,7 @@ export function configureFetchProvider(framework: Framework) {
|
|||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
// intercept & parse response before returning
|
// intercept & parse response before returning
|
||||||
const response = new Response(data, {
|
const response = new Response(new Blob([data], { type: contentType }), {
|
||||||
headers: nativeResponse.headers,
|
headers: nativeResponse.headers,
|
||||||
status: nativeResponse.status,
|
status: nativeResponse.status,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-page-meta';
|
import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-page-meta';
|
||||||
import { useDocCollectionPage } from '@affine/core/components/hooks/use-block-suite-workspace-page';
|
import { useDocCollectionPage } from '@affine/core/components/hooks/use-block-suite-workspace-page';
|
||||||
import { FetchService } from '@affine/core/modules/cloud';
|
import { FetchService, GraphQLService } from '@affine/core/modules/cloud';
|
||||||
import { DebugLogger } from '@affine/debug';
|
import { DebugLogger } from '@affine/debug';
|
||||||
import type { ListHistoryQuery } from '@affine/graphql';
|
import type { ListHistoryQuery } from '@affine/graphql';
|
||||||
import { listHistoryQuery, recoverDocMutation } from '@affine/graphql';
|
import { listHistoryQuery, recoverDocMutation } from '@affine/graphql';
|
||||||
@@ -102,11 +102,16 @@ const docCollectionMap = new Map<string, DocCollection>();
|
|||||||
// assume the workspace is a cloud workspace since the history feature is only enabled for cloud workspace
|
// assume the workspace is a cloud workspace since the history feature is only enabled for cloud workspace
|
||||||
const getOrCreateShellWorkspace = (
|
const getOrCreateShellWorkspace = (
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
fetchService: FetchService
|
fetchService: FetchService,
|
||||||
|
graphQLService: GraphQLService
|
||||||
) => {
|
) => {
|
||||||
let docCollection = docCollectionMap.get(workspaceId);
|
let docCollection = docCollectionMap.get(workspaceId);
|
||||||
if (!docCollection) {
|
if (!docCollection) {
|
||||||
const blobStorage = new CloudBlobStorage(workspaceId, fetchService);
|
const blobStorage = new CloudBlobStorage(
|
||||||
|
workspaceId,
|
||||||
|
fetchService,
|
||||||
|
graphQLService
|
||||||
|
);
|
||||||
docCollection = new DocCollection({
|
docCollection = new DocCollection({
|
||||||
id: workspaceId,
|
id: workspaceId,
|
||||||
blobSources: {
|
blobSources: {
|
||||||
@@ -144,6 +149,7 @@ export const useSnapshotPage = (
|
|||||||
ts?: string
|
ts?: string
|
||||||
) => {
|
) => {
|
||||||
const fetchService = useService(FetchService);
|
const fetchService = useService(FetchService);
|
||||||
|
const graphQLService = useService(GraphQLService);
|
||||||
const snapshot = usePageHistory(docCollection.id, pageDocId, ts);
|
const snapshot = usePageHistory(docCollection.id, pageDocId, ts);
|
||||||
const page = useMemo(() => {
|
const page = useMemo(() => {
|
||||||
if (!ts) {
|
if (!ts) {
|
||||||
@@ -152,7 +158,8 @@ export const useSnapshotPage = (
|
|||||||
const pageId = pageDocId + '-' + ts;
|
const pageId = pageDocId + '-' + ts;
|
||||||
const historyShellWorkspace = getOrCreateShellWorkspace(
|
const historyShellWorkspace = getOrCreateShellWorkspace(
|
||||||
docCollection.id,
|
docCollection.id,
|
||||||
fetchService
|
fetchService,
|
||||||
|
graphQLService
|
||||||
);
|
);
|
||||||
let page = historyShellWorkspace.getDoc(pageId);
|
let page = historyShellWorkspace.getDoc(pageId);
|
||||||
if (!page && snapshot) {
|
if (!page && snapshot) {
|
||||||
@@ -167,18 +174,19 @@ export const useSnapshotPage = (
|
|||||||
}); // must load before applyUpdate
|
}); // must load before applyUpdate
|
||||||
}
|
}
|
||||||
return page ?? undefined;
|
return page ?? undefined;
|
||||||
}, [ts, pageDocId, docCollection.id, fetchService, snapshot]);
|
}, [ts, pageDocId, docCollection.id, fetchService, graphQLService, snapshot]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const historyShellWorkspace = getOrCreateShellWorkspace(
|
const historyShellWorkspace = getOrCreateShellWorkspace(
|
||||||
docCollection.id,
|
docCollection.id,
|
||||||
fetchService
|
fetchService,
|
||||||
|
graphQLService
|
||||||
);
|
);
|
||||||
// apply the rootdoc's update to the current workspace
|
// apply the rootdoc's update to the current workspace
|
||||||
// this makes sure the page reference links are not deleted ones in the preview
|
// this makes sure the page reference links are not deleted ones in the preview
|
||||||
const update = encodeStateAsUpdate(docCollection.doc);
|
const update = encodeStateAsUpdate(docCollection.doc);
|
||||||
applyUpdate(historyShellWorkspace.doc, update);
|
applyUpdate(historyShellWorkspace.doc, update);
|
||||||
}, [docCollection, fetchService]);
|
}, [docCollection, fetchService, graphQLService]);
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-he
|
|||||||
import { PageDetailEditor } from '@affine/core/components/page-detail-editor';
|
import { PageDetailEditor } from '@affine/core/components/page-detail-editor';
|
||||||
import { SharePageNotFoundError } from '@affine/core/components/share-page-not-found-error';
|
import { SharePageNotFoundError } from '@affine/core/components/share-page-not-found-error';
|
||||||
import { AppContainer } from '@affine/core/desktop/components/app-container';
|
import { AppContainer } from '@affine/core/desktop/components/app-container';
|
||||||
import { AuthService, FetchService } from '@affine/core/modules/cloud';
|
import {
|
||||||
|
AuthService,
|
||||||
|
FetchService,
|
||||||
|
GraphQLService,
|
||||||
|
} from '@affine/core/modules/cloud';
|
||||||
import {
|
import {
|
||||||
type Editor,
|
type Editor,
|
||||||
type EditorSelector,
|
type EditorSelector,
|
||||||
@@ -147,7 +151,7 @@ const SharePageInner = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const workspacesService = useService(WorkspacesService);
|
const workspacesService = useService(WorkspacesService);
|
||||||
const fetchService = useService(FetchService);
|
const fetchService = useService(FetchService);
|
||||||
|
const graphQLService = useService(GraphQLService);
|
||||||
const [workspace, setWorkspace] = useState<Workspace | null>(null);
|
const [workspace, setWorkspace] = useState<Workspace | null>(null);
|
||||||
const [page, setPage] = useState<Doc | null>(null);
|
const [page, setPage] = useState<Doc | null>(null);
|
||||||
const [editor, setEditor] = useState<Editor | null>(null);
|
const [editor, setEditor] = useState<Editor | null>(null);
|
||||||
@@ -181,7 +185,9 @@ const SharePageInner = ({
|
|||||||
return EmptyBlobStorage;
|
return EmptyBlobStorage;
|
||||||
},
|
},
|
||||||
getRemoteBlobStorages() {
|
getRemoteBlobStorages() {
|
||||||
return [new CloudBlobStorage(workspaceId, fetchService)];
|
return [
|
||||||
|
new CloudBlobStorage(workspaceId, fetchService, graphQLService),
|
||||||
|
];
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -221,6 +227,7 @@ const SharePageInner = ({
|
|||||||
workspaceBinary,
|
workspaceBinary,
|
||||||
docBinary,
|
docBinary,
|
||||||
fetchService,
|
fetchService,
|
||||||
|
graphQLService,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const pageTitle = useLiveData(page?.title$);
|
const pageTitle = useLiveData(page?.title$);
|
||||||
|
|||||||
@@ -237,7 +237,11 @@ export class CloudWorkspaceFlavourProviderService
|
|||||||
return localBlob;
|
return localBlob;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cloudBlob = new CloudBlobStorage(id, this.fetchService);
|
const cloudBlob = new CloudBlobStorage(
|
||||||
|
id,
|
||||||
|
this.fetchService,
|
||||||
|
this.graphqlService
|
||||||
|
);
|
||||||
return await cloudBlob.get(blob);
|
return await cloudBlob.get(blob);
|
||||||
}
|
}
|
||||||
getEngineProvider(workspaceId: string): WorkspaceEngineProvider {
|
getEngineProvider(workspaceId: string): WorkspaceEngineProvider {
|
||||||
@@ -259,7 +263,11 @@ export class CloudWorkspaceFlavourProviderService
|
|||||||
},
|
},
|
||||||
getRemoteBlobStorages: () => {
|
getRemoteBlobStorages: () => {
|
||||||
return [
|
return [
|
||||||
new CloudBlobStorage(workspaceId, this.fetchService),
|
new CloudBlobStorage(
|
||||||
|
workspaceId,
|
||||||
|
this.fetchService,
|
||||||
|
this.graphqlService
|
||||||
|
),
|
||||||
new StaticBlobStorage(),
|
new StaticBlobStorage(),
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { FetchService } from '@affine/core/modules/cloud';
|
import type { FetchService, GraphQLService } from '@affine/core/modules/cloud';
|
||||||
import {
|
import {
|
||||||
deleteBlobMutation,
|
deleteBlobMutation,
|
||||||
fetcher,
|
|
||||||
listBlobsQuery,
|
listBlobsQuery,
|
||||||
setBlobMutation,
|
setBlobMutation,
|
||||||
UserFriendlyError,
|
UserFriendlyError,
|
||||||
@@ -14,7 +13,8 @@ import { bufferToBlob } from '../../utils/buffer-to-blob';
|
|||||||
export class CloudBlobStorage implements BlobStorage {
|
export class CloudBlobStorage implements BlobStorage {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly workspaceId: string,
|
private readonly workspaceId: string,
|
||||||
private readonly fetchService: FetchService
|
private readonly fetchService: FetchService,
|
||||||
|
private readonly gqlService: GraphQLService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
name = 'cloud';
|
name = 'cloud';
|
||||||
@@ -46,7 +46,8 @@ export class CloudBlobStorage implements BlobStorage {
|
|||||||
|
|
||||||
async set(key: string, value: Blob) {
|
async set(key: string, value: Blob) {
|
||||||
// set blob will check blob size & quota
|
// set blob will check blob size & quota
|
||||||
return await fetcher({
|
return await this.gqlService
|
||||||
|
.gql({
|
||||||
query: setBlobMutation,
|
query: setBlobMutation,
|
||||||
variables: {
|
variables: {
|
||||||
workspaceId: this.workspaceId,
|
workspaceId: this.workspaceId,
|
||||||
@@ -65,7 +66,7 @@ export class CloudBlobStorage implements BlobStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async delete(key: string) {
|
async delete(key: string) {
|
||||||
await fetcher({
|
await this.gqlService.gql({
|
||||||
query: deleteBlobMutation,
|
query: deleteBlobMutation,
|
||||||
variables: {
|
variables: {
|
||||||
workspaceId: key,
|
workspaceId: key,
|
||||||
@@ -75,7 +76,7 @@ export class CloudBlobStorage implements BlobStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async list() {
|
async list() {
|
||||||
const result = await fetcher({
|
const result = await this.gqlService.gql({
|
||||||
query: listBlobsQuery,
|
query: listBlobsQuery,
|
||||||
variables: {
|
variables: {
|
||||||
workspaceId: this.workspaceId,
|
workspaceId: this.workspaceId,
|
||||||
|
|||||||
Reference in New Issue
Block a user