precompute call waveforms and stop list-time audio loading
This commit is contained in:
@@ -103,6 +103,7 @@ type CommItem = {
|
||||
text: string;
|
||||
audioUrl?: string;
|
||||
duration?: string;
|
||||
waveform?: number[];
|
||||
transcript?: string[];
|
||||
deliveryStatus?: "PENDING" | "SENT" | "DELIVERED" | "READ" | "FAILED" | string | null;
|
||||
};
|
||||
@@ -1262,6 +1263,19 @@ function parseDurationToSeconds(raw?: string) {
|
||||
}
|
||||
|
||||
function buildCallWavePeaks(item: CommItem, size = 320) {
|
||||
const stored = Array.isArray(item.waveform)
|
||||
? item.waveform.map((value) => Number(value)).filter((value) => Number.isFinite(value) && value > 0)
|
||||
: [];
|
||||
if (stored.length) {
|
||||
const sampled = new Float32Array(size);
|
||||
for (let i = 0; i < size; i += 1) {
|
||||
const t = size <= 1 ? 0 : i / (size - 1);
|
||||
const idx = Math.min(stored.length - 1, Math.round(t * (stored.length - 1)));
|
||||
sampled[i] = Math.max(0.05, Math.min(1, stored[idx] ?? 0.05));
|
||||
}
|
||||
return sampled;
|
||||
}
|
||||
|
||||
const source = `${item.text} ${(item.transcript ?? []).join(" ")}`.trim() || item.contact;
|
||||
let seed = 0;
|
||||
for (let i = 0; i < source.length; i += 1) {
|
||||
@@ -1295,7 +1309,6 @@ async function ensureCommCallWave(itemId: string) {
|
||||
|
||||
const callItem = visibleThreadItems.value.find((item) => item.id === itemId && item.kind === "call");
|
||||
if (!callItem) return;
|
||||
const audioUrl = getCallAudioUrl(callItem);
|
||||
|
||||
const { WaveSurfer } = await loadWaveSurferModules();
|
||||
const durationSeconds =
|
||||
@@ -1314,12 +1327,7 @@ async function ensureCommCallWave(itemId: string) {
|
||||
barWidth: 0,
|
||||
});
|
||||
|
||||
try {
|
||||
if (!audioUrl) throw new Error("missing_audio_url");
|
||||
await ws.load(audioUrl);
|
||||
} catch {
|
||||
await ws.load("", [peaks], durationSeconds);
|
||||
}
|
||||
await ws.load("", [peaks], durationSeconds);
|
||||
commCallWaveSurfers.set(itemId, ws);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ query CommunicationsQuery {
|
||||
text
|
||||
audioUrl
|
||||
duration
|
||||
waveform
|
||||
transcript
|
||||
deliveryStatus
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ query GetClientTimelineQuery($contactId: ID!, $limit: Int) {
|
||||
text
|
||||
audioUrl
|
||||
duration
|
||||
waveform
|
||||
transcript
|
||||
deliveryStatus
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "ContactMessage" ADD COLUMN "waveformJson" JSONB;
|
||||
|
||||
@@ -166,6 +166,7 @@ model ContactMessage {
|
||||
content String
|
||||
audioUrl String?
|
||||
durationSec Int?
|
||||
waveformJson Json?
|
||||
transcriptJson Json?
|
||||
occurredAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@ -633,6 +633,9 @@ async function getCommunications(auth: AuthContext | null) {
|
||||
text: m.content,
|
||||
audioUrl: resolveContactMessageAudioUrl(m),
|
||||
duration: m.durationSec ? new Date(m.durationSec * 1000).toISOString().slice(14, 19) : "",
|
||||
waveform: Array.isArray(m.waveformJson)
|
||||
? m.waveformJson.map((value) => Number(value)).filter((value) => Number.isFinite(value))
|
||||
: [],
|
||||
transcript: Array.isArray(m.transcriptJson) ? ((m.transcriptJson as any) as string[]) : [],
|
||||
deliveryStatus: resolveDeliveryStatus(m),
|
||||
}));
|
||||
@@ -953,6 +956,9 @@ async function getClientTimeline(auth: AuthContext | null, contactIdInput: strin
|
||||
text: m.content,
|
||||
audioUrl: resolveContactMessageAudioUrl(m),
|
||||
duration: m.durationSec ? new Date(m.durationSec * 1000).toISOString().slice(14, 19) : "",
|
||||
waveform: Array.isArray(m.waveformJson)
|
||||
? m.waveformJson.map((value) => Number(value)).filter((value) => Number.isFinite(value))
|
||||
: [],
|
||||
transcript: Array.isArray(m.transcriptJson) ? ((m.transcriptJson as any) as string[]) : [],
|
||||
deliveryStatus: resolveDeliveryStatus(m),
|
||||
},
|
||||
@@ -2014,6 +2020,7 @@ export const crmGraphqlSchema = buildSchema(`
|
||||
text: String!
|
||||
audioUrl: String!
|
||||
duration: String!
|
||||
waveform: [Float!]!
|
||||
transcript: [String!]!
|
||||
deliveryStatus: String
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user