feat: restore Wolai workspace navigation and assets
This commit is contained in:
@@ -138,6 +138,39 @@ export const createDocumentSessionRuntime = (dependencies = {}) => {
|
||||
|| localMarkdownRelativePathFromDocumentId(session?.documentId)
|
||||
);
|
||||
|
||||
const localFolderNavigationFallbackUrl = (session, reason) => {
|
||||
const url = new URL('/', window.location.origin);
|
||||
url.searchParams.set('sourceKind', 'local_folder');
|
||||
if (session?.rootUri) url.searchParams.set('rootUri', session.rootUri);
|
||||
url.searchParams.set('treeView', 'filetree');
|
||||
const relativePath = sessionRelativePath(session);
|
||||
const currentScope = String(new URL(window.location.href).searchParams.get('fileTreeScope') || '').trim();
|
||||
const parentScope = relativePath.includes('/') ? relativePath.split('/').slice(0, -1).join('/') : '';
|
||||
const scope = currentScope || parentScope;
|
||||
if (scope) url.searchParams.set('fileTreeScope', scope);
|
||||
if (session?.documentId) url.searchParams.set('missingPage', session.documentId);
|
||||
if (reason) url.searchParams.set('routeGuard', reason);
|
||||
return url;
|
||||
};
|
||||
|
||||
const navigateLocalMarkdownDeletedFallback = (session, reason = 'local_markdown_deleted') => {
|
||||
if (!session || session.sessionKind === 'resource') return false;
|
||||
if (session.saveTimer) {
|
||||
window.clearTimeout(session.saveTimer);
|
||||
session.saveTimer = 0;
|
||||
}
|
||||
if (session.externalRefreshTimer) {
|
||||
window.clearTimeout(session.externalRefreshTimer);
|
||||
session.externalRefreshTimer = 0;
|
||||
}
|
||||
session.externalChangePending = false;
|
||||
session.hasExternalConflict = false;
|
||||
session.bufferDirtyState = 'Deleted';
|
||||
clearSessionConflictSurface(session);
|
||||
window.location.assign(localFolderNavigationFallbackUrl(session, reason).toString());
|
||||
return true;
|
||||
};
|
||||
|
||||
const localFolderEventItems = (payload) => {
|
||||
if (!payload || typeof payload !== 'object') return [];
|
||||
const changedPaths = Array.isArray(payload.changedPaths)
|
||||
@@ -151,6 +184,7 @@ export const createDocumentSessionRuntime = (dependencies = {}) => {
|
||||
relativePath: String(item.relativePath || item.relative_path || item.path || '').trim(),
|
||||
documentId: String(item.documentId || item.document_id || '').trim(),
|
||||
eventKind: String(item.eventKind || item.event_kind || item.changeType || item.change_type || '').trim(),
|
||||
changeType: String(item.changeType || item.change_type || '').trim(),
|
||||
selfWriteEcho: Boolean(item.selfWriteEcho || item.self_write_echo),
|
||||
fileVersion: String(item.fileVersion || item.file_version || item.observedFileVersion || item.observed_file_version || '').trim(),
|
||||
observedFileVersion: String(item.observedFileVersion || item.observed_file_version || '').trim(),
|
||||
@@ -1167,19 +1201,7 @@ export const createDocumentSessionRuntime = (dependencies = {}) => {
|
||||
const bufferState = await fetchSessionBufferState(session);
|
||||
const dirtyState = String(bufferState?.dirtyState || session.bufferDirtyState || '').trim();
|
||||
if (dirtyState === 'Deleted') {
|
||||
session.lastExternalConflictEnvelope = {
|
||||
code: 'local_markdown_deleted',
|
||||
documentId: session.documentId,
|
||||
rootUri: session.rootUri || null,
|
||||
currentDiskVersion: bufferState?.fileVersion || session.conflictDetectionKey || session.fileVersion || null,
|
||||
editorBaseVersion: session.conflictDetectionKey || session.fileVersion || null,
|
||||
externalActor: bufferState?.externalActor || null,
|
||||
dirtyState,
|
||||
bufferFileVersion: bufferState?.fileVersion || session.fileVersion || null,
|
||||
message: '当前本地 Markdown 文件已被删除,请恢复文件或关闭当前标签',
|
||||
suggestedActions: ['keep_editor', 'open_diff'],
|
||||
};
|
||||
markSessionExternalConflict(session, session.lastExternalConflictEnvelope.message);
|
||||
navigateLocalMarkdownDeletedFallback(session);
|
||||
return;
|
||||
}
|
||||
if (session.hasExternalConflict) {
|
||||
@@ -1209,13 +1231,24 @@ export const createDocumentSessionRuntime = (dependencies = {}) => {
|
||||
cache: 'no-store',
|
||||
headers: { accept: 'application/json' },
|
||||
});
|
||||
const payload = await response.json().catch(() => null);
|
||||
if (!response.ok) {
|
||||
const errorCode = String(payload?.error?.code || payload?.code || '').trim();
|
||||
if (session.sourceKind === 'local_folder' && (response.status === 404 || errorCode === 'local_markdown_not_found')) {
|
||||
navigateLocalMarkdownDeletedFallback(session, 'local_markdown_not_found');
|
||||
return;
|
||||
}
|
||||
const conflictEnvelope = conflictEnvelopeFromResponse(payload);
|
||||
if (response.status === 409 && conflictEnvelope) {
|
||||
session.lastExternalConflictEnvelope = conflictEnvelope;
|
||||
markSessionExternalConflict(session, conflictMessageFromEnvelope(session, conflictEnvelope));
|
||||
return;
|
||||
}
|
||||
if (session.sourceKind === 'local_folder') {
|
||||
markSessionExternalConflict(session, externalConflictMessage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const payload = await response.json();
|
||||
const conflictEnvelope = conflictEnvelopeFromResponse(payload);
|
||||
if (response.status === 409 && conflictEnvelope) {
|
||||
session.lastExternalConflictEnvelope = conflictEnvelope;
|
||||
@@ -1404,6 +1437,11 @@ export const createDocumentSessionRuntime = (dependencies = {}) => {
|
||||
|| (!documentId && relativePath && relativeTarget && relativePath === relativeTarget)
|
||||
);
|
||||
if (!targetsCurrentDocument) return;
|
||||
const changeType = String(item.changeType || '').trim();
|
||||
if (changeType === 'deleted') {
|
||||
navigateLocalMarkdownDeletedFallback(targetSession);
|
||||
return;
|
||||
}
|
||||
if (item.selfWriteEcho === true) {
|
||||
targetSession.externalChangePending = false;
|
||||
targetSession.lastSelfSaveSignalAt = Date.now();
|
||||
|
||||
Reference in New Issue
Block a user