From ca0566b838f6be033d6ee0ae9efeff14435344b2 Mon Sep 17 00:00:00 2001 From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com> Date: Wed, 16 Oct 2024 01:51:19 +0300 Subject: [PATCH] feat: add docx format --- README.md | 2 +- desktop/bun.lockb | Bin 182968 -> 190161 bytes desktop/package.json | 1 + desktop/src/components/FormatSelect.tsx | 10 +++--- desktop/src/components/HtmlView.tsx | 9 +++-- desktop/src/components/TextArea.tsx | 27 +++++++++++---- desktop/src/lib/docx.ts | 43 ++++++++++++++++++++++++ desktop/src/pages/batch/viewModel.tsx | 17 ++++++++-- 8 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 desktop/src/lib/docx.ts diff --git a/README.md b/README.md index 724e33be..8ade54c2 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ - 🎙️ Transcribe audio / video - 🎶 Option to transcribe audio from popular websites (YouTube, Vimeo, Facebook, Twitter and more!) - 📂 Batch transcribe multiple files! -- 📝 Support `SRT`, `VTT`, `TXT`, `HTML`, `PDF`, `JSON` formats +- 📝 Support `SRT`, `VTT`, `TXT`, `HTML`, `PDF`, `JSON`, `DOCX` formats - 👀 Realtime preview - ✨ Summarize transcripts: Get concise summaries of transcripts via Claude API integration - 🌐 Translate to English from any language diff --git a/desktop/bun.lockb b/desktop/bun.lockb index 907e49cc79674834a84dd2ef07f979b772ebdc06..021bc212fe066df2a5e04ed4fce5d38dd89dc131 100755 GIT binary patch delta 27504 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 delta 23322 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 R^@_4! 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 I+YK)Ge=yP*egFUf diff --git a/desktop/package.json b/desktop/package.json index ee82c4fa..e1f5309e 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -25,6 +25,7 @@ "@tauri-apps/plugin-store": "^2.0.0", "@tauri-apps/plugin-updater": "^2.0.0", "@tauri-apps/plugin-window-state": "^2.0.0", + "docx": "^9.0.2", "format-duration": "^3.0.2", "i18next": "^23.14.0", "i18next-resources-to-backend": "^1.2.1", diff --git a/desktop/src/components/FormatSelect.tsx b/desktop/src/components/FormatSelect.tsx index 33c0fbd3..b3f402fd 100644 --- a/desktop/src/components/FormatSelect.tsx +++ b/desktop/src/components/FormatSelect.tsx @@ -1,7 +1,7 @@ import { Dispatch, SetStateAction } from 'react' import { useTranslation } from 'react-i18next' -export type TextFormat = 'normal' | 'srt' | 'vtt' | 'html' | 'pdf' | 'json' +export type TextFormat = 'normal' | 'srt' | 'vtt' | 'html' | 'pdf' | 'json' | 'docx' export type FormatExtensions = { [name in TextFormat]: string } @@ -12,6 +12,7 @@ export const formatExtensions: FormatExtensions = { html: '.html', pdf: '.pdf', json: '.json', + docx: '.docx', } interface FormatSelectProps { @@ -32,9 +33,10 @@ export default function FormatSelect({ format, setFormat }: FormatSelectProps) { }} className="select select-bordered"> - - - + + + + ) diff --git a/desktop/src/components/HtmlView.tsx b/desktop/src/components/HtmlView.tsx index 22755e3e..6f14fb5d 100644 --- a/desktop/src/components/HtmlView.tsx +++ b/desktop/src/components/HtmlView.tsx @@ -9,10 +9,15 @@ interface HTMLViewProps { preference: Preference } -function formatDuration(start: number, stop: number) { +export function formatDuration(start: number, stop: number, direction: 'rtl' | 'ltr' = 'ltr') { const startFmt = formatTimestamp(start, false, '', false) const stopFmt = formatTimestamp(stop, false, '', false) - return `${startFmt} --> ${stopFmt}` + const duration = `${startFmt} --> ${stopFmt}` + + if (direction === 'rtl') { + return `\u202B${duration}\u202C` // Use Unicode characters for right-to-left embedding + } + return duration } export default function HTMLView({ segments, file, preference }: HTMLViewProps) { diff --git a/desktop/src/components/TextArea.tsx b/desktop/src/components/TextArea.tsx index e4660a09..a310250d 100644 --- a/desktop/src/components/TextArea.tsx +++ b/desktop/src/components/TextArea.tsx @@ -14,6 +14,8 @@ import HTMLView from './HtmlView' import toast from 'react-hot-toast' import { invoke } from '@tauri-apps/api/core' import * as clipboard from '@tauri-apps/plugin-clipboard-manager' +import { toDocx } from '~/lib/docx' +import { path } from '@tauri-apps/api' function Copy({ text }: { text: string }) { const { t } = useTranslation() @@ -167,6 +169,7 @@ export default function TextArea({ window.print() return } + const ext = formatExtensions[format].slice(1) const defaultPath = await invoke('get_save_path', { srcPath: file.path, targetExt: ext }) const filePath = await dialog.save({ @@ -179,8 +182,17 @@ export default function TextArea({ canCreateDirectories: true, defaultPath: defaultPath.path, }) + if (filePath) { - fs.writeTextFile(filePath, text) + if (format === 'docx') { + const fileName = await path.basename(filePath) + const doc = await toDocx(fileName, segments!, preference.textAreaDirection) + const arrayBuffer = await doc.arrayBuffer() + const buffer = new Uint8Array(arrayBuffer) + fs.writeFile(filePath, buffer) + } else { + fs.writeTextFile(filePath, text) + } toast( (mytoast) => ( @@ -295,15 +307,16 @@ export default function TextArea({ }} className="select select-bordered"> - - - - - + + + + + + - {['html', 'pdf'].includes(preference.textFormat) ? ( + {['html', 'pdf', 'docx'].includes(preference.textFormat) ? ( ) : (