fundon
2024-09-25 04:16:58 +00:00
parent e839947dd5
commit 4daa959894
6 changed files with 95 additions and 45 deletions

View File

@@ -27,7 +27,7 @@ export const generateUrl = ({
pageId, pageId,
blockIds, blockIds,
elementIds, elementIds,
shareMode, shareMode: mode,
xywh, // not needed currently xywh, // not needed currently
}: UseSharingUrl) => { }: UseSharingUrl) => {
// Base URL construction // Base URL construction
@@ -36,13 +36,8 @@ export const generateUrl = ({
try { try {
const url = new URL(`/workspace/${workspaceId}/${pageId}`, baseUrl); const url = new URL(`/workspace/${workspaceId}/${pageId}`, baseUrl);
const search = toURLSearchParams({ const search = toURLSearchParams({ mode, blockIds, elementIds, xywh });
mode: shareMode, if (search?.size) url.search = search.toString();
blockIds,
elementIds,
xywh,
});
if (search) url.search = search.toString();
return url.toString(); return url.toString();
} catch { } catch {
return null; return null;

View File

@@ -175,16 +175,21 @@ const DetailPageImpl = memo(function DetailPageImpl() {
refNodeSlots.docLinkClicked.on(({ pageId, params }) => { refNodeSlots.docLinkClicked.on(({ pageId, params }) => {
if (params) { if (params) {
const { mode, blockIds, elementIds } = params; const { mode, blockIds, elementIds } = params;
return jumpToPageBlock( jumpToPageBlock(
docCollection.id, docCollection.id,
pageId, pageId,
mode, mode,
blockIds, blockIds,
elementIds elementIds
); );
return;
} }
return openPage(docCollection.id, pageId); if (editor.doc.id === pageId) {
return;
}
openPage(docCollection.id, pageId);
}) })
); );
} }

View File

@@ -247,13 +247,12 @@ const SharePageInner = ({
refNodeSlots.docLinkClicked.on(({ pageId, params }) => { refNodeSlots.docLinkClicked.on(({ pageId, params }) => {
if (params) { if (params) {
const { mode, blockIds, elementIds } = params; const { mode, blockIds, elementIds } = params;
return jumpToPageBlock( jumpToPageBlock(workspaceId, pageId, mode, blockIds, elementIds);
workspaceId, return;
pageId, }
mode,
blockIds, if (editor.doc.id === pageId) {
elementIds return;
);
} }
return openPage(workspaceId, pageId); return openPage(workspaceId, pageId);

View File

@@ -1,4 +1,5 @@
import { toURLSearchParams } from '@affine/core/modules/navigation'; import { toURLSearchParams } from '@affine/core/modules/navigation';
import type { ReferenceParams } from '@blocksuite/blocks';
import type { WorkspaceService } from '@toeverything/infra'; import type { WorkspaceService } from '@toeverything/infra';
import { import {
fromPromise, fromPromise,
@@ -278,17 +279,14 @@ export class DocsSearchService extends Service {
} }
); );
const refs: { const refs: ({ docId: string } & ReferenceParams)[] = nodes.flatMap(
docId: string; node => {
mode?: string; const { ref } = node.fields;
blockIds?: string[]; return typeof ref === 'string'
elementIds?: string[]; ? [JSON.parse(ref)]
}[] = nodes.flatMap(node => { : ref.map(item => JSON.parse(item));
const { ref } = node.fields; }
return typeof ref === 'string' );
? [JSON.parse(ref)]
: ref.map(item => JSON.parse(item));
});
const docData = await this.indexer.docIndex.getAll( const docData = await this.indexer.docIndex.getAll(
Array.from(new Set(refs.map(ref => ref.docId))) Array.from(new Set(refs.map(ref => ref.docId)))
@@ -352,17 +350,14 @@ export class DocsSearchService extends Service {
.pipe( .pipe(
switchMap(({ nodes }) => { switchMap(({ nodes }) => {
return fromPromise(async () => { return fromPromise(async () => {
const refs: { const refs: ({ docId: string } & ReferenceParams)[] = nodes.flatMap(
docId: string; node => {
mode?: string; const { ref } = node.fields;
blockIds?: string[]; return typeof ref === 'string'
elementIds?: string[]; ? [JSON.parse(ref)]
}[] = nodes.flatMap(node => { : ref.map(item => JSON.parse(item));
const { ref } = node.fields; }
return typeof ref === 'string' );
? [JSON.parse(ref)]
: ref.map(item => JSON.parse(item));
});
const docData = await this.indexer.docIndex.getAll( const docData = await this.indexer.docIndex.getAll(
Array.from(new Set(refs.map(ref => ref.docId))) Array.from(new Set(refs.map(ref => ref.docId)))

View File

@@ -1,6 +1,6 @@
import { afterEach } from 'node:test'; import { afterEach } from 'node:test';
import { beforeEach, expect, test, vi } from 'vitest'; import { beforeEach, describe, expect, test, vi } from 'vitest';
import { resolveLinkToDoc, toURLSearchParams } from '../utils'; import { resolveLinkToDoc, toURLSearchParams } from '../utils';
@@ -84,12 +84,64 @@ const testCases: [string, ReturnType<typeof resolveLinkToDoc>][] = [
docId: '-Uge-K6SYcAbcNYfQ5U-j', docId: '-Uge-K6SYcAbcNYfQ5U-j',
}, },
], ],
[
'http//localhost:8000/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?mode=edgeless&elementIds=,yyyy,',
{
workspaceId: '48__RTCSwASvWZxyAk3Jw',
docId: '-Uge-K6SYcAbcNYfQ5U-j',
mode: 'edgeless',
elementIds: ['yyyy'],
},
],
]; ];
for (const [input, expected] of testCases) { for (const [input, expected] of testCases) {
defineTest(input, expected); defineTest(input, expected);
} }
// self-hosted
describe('resolveLinkToDoc in self-hosted', () => {
beforeEach(() => {
vi.unstubAllGlobals();
vi.stubGlobal('location', { origin: 'https://local.first' });
});
const testCases: [string, ReturnType<typeof resolveLinkToDoc>][] = [
['http://example.com/', null],
[
'/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?blockIds=xxxx',
{
workspaceId: '48__RTCSwASvWZxyAk3Jw',
docId: '-Uge-K6SYcAbcNYfQ5U-j',
blockIds: ['xxxx'],
},
],
[
'http://affine.pro/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?blockIds=xxxx',
{
workspaceId: '48__RTCSwASvWZxyAk3Jw',
docId: '-Uge-K6SYcAbcNYfQ5U-j',
blockIds: ['xxxx'],
},
],
[
'https://local.first/workspace/48__RTCSwASvWZxyAk3Jw/-Uge-K6SYcAbcNYfQ5U-j?blockIds=xxxx',
{
workspaceId: '48__RTCSwASvWZxyAk3Jw',
docId: '-Uge-K6SYcAbcNYfQ5U-j',
blockIds: ['xxxx'],
},
],
];
for (const [input, expected] of testCases) {
test(`resolveLinkToDoc(${input})InSelfHosted`, () => {
const result = resolveLinkToDoc(input);
expect(result).toEqual(expected);
});
}
});
function defineTestWithToURLSearchParams( function defineTestWithToURLSearchParams(
input?: Partial<Record<string, string | string[]>>, input?: Partial<Record<string, string | string[]>>,
expected?: ReturnType<typeof toURLSearchParams> expected?: ReturnType<typeof toURLSearchParams>

View File

@@ -3,23 +3,27 @@ import { isNil, pick, pickBy } from 'lodash-es';
import type { ParsedQuery, ParseOptions } from 'query-string'; import type { ParsedQuery, ParseOptions } from 'query-string';
import queryString from 'query-string'; import queryString from 'query-string';
function maybeAffineOrigin(origin: string) { function maybeAffineOrigin(origin: string, baseUrl: string) {
return ( return (
origin.startsWith('file://') || origin.startsWith('file://') ||
origin.startsWith('affine://') || origin.startsWith('affine://') ||
origin.endsWith('affine.pro') || // stable/beta origin.endsWith('affine.pro') || // stable/beta
origin.endsWith('affine.fail') || // canary origin.endsWith('affine.fail') || // canary
origin.includes('localhost') // dev origin === baseUrl // localhost or self-hosted
); );
} }
export const resolveRouteLinkMeta = (href: string) => { export const resolveRouteLinkMeta = (
href: string,
baseUrl = location.origin
) => {
try { try {
const url = new URL(href, location.origin); const url = new URL(href, baseUrl);
// check if origin is one of affine's origins // check if origin is one of affine's origins
// check if origin is localhost or self-hosted
if (!maybeAffineOrigin(url.origin)) { if (!maybeAffineOrigin(url.origin, baseUrl)) {
return null; return null;
} }