feat(m5d): demand-driven deep backfill + per-user ETA
Per-user opt-in to full-history (deep) backfill so a new user's unique channels no longer trigger a big shared-quota burst. - migration 0007: Subscription.deep_requested (default false); seed admins' existing subscriptions to preserve today's global-backfill behaviour - run_deep_backfill is now demand-driven: only channels at least one user has requested are deep-backfilled; recent backfill stays unconditional (cheap) - estimate_deep_backfill ETA helper (quota-bound) surfaced in /api/sync/my-status - POST /api/sync/deep-all to opt all my channels in; PATCH channels accepts deep_requested - UI: per-channel Full history toggle, Backfill everything action, deep progress + ETA in Channels header and Settings - Sync
This commit is contained in:
parent
ba2abf5019
commit
6eb78b9475
9 changed files with 256 additions and 18 deletions
|
|
@ -34,6 +34,19 @@ export function formatDuration(sec: number | null): string {
|
|||
return h > 0 ? `${h}:${pad(m)}:${pad(s)}` : `${m}:${pad(s)}`;
|
||||
}
|
||||
|
||||
/** Coarse, human ETA for a remaining duration in seconds ("~3 hours", "~2 days"). */
|
||||
export function formatEta(seconds: number): string {
|
||||
if (seconds <= 0) return "done";
|
||||
const hours = seconds / 3600;
|
||||
if (hours < 1) return "< 1 hour";
|
||||
if (hours < 24) {
|
||||
const h = Math.round(hours);
|
||||
return `~${h} hour${h === 1 ? "" : "s"}`;
|
||||
}
|
||||
const d = Math.round(hours / 24);
|
||||
return `~${d} day${d === 1 ? "" : "s"}`;
|
||||
}
|
||||
|
||||
export function formatViews(n: number | null): string {
|
||||
if (n == null) return "";
|
||||
if (n >= 1e9) return `${(n / 1e9).toFixed(1).replace(/\.0$/, "")}B`;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue