feat: Rename to Toju and add translation
Some checks failed
Deploy Web Apps / deploy (push) Successful in 5m52s
Build Android APK / build-android-apk (push) Failing after 23m15s
Queue Release Build / prepare (push) Successful in 1m42s
Queue Release Build / build-linux (push) Failing after 9m33s
Queue Release Build / build-windows (push) Successful in 26m5s
Queue Release Build / finalize (push) Has been skipped

This commit is contained in:
2026-06-05 17:13:03 +02:00
parent 8ecfc9a1fe
commit ee293d7daf
301 changed files with 8247 additions and 2218 deletions

View File

@@ -8,7 +8,7 @@
<button
type="button"
class="inline-flex h-11 w-11 flex-shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground md:h-8 md:w-8"
aria-label="Back to settings"
aria-label="{{ 'plugins.manager.backToSettings' | translate }}"
(click)="close()"
>
<ng-icon
@@ -32,7 +32,7 @@
name="lucidePlay"
size="16"
/>
Activate ready plugins
{{ 'plugins.manager.activateReady' | translate }}
</button>
<button
type="button"
@@ -43,14 +43,14 @@
name="lucideStore"
size="16"
/>
Open Plugin Store
{{ 'plugins.manager.openStore' | translate }}
</button>
</div>
</header>
<nav
class="no-scrollbar flex gap-2 overflow-x-auto border-b border-border px-3 py-2 md:px-4"
aria-label="Plugin manager sections"
aria-label="{{ 'plugins.manager.sectionsAria' | translate }}"
>
<button
type="button"
@@ -62,7 +62,7 @@
name="lucidePackage"
size="16"
/>
Installed
{{ 'plugins.manager.tabs.installed' | translate }}
</button>
<button
type="button"
@@ -74,7 +74,7 @@
name="lucideSettings"
size="16"
/>
Extension points
{{ 'plugins.manager.tabs.extensions' | translate }}
</button>
<button
type="button"
@@ -86,7 +86,7 @@
name="lucideShield"
size="16"
/>
Requirements
{{ 'plugins.manager.tabs.requirements' | translate }}
</button>
<button
type="button"
@@ -98,7 +98,7 @@
name="lucideSettings"
size="16"
/>
Settings
{{ 'plugins.manager.tabs.settings' | translate }}
</button>
<button
type="button"
@@ -110,7 +110,7 @@
name="lucidePackage"
size="16"
/>
Docs
{{ 'plugins.manager.tabs.docs' | translate }}
</button>
<button
type="button"
@@ -122,7 +122,7 @@
name="lucideBug"
size="16"
/>
Logs
{{ 'plugins.manager.tabs.logs' | translate }}
</button>
</nav>
@@ -134,20 +134,7 @@
class="grid gap-3 md:grid-cols-2 xl:grid-cols-4"
data-testid="plugin-extension-counts"
>
@for (
item of [
{ label: 'Settings pages', value: extensionCounts().settingsPages },
{ label: 'App pages', value: extensionCounts().appPages },
{ label: 'Side panels', value: extensionCounts().sidePanels },
{ label: 'Channel sections', value: extensionCounts().channelSections },
{ label: 'Composer actions', value: extensionCounts().composerActions },
{ label: 'Profile actions', value: extensionCounts().profileActions },
{ label: 'Toolbar actions', value: extensionCounts().toolbarActions },
{ label: 'Slash commands', value: extensionCounts().slashCommands },
{ label: 'Embed renderers', value: extensionCounts().embeds }
];
track item.label
) {
@for (item of extensionCountItems(); track item.label) {
<article class="rounded-lg border border-border bg-card p-3">
<p class="text-sm text-muted-foreground">{{ item.label }}</p>
<p class="mt-2 text-2xl font-semibold">{{ item.value }}</p>
@@ -159,17 +146,19 @@
class="rounded-lg border border-border bg-card p-4"
data-testid="plugin-conflict-diagnostics"
>
<h3 class="text-sm font-semibold">Conflict diagnostics</h3>
<h3 class="text-sm font-semibold">{{ 'plugins.manager.conflicts.title' | translate }}</h3>
@if (uiConflicts().length === 0) {
<p class="mt-2 text-sm text-muted-foreground">
No duplicate route, action, embed, channel, panel, or settings contribution ids detected.
{{ 'plugins.manager.conflicts.none' | translate }}
</p>
} @else {
<div class="mt-3 space-y-2">
@for (conflict of uiConflicts(); track conflict.kind + conflict.contributionId) {
<div class="rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-sm">
<span class="font-medium">{{ conflict.kind }} / {{ conflict.contributionId }}</span>
<span class="text-muted-foreground"> conflicts in {{ conflict.pluginIds.join(', ') }}</span>
<span class="text-muted-foreground">
{{ 'plugins.manager.conflicts.conflictsIn' | translate: { plugins: conflict.pluginIds.join(', ') } }}
</span>
</div>
}
</div>
@@ -184,7 +173,7 @@
>
@if (requirementComparisons().length === 0) {
<p class="rounded-lg border border-border bg-card p-4 text-sm text-muted-foreground">
No server plugin requirements for the current room.
{{ 'plugins.manager.requirements.empty' | translate }}
</p>
} @else {
@for (comparison of requirementComparisons(); track comparison.pluginId) {
@@ -197,9 +186,13 @@
<span class="rounded bg-muted px-2 py-1 text-xs text-muted-foreground">{{ comparison.status }}</span>
</div>
@if (comparison.requirement) {
<p class="mt-3 text-sm text-muted-foreground">Server status: {{ comparison.requirement.status }}</p>
<p class="mt-3 text-sm text-muted-foreground">
{{ 'plugins.manager.requirements.serverStatus' | translate: { status: comparison.requirement.status } }}
</p>
@if (comparison.requirement.versionRange) {
<p class="mt-1 text-sm text-muted-foreground">Version range: {{ comparison.requirement.versionRange }}</p>
<p class="mt-1 text-sm text-muted-foreground">
{{ 'plugins.manager.requirements.versionRange' | translate: { range: comparison.requirement.versionRange } }}
</p>
}
@if (comparison.requirement.reason) {
<p class="mt-1 text-sm text-muted-foreground">{{ comparison.requirement.reason }}</p>
@@ -229,7 +222,7 @@
</div>
<section class="rounded-lg border border-border bg-card p-3 md:p-4">
@if (selectedPlugin(); as plugin) {
<h3 class="text-sm font-semibold">{{ plugin.manifest.title }} settings</h3>
<h3 class="text-sm font-semibold">{{ plugin.manifest.title }} {{ 'plugins.manager.settings.settingsSuffix' | translate }}</h3>
@if (selectedSettingsPages().length > 0) {
<div class="mt-4 space-y-3">
@for (page of selectedSettingsPages(); track page.id) {
@@ -243,7 +236,7 @@
@if (selectedSettingsSchema()) {
<pre class="mt-3 max-h-[420px] overflow-auto rounded-md bg-muted p-3 text-xs">{{ selectedSettingsSchema() | json }}</pre>
} @else {
<p class="mt-2 text-sm text-muted-foreground">This plugin does not declare a settings schema.</p>
<p class="mt-2 text-sm text-muted-foreground">{{ 'plugins.manager.settings.noSchema' | translate }}</p>
}
}
</section>
@@ -289,7 +282,7 @@
@case ('logs') {
<div class="space-y-3">
@if (!selectedPlugin()) {
<p class="text-sm text-muted-foreground">No plugins installed.</p>
<p class="text-sm text-muted-foreground">{{ 'plugins.manager.logs.noPlugins' | translate }}</p>
} @else {
<div class="flex flex-wrap gap-2">
@for (entry of entries(); track trackEntry($index, entry)) {
@@ -305,7 +298,7 @@
</div>
<div class="rounded-lg border border-border bg-card">
@if (selectedLogs().length === 0) {
<p class="p-4 text-sm text-muted-foreground">No logs for selected plugin.</p>
<p class="p-4 text-sm text-muted-foreground">{{ 'plugins.manager.logs.noLogs' | translate }}</p>
} @else {
@for (log of selectedLogs(); track log.timestamp) {
<div class="border-b border-border px-4 py-3 last:border-b-0">
@@ -360,7 +353,7 @@
class="inline-flex min-h-11 items-center justify-center gap-1.5 rounded-md border border-border px-2 text-sm hover:bg-muted md:h-8 md:min-h-0"
(click)="selectPlugin(entry.manifest.id)"
>
Select
{{ 'plugins.manager.installed.select' | translate }}
</button>
<button
type="button"
@@ -371,7 +364,7 @@
[name]="entry.enabled ? 'lucideX' : 'lucideCheck'"
size="14"
/>
{{ entry.enabled ? 'Disable' : 'Enable' }}
{{ (entry.enabled ? 'plugins.manager.installed.disable' : 'plugins.manager.installed.enable') | translate }}
</button>
<button
type="button"
@@ -383,7 +376,7 @@
name="lucidePlay"
size="14"
/>
Activate
{{ 'plugins.manager.installed.activate' | translate }}
</button>
<button
type="button"
@@ -395,7 +388,7 @@
name="lucideRefreshCw"
size="14"
/>
Reload
{{ 'plugins.manager.installed.reload' | translate }}
</button>
<button
type="button"
@@ -407,7 +400,7 @@
name="lucideX"
size="14"
/>
Unload
{{ 'plugins.manager.installed.unload' | translate }}
</button>
</div>
</div>
@@ -426,17 +419,17 @@
name="lucideShield"
size="18"
/>
<h3 class="text-sm font-semibold">Capabilities</h3>
<h3 class="text-sm font-semibold">{{ 'plugins.manager.capabilities.title' | translate }}</h3>
</div>
@if ((plugin.manifest.capabilities?.length ?? 0) === 0) {
<p class="mt-3 text-sm text-muted-foreground">Plugin requests no capabilities.</p>
<p class="mt-3 text-sm text-muted-foreground">{{ 'plugins.manager.capabilities.none' | translate }}</p>
} @else {
<button
type="button"
class="mt-3 min-h-11 rounded-md border border-border px-3 text-sm hover:bg-muted md:h-8 md:min-h-0"
(click)="grantAll(plugin)"
>
Grant all requested
{{ 'plugins.manager.capabilities.grantAll' | translate }}
</button>
<div class="mt-3 space-y-2">
@for (capability of plugin.manifest.capabilities; track trackCapability($index, capability)) {
@@ -453,7 +446,9 @@
</div>
}
@if (missingCapabilities().length > 0) {
<p class="mt-3 text-xs text-muted-foreground">Missing: {{ missingCapabilities().join(', ') }}</p>
<p class="mt-3 text-xs text-muted-foreground">
{{ 'plugins.manager.capabilities.missing' | translate: { capabilities: missingCapabilities().join(', ') } }}
</p>
}
}
</aside>