feat(i18n): wire t() into SettingsTab.ts

This commit is contained in:
svemagie
2026-04-14 12:44:41 +02:00
parent 86fd568d96
commit 196aea2770
+48 -59
View File
@@ -15,6 +15,7 @@ import { App, Notice, PluginSettingTab, Setting } from "obsidian";
import type MicropubPlugin from "./main"; import type MicropubPlugin from "./main";
import { MicropubClient } from "./MicropubClient"; import { MicropubClient } from "./MicropubClient";
import { IndieAuth } from "./IndieAuth"; import { IndieAuth } from "./IndieAuth";
import { t } from "./i18n";
export class MicropubSettingsTab extends PluginSettingTab { export class MicropubSettingsTab extends PluginSettingTab {
constructor( constructor(
@@ -28,10 +29,10 @@ export class MicropubSettingsTab extends PluginSettingTab {
const { containerEl } = this; const { containerEl } = this;
containerEl.empty(); containerEl.empty();
containerEl.createEl("h2", { text: "Micropub Publisher" }); containerEl.createEl("h2", { text: t("settingsTitle") });
// ── Site URL + Sign In ─────────────────────────────────────────────── // ── Site URL + Sign In ───────────────────────────────────────────────
containerEl.createEl("h3", { text: "Account" }); containerEl.createEl("h3", { text: t("settingsAccount") });
// Show current sign-in status // Show current sign-in status
if (this.plugin.settings.me && this.plugin.settings.accessToken) { if (this.plugin.settings.me && this.plugin.settings.accessToken) {
@@ -41,16 +42,16 @@ export class MicropubSettingsTab extends PluginSettingTab {
} }
// ── Endpoints (collapsed / advanced) ──────────────────────────────── // ── Endpoints (collapsed / advanced) ────────────────────────────────
containerEl.createEl("h3", { text: "Endpoints" }); containerEl.createEl("h3", { text: t("settingsEndpoints") });
containerEl.createEl("p", { containerEl.createEl("p", {
text: "These are filled automatically when you sign in. Only edit them manually if your server uses non-standard paths.", text: t("settingsEndpointsHint"),
cls: "setting-item-description", cls: "setting-item-description",
}); });
new Setting(containerEl) new Setting(containerEl)
.setName("Micropub endpoint") .setName(t("settingMicropubEndpoint"))
.setDesc("e.g. https://blog.giersig.eu/micropub") .setDesc(t("settingMicropubEndpointDesc"))
.addText((text) => .addText((text) =>
text text
.setPlaceholder("https://example.com/micropub") .setPlaceholder("https://example.com/micropub")
@@ -62,8 +63,8 @@ export class MicropubSettingsTab extends PluginSettingTab {
); );
new Setting(containerEl) new Setting(containerEl)
.setName("Media endpoint") .setName(t("settingMediaEndpoint"))
.setDesc("For image uploads. Auto-discovered if blank.") .setDesc(t("settingMediaEndpointDesc"))
.addText((text) => .addText((text) =>
text text
.setPlaceholder("https://example.com/micropub/media") .setPlaceholder("https://example.com/micropub/media")
@@ -75,16 +76,16 @@ export class MicropubSettingsTab extends PluginSettingTab {
); );
// ── Publish behaviour ──────────────────────────────────────────────── // ── Publish behaviour ────────────────────────────────────────────────
containerEl.createEl("h3", { text: "Publish Behaviour" }); containerEl.createEl("h3", { text: t("settingsPublishBehaviour") });
new Setting(containerEl) new Setting(containerEl)
.setName("Default visibility") .setName(t("settingVisibility"))
.setDesc("Applies when the note has no explicit visibility property.") .setDesc(t("settingVisibilityDesc"))
.addDropdown((drop) => .addDropdown((drop) =>
drop drop
.addOption("public", "Public") .addOption("public", t("visibilityPublic"))
.addOption("unlisted", "Unlisted") .addOption("unlisted", t("visibilityUnlisted"))
.addOption("private", "Private") .addOption("private", t("visibilityPrivate"))
.setValue(this.plugin.settings.defaultVisibility) .setValue(this.plugin.settings.defaultVisibility)
.onChange(async (value) => { .onChange(async (value) => {
this.plugin.settings.defaultVisibility = value as this.plugin.settings.defaultVisibility = value as
@@ -96,11 +97,8 @@ export class MicropubSettingsTab extends PluginSettingTab {
); );
new Setting(containerEl) new Setting(containerEl)
.setName("Write URL back to note") .setName(t("settingWriteUrl"))
.setDesc( .setDesc(t("settingWriteUrlDesc"))
"After publishing, store the post URL as `mp-url` in frontmatter. " +
"Subsequent publishes will update the existing post instead of creating a new one.",
)
.addToggle((toggle) => .addToggle((toggle) =>
toggle toggle
.setValue(this.plugin.settings.writeUrlToFrontmatter) .setValue(this.plugin.settings.writeUrlToFrontmatter)
@@ -111,16 +109,13 @@ export class MicropubSettingsTab extends PluginSettingTab {
); );
new Setting(containerEl) new Setting(containerEl)
.setName("Syndication dialog") .setName(t("settingSyndDialog"))
.setDesc( .setDesc(t("settingSyndDialogDesc"))
"When to show the cross-posting dialog before publishing. " +
"'When needed' shows it only if the note has no mp-syndicate-to frontmatter.",
)
.addDropdown((drop) => .addDropdown((drop) =>
drop drop
.addOption("when-needed", "When needed") .addOption("when-needed", t("syndDialogWhenNeeded"))
.addOption("always", "Always") .addOption("always", t("syndDialogAlways"))
.addOption("never", "Never") .addOption("never", t("syndDialogNever"))
.setValue(this.plugin.settings.showSyndicationDialog) .setValue(this.plugin.settings.showSyndicationDialog)
.onChange(async (value) => { .onChange(async (value) => {
this.plugin.settings.showSyndicationDialog = value as this.plugin.settings.showSyndicationDialog = value as
@@ -134,16 +129,16 @@ export class MicropubSettingsTab extends PluginSettingTab {
// Show configured defaults with a clear button // Show configured defaults with a clear button
const defaults = this.plugin.settings.defaultSyndicateTo; const defaults = this.plugin.settings.defaultSyndicateTo;
const defaultsSetting = new Setting(containerEl) const defaultsSetting = new Setting(containerEl)
.setName("Default syndication targets") .setName(t("settingSyndDefaults"))
.setDesc( .setDesc(
defaults.length > 0 defaults.length > 0
? defaults.join(", ") ? defaults.join(", ")
: "None configured. Targets checked by default in the publish dialog.", : t("settingSyndDefaultsNone"),
); );
if (defaults.length > 0) { if (defaults.length > 0) {
defaultsSetting.addButton((btn) => defaultsSetting.addButton((btn) =>
btn btn
.setButtonText("Clear defaults") .setButtonText(t("btnClearDefaults"))
.setWarning() .setWarning()
.onClick(async () => { .onClick(async () => {
this.plugin.settings.defaultSyndicateTo = []; this.plugin.settings.defaultSyndicateTo = [];
@@ -154,14 +149,11 @@ export class MicropubSettingsTab extends PluginSettingTab {
} }
// ── Digital Garden ─────────────────────────────────────────────────── // ── Digital Garden ───────────────────────────────────────────────────
containerEl.createEl("h3", { text: "Digital Garden" }); containerEl.createEl("h3", { text: t("settingsDigitalGarden") });
new Setting(containerEl) new Setting(containerEl)
.setName("Map #garden/* tags to gardenStage") .setName(t("settingGardenTags"))
.setDesc( .setDesc(t("settingGardenTagsDesc"))
"Obsidian tags like #garden/plant become a `garden-stage: plant` Micropub " +
"property. The blog renders these as growth stage badges at /garden/.",
)
.addToggle((toggle) => .addToggle((toggle) =>
toggle toggle
.setValue(this.plugin.settings.mapGardenTags) .setValue(this.plugin.settings.mapGardenTags)
@@ -172,7 +164,7 @@ export class MicropubSettingsTab extends PluginSettingTab {
); );
containerEl.createEl("p", { containerEl.createEl("p", {
text: "Stages: plant 🌱 · cultivate 🌿 · question ❓ · repot 🪴 · revitalize ✨ · revisit 🔄", text: t("settingGardenStages"),
cls: "setting-item-description", cls: "setting-item-description",
}); });
} }
@@ -182,14 +174,11 @@ export class MicropubSettingsTab extends PluginSettingTab {
private renderSignedOut(containerEl: HTMLElement): void { private renderSignedOut(containerEl: HTMLElement): void {
// Site URL input + Sign In button on the same row // Site URL input + Sign In button on the same row
new Setting(containerEl) new Setting(containerEl)
.setName("Site URL") .setName(t("settingSiteUrl"))
.setDesc( .setDesc(t("settingSiteUrlDesc"))
"Your site's home page. Clicking Sign in opens your blog's login page " +
"in the browser — the same flow iA Writer uses.",
)
.addText((text) => .addText((text) =>
text text
.setPlaceholder("https://blog.giersig.eu") .setPlaceholder(t("settingSiteUrlPlaceholder"))
.setValue(this.plugin.settings.siteUrl) .setValue(this.plugin.settings.siteUrl)
.onChange(async (value) => { .onChange(async (value) => {
this.plugin.settings.siteUrl = value.trim(); this.plugin.settings.siteUrl = value.trim();
@@ -198,17 +187,17 @@ export class MicropubSettingsTab extends PluginSettingTab {
) )
.addButton((btn) => { .addButton((btn) => {
btn btn
.setButtonText("Sign in") .setButtonText(t("btnSignIn"))
.setCta() .setCta()
.onClick(async () => { .onClick(async () => {
const siteUrl = this.plugin.settings.siteUrl.trim(); const siteUrl = this.plugin.settings.siteUrl.trim();
if (!siteUrl) { if (!siteUrl) {
new Notice("Enter your site URL first."); new Notice(t("noticeEnterSiteUrl"));
return; return;
} }
btn.setDisabled(true); btn.setDisabled(true);
btn.setButtonText("Opening browser"); btn.setButtonText(t("btnOpeningBrowser"));
try { try {
const result = await IndieAuth.signIn(siteUrl); const result = await IndieAuth.signIn(siteUrl);
@@ -245,12 +234,12 @@ export class MicropubSettingsTab extends PluginSettingTab {
} }
} }
new Notice(`✅ Signed in as ${result.me}`); new Notice(t("noticeSignedInAs", { me: result.me }));
this.display(); // Refresh to show signed-in state this.display(); // Refresh to show signed-in state
} catch (err: unknown) { } catch (err: unknown) {
new Notice(`Sign-in failed: ${String(err)}`, 8000); new Notice(t("noticeSignInFailed", { error: String(err) }), 8000);
btn.setDisabled(false); btn.setDisabled(false);
btn.setButtonText("Sign in"); btn.setButtonText(t("btnSignIn"));
} }
}); });
}); });
@@ -258,15 +247,15 @@ export class MicropubSettingsTab extends PluginSettingTab {
// Divider + manual token fallback (collapsed by default) // Divider + manual token fallback (collapsed by default)
const details = containerEl.createEl("details"); const details = containerEl.createEl("details");
details.createEl("summary", { details.createEl("summary", {
text: "Or paste a token manually", text: t("manualTokenSummary"),
cls: "setting-item-description", cls: "setting-item-description",
}); });
details.style.marginTop = "8px"; details.style.marginTop = "8px";
details.style.marginBottom = "8px"; details.style.marginBottom = "8px";
new Setting(details) new Setting(details)
.setName("Access token") .setName(t("settingAccessToken"))
.setDesc("Bearer token from your Indiekit admin panel.") .setDesc(t("settingAccessTokenDesc"))
.addText((text) => { .addText((text) => {
text text
.setPlaceholder("your-bearer-token") .setPlaceholder("your-bearer-token")
@@ -278,12 +267,12 @@ export class MicropubSettingsTab extends PluginSettingTab {
text.inputEl.type = "password"; text.inputEl.type = "password";
}) })
.addButton((btn) => .addButton((btn) =>
btn.setButtonText("Verify").onClick(async () => { btn.setButtonText(t("btnVerify")).onClick(async () => {
if ( if (
!this.plugin.settings.micropubEndpoint || !this.plugin.settings.micropubEndpoint ||
!this.plugin.settings.accessToken !this.plugin.settings.accessToken
) { ) {
new Notice("Set the Micropub endpoint and token first."); new Notice(t("noticeSetEndpointFirst"));
return; return;
} }
btn.setDisabled(true); btn.setDisabled(true);
@@ -294,9 +283,9 @@ export class MicropubSettingsTab extends PluginSettingTab {
() => this.plugin.settings.accessToken, () => this.plugin.settings.accessToken,
); );
await client.fetchConfig(); await client.fetchConfig();
new Notice("✅ Token is valid!"); new Notice(t("noticeTokenValid"));
} catch (err: unknown) { } catch (err: unknown) {
new Notice(`Token check failed: ${String(err)}`); new Notice(t("noticeTokenCheckFailed", { error: String(err) }));
} finally { } finally {
btn.setDisabled(false); btn.setDisabled(false);
} }
@@ -327,7 +316,7 @@ export class MicropubSettingsTab extends PluginSettingTab {
const info = banner.createDiv(); const info = banner.createDiv();
info.createEl("div", { info.createEl("div", {
text: "Signed in", text: t("lblSignedIn"),
attr: { style: "font-size:.75rem;color:var(--text-muted);margin-bottom:2px" }, attr: { style: "font-size:.75rem;color:var(--text-muted);margin-bottom:2px" },
}); });
info.createEl("div", { info.createEl("div", {
@@ -336,7 +325,7 @@ export class MicropubSettingsTab extends PluginSettingTab {
}); });
new Setting(containerEl) new Setting(containerEl)
.setName("Site URL") .setName(t("settingSiteUrl"))
.addText((text) => .addText((text) =>
text text
.setValue(this.plugin.settings.siteUrl) .setValue(this.plugin.settings.siteUrl)
@@ -344,7 +333,7 @@ export class MicropubSettingsTab extends PluginSettingTab {
) )
.addButton((btn) => .addButton((btn) =>
btn btn
.setButtonText("Sign out") .setButtonText(t("btnSignOut"))
.setWarning() .setWarning()
.onClick(async () => { .onClick(async () => {
this.plugin.settings.accessToken = ""; this.plugin.settings.accessToken = "";