db24ea5 ←334e693antonApr 11, 2026 api

edit main.ts via macOS

M /sublimated/undefined +6 -19
16 unmodified lines
17 settings: SublimatedSettings = DEFAULT_SETTINGS;
18 lastMetadata: FileMetadata | null = null;
19
20 private statusBarEl: HTMLElement | null = null;
21 private isSublimatedVault = false;
21
22 async onload(): Promise<void> {
23 await this.loadSettings();
24
26 // detect if this vault is a sublimated workspace
27 this.isSublimatedVault = await this.checkSublimatedVault();
28
25 // status bar
26 this.statusBarEl = this.addStatusBarItem();
27 this.statusBarEl.addClass("sbl-status-bar");
28 this.statusBarEl.addEventListener("click", () =>
73 unmodified lines
102 async saveSettings(): Promise<void> {
103 await this.saveData(this.settings);
104 }
105
110 // check for .sbl/ folder in vault root
111 private async checkSublimatedVault(): Promise<boolean> {
112 const adapter = this.app.vault.adapter;
113 return adapter.exists(normalizePath(".sbl"));
114 }
115
106 // detect workspace from xattrs on the currently active file.
107 // every synced file carries com.sublimated.space#PS, so any file
108 // with sublimated metadata identifies the workspace.
109 detectWorkspace(): { space: string | null } | null {
117 if (!this.isSublimatedVault) return null;
110 if (!this.lastMetadata) return null;
111 if (!this.lastMetadata.space && !this.lastMetadata.id) return null;
112 return {
119 space: this.lastMetadata?.space ?? null,
113 space: this.lastMetadata.space ?? null,
114 };
115 }
116
117 private async refreshMetadata(): Promise<void> {
27 unmodified lines
145
146 private updateStatusBar(meta: FileMetadata | null): void {
147 if (!this.statusBarEl) return;
148
155 if (!this.isSublimatedVault) {
149 // no sublimated xattrs → file isn't tracked by sublimated, hide status bar
150 if (!meta || (!meta.space && !meta.id)) {
151 this.statusBarEl.setText("");
152 return;
153 }
154
160 if (!meta) {
161 this.statusBarEl.setText("sublimated");
162 return;
163 }
164
155 // compact format: "✓ synced v21 by anton" (sync + version + author + optional branch/visibility)
156 const parts: string[] = [];
157
167 if (meta.version) {
168 parts.push(`v${meta.version}`);
169 }
170
158 if (meta.syncStatus) {
159 const icon = syncStatusIcon(meta.syncStatus);
173 parts.push(`${icon} ${meta.syncStatus}`);
160 parts.push(icon ? `${icon} ${meta.syncStatus}` : meta.syncStatus);
161 }
162
163 if (meta.version) {
164 parts.push(`v${meta.version}`);
165 }
166
167 if (meta.modifiedBy) {
168 const prefix =
169 meta.modifiedByType === "ai_agent" ? "by AI:" : "by";
170 parts.push(`${prefix} ${meta.modifiedBy}`);
6 unmodified lines
177 if (meta.visibility) {
178 parts.push(visibilityIcon(meta.visibility));
179 }
180
190 if (parts.length > 0) {
191 this.statusBarEl.setText(`sublimated: ${parts.join(" · ")}`);
192 } else {
193 this.statusBarEl.setText("sublimated");
194 }
181 this.statusBarEl.setText(parts.join(" "));
182
183 // show pointer cursor when URL available
184 if (meta.url) {
185 this.statusBarEl.addClass("sbl-clickable");
96 unmodified lines