main f6d8405

+page.svelte RawHistoryFolder

1<script lang="ts">
2	import { onMount } from 'svelte';
3	import { browser } from '$app/environment';
4	import ChatRoomsWindow from '$lib/components/desktop/chat-rooms-window.svelte';
5	import DesktopIcons from '$lib/components/desktop-icons.svelte';
6	import Taskbar from '$lib/components/desktop/taskbar.svelte';
7	import BuddyList from '$lib/components/desktop/buddy-list.svelte';
8	import ImWindow from '$lib/components/desktop/im-window.svelte';
9	import SignOnWindow from '$lib/components/desktop/sign-on-window.svelte';
10	import ProfileWindow from '$lib/components/desktop/profile-window.svelte';
11	import AwayWindow from '$lib/components/desktop/away-window.svelte';
12	import NewRoomWindow from '$lib/components/desktop/new-room-window.svelte';
13	import AboutWindow from '$lib/components/desktop/about-window.svelte';
14	import PreferencesWindow from '$lib/components/desktop/preferences-window.svelte';
15	import {
16		desktop,
17		CHAT_WINDOW_ID,
18		type ImWindowProps,
19		type ProfileWindowProps
20	} from '$lib/states/desktop.svelte';
21	import { chatState } from '$lib/states/chat.svelte';
22
23	const props = $props();
24	const pageData = $derived(props.data);
25
26	const currentUser = $derived(chatState.getCurrentUser());
27
28	// Initial desktop layout: the General room, plus the buddy list when signed in.
29	onMount(() => {
30		if (!browser) return;
31		desktop.openChatRoom(null, 'General');
32		if (pageData.user) {
33			desktop.openBuddyList();
34		} else {
35			desktop.openLogin('signin');
36		}
37		desktop.focus(CHAT_WINDOW_ID);
38	});
39
40	// When the session appears (login) make sure the buddy list is around;
41	// when it disappears (logout) close private windows.
42	let lastUserId: string | null = null;
43	$effect(() => {
44		const id = currentUser?.id ?? null;
45		if (id === lastUserId) return;
46		lastUserId = id;
47		if (id) {
48			if (!desktop.has('buddy-list')) desktop.openBuddyList();
49		} else {
50			for (const w of desktop.windows) {
51				if (w.kind === 'im' || w.kind === 'buddy-list' || w.kind === 'away') desktop.close(w.id);
52			}
53		}
54	});
55
56	function onDesktopClick(e: MouseEvent) {
57		if (e.target === e.currentTarget) desktop.blurAll();
58	}
59</script>
60
61<div
62	class="desktop"
63	class:signing-on={desktop.signingOn}
64	onmousedown={onDesktopClick}
65	role="presentation"
66>
67	<DesktopIcons />
68
69	{#each desktop.windows as win (win.id)}
70		{#if win.kind === 'chat-room'}
71			<ChatRoomsWindow initialTextStyle={pageData.textStyle} />
72		{:else if win.kind === 'buddy-list'}
73			<BuddyList />
74		{:else if win.kind === 'im'}
75			{@const p = win.props as unknown as ImWindowProps}
76			<ImWindow roomId={p.roomId} otherUserId={p.otherUserId} otherNickname={p.otherNickname} />
77		{:else if win.kind === 'login'}
78			<SignOnWindow tab={(win.props.tab as 'signin' | 'signup') ?? 'signin'} />
79		{:else if win.kind === 'profile'}
80			{@const p = win.props as unknown as ProfileWindowProps}
81			<ProfileWindow userId={p.userId} nickname={p.nickname} />
82		{:else if win.kind === 'away'}
83			<AwayWindow />
84		{:else if win.kind === 'new-room'}
85			<NewRoomWindow />
86		{:else if win.kind === 'about'}
87			<AboutWindow />
88		{:else if win.kind === 'preferences'}
89			<PreferencesWindow />
90		{/if}
91	{/each}
92
93	<Taskbar />
94</div>
95
96<style>
97	.desktop {
98		position: absolute;
99		inset: 0;
100		box-sizing: border-box;
101		overflow: hidden;
102	}
103</style>

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 3

Tags 8

↑↓ moveenter openesc close