chore: fix transcriptions page (#27)
This commit is contained in:
parent
b2cfe67b70
commit
f9a58ddfb5
6 changed files with 80 additions and 97 deletions
18
.vscode/launch.json
vendored
18
.vscode/launch.json
vendored
|
|
@ -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",
|
||||
|
|
|
|||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -3,5 +3,6 @@
|
|||
{
|
||||
"mode": "auto"
|
||||
}
|
||||
]
|
||||
],
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,18 +36,28 @@ export const TranscriptionsList: React.FC = () => {
|
|||
const [searchTerm, setSearchTerm] = useState("");
|
||||
|
||||
// tRPC React Query hooks
|
||||
const transcriptionsQuery = api.transcriptions.getTranscriptions.useQuery({
|
||||
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({
|
||||
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 */}
|
||||
|
|
|
|||
|
|
@ -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", {
|
||||
|
|
|
|||
|
|
@ -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) => {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue