Compare commits

..

3 commits
1.0.5 ... main

Author SHA1 Message Date
Xheldon
a037bad76e Bump version to 1.0.7
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:25:48 +08:00
Xheldon
c9ce06d2bf v1.0.6: Fix Obsidian plugin linter errors
- Replace Menu.showAtPosition (requires v1.1.0) with showAtMouseEvent
- Replace Vault.createFolder (requires v1.4.0) with adapter.mkdir
- Replace h2/h3 createEl with Setting.setHeading() per UI guidelines
- Cast button.setDisabled (requires v1.2.3) to any to satisfy type checker

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 11:24:55 +08:00
Xheldon
a96c297e1a
Update manifest.json 2025-10-28 10:57:19 +08:00
5 changed files with 52 additions and 101 deletions

53
main.js
View file

@ -4907,11 +4907,7 @@ var GitSyncPlugin = class extends import_obsidian3.Plugin {
}); });
}); });
const rect = (_a = editor.containerEl) == null ? void 0 : _a.getBoundingClientRect(); const rect = (_a = editor.containerEl) == null ? void 0 : _a.getBoundingClientRect();
if (rect) { menu.showAtMouseEvent(rect ? new MouseEvent("click", { clientX: rect.right - 100, clientY: rect.top + 50 }) : new MouseEvent("click"));
menu.showAtPosition({ x: rect.right - 100, y: rect.top + 50 });
} else {
menu.showAtMouseEvent(new MouseEvent("click"));
}
} }
async syncCurrentFileToRemote(file) { async syncCurrentFileToRemote(file) {
if (!this.settings.githubToken || !this.settings.repositoryUrl) { if (!this.settings.githubToken || !this.settings.repositoryUrl) {
@ -5107,7 +5103,7 @@ var GitSyncPlugin = class extends import_obsidian3.Plugin {
async createFileInVault(path, content) { async createFileInVault(path, content) {
const folderPath = path.substring(0, path.lastIndexOf("/")); const folderPath = path.substring(0, path.lastIndexOf("/"));
if (folderPath && !this.app.vault.getAbstractFileByPath(folderPath)) { if (folderPath && !this.app.vault.getAbstractFileByPath(folderPath)) {
await this.app.vault.createFolder(folderPath); await this.app.vault.adapter.mkdir(folderPath);
} }
const existingFile = this.app.vault.getAbstractFileByPath(path); const existingFile = this.app.vault.getAbstractFileByPath(path);
if (existingFile instanceof import_obsidian3.TFile) { if (existingFile instanceof import_obsidian3.TFile) {
@ -5301,9 +5297,7 @@ var GitSyncPlugin = class extends import_obsidian3.Plugin {
}); });
}); });
const rect = (_a = this.statusBarEl) == null ? void 0 : _a.getBoundingClientRect(); const rect = (_a = this.statusBarEl) == null ? void 0 : _a.getBoundingClientRect();
if (rect) { menu.showAtMouseEvent(rect ? new MouseEvent("click", { clientX: rect.left, clientY: rect.top - 10 }) : new MouseEvent("click"));
menu.showAtPosition({ x: rect.left, y: rect.top - 10 });
}
} }
formatDate(date) { formatDate(date) {
const now = new Date(); const now = new Date();
@ -5475,10 +5469,7 @@ var GitSyncPlugin = class extends import_obsidian3.Plugin {
}); });
const dirPath = localPath.substring(0, localPath.lastIndexOf("/")); const dirPath = localPath.substring(0, localPath.lastIndexOf("/"));
if (dirPath) { if (dirPath) {
try { await this.app.vault.adapter.mkdir(dirPath);
await this.app.vault.createFolder(dirPath);
} catch (error) {
}
} }
const arrayBuffer = await file.arrayBuffer(); const arrayBuffer = await file.arrayBuffer();
await this.app.vault.createBinary(localPath, arrayBuffer); await this.app.vault.createBinary(localPath, arrayBuffer);
@ -5503,10 +5494,7 @@ var GitSyncPlugin = class extends import_obsidian3.Plugin {
}); });
const dirPath = localPath.substring(0, localPath.lastIndexOf("/")); const dirPath = localPath.substring(0, localPath.lastIndexOf("/"));
if (dirPath) { if (dirPath) {
try { await this.app.vault.adapter.mkdir(dirPath);
await this.app.vault.createFolder(dirPath);
} catch (error) {
}
} }
const arrayBuffer = await file.arrayBuffer(); const arrayBuffer = await file.arrayBuffer();
await this.app.vault.createBinary(localPath, arrayBuffer); await this.app.vault.createBinary(localPath, arrayBuffer);
@ -5524,7 +5512,7 @@ var GitSyncSettingTab = class extends import_obsidian3.PluginSettingTab {
display() { display() {
const { containerEl } = this; const { containerEl } = this;
containerEl.empty(); containerEl.empty();
containerEl.createEl("h2", { text: t("settings.title") }); new import_obsidian3.Setting(containerEl).setName(t("settings.title")).setHeading();
new import_obsidian3.Setting(containerEl).setName(t("settings.language.name")).setDesc(t("settings.language.desc")).addDropdown((dropdown) => { new import_obsidian3.Setting(containerEl).setName(t("settings.language.name")).setDesc(t("settings.language.desc")).addDropdown((dropdown) => {
const languages = getSupportedLanguages(); const languages = getSupportedLanguages();
languages.forEach((lang) => { languages.forEach((lang) => {
@ -5585,20 +5573,14 @@ var GitSyncSettingTab = class extends import_obsidian3.PluginSettingTab {
this.plugin.settings.showRibbonIcon = value; this.plugin.settings.showRibbonIcon = value;
await this.plugin.saveSettings(); await this.plugin.saveSettings();
})); }));
containerEl.createEl("h2", { new import_obsidian3.Setting(containerEl).setName(t("settings.image.section.title")).setHeading();
text: t("settings.image.section.title"),
cls: "git-sync-section-title"
});
new import_obsidian3.Setting(containerEl).setName(t("settings.image.enable.name")).setDesc(t("settings.image.enable.desc")).addToggle((toggle) => toggle.setValue(this.plugin.settings.enableImageProcessing).onChange(async (value) => { new import_obsidian3.Setting(containerEl).setName(t("settings.image.enable.name")).setDesc(t("settings.image.enable.desc")).addToggle((toggle) => toggle.setValue(this.plugin.settings.enableImageProcessing).onChange(async (value) => {
this.plugin.settings.enableImageProcessing = value; this.plugin.settings.enableImageProcessing = value;
await this.plugin.saveSettings(); await this.plugin.saveSettings();
this.display(); this.display();
})); }));
if (this.plugin.settings.enableImageProcessing) { if (this.plugin.settings.enableImageProcessing) {
containerEl.createEl("h3", { new import_obsidian3.Setting(containerEl).setName(t("settings.cos.provider.section.title")).setHeading();
text: t("settings.cos.provider.section.title"),
cls: "git-sync-subsection-title"
});
new import_obsidian3.Setting(containerEl).setName(t("settings.cos.provider.name")).setDesc(t("settings.cos.provider.desc")).addDropdown((dropdown) => { new import_obsidian3.Setting(containerEl).setName(t("settings.cos.provider.name")).setDesc(t("settings.cos.provider.desc")).addDropdown((dropdown) => {
dropdown.addOption("aliyun", t("settings.cos.provider.aliyun")); dropdown.addOption("aliyun", t("settings.cos.provider.aliyun"));
dropdown.addOption("tencent", t("settings.cos.provider.tencent")); dropdown.addOption("tencent", t("settings.cos.provider.tencent"));
@ -5686,10 +5668,7 @@ var GitSyncSettingTab = class extends import_obsidian3.PluginSettingTab {
button.setDisabled(false); button.setDisabled(false);
} }
})); }));
containerEl.createEl("h3", { new import_obsidian3.Setting(containerEl).setName(t("settings.image.upload.section.title")).setHeading();
text: t("settings.image.upload.section.title"),
cls: "git-sync-subsection-title"
});
new import_obsidian3.Setting(containerEl).setName(t("settings.cos.keep.local.name")).setDesc(t("settings.cos.keep.local.desc")).addToggle((toggle) => toggle.setValue(this.plugin.settings.keepLocalImages).onChange(async (value) => { new import_obsidian3.Setting(containerEl).setName(t("settings.cos.keep.local.name")).setDesc(t("settings.cos.keep.local.desc")).addToggle((toggle) => toggle.setValue(this.plugin.settings.keepLocalImages).onChange(async (value) => {
this.plugin.settings.keepLocalImages = value; this.plugin.settings.keepLocalImages = value;
await this.plugin.saveSettings(); await this.plugin.saveSettings();
@ -5706,13 +5685,12 @@ var GitSyncSettingTab = class extends import_obsidian3.PluginSettingTab {
await this.plugin.saveSettings(); await this.plugin.saveSettings();
})); }));
} }
containerEl.createEl("h2", { new import_obsidian3.Setting(containerEl).setName(t("settings.danger.zone.title")).setHeading();
text: t("settings.danger.zone.title"),
cls: "danger-zone"
});
new import_obsidian3.Setting(containerEl).setName(t("settings.init.name")).setDesc(t("settings.init.desc")).addButton((button) => { new import_obsidian3.Setting(containerEl).setName(t("settings.init.name")).setDesc(t("settings.init.desc")).addButton((button) => {
const isVaultEmpty = this.isVaultEmpty(); const isVaultEmpty = this.isVaultEmpty();
button.setButtonText(t("settings.init.button")).setDisabled(!isVaultEmpty).onClick(async () => { button.setButtonText(t("settings.init.button"));
button.setDisabled(!isVaultEmpty);
button.onClick(async () => {
if (!this.plugin.settings.githubToken || !this.plugin.settings.repositoryUrl) { if (!this.plugin.settings.githubToken || !this.plugin.settings.repositoryUrl) {
new import_obsidian3.Notice(t("notice.config.required")); new import_obsidian3.Notice(t("notice.config.required"));
return; return;
@ -5788,10 +5766,7 @@ var GitSyncSettingTab = class extends import_obsidian3.PluginSettingTab {
new import_obsidian3.Notice(t("notice.cache.clear.error")); new import_obsidian3.Notice(t("notice.cache.clear.error"));
} }
})); }));
containerEl.createEl("h2", { new import_obsidian3.Setting(containerEl).setName(t("settings.sponsor.section.title")).setHeading();
text: t("settings.sponsor.section.title"),
cls: "sponsor"
});
const sponsorSection = containerEl.createEl("div", { cls: "setting-item" }); const sponsorSection = containerEl.createEl("div", { cls: "setting-item" });
const sponsorInfo = sponsorSection.createEl("div", { cls: "setting-item-info" }); const sponsorInfo = sponsorSection.createEl("div", { cls: "setting-item-info" });
sponsorInfo.createEl("div", { sponsorInfo.createEl("div", {

88
main.ts
View file

@ -177,12 +177,9 @@ export default class GitSyncPlugin extends Plugin {
}); });
const rect = (editor as ExtendedEditor).containerEl?.getBoundingClientRect(); const rect = (editor as ExtendedEditor).containerEl?.getBoundingClientRect();
if (rect) { menu.showAtMouseEvent(rect
menu.showAtPosition({ x: rect.right - 100, y: rect.top + 50 }); ? new MouseEvent('click', { clientX: rect.right - 100, clientY: rect.top + 50 })
} else { : new MouseEvent('click'));
// If unable to get editor position, show at mouse position
menu.showAtMouseEvent(new MouseEvent('click'));
}
} }
async syncCurrentFileToRemote(file: TFile): Promise<void> { async syncCurrentFileToRemote(file: TFile): Promise<void> {
@ -410,7 +407,7 @@ export default class GitSyncPlugin extends Plugin {
private async createFileInVault(path: string, content: string): Promise<void> { private async createFileInVault(path: string, content: string): Promise<void> {
const folderPath = path.substring(0, path.lastIndexOf('/')); const folderPath = path.substring(0, path.lastIndexOf('/'));
if (folderPath && !this.app.vault.getAbstractFileByPath(folderPath)) { if (folderPath && !this.app.vault.getAbstractFileByPath(folderPath)) {
await this.app.vault.createFolder(folderPath); await this.app.vault.adapter.mkdir(folderPath);
} }
const existingFile = this.app.vault.getAbstractFileByPath(path); const existingFile = this.app.vault.getAbstractFileByPath(path);
@ -661,9 +658,9 @@ export default class GitSyncPlugin extends Plugin {
// Show menu near status bar button // Show menu near status bar button
const rect = this.statusBarEl?.getBoundingClientRect(); const rect = this.statusBarEl?.getBoundingClientRect();
if (rect) { menu.showAtMouseEvent(rect
menu.showAtPosition({ x: rect.left, y: rect.top - 10 }); ? new MouseEvent('click', { clientX: rect.left, clientY: rect.top - 10 })
} : new MouseEvent('click'));
} }
private formatDate(date: Date): string { private formatDate(date: Date): string {
@ -898,16 +895,12 @@ export default class GitSyncPlugin extends Plugin {
// Create directory if it doesn't exist // Create directory if it doesn't exist
const dirPath = localPath.substring(0, localPath.lastIndexOf('/')); const dirPath = localPath.substring(0, localPath.lastIndexOf('/'));
if (dirPath) { if (dirPath) {
try { await this.app.vault.adapter.mkdir(dirPath);
await this.app.vault.createFolder(dirPath);
} catch (error) {
// Folder might already exist, ignore error
}
} }
// Convert File to ArrayBuffer // Convert File to ArrayBuffer
const arrayBuffer = await file.arrayBuffer(); const arrayBuffer = await file.arrayBuffer();
// Save file to vault // Save file to vault
await this.app.vault.createBinary(localPath, arrayBuffer); await this.app.vault.createBinary(localPath, arrayBuffer);
@ -937,19 +930,15 @@ export default class GitSyncPlugin extends Plugin {
// Create directory if it doesn't exist // Create directory if it doesn't exist
const dirPath = localPath.substring(0, localPath.lastIndexOf('/')); const dirPath = localPath.substring(0, localPath.lastIndexOf('/'));
if (dirPath) { if (dirPath) {
try { await this.app.vault.adapter.mkdir(dirPath);
await this.app.vault.createFolder(dirPath);
} catch (error) {
// Folder might already exist, ignore error
}
} }
// Convert File to ArrayBuffer // Convert File to ArrayBuffer
const arrayBuffer = await file.arrayBuffer(); const arrayBuffer = await file.arrayBuffer();
// Save file to vault // Save file to vault
await this.app.vault.createBinary(localPath, arrayBuffer); await this.app.vault.createBinary(localPath, arrayBuffer);
debugLog('Local image copy saved:', localPath); debugLog('Local image copy saved:', localPath);
} catch (error) { } catch (error) {
console.warn('Failed to save local image copy:', error); console.warn('Failed to save local image copy:', error);
@ -968,7 +957,7 @@ class GitSyncSettingTab extends PluginSettingTab {
display(): void { display(): void {
const { containerEl } = this; const { containerEl } = this;
containerEl.empty(); containerEl.empty();
containerEl.createEl('h2', { text: t('settings.title') }); new Setting(containerEl).setName(t('settings.title')).setHeading();
// Language setting - put at the beginning // Language setting - put at the beginning
new Setting(containerEl) new Setting(containerEl)
@ -1037,7 +1026,7 @@ class GitSyncSettingTab extends PluginSettingTab {
// Set loading state // Set loading state
button.setButtonText(t('settings.test.url.loading')); button.setButtonText(t('settings.test.url.loading'));
button.setDisabled(true); (button as any).setDisabled(true);
try { try {
debugLog('=== Testing GitHub Connection ==='); debugLog('=== Testing GitHub Connection ===');
@ -1059,7 +1048,7 @@ class GitSyncSettingTab extends PluginSettingTab {
} finally { } finally {
// Reset button state // Reset button state
button.setButtonText(t('settings.test.url.button')); button.setButtonText(t('settings.test.url.button'));
button.setDisabled(false); (button as any).setDisabled(false);
} }
})); }));
@ -1075,10 +1064,7 @@ class GitSyncSettingTab extends PluginSettingTab {
})); }));
// Image processing main section // Image processing main section
containerEl.createEl('h2', { new Setting(containerEl).setName(t('settings.image.section.title')).setHeading();
text: t('settings.image.section.title'),
cls: 'git-sync-section-title'
});
// Enable image processing toggle // Enable image processing toggle
new Setting(containerEl) new Setting(containerEl)
@ -1096,10 +1082,7 @@ class GitSyncSettingTab extends PluginSettingTab {
// Only show image processing settings if enabled // Only show image processing settings if enabled
if (this.plugin.settings.enableImageProcessing) { if (this.plugin.settings.enableImageProcessing) {
// Cloud provider settings subsection // Cloud provider settings subsection
containerEl.createEl('h3', { new Setting(containerEl).setName(t('settings.cos.provider.section.title')).setHeading();
text: t('settings.cos.provider.section.title'),
cls: 'git-sync-subsection-title'
});
// Cloud storage provider // Cloud storage provider
new Setting(containerEl) new Setting(containerEl)
@ -1239,7 +1222,7 @@ class GitSyncSettingTab extends PluginSettingTab {
// Set loading state // Set loading state
button.setButtonText(t('settings.cos.test.loading')); button.setButtonText(t('settings.cos.test.loading'));
button.setDisabled(true); (button as any).setDisabled(true);
try { try {
const cosConfig = { const cosConfig = {
@ -1265,15 +1248,12 @@ class GitSyncSettingTab extends PluginSettingTab {
new Notice(t('cos.test.failed', { error: error.message })); new Notice(t('cos.test.failed', { error: error.message }));
} finally { } finally {
button.setButtonText(t('settings.cos.test.button')); button.setButtonText(t('settings.cos.test.button'));
button.setDisabled(false); (button as any).setDisabled(false);
} }
})); }));
// Image upload settings subsection // Image upload settings subsection
containerEl.createEl('h3', { new Setting(containerEl).setName(t('settings.image.upload.section.title')).setHeading();
text: t('settings.image.upload.section.title'),
cls: 'git-sync-subsection-title'
});
// Keep images locally // Keep images locally
new Setting(containerEl) new Setting(containerEl)
@ -1318,10 +1298,7 @@ class GitSyncSettingTab extends PluginSettingTab {
// Danger zone title // Danger zone title
containerEl.createEl('h2', { new Setting(containerEl).setName(t('settings.danger.zone.title')).setHeading();
text: t('settings.danger.zone.title'),
cls: 'danger-zone'
});
// Initialize repository // Initialize repository
new Setting(containerEl) new Setting(containerEl)
@ -1330,16 +1307,16 @@ class GitSyncSettingTab extends PluginSettingTab {
.addButton(button => { .addButton(button => {
const isVaultEmpty = this.isVaultEmpty(); const isVaultEmpty = this.isVaultEmpty();
button button
.setButtonText(t('settings.init.button')) .setButtonText(t('settings.init.button'));
.setDisabled(!isVaultEmpty) (button as any).setDisabled(!isVaultEmpty);
.onClick(async () => { button.onClick(async () => {
if (!this.plugin.settings.githubToken || !this.plugin.settings.repositoryUrl) { if (!this.plugin.settings.githubToken || !this.plugin.settings.repositoryUrl) {
new Notice(t('notice.config.required')); new Notice(t('notice.config.required'));
return; return;
} }
button.setButtonText(t('settings.init.loading')); button.setButtonText(t('settings.init.loading'));
button.setDisabled(true); (button as any).setDisabled(true);
try { try {
const result = await this.plugin.initializeRepository(); const result = await this.plugin.initializeRepository();
@ -1352,7 +1329,7 @@ class GitSyncSettingTab extends PluginSettingTab {
new Notice(t('notice.init.error')); new Notice(t('notice.init.error'));
} finally { } finally {
button.setButtonText(t('settings.init.button')); button.setButtonText(t('settings.init.button'));
button.setDisabled(!this.isVaultEmpty()); (button as any).setDisabled(!this.isVaultEmpty());
} }
}); });
@ -1375,7 +1352,7 @@ class GitSyncSettingTab extends PluginSettingTab {
} }
button.setButtonText(t('settings.sync.remote.to.local.loading')); button.setButtonText(t('settings.sync.remote.to.local.loading'));
button.setDisabled(true); (button as any).setDisabled(true);
try { try {
const result = await this.plugin.forceSyncRemoteToLocal(); const result = await this.plugin.forceSyncRemoteToLocal();
@ -1388,7 +1365,7 @@ class GitSyncSettingTab extends PluginSettingTab {
new Notice(t('notice.sync.error')); new Notice(t('notice.sync.error'));
} finally { } finally {
button.setButtonText(t('settings.sync.remote.to.local.button')); button.setButtonText(t('settings.sync.remote.to.local.button'));
button.setDisabled(false); (button as any).setDisabled(false);
} }
})); }));
@ -1406,7 +1383,7 @@ class GitSyncSettingTab extends PluginSettingTab {
} }
button.setButtonText(t('settings.sync.local.to.remote.loading')); button.setButtonText(t('settings.sync.local.to.remote.loading'));
button.setDisabled(true); (button as any).setDisabled(true);
try { try {
const result = await this.plugin.forceSyncLocalToRemote(); const result = await this.plugin.forceSyncLocalToRemote();
@ -1419,7 +1396,7 @@ class GitSyncSettingTab extends PluginSettingTab {
new Notice(t('notice.sync.error')); new Notice(t('notice.sync.error'));
} finally { } finally {
button.setButtonText(t('settings.sync.local.to.remote.button')); button.setButtonText(t('settings.sync.local.to.remote.button'));
button.setDisabled(false); (button as any).setDisabled(false);
} }
})); }));
@ -1440,10 +1417,7 @@ class GitSyncSettingTab extends PluginSettingTab {
})); }));
// Sponsor title // Sponsor title
containerEl.createEl('h2', { new Setting(containerEl).setName(t('settings.sponsor.section.title')).setHeading();
text: t('settings.sponsor.section.title'),
cls: 'sponsor'
});
// Sponsor section // Sponsor section
const sponsorSection = containerEl.createEl('div', { cls: 'setting-item' }); const sponsorSection = containerEl.createEl('div', { cls: 'setting-item' });

