chore: fix transcriptions page (#27)

This commit is contained in:
Haritabh 2025-06-28 11:36:55 +05:30 committed by GitHub
parent b2cfe67b70
commit f9a58ddfb5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 80 additions and 97 deletions

18
.vscode/launch.json vendored
View file

@ -1,23 +1,5 @@
{
"configurations": [
{
"type": "swift",
"request": "launch",
"args": [],
"cwd": "${workspaceFolder:amical}/packages/native-helpers/swift-helper",
"name": "Debug KeyTapHelper (packages/native-helpers/swift-helper)",
"program": "${workspaceFolder:amical}/packages/native-helpers/swift-helper/.build/debug/KeyTapHelper",
"preLaunchTask": "swift: Build Debug KeyTapHelper (packages/native-helpers/swift-helper)"
},
{
"type": "swift",
"request": "launch",
"args": [],
"cwd": "${workspaceFolder:amical}/packages/native-helpers/swift-helper",
"name": "Release KeyTapHelper (packages/native-helpers/swift-helper)",
"program": "${workspaceFolder:amical}/packages/native-helpers/swift-helper/.build/release/KeyTapHelper",
"preLaunchTask": "swift: Build Release KeyTapHelper (packages/native-helpers/swift-helper)"
},
{
"type": "swift",
"request": "launch",

View file

@ -3,5 +3,6 @@
{
"mode": "auto"
}
]
],
"editor.formatOnSave": true
}

View file

@ -36,18 +36,28 @@ export const TranscriptionsList: React.FC = () => {
const [searchTerm, setSearchTerm] = useState("");
// tRPC React Query hooks
const transcriptionsQuery = api.transcriptions.getTranscriptions.useQuery({
limit: 50,
offset: 0,
sortBy: "timestamp",
sortOrder: "desc",
search: searchTerm || undefined,
});
const transcriptionsQuery = api.transcriptions.getTranscriptions.useQuery(
{
limit: 50,
offset: 0,
sortBy: "timestamp",
sortOrder: "desc",
search: searchTerm || undefined,
},
{
refetchInterval: 2000, // Poll every 2 seconds, auto-pauses when out of focus
},
);
const transcriptionsCountQuery =
api.transcriptions.getTranscriptionsCount.useQuery({
search: searchTerm || undefined,
});
api.transcriptions.getTranscriptionsCount.useQuery(
{
search: searchTerm || undefined,
},
{
refetchInterval: 2000, // Poll every 2 seconds, auto-pauses when out of focus
},
);
const utils = api.useUtils();
@ -110,14 +120,6 @@ export const TranscriptionsList: React.FC = () => {
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<div></div>
<div className="flex items-center space-x-2">
<Button variant="outline">Export All</Button>
<Button>New Recording</Button>
</div>
</div>
{/* Search and Filter Bar */}
<div className="flex items-center space-x-4">
<div className="relative flex-1 max-w-sm">
@ -129,10 +131,6 @@ export const TranscriptionsList: React.FC = () => {
className="pl-10"
/>
</div>
<Button variant="outline" size="sm">
<Filter className="h-4 w-4 mr-2" />
Filter
</Button>
</div>
{/* Transcriptions Grid */}

View file

@ -351,6 +351,35 @@ app.on("ready", async () => {
hasResult: !!transcription,
});
// Save transcription to database
if (
transcription &&
typeof transcription === "string" &&
transcription.trim().length > 0
) {
try {
const { createTranscription } = await import(
"../db/transcriptions.js"
);
const savedTranscription = await createTranscription({
text: transcription,
timestamp: new Date(),
audioFile: filePath,
language: "en", // Default to English, could be made configurable
});
logger.db.info("Transcription saved to database", {
transcriptionId: savedTranscription.id,
textLength: transcription.length,
audioFile: filePath,
});
} catch (dbError) {
logError(
dbError instanceof Error ? dbError : new Error(String(dbError)),
"saving transcription to database",
);
}
}
// Copy transcription to clipboard
if (transcription && typeof transcription === "string") {
logger.main.info("Transcription pasted to active application");
@ -421,7 +450,7 @@ app.on("ready", async () => {
});
});
transcriptionSession.on("session-completed", (sessionResult) => {
transcriptionSession.on("session-completed", async (sessionResult) => {
logger.ai.info("Transcription session completed", {
sessionId: sessionResult.sessionId,
finalTextLength: sessionResult.finalText.length,
@ -429,15 +458,40 @@ app.on("ready", async () => {
totalProcessingTimeMs: sessionResult.totalProcessingTimeMs,
});
// Paste the final result to active application
// Save chunk-based transcription to database
if (
sessionResult.finalText &&
sessionResult.finalText.trim().length > 0
) {
try {
const { createTranscription } = await import(
"../db/transcriptions.js"
);
const savedTranscription = await createTranscription({
text: sessionResult.finalText,
timestamp: new Date(),
audioFile: null, // Chunk-based transcriptions don't have a single audio file
language: "en", // Default to English, could be made configurable
});
logger.db.info("Chunk-based transcription saved to database", {
transcriptionId: savedTranscription.id,
sessionId: sessionResult.sessionId,
textLength: sessionResult.finalText.length,
totalChunks: sessionResult.chunkResults.length,
});
} catch (dbError) {
logError(
dbError instanceof Error ? dbError : new Error(String(dbError)),
"saving chunk-based transcription to database",
);
}
// Paste the final result to active application
logger.main.info(
"Final transcription pasted to active application",
{
textLength: sessionResult.finalText.length,
sessionId: sessionResult.sessionId,
},
);
swiftIOBridgeClientInstance!.call("pasteText", {

View file

@ -92,29 +92,7 @@ const api: ElectronAPI = {
setFormatterConfig: (config: FormatterConfig) =>
ipcRenderer.invoke("set-formatter-config", config),
// Transcription Database API
getTranscriptions: (options?: {
limit?: number;
offset?: number;
sortBy?: "timestamp" | "createdAt";
sortOrder?: "asc" | "desc";
search?: string;
}) => ipcRenderer.invoke("get-transcriptions", options),
getTranscriptionById: (id: number) =>
ipcRenderer.invoke("get-transcription-by-id", id),
createTranscription: (
data: Omit<NewTranscription, "id" | "createdAt" | "updatedAt">,
) => ipcRenderer.invoke("create-transcription", data),
updateTranscription: (
id: number,
data: Partial<Omit<Transcription, "id" | "createdAt">>,
) => ipcRenderer.invoke("update-transcription", id, data),
deleteTranscription: (id: number) =>
ipcRenderer.invoke("delete-transcription", id),
getTranscriptionsCount: (search?: string) =>
ipcRenderer.invoke("get-transcriptions-count", search),
searchTranscriptions: (searchTerm: string, limit?: number) =>
ipcRenderer.invoke("search-transcriptions", searchTerm, limit),
// Transcription Database API (moved to tRPC)
// Vocabulary Database API
on: (channel: string, callback: (...args: any[]) => void) => {

View file

@ -52,37 +52,7 @@ export interface ElectronAPI {
config: import("../modules/formatter").FormatterConfig,
) => Promise<void>;
// Transcription Database API
getTranscriptions: (options?: {
limit?: number;
offset?: number;
sortBy?: "timestamp" | "createdAt";
sortOrder?: "asc" | "desc";
search?: string;
}) => Promise<import("../db/schema").Transcription[]>;
getTranscriptionById: (
id: number,
) => Promise<import("../db/schema").Transcription | null>;
createTranscription: (
data: Omit<
import("../db/schema").NewTranscription,
"id" | "createdAt" | "updatedAt"
>,
) => Promise<import("../db/schema").Transcription>;
updateTranscription: (
id: number,
data: Partial<
Omit<import("../db/schema").Transcription, "id" | "createdAt">
>,
) => Promise<import("../db/schema").Transcription | null>;
deleteTranscription: (
id: number,
) => Promise<import("../db/schema").Transcription | null>;
getTranscriptionsCount: (search?: string) => Promise<number>;
searchTranscriptions: (
searchTerm: string,
limit?: number,
) => Promise<import("../db/schema").Transcription[]>;
// Transcription Database API (moved to tRPC)
on: (channel: string, callback: (...args: any[]) => void) => void;
off: (channel: string, callback: (...args: any[]) => void) => void;