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

@@ -6,12 +6,12 @@
appThemeNode="serversRailCreateButton"
type="button"
class="flex h-12 w-12 items-center justify-center overflow-hidden rounded-2xl bg-primary transition-[border-radius,background-color] duration-150 ease-out hover:rounded-xl hover:bg-primary/90 active:rounded-lg md:h-11 md:w-11"
title="Dashboard"
[title]="'serversRail.dashboard' | translate"
(click)="goToDashboard()"
>
<img
src="toju-icon.png"
alt="Toju"
[attr.alt]="'common.brand' | translate"
class="h-full w-full object-contain p-1"
/>
</button>
@@ -35,7 +35,7 @@
: 'bg-emerald-500/15 text-emerald-600 hover:bg-emerald-500/25'
"
[attr.data-testid]="'server-rail-call-' + call.callId"
title="Open private call"
[title]="'serversRail.openPrivateCall' | translate"
[attr.aria-current]="isSelectedCall($index) ? 'page' : null"
(click)="openCall(call.callId)"
>
@@ -121,7 +121,7 @@
@if (voicePresenceCount(room.id) > 0) {
<span
class="absolute -bottom-1 -right-1 flex h-4 w-4 items-center justify-center rounded-full bg-emerald-500 text-white shadow-sm ring-2 ring-card"
[title]="voicePresenceCount(room.id) + (voicePresenceCount(room.id) === 1 ? ' user in voice' : ' users in voice')"
[title]="voicePresenceTitle(room.id)"
>
<svg
viewBox="0 0 16 16"
@@ -150,8 +150,8 @@
type="button"
class="relative z-10 grid h-12 w-12 place-items-center rounded-xl bg-card text-emerald-500 transition-[border-radius,background-color,color] duration-150 ease-out hover:rounded-lg hover:bg-emerald-500 hover:text-white active:rounded-2xl md:h-11 md:w-11"
data-testid="server-rail-create"
title="Create a server"
aria-label="Create a server"
[title]="'serversRail.createServer' | translate"
[attr.aria-label]="'serversRail.createServer' | translate"
(click)="openCreateDialog()"
>
<ng-icon
@@ -190,7 +190,7 @@
(click)="toggleRoomNotifications()"
class="context-menu-item"
>
{{ isRoomNotificationsMuted(contextRoom()?.id || '') ? 'Unmute Notifications' : 'Mute Notifications' }}
{{ (isRoomNotificationsMuted(contextRoom()?.id || '') ? 'serversRail.unmuteNotifications' : 'serversRail.muteNotifications') | translate }}
</button>
<div class="context-menu-divider"></div>
<button
@@ -198,49 +198,49 @@
(click)="openLeaveConfirm()"
class="context-menu-item"
>
Leave Server
{{ 'serversRail.leaveServer' | translate }}
</button>
</app-context-menu>
}
@if (showBannedDialog()) {
<app-confirm-dialog
title="Banned"
confirmLabel="OK"
cancelLabel="Close"
[title]="'serversRail.banned.title' | translate"
[confirmLabel]="'common.ok' | translate"
[cancelLabel]="'common.close' | translate"
variant="danger"
[widthClass]="'w-96 max-w-[90vw]'"
(confirmed)="closeBannedDialog()"
(cancelled)="closeBannedDialog()"
>
<p>You are banned from {{ bannedServerName() || 'this server' }}.</p>
<p>{{ 'serversRail.banned.message' | translate: { server: bannedServerName() || ('common.thisServer' | translate) } }}</p>
</app-confirm-dialog>
}
@if (showPasswordDialog() && passwordPromptRoom()) {
<app-confirm-dialog
title="Password required"
confirmLabel="Join server"
cancelLabel="Cancel"
[title]="'serversRail.password.title' | translate"
[confirmLabel]="'serversRail.password.confirmLabel' | translate"
[cancelLabel]="'common.cancel' | translate"
[widthClass]="'w-[420px] max-w-[92vw]'"
(confirmed)="confirmPasswordJoin()"
(cancelled)="closePasswordDialog()"
>
<div class="space-y-3 text-left">
<p>Enter the password to rejoin {{ passwordPromptRoom()!.name }}.</p>
<p>{{ 'serversRail.password.prompt' | translate: { serverName: passwordPromptRoom()!.name } }}</p>
<div>
<label
for="rail-join-password"
class="mb-1 block text-xs font-medium uppercase tracking-wide text-muted-foreground"
>
Server password
{{ 'serversRail.password.label' | translate }}
</label>
<input
id="rail-join-password"
type="password"
[(ngModel)]="joinPassword"
placeholder="Enter password"
[placeholder]="'serversRail.password.placeholder' | translate"
class="w-full rounded-lg border border-border bg-secondary px-3 py-2 text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary"
/>
</div>

View File

@@ -45,6 +45,7 @@ import {
ContextMenuComponent,
LeaveServerDialogComponent
} from '../../../shared';
import { AppI18nService, APP_TRANSLATE_IMPORTS } from '../../../core/i18n';
const ACTIVATION_DEBOUNCE_MS = 150;
@@ -61,12 +62,14 @@ const ACTIVATION_DEBOUNCE_MS = 150;
DmRailComponent,
LeaveServerDialogComponent,
ThemeNodeDirective,
UserBarComponent
UserBarComponent,
...APP_TRANSLATE_IMPORTS
],
viewProviders: [provideIcons({ lucidePhone, lucidePlus })],
templateUrl: './servers-rail.component.html'
})
export class ServersRailComponent {
private readonly appI18n = inject(AppI18nService);
private store = inject(Store);
private router = inject(Router);
private voiceSession = inject(VoiceSessionFacade);
@@ -420,6 +423,15 @@ export class ServersRailComponent {
return this.voicePresenceByRoom()[roomId] ?? 0;
}
voicePresenceTitle(roomId: string): string {
const count = this.voicePresenceCount(roomId);
return this.appI18n.instant(
count === 1 ? 'serversRail.voicePresence.oneUser' : 'serversRail.voicePresence.manyUsers',
{ count }
);
}
formatUnreadCount(count: number): string {
return count > 99 ? '99+' : String(count);
}
@@ -627,7 +639,7 @@ export class ServersRailComponent {
status?: number;
};
const errorCode = serverError?.error?.errorCode;
const message = serverError?.error?.error || 'Failed to join server';
const message = serverError?.error?.error || this.appI18n.instant('serversRail.joinFailed');
if (errorCode === 'PASSWORD_REQUIRED') {
this.passwordPromptRoom.set(room);