Skip to content

Commit

Permalink
fix: support redirect to default page
Browse files Browse the repository at this point in the history
  • Loading branch information
qinluhe committed Oct 22, 2024
1 parent 15949a7 commit b4480c5
Show file tree
Hide file tree
Showing 44 changed files with 523 additions and 242 deletions.
32 changes: 29 additions & 3 deletions frontend/appflowy_web_app/deploy/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@ const logRequestTimer = (req: Request) => {
};
};

const fetchMetaData = async (url: string) => {
const fetchMetaData = async (namespace: string, publishName?: string) => {
let url = `${baseURL}/api/workspace/published/${namespace}`;

if (publishName) {
url += `/${publishName}`;
}

logger.info(`Fetching meta data from ${url}`);
try {
const response = await fetch(url, {
Expand Down Expand Up @@ -108,7 +114,7 @@ const createServer = async (req: Request) => {
logger.info(`Namespace: ${namespace}, Publish Name: ${publishName}`);

if (req.method === 'GET') {
if (namespace === '' || !publishName) {
if (namespace === '') {
timer();
return new Response(null, {
status: 302,
Expand All @@ -121,7 +127,27 @@ const createServer = async (req: Request) => {
let metaData;

try {
metaData = await fetchMetaData(`${baseURL}/api/workspace/published/${namespace}/${publishName}`);
const data = await fetchMetaData(namespace, publishName);

if (publishName) {
metaData = data;
} else {

const publishInfo = data?.data?.info;

if (publishInfo) {
const newURL = `/${publishInfo.namespace}/${publishInfo.publish_name}`;

logger.info('Redirecting to default page: ', newURL);
timer();
return new Response(null, {
status: 302,
headers: {
Location: newURL,
},
});
}
}
} catch (error) {
logger.error(`Error fetching meta data: ${error}`);
}
Expand Down
Binary file modified frontend/appflowy_web_app/public/og-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface DatabaseContextState {
loadView?: LoadView;
createRowDoc?: CreateRowDoc;
loadViewMeta?: LoadViewMeta;
navigateToView?: (viewId: string) => Promise<void>;
navigateToView?: (viewId: string, blockId?: string) => Promise<void>;
}

export const DatabaseContext = createContext<DatabaseContextState | null>(null);
Expand Down
22 changes: 19 additions & 3 deletions frontend/appflowy_web_app/src/application/publish/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface PublishContextType {
isTemplate?: boolean;
isTemplateThumb?: boolean;
viewMeta?: ViewMeta;
toView: (viewId: string) => Promise<void>;
toView: (viewId: string, blockId?: string) => Promise<void>;
loadViewMeta: LoadViewMeta;
createRowDoc?: CreateRowDoc;
loadView: LoadView;
Expand Down Expand Up @@ -176,7 +176,7 @@ export const PublishProvider = ({
}, [service, publishName]);
const navigate = useNavigate();
const toView = useCallback(
async (viewId: string) => {
async (viewId: string, blockId?: string) => {
try {
const res = await service?.getPublishInfo(viewId);

Expand All @@ -187,7 +187,23 @@ export const PublishProvider = ({
const { namespace: viewNamespace, publishName } = res;

prevViewMeta.current = undefined;
navigate(`/${viewNamespace}/${publishName}${isTemplate ? '?template=true' : ''}`, {
const searchParams = new URLSearchParams('');

if (blockId) {
searchParams.set('blockId', blockId);
}

if (isTemplate) {
searchParams.set('template', 'true');
}

let url = `/${viewNamespace}/${publishName}`;

if (searchParams.toString()) {
url += `?${searchParams.toString()}`;
}

navigate(url, {
replace: true,
});
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
Subscriptions,
SubscriptionPlan,
SubscriptionInterval,
RequestAccessInfoStatus,
RequestAccessInfoStatus, ViewInfo,
} from '@/application/types';
import { GlobalComment, Reaction } from '@/application/comment.type';
import { initGrantService, refreshToken } from '@/application/services/js-services/http/gotrue';
Expand Down Expand Up @@ -274,10 +274,22 @@ export async function getUserWorkspaceInfo (): Promise<{
}

export async function getPublishViewMeta (namespace: string, publishName: string) {
const url = `/api/workspace/published/${namespace}/${publishName}`;
const response = await axiosInstance?.get(url);
const url = `/api/workspace/v1/published/${namespace}/${publishName}`;
const response = await axiosInstance?.get<{
code: number;
data: {
view: ViewInfo;
child_views: ViewInfo[];
ancestor_views: ViewInfo[];
};
message: string;
}>(url);

return response?.data;
if (response?.data.code !== 0) {
return Promise.reject(response?.data);
}

return response?.data.data;
}

export async function getPublishViewBlob (namespace: string, publishName: string) {
Expand All @@ -289,7 +301,7 @@ export async function getPublishViewBlob (namespace: string, publishName: string
return blobToBytes(response?.data);
}

export async function updateCollab (workspaceId: string, objectId: string, docState: Uint8Array, context: {
export async function updateCollab (workspaceId: string, objectId: string, collabType: Types, docState: Uint8Array, context: {
version_vector: number;
}) {
const url = `/api/workspace/v1/${workspaceId}/collab/${objectId}/web-update`;
Expand All @@ -298,6 +310,7 @@ export async function updateCollab (workspaceId: string, objectId: string, docSt
message: string;
}>(url, {
doc_state: Array.from(docState),
collab_type: collabType,
});

if (response?.data.code !== 0) {
Expand Down Expand Up @@ -1220,3 +1233,4 @@ export async function importFile (file: File, onProgress: (progress: number) =>

return Promise.reject(response?.data);
}

Original file line number Diff line number Diff line change
Expand Up @@ -459,15 +459,17 @@ export class AFClientService implements AFService {
return APIService.getActiveSubscription(workspaceId);
}

registerDocUpdate (doc: Y.Doc, workspaceId: string, objectId: string) {
registerDocUpdate (doc: Y.Doc, context: {
workspaceId: string, objectId: string, collabType: Types
}) {
const token = getTokenParsed();
const userId = token?.user.id;

if (!userId) {
throw new Error('User not found');
}

const sync = new SyncManager(doc, userId, workspaceId, objectId);
const sync = new SyncManager(doc, { userId, ...context });

sync.initialize();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { updateCollab } from '@/application/services/js-services/http/http_api';
import { CollabOrigin } from '@/application/types';
import { CollabOrigin, Types } from '@/application/types';
import { debounce } from 'lodash-es';
import * as Y from 'yjs';

Expand All @@ -17,7 +17,9 @@ export class SyncManager {

private isSending = false;

constructor (private doc: Y.Doc, private uuid: string, private workspaceId: string, private objectId: string) {
constructor (private doc: Y.Doc, private context: {
userId: string, workspaceId: string, objectId: string, collabType: Types
}) {
this.versionVector = this.loadVersionVector();
this.hasUnsyncedChanges = this.loadUnsyncedFlag();
this.lastSyncedAt = this.loadLastSyncedAt();
Expand All @@ -33,7 +35,7 @@ export class SyncManager {
}

private getStorageKey (baseKey: string): string {
return `${this.uuid}_${baseKey}_${this.workspaceId}_${this.objectId}`;
return `${this.context.userId}_${baseKey}_${this.context.workspaceId}_${this.context.objectId}`;
}

private loadVersionVector (): number {
Expand Down Expand Up @@ -81,7 +83,7 @@ export class SyncManager {
const update = Y.encodeStateAsUpdate(this.doc);
const context = { version_vector: this.versionVector };

const response = await updateCollab(this.workspaceId, this.objectId, update, context);
const response = await updateCollab(this.context.workspaceId, this.context.objectId, this.context.collabType, update, context);

if (response) {
console.log(`Update sent successfully. Server version: ${response.version_vector}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
UserWorkspaceInfo,
View,
Workspace,
YDoc, DatabaseRelations, GetRequestAccessInfoResponse, Subscriptions, SubscriptionPlan, SubscriptionInterval,
YDoc, DatabaseRelations, GetRequestAccessInfoResponse, Subscriptions, SubscriptionPlan, SubscriptionInterval, Types,
} from '@/application/types';
import { GlobalComment, Reaction } from '@/application/comment.type';
import { ViewMeta } from '@/application/db/tables/view_metas';
Expand Down Expand Up @@ -64,7 +64,9 @@ export interface AppService {
getSubscriptionLink: (workspaceId: string, plan: SubscriptionPlan, interval: SubscriptionInterval) => Promise<string>;
getSubscriptions: () => Promise<Subscriptions>;
getActiveSubscription: (workspaceId: string) => Promise<SubscriptionPlan[]>;
registerDocUpdate: (doc: YDoc, workspaceId: string, objectId: string) => void;
registerDocUpdate: (doc: YDoc, context: {
workspaceId: string, objectId: string, collabType: Types
}) => void;
importFile: (file: File, onProgress: (progress: number) => void) => Promise<void>;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ export class AFClientService implements AFService {
return Promise.reject('Method not implemented');
}

registerDocUpdate (_doc: YDoc, _workspaceId: string, _objectId: string): void {
registerDocUpdate (): void {
throw new Error('Method not implemented.');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { YjsEditorKey, YSharedRoot } from '@/application/types';
import { generateId, getTestingDocData, insertBlock, withTestingYDoc } from './withTestingYjsEditor';
import { yDocToSlateContent, deltaInsertToSlateNode, yDataToSlateContent } from '@/application/slate-yjs/utils/convert';
import { expect } from '@jest/globals';
Expand All @@ -9,15 +10,16 @@ describe('convert yjs data to slate content', () => {
it('should return undefined if root block is not exist', () => {
const doc = new Y.Doc();

const sharedRoot = doc.getMap(YjsEditorKey.data_section) as YSharedRoot;
expect(yDocToSlateContent(doc)).toBeUndefined();

const doc2 = withTestingYDoc('1');
const { blocks, childrenMap, textMap, pageId } = getTestingDocData(doc2);
expect(yDataToSlateContent({ blocks, rootId: '2', childrenMap, textMap })).toBeUndefined();
const { blocks, pageId } = getTestingDocData(doc2);
expect(yDataToSlateContent(sharedRoot)).toBeUndefined();

blocks.delete(pageId);

expect(yDataToSlateContent({ blocks, rootId: pageId, childrenMap, textMap })).toBeUndefined();
expect(yDataToSlateContent(sharedRoot)).toBeUndefined();
});
it('should match empty array', () => {
const doc = withTestingYDoc('1');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,21 @@ import { BasePoint, BaseRange, Editor, Element, Node, NodeEntry, Path, Range, Te
import { ReactEditor } from 'slate-react';

export const CustomEditor = {
// find entry from blockId
getBlockEntry (editor: YjsEditor, blockId: string): NodeEntry<Element> | undefined {
const [entry] = editor.nodes({
at: [],
match: (n) => !Editor.isEditor(n) && Element.isElement(n) && n.blockId === blockId,
});

if (!entry) {
return;
}

return entry as NodeEntry<Element>;
},
// Get the text content of a block node, including the text content of its children and formula nodes
getBlockTextContent (node: Node): string {
getBlockTextContent (node: Node, depth: number = Infinity): string {
if (Text.isText(node)) {
if (node.formula) {
return node.formula;
Expand All @@ -56,7 +69,13 @@ export const CustomEditor = {
return node.text || '';
}

return node.children.map((n) => CustomEditor.getBlockTextContent(n)).join('');
if (depth <= 0) {
return ''; // Prevent infinite recursion
}

return node.children
.map((n) => CustomEditor.getBlockTextContent(n, depth - 1))
.join('');
},

setBlockData<T = BlockData> (editor: YjsEditor, blockId: string, updateData: T, select?: boolean) {
Expand All @@ -75,10 +94,7 @@ export const CustomEditor = {
const newProperties = {
data: newData,
} as Partial<Element>;
const [entry] = editor.nodes({
at: [],
match: (n) => !Editor.isEditor(n) && Element.isElement(n) && n.blockId === blockId,
});
const entry = CustomEditor.getBlockEntry(editor, blockId);

if (!entry) {
console.error('Block not found');
Expand Down
Loading

0 comments on commit b4480c5

Please sign in to comment.