Files
native/src/lib/files-drive.ts
T
Linus Rath 7b18063630 fix: stop a start-up crash, and stale views after sign-out or a new server
- The app crashed on every cold start whose cached folders held a
  shared or group folder, which on Stalwart 1.0 every group member has:
  the sidebar works out the accounts to span while it renders, before
  the session is up, and the JMAP client's account id throws until one
  is. The client now also names its account without throwing, for code
  that runs while rendering; the mail list's account helpers (the
  sidebar's accounts, a row's account, the viewer's pages) use it, and
  a read receipt sent by itself waits for the session. API calls still
  throw without a session.
- Signing out of the last account left the app on an empty mail view
  ("No mailboxes found") with nothing to retry: the account list was
  read before the account was removed, so the app switched to the
  account it had just signed out of, which did nothing. It is read
  again now, and the sign-in screen shows. A failed switch to the next
  account no longer puts the signed-out one back: when its server does
  not answer, that account shows offline, as on a cold start, and one
  whose sign-in is refused is skipped.
- After signing in with the same address on another server (another
  port) or on a server reinstalled at the address (0.16 to 1.0), Files
  kept showing the old server's drive without asking the new one, and
  actions on its rows would have used the old server's ids. The local
  account id leaves the port out and stays the same there, so the
  drive now also starts over when the server behind the session
  changes, and is read again with every new session. The account id
  itself is unchanged: it keys the stored credentials and every
  per-account cache, and changing it would sign such accounts out and
  orphan their data.
2026-09-26 01:44:47 +02:00

42 lines
1.8 KiB
TypeScript

import type { JMAPSession } from '../api/types';
import { sessionFingerprint } from './server-fingerprint';
/** The signed-in account and the server the Files drive on screen was read from. */
export interface DriveScope {
/** Local account id (username@host). */
account: string | null;
/** Fingerprint of the session it was read with (lib/server-fingerprint); null without one. */
server: string | null;
}
export type DriveAction =
/** First read, when the screen mounts. */
| 'load'
/** Start over: the nodes, the folder stack and the selection are another drive's. */
| 'reset'
/** Read again in place: a new session of the same server. */
| 'reload'
/** Leave it: the session was lost, there is nothing to read with. */
| 'keep';
/**
* What a change of the signed-in account or of its session means for the
* drive on screen. The local account id leaves the port out, and a server
* reinstalled at the same address (Stalwart 1.0 has no migration from 0.16)
* keeps it too; there the node ids name other files, and acting on the rows
* on screen would reach them. The session fingerprint tells those servers
* apart. Resolves to the action and the scope the drive then belongs to.
*/
export function driveChange(
loaded: DriveScope | undefined,
account: string | null,
session: JMAPSession | null,
): { action: DriveAction; scope: DriveScope } {
const server = session ? sessionFingerprint(session) : null;
if (!loaded) return { action: 'load', scope: { account, server } };
if (loaded.account !== account) return { action: 'reset', scope: { account, server } };
if (!server) return { action: 'keep', scope: loaded };
if (loaded.server && loaded.server !== server) return { action: 'reset', scope: { account, server } };
return { action: 'reload', scope: { account, server } };
}