v0.1.1 88fcae1

+server.ts RawHistoryFolder

1import { error } from '@sveltejs/kit';
2import { sseEmitter } from '$lib/sseEmitter';
3import db from '$lib/db/db.server';
4import { users } from '$lib/db/schema';
5import { eq } from 'drizzle-orm';
6import { validateSessionToken, generateSessionToken, createSession } from '$lib/api/session.server';
7import { setSessionTokenCookie } from '$lib/api/session.cookie';
8
9export async function POST({ request, cookies, locals }) {
10    if (!locals.user) {
11        throw error(401, 'Authentication required');
12    }
13
14    const { status } = await request.json();
15    const validStatuses = ['online', 'away', 'busy', 'offline'];
16    if (!validStatuses.includes(status)) {
17        throw error(400, 'Invalid status');
18    }
19
20    const userId = locals.user.id;
21    console.debug('Updating status for user', userId, 'to', status);
22
23    // Update the user status in the database
24    await db.update(users)
25        .set({ status, lastSeen: status === 'offline' ? Date.now() : null })
26        .where(eq(users.id, userId));
27    console.debug('Status updated in database');
28
29    // Renew session if status is online and session is near expiry
30    if (status === 'online') {
31        const token = cookies.get('session');
32        if (token) {
33            const result = await validateSessionToken(token);
34            if (result.session) {
35                const now = Date.now();
36                const remaining = result.session.expiresAt - now;
37                const threshold = 15 * 60 * 1000; // 15 minutes in milliseconds
38                if (remaining < threshold) {
39                    const newToken = generateSessionToken();
40                    const newSession = await createSession(newToken, userId);
41                    setSessionTokenCookie({ cookies }, newToken, newSession.expiresAt);
42                    console.debug('Session renewed for user', userId);
43                }
44            }
45        }
46    }
47
48    // Broadcast the status update via SSE
49    sseEmitter.emit('sse', { type: 'userStatusUpdate', data: { userId, status, lastSeen: status === 'offline' ? Date.now() : null } });
50
51    return new Response(JSON.stringify({ success: true }), { status: 200, headers: { 'Content-Type': 'application/json' } });
52}

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