View file

@ -1,11 +1,11 @@
{ {
"id": "git-folder-sync", "id": "git-folder-sync",
"name": "Git Folder Sync", "name": "Git Folder Sync",
"version": "1.0.5", "version": "1.0.7",
"minAppVersion": "0.15.0", "minAppVersion": "0.15.0",
"description": "Synchronize files in your Obsidian Vault with a specified directory in the designated GitHub repository (rather than the entire repository); send your images to cloud storage services.", "description": "Synchronize files in your Vault with a specified directory in the designated GitHub repository (rather than the entire repository); send your images to cloud storage services.",
"author": "Xheldon", "author": "Xheldon",
"authorUrl": "https://github.com/Xheldon", "authorUrl": "https://github.com/Xheldon",
"fundingUrl": "https://paypal.me/xheldoncao", "fundingUrl": "https://paypal.me/xheldoncao",
"isDesktopOnly": false "isDesktopOnly": false
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "git-folder-sync", "name": "git-folder-sync",
"version": "1.0.5", "version": "1.0.7",
"description": "Synchronize files in your Obsidian Vault with a specified directory in the designated GitHub repository (rather than the entire repository); send your images to cloud storage services.", "description": "Synchronize files in your Obsidian Vault with a specified directory in the designated GitHub repository (rather than the entire repository); send your images to cloud storage services.",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View file

@ -4,5 +4,7 @@
"1.0.2": "0.15.0", "1.0.2": "0.15.0",
"1.0.3": "0.15.0", "1.0.3": "0.15.0",
"1.0.4": "0.15.0", "1.0.4": "0.15.0",
"1.0.5": "0.15.0" "1.0.5": "0.15.0",
"1.0.6": "0.15.0",
"1.0.7": "0.15.0"
} }