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

@@ -51,6 +51,7 @@ import {
PluginStoreService
} from '../../../domains/plugins';
import { getPluginInstallScope } from '../../../domains/plugins/domain/logic/plugin-install-scope.logic';
import { AppI18nService, APP_TRANSLATE_IMPORTS } from '../../../core/i18n';
@Component({
selector: 'app-title-bar',
@@ -60,7 +61,8 @@ import { getPluginInstallScope } from '../../../domains/plugins/domain/logic/plu
NgIcon,
LeaveServerDialogComponent,
ThemeNodeDirective,
ModalBackdropComponent
ModalBackdropComponent,
...APP_TRANSLATE_IMPORTS
],
viewProviders: [
provideIcons({ lucideMinus,
@@ -79,6 +81,7 @@ import { getPluginInstallScope } from '../../../domains/plugins/domain/logic/plu
* Electron-style title bar with window controls, navigation, and server menu.
*/
export class TitleBarComponent {
private readonly appI18n = inject(AppI18nService);
private store = inject(Store);
private electronBridge = inject(ElectronBridgeService);
private serverDirectory = inject(ServerDirectoryFacade);
@@ -99,8 +102,8 @@ export class TitleBarComponent {
showMenuState = computed(() => false);
currentUser = this.store.selectSignal(selectCurrentUser);
username = computed(() => this.currentUser()?.displayName || 'Guest');
serverName = computed(() => this.serverDirectory.activeServer()?.name || 'No Server');
username = computed(() => this.currentUser()?.displayName || this.appI18n.instant('shell.titleBar.guest'));
serverName = computed(() => this.serverDirectory.activeServer()?.name || this.appI18n.instant('shell.titleBar.noServer'));
isConnected = computed(() => this.webrtc.isConnected());
isReconnecting = computed(() => !this.webrtc.isConnected() && this.webrtc.hasEverConnected());
isAuthed = computed(() => !!this.currentUser());
@@ -131,7 +134,7 @@ export class TitleBarComponent {
const textChannels = this.textChannels();
if (textChannels.length === 0) {
return 'No text channels';
return this.appI18n.instant('shell.titleBar.noTextChannels');
}
const id = this.activeChannelId();
@@ -143,17 +146,17 @@ export class TitleBarComponent {
const voiceChannelId = this.currentUser()?.voiceState?.roomId;
const voiceChannel = this.voiceChannels().find((channel) => channel.id === voiceChannelId);
return voiceChannel?.name || 'Voice Lounge';
return voiceChannel?.name || this.appI18n.instant('shell.titleBar.voiceLounge');
});
roomContextMeta = computed(() => {
if (!this.currentRoom()) {
return '';
}
const parts = [`${this.textChannels().length} text`];
const parts = [this.appI18n.instant('shell.titleBar.textChannelCount', { count: this.textChannels().length })];
if (this.voiceChannels().length > 0) {
parts.push(`${this.voiceChannels().length} voice`);
parts.push(this.appI18n.instant('shell.titleBar.voiceChannelCount', { count: this.voiceChannels().length }));
}
return parts.join(' | ');
@@ -246,7 +249,7 @@ export class TitleBarComponent {
const result = await api.openDocusaurusDocs();
if (result && !result.opened) {
this.inviteStatus.set(result.reason ?? 'Unable to open documentation.');
this.inviteStatus.set(result.reason ?? this.appI18n.instant('shell.titleBar.docsOpenFailed'));
}
}
@@ -275,7 +278,7 @@ export class TitleBarComponent {
}
this.creatingInvite.set(true);
this.inviteStatus.set('Creating invite link...');
this.inviteStatus.set(this.appI18n.instant('shell.titleBar.creatingInvite'));
try {
const invite = await firstValueFrom(this.serverDirectory.createInvite(
@@ -289,11 +292,11 @@ export class TitleBarComponent {
));
await this.copyInviteLink(invite.inviteUrl);
this.inviteStatus.set('Invite link copied to clipboard.');
this.inviteStatus.set(this.appI18n.instant('shell.titleBar.inviteCopied'));
} catch (error: unknown) {
const inviteError = error as { error?: { error?: string } };
this.inviteStatus.set(inviteError?.error?.error || 'Unable to create invite link.');
this.inviteStatus.set(inviteError?.error?.error || this.appI18n.instant('shell.titleBar.inviteCreateFailed'));
} finally {
this.creatingInvite.set(false);
}
@@ -362,7 +365,7 @@ export class TitleBarComponent {
try {
await this.pluginStore.installServerRequirementsLocally(room.id, requirements, { activate: true });
} catch (error) {
this.pluginRequirementError.set(error instanceof Error ? error.message : 'Unable to install server plugin');
this.pluginRequirementError.set(error instanceof Error ? error.message : this.appI18n.instant('shell.titleBar.pluginInstallFailed'));
} finally {
this.pluginRequirementBusy.set(false);
}
@@ -413,7 +416,7 @@ export class TitleBarComponent {
document.body.removeChild(textarea);
}
window.prompt('Copy this invite link', inviteUrl);
window.prompt(this.appI18n.instant('shell.titleBar.copyInvitePrompt'), inviteUrl);
}
private toSourceSelector(room: Room): { sourceId?: string; sourceUrl?: string } {