Add resumable uploads, proxy discovery, PWA install and 2 GiB personal vaults

This commit is contained in:
2026-10-12 15:54:26 +09:00
parent 439c2ae61b
commit 464715aa69
43 changed files with 1647 additions and 137 deletions

View File

@@ -515,15 +515,8 @@ export class Accounts {
: null,
};
}
used(userId: string) {
const db = this.service.db;
const owned = db
.select()
.from(s.files)
.where(and(eq(s.files.ownerUserId, userId), inArray(s.files.status, ['stored', 'cleaning'])))
.all();
const accounted = new Map(owned.map((f) => [f.id, f.size]));
const preserved = db
vaultFiles(userId: string) {
const rows = this.service.db
.select({ file: s.files })
.from(s.access)
.innerJoin(s.items, eq(s.access.itemId, s.items.id))
@@ -531,14 +524,31 @@ export class Accounts {
.where(
and(
eq(s.access.userId, userId),
or(eq(s.access.favorite, true), eq(s.access.role, 'self')),
inArray(s.access.role, ['self', 'recipient']),
isNull(s.access.deletedAt),
gt(s.items.expiresAt, Date.now()),
eq(s.files.status, 'stored'),
),
)
.all();
for (const { file } of preserved) accounted.set(file.id, file.size);
return [...accounted.values()].reduce((a, b) => a + b, 0);
return new Map(rows.map(({ file }) => [file.id, file.size]));
}
used(userId: string) {
return [...this.vaultFiles(userId).values()].reduce((sum, bytes) => sum + bytes, 0);
}
canStoreFile(userId: string, file: typeof s.files.$inferSelect) {
const files = this.vaultFiles(userId);
if (files.has(file.id)) return true;
const reserved = this.service.db
.select()
.from(s.reservations)
.where(and(eq(s.reservations.userId, userId), gt(s.reservations.expiresAt, Date.now())))
.all()
.reduce((sum, row) => sum + row.bytes, 0);
return (
[...files.values()].reduce((sum, bytes) => sum + bytes, 0) + reserved + file.size <=
this.service.cfg.userQuota
);
}
ensureQuota(userId: string, bytes: number) {
if (this.used(userId) + bytes > this.service.cfg.userQuota)