recappi 0.1.68 → 0.1.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2007,6 +2007,7 @@ function AppShell({
2007
2007
  const [selected, setSelected] = useState8(0);
2008
2008
  const [spinnerFrame, setSpinnerFrame] = useState8(0);
2009
2009
  const [loadingMoreRecordings, setLoadingMoreRecordings] = useState8(false);
2010
+ const [loaded, setLoaded] = useState8(false);
2010
2011
  const [loadError, setLoadError] = useState8(void 0);
2011
2012
  const [notice, setNotice] = useState8(void 0);
2012
2013
  const [summaryCache, setSummaryCache] = useState8(() => /* @__PURE__ */ new Map());
@@ -2246,6 +2247,7 @@ function AppShell({
2246
2247
  } else {
2247
2248
  setAccountStatus("error");
2248
2249
  }
2250
+ setLoaded(true);
2249
2251
  }, [fetchJobs, fetchRecordings, fetchDashboardStats, fetchAccountStatus]);
2250
2252
  const transcribeStoppedRecording = useCallback(async () => {
2251
2253
  const current = liveRecord;
@@ -2446,10 +2448,10 @@ function AppShell({
2446
2448
  }, [refresh, pollMs]);
2447
2449
  const hasRunning = jobs.some((item) => item.status === "running");
2448
2450
  useEffect4(() => {
2449
- if (!hasRunning) return;
2451
+ if (!hasRunning && loaded) return;
2450
2452
  const id = setInterval(() => setSpinnerFrame((f) => f + 1), spinnerMs);
2451
2453
  return () => clearInterval(id);
2452
- }, [hasRunning, spinnerMs]);
2454
+ }, [hasRunning, loaded, spinnerMs]);
2453
2455
  const jobRank = (s) => s === "running" ? 4 : s === "queued" ? 3 : s === "failed" ? 2 : s === "succeeded" ? 1 : 0;
2454
2456
  const jobStatusByRecording = /* @__PURE__ */ new Map();
2455
2457
  for (const job of jobs) {
@@ -2682,12 +2684,12 @@ function AppShell({
2682
2684
  }
2683
2685
  if (screen.kind === "jobDetail") {
2684
2686
  const job = jobs.find((j) => j.jobId === screen.jobId);
2685
- if (!job) return /* @__PURE__ */ jsx19(Missing, { label: "Job" });
2687
+ if (!job) return !loaded ? /* @__PURE__ */ jsx19(Loading, { label: "job" }) : /* @__PURE__ */ jsx19(Missing, { label: "Job" });
2686
2688
  return /* @__PURE__ */ jsx19(Detail, { notice, children: /* @__PURE__ */ jsx19(JobDetailView, { item: job, origin, spinnerFrame, nowMs: now() }) });
2687
2689
  }
2688
2690
  if (screen.kind === "recordingDetail") {
2689
2691
  const rec = recordings.find((r) => r.recordingId === screen.recordingId);
2690
- if (!rec) return /* @__PURE__ */ jsx19(Missing, { label: "Recording" });
2692
+ if (!rec) return !loaded ? /* @__PURE__ */ jsx19(Loading, { label: "recording" }) : /* @__PURE__ */ jsx19(Missing, { label: "Recording" });
2691
2693
  const detailTranscript = rec.activeTranscriptId ? transcriptCache.get(rec.activeTranscriptId) : void 0;
2692
2694
  return /* @__PURE__ */ jsx19(Detail, { notice, children: /* @__PURE__ */ jsx19(
2693
2695
  RecordingDetailView,
@@ -2754,7 +2756,14 @@ function AppShell({
2754
2756
  const tab = screen.kind === "jobs" ? "jobs" : screen.kind === "account" ? "account" : "overview";
2755
2757
  let body;
2756
2758
  let position = "";
2757
- if (screen.kind === "overview") {
2759
+ if (!loaded) {
2760
+ position = "";
2761
+ const spin = "\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F"[spinnerFrame % 10];
2762
+ body = /* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsxs16(Text17, { color: "cyan", children: [
2763
+ spin,
2764
+ " Loading\u2026"
2765
+ ] }) });
2766
+ } else if (screen.kind === "overview") {
2758
2767
  const listBudget = Math.max(3, size.rows - 6);
2759
2768
  const buckets = recordings.map((r) => dateBucket(r.createdAt, now()));
2760
2769
  const win = groupedListWindow(buckets, selected, listBudget);
@@ -2830,6 +2839,13 @@ function Missing({ label }) {
2830
2839
  /* @__PURE__ */ jsx19(Text17, { dimColor: true, children: "esc back \xB7 q quit" })
2831
2840
  ] });
2832
2841
  }
2842
+ function Loading({ label }) {
2843
+ return /* @__PURE__ */ jsx19(Box17, { paddingX: 1, children: /* @__PURE__ */ jsxs16(Text17, { color: "cyan", children: [
2844
+ "Loading ",
2845
+ label,
2846
+ "\u2026"
2847
+ ] }) });
2848
+ }
2833
2849
  var RECORDINGS_PAGE_SIZE, RECORDINGS_PREFETCH_REMAINING;
2834
2850
  var init_AppShell = __esm({
2835
2851
  "src/tui/AppShell.tsx"() {
@@ -17895,6 +17911,9 @@ var jobDataSchema = external_exports.object({
17895
17911
  model: external_exports.string().optional(),
17896
17912
  language: external_exports.string().nullable().optional(),
17897
17913
  progressPercent: external_exports.number().min(0).max(100).nullable().optional(),
17914
+ claimExpiresAt: external_exports.number().int().nullable().optional(),
17915
+ lastHeartbeatAt: external_exports.number().int().nullable().optional(),
17916
+ heartbeatPhase: external_exports.string().nullable().optional(),
17898
17917
  processedDurationMs: external_exports.number().int().nonnegative().nullable().optional(),
17899
17918
  recording: external_exports.object({
17900
17919
  title: external_exports.string().nullable().optional(),
@@ -17921,6 +17940,8 @@ var jobListItemSchema = external_exports.object({
17921
17940
  enqueuedAt: external_exports.number().int().nullable().optional(),
17922
17941
  startedAt: external_exports.number().int().nullable().optional(),
17923
17942
  finishedAt: external_exports.number().int().nullable().optional(),
17943
+ claimExpiresAt: external_exports.number().int().nullable().optional(),
17944
+ lastHeartbeatAt: external_exports.number().int().nullable().optional(),
17924
17945
  processedDurationMs: external_exports.number().int().nonnegative().nullable().optional(),
17925
17946
  heartbeatPhase: external_exports.string().nullable().optional(),
17926
17947
  recording: external_exports.object({
@@ -19560,6 +19581,9 @@ var RecappiApiClient = class {
19560
19581
  ...typeof parsed.model === "string" ? { model: parsed.model } : {},
19561
19582
  ...typeof parsed.language === "string" || parsed.language === null ? { language: parsed.language } : {},
19562
19583
  ...progressPercent !== void 0 ? { progressPercent } : {},
19584
+ ...typeof parsed.claimExpiresAt === "number" || parsed.claimExpiresAt === null ? { claimExpiresAt: parsed.claimExpiresAt } : {},
19585
+ ...typeof parsed.lastHeartbeatAt === "number" || parsed.lastHeartbeatAt === null ? { lastHeartbeatAt: parsed.lastHeartbeatAt } : {},
19586
+ ...typeof parsed.heartbeatPhase === "string" || parsed.heartbeatPhase === null ? { heartbeatPhase: parsed.heartbeatPhase } : {},
19563
19587
  ...processedDurationMs !== void 0 ? { processedDurationMs } : {},
19564
19588
  ...recording ? {
19565
19589
  recording: {
@@ -19824,6 +19848,8 @@ function mapJobListItem(row) {
19824
19848
  ...typeof row.enqueuedAt === "number" || row.enqueuedAt === null ? { enqueuedAt: row.enqueuedAt } : {},
19825
19849
  ...typeof row.startedAt === "number" || row.startedAt === null ? { startedAt: row.startedAt } : {},
19826
19850
  ...typeof row.finishedAt === "number" || row.finishedAt === null ? { finishedAt: row.finishedAt } : {},
19851
+ ...typeof row.claimExpiresAt === "number" || row.claimExpiresAt === null ? { claimExpiresAt: row.claimExpiresAt } : {},
19852
+ ...typeof row.lastHeartbeatAt === "number" || row.lastHeartbeatAt === null ? { lastHeartbeatAt: row.lastHeartbeatAt } : {},
19827
19853
  ...typeof row.processedDurationMs === "number" || row.processedDurationMs === null ? { processedDurationMs: row.processedDurationMs } : {},
19828
19854
  ...typeof row.heartbeatPhase === "string" || row.heartbeatPhase === null ? { heartbeatPhase: row.heartbeatPhase } : {},
19829
19855
  recording: {