fix: Mobile style fixes and other small ui fixes

This commit is contained in:
2026-05-18 23:14:16 +02:00
parent afb64520ed
commit 94428ed170
32 changed files with 808 additions and 239 deletions

View File

@@ -2,7 +2,6 @@
import {
Component,
DestroyRef,
Type,
computed,
effect,
inject,
@@ -36,6 +35,7 @@ import { RoomsActions } from '../../../store/rooms/rooms.actions';
import { DatabaseService } from '../../../infrastructure/persistence';
import { NotificationsFacade } from '../../../domains/notifications';
import { DirectCallService, DirectCallSession } from '../../../domains/direct-call';
import { DmRailComponent } from '../../../domains/direct-message/feature/dm-rail/dm-rail.component';
import { type ServerInfo, ServerDirectoryFacade } from '../../../domains/server-directory';
import { ThemeNodeDirective } from '../../../domains/theme';
import { hasRoomBanForUser } from '../../../domains/access-control';
@@ -54,6 +54,7 @@ import {
NgIcon,
ConfirmDialogComponent,
ContextMenuComponent,
DmRailComponent,
LeaveServerDialogComponent,
ThemeNodeDirective,
UserBarComponent
@@ -71,12 +72,12 @@ export class ServersRailComponent {
private serverDirectory = inject(ServerDirectoryFacade);
private destroyRef = inject(DestroyRef);
private banLookupRequestVersion = 0;
private visibleSavedRoomCache: Room[] = [];
private savedRoomJoinRequests = new Subject<{ room: Room; password?: string }>();
savedRooms = this.store.selectSignal(selectSavedRooms);
currentRoom = this.store.selectSignal(selectCurrentRoom);
showMenu = signal(false);
dmRailComponent = signal<Type<unknown> | null>(null);
menuX = signal(72);
menuY = signal(100);
contextRoom = signal<Room | null>(null);
@@ -95,9 +96,9 @@ export class ServersRailComponent {
isOnDirectMessage = toSignal(
this.router.events.pipe(
filter((navigationEvent): navigationEvent is NavigationEnd => navigationEvent instanceof NavigationEnd),
map((navigationEvent) => navigationEvent.urlAfterRedirects.startsWith('/dm/') || navigationEvent.urlAfterRedirects.startsWith('/pm/'))
map((navigationEvent) => this.isDirectMessageUrl(navigationEvent.urlAfterRedirects))
),
{ initialValue: this.router.url.startsWith('/dm/') || this.router.url.startsWith('/pm/') }
{ initialValue: this.isDirectMessageUrl(this.router.url) }
);
isOnCall = toSignal(
this.router.events.pipe(
@@ -139,7 +140,7 @@ export class ServersRailComponent {
passwordPromptRoom = signal<Room | null>(null);
joinPassword = signal('');
joinPasswordError = signal<string | null>(null);
visibleSavedRooms = computed(() => this.savedRooms().filter((room) => !this.isRoomMarkedBanned(room)));
visibleSavedRooms = computed(() => this.stabilizeVisibleSavedRooms(this.savedRooms().filter((room) => !this.isRoomMarkedBanned(room))));
voicePresenceByRoom = computed(() => {
const presence: Record<string, number> = {};
const seenByRoom = new Map<string, Set<string>>();
@@ -182,10 +183,6 @@ export class ServersRailComponent {
});
constructor() {
void import('../../../domains/direct-message/feature/dm-rail/dm-rail.component').then((module) => {
this.dmRailComponent.set(module.DmRailComponent);
});
effect(() => {
const rooms = this.savedRooms();
const currentUser = this.currentUser();
@@ -237,6 +234,7 @@ export class ServersRailComponent {
}
joinSavedRoom(room: Room): void {
const targetRoom = this.savedRooms().find((savedRoom) => savedRoom.id === room.id) ?? room;
const currentUserId = localStorage.getItem('metoyou_currentUserId');
if (!currentUserId) {
@@ -244,20 +242,20 @@ export class ServersRailComponent {
return;
}
if (this.isRoomMarkedBanned(room)) {
this.bannedServerName.set(room.name);
if (this.isRoomMarkedBanned(targetRoom)) {
this.bannedServerName.set(targetRoom.name);
this.showBannedDialog.set(true);
return;
}
this.optimisticSelectedRoomId.set(room.id);
this.activateSavedRoom(room);
this.savedRoomJoinRequests.next({ room });
this.optimisticSelectedRoomId.set(targetRoom.id);
this.activateSavedRoom(targetRoom);
this.savedRoomJoinRequests.next({ room: targetRoom });
}
openCall(callId: string): void {
this.optimisticSelectedRoomId.set(null);
void this.router.navigate(['/call', callId]);
void this.directCalls.openCallView(callId);
}
isSelectedCall(callIndex: number): boolean {
@@ -392,17 +390,46 @@ export class ServersRailComponent {
}
isSelectedRoom(room: Room): boolean {
if (this.isOnDirectMessage() || this.isOnCall()) {
return false;
}
const optimisticRoomId = this.optimisticSelectedRoomId();
if (optimisticRoomId) {
return optimisticRoomId === room.id;
}
if (this.isOnDirectMessage() || this.isOnCall()) {
return false;
return this.currentRoom()?.id === room.id;
}
private stabilizeVisibleSavedRooms(nextRooms: Room[]): Room[] {
const previousById = new Map(this.visibleSavedRoomCache.map((room) => [room.id, room]));
const stabilizedRooms = nextRooms.map((room) => {
const previousRoom = previousById.get(room.id);
return previousRoom && this.hasSameRailRoomView(previousRoom, room) ? previousRoom : room;
});
if (
stabilizedRooms.length === this.visibleSavedRoomCache.length
&& stabilizedRooms.every((room, index) => room === this.visibleSavedRoomCache[index])
) {
return this.visibleSavedRoomCache;
}
return this.currentRoom()?.id === room.id;
this.visibleSavedRoomCache = stabilizedRooms;
return stabilizedRooms;
}
private hasSameRailRoomView(previousRoom: Room, nextRoom: Room): boolean {
return previousRoom.id === nextRoom.id && previousRoom.name === nextRoom.name && previousRoom.icon === nextRoom.icon;
}
private isDirectMessageUrl(url: string): boolean {
const path = url.split(/[?#]/, 1)[0];
return path === '/dm' || path.startsWith('/dm/') || path === '/pm' || path.startsWith('/pm/');
}
private async refreshBannedLookup(rooms: Room[], currentUser: User | null): Promise<void> {