Merge branch 'sync-workspace-files-toggle'

This commit is contained in:
tiagoarroz 2026-05-08 12:10:31 +01:00
commit 3b3feda07b
4 changed files with 66 additions and 19 deletions

View file

@ -139,16 +139,21 @@ export default class EventsListener {
}
}
private isWorkspaceFile(filePath: string): boolean {
return (
filePath === `${this.vault.configDir}/workspace.json` ||
filePath === `${this.vault.configDir}/workspace-mobile.json`
);
}
private async isSyncable(filePath: string) {
if (filePath === `${this.vault.configDir}/${MANIFEST_FILE_NAME}`) {
// Manifest file must always be synced
return true;
} else if (
filePath === `${this.vault.configDir}/workspace.json` ||
filePath === `${this.vault.configDir}/workspace-mobile.json`
) {
// Obsidian recommends not syncing the workspace files
return false;
} else if (this.isWorkspaceFile(filePath)) {
// Workspace files are synced only when config directory sync is enabled
// and the dedicated workspace-files option is enabled too.
return this.settings.syncConfigDir && this.settings.syncWorkspaceFiles;
} else if (filePath === `${this.vault.configDir}/${LOG_FILE_NAME}`) {
// Don't sync the log file, doesn't make sense
return false;

View file

@ -9,6 +9,7 @@ export interface GitHubSyncSettings {
syncInterval: number;
syncOnStartup: boolean;
syncConfigDir: boolean;
syncWorkspaceFiles: boolean;
conflictHandling: "overwriteLocal" | "ask" | "overwriteRemote";
autoResolveLogConflicts: boolean;
conflictViewMode: "default" | "unified" | "split";
@ -29,6 +30,7 @@ export const DEFAULT_SETTINGS: GitHubSyncSettings = {
syncInterval: 1,
syncOnStartup: false,
syncConfigDir: false,
syncWorkspaceFiles: false,
conflictHandling: "ask",
autoResolveLogConflicts: true,
conflictViewMode: "default",

View file

@ -180,6 +180,23 @@ export default class GitHubSyncSettingsTab extends PluginSettingTab {
});
});
new Setting(containerEl)
.setName("Sync workspace files")
.setDesc("Sync workspace.json and workspace-mobile.json files")
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.syncWorkspaceFiles)
.onChange(async (value) => {
this.plugin.settings.syncWorkspaceFiles = value;
if (value && this.plugin.settings.syncConfigDir) {
await this.plugin.syncManager.addConfigDirToMetadata();
} else if (!value) {
await this.plugin.syncManager.removeWorkspaceFilesFromMetadata();
}
await this.plugin.saveSettings();
});
});
const conflictHandlingOptions = {
overwriteLocal: "Overwrite local file",
ask: "Ask",

View file

@ -312,11 +312,8 @@ export default class SyncManager {
return;
}
if (targetPath === `${this.vault.configDir}/${LOG_FILE_NAME}`) {
// We don't want to download the log file if the user synced it in the past.
// This is necessary because in the past we forgot to ignore the log file
// from syncing if the user enabled configs sync.
// To avoid downloading it we ignore it if still present in the remote repo.
if (this.isVolatileSyncArtifact(targetPath)) {
await this.logger.info("Skipping volatile sync artifact", targetPath);
return;
}
@ -714,8 +711,23 @@ export default class SyncManager {
return filePath === `${this.vault.configDir}/${LOG_FILE_NAME}`;
}
private isWorkspaceFile(filePath: string): boolean {
return (
filePath === `${this.vault.configDir}/workspace.json` ||
filePath === `${this.vault.configDir}/workspace-mobile.json`
);
}
private shouldSyncWorkspaceFiles(): boolean {
return this.settings.syncConfigDir && this.settings.syncWorkspaceFiles;
}
private isVolatileSyncArtifact(filePath: string): boolean {
return this.isLogFile(filePath);
// Keep these files out of metadata when they should not be synced.
return (
this.isLogFile(filePath) ||
(this.isWorkspaceFile(filePath) && !this.shouldSyncWorkspaceFiles())
);
}
private filterRemoteMetadataFiles(filesMetadata: {
@ -736,7 +748,7 @@ export default class SyncManager {
}
/**
* Remove artefactos volateis do metadata local para evitar conflitos recorrentes.
* Removes volatile artifacts from local metadata to prevent recurring conflicts.
*/
private async removeVolatileArtifactsFromLocalMetadata() {
let changed = false;
@ -752,7 +764,7 @@ export default class SyncManager {
}
/**
* Reconcilia SHAs do metadata remoto com a tree atual para remover referencias obsoletas.
* Reconciles remote metadata SHAs with the current tree to remove stale references.
*/
private async reconcileRemoteMetadataWithTree(
remoteMetadataFiles: {
@ -788,7 +800,7 @@ export default class SyncManager {
}
/**
* Tenta obter o blob pelo SHA do metadata e, em caso de 404, tenta pelo SHA atual da tree.
* Tries to load a blob by metadata SHA and, on 404, retries with the current tree SHA.
*/
private async getRemoteFileContentWithFallback(
filePath: string,
@ -1273,10 +1285,6 @@ export default class SyncManager {
folders.push(...res.folders);
}
files.forEach((filePath: string) => {
if (filePath === `${this.vault.configDir}/workspace.json`) {
// Obsidian recommends not syncing the workspace file
return;
}
if (
isGitignored(gitignoreMatcher, filePath) ||
this.isVolatileSyncArtifact(filePath)
@ -1388,6 +1396,21 @@ export default class SyncManager {
this.metadataStore.save();
}
/**
* Removes workspace files from local metadata.
* Useful when the user disables workspace files synchronization.
*/
async removeWorkspaceFilesFromMetadata() {
await this.logger.info("Removing workspace files from metadata");
[
`${this.vault.configDir}/workspace.json`,
`${this.vault.configDir}/workspace-mobile.json`,
].forEach((filePath: string) => {
delete this.metadataStore.data.files[filePath];
});
this.metadataStore.save();
}
getFileMetadata(filePath: string): FileMetadata {
return this.metadataStore.data.files[filePath];
}