karaoke-gen 0.105.4__py3-none-any.whl → 0.107.0__py3-none-any.whl

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.
Files changed (322) hide show
  1. backend/api/routes/users.py +14 -3
  2. backend/config.py +3 -0
  3. backend/services/encoding_interface.py +4 -0
  4. backend/services/job_notification_service.py +4 -21
  5. backend/tests/test_job_notification_service.py +24 -58
  6. backend/tests/test_video_worker_orchestrator.py +189 -0
  7. backend/workers/video_worker_orchestrator.py +7 -0
  8. karaoke_gen/instrumental_review/server.py +145 -35
  9. karaoke_gen/nextjs_frontend/__init__.py +98 -0
  10. karaoke_gen/nextjs_frontend/out/404/index.html +1 -0
  11. karaoke_gen/nextjs_frontend/out/404.html +1 -0
  12. karaoke_gen/nextjs_frontend/out/__next.__PAGE__.txt +9 -0
  13. karaoke_gen/nextjs_frontend/out/__next._full.txt +22 -0
  14. karaoke_gen/nextjs_frontend/out/__next._head.txt +8 -0
  15. karaoke_gen/nextjs_frontend/out/__next._index.txt +9 -0
  16. karaoke_gen/nextjs_frontend/out/__next._tree.txt +2 -0
  17. karaoke_gen/nextjs_frontend/out/_next/static/chunks/01a7f8fe40f1ff47.js +1 -0
  18. karaoke_gen/nextjs_frontend/out/_next/static/chunks/112f346e31f991df.js +4 -0
  19. karaoke_gen/nextjs_frontend/out/_next/static/chunks/16d1a4dd9d8a873a.js +3 -0
  20. karaoke_gen/nextjs_frontend/out/_next/static/chunks/1ab85c362b8b0e86.js +9 -0
  21. karaoke_gen/nextjs_frontend/out/_next/static/chunks/247eb132b7f7b574.js +1 -0
  22. karaoke_gen/nextjs_frontend/out/_next/static/chunks/2b80d15cc95e4818.js +1 -0
  23. karaoke_gen/nextjs_frontend/out/_next/static/chunks/32c7eba5cd46c1bc.js +7 -0
  24. karaoke_gen/nextjs_frontend/out/_next/static/chunks/483f26794eae53d0.js +1 -0
  25. karaoke_gen/nextjs_frontend/out/_next/static/chunks/550c3b02e85f196a.js +1 -0
  26. karaoke_gen/nextjs_frontend/out/_next/static/chunks/55c5ade44387bef8.js +1 -0
  27. karaoke_gen/nextjs_frontend/out/_next/static/chunks/5628d92b5893add2.css +1 -0
  28. karaoke_gen/nextjs_frontend/out/_next/static/chunks/56ebf7665e4341c8.js +7 -0
  29. karaoke_gen/nextjs_frontend/out/_next/static/chunks/5997132b61dec430.js +1 -0
  30. karaoke_gen/nextjs_frontend/out/_next/static/chunks/5ea55255bce3eb9e.js +5 -0
  31. karaoke_gen/nextjs_frontend/out/_next/static/chunks/5eda89a57490b3cd.js +1 -0
  32. karaoke_gen/nextjs_frontend/out/_next/static/chunks/692f5d9e0d700c76.js +3 -0
  33. karaoke_gen/nextjs_frontend/out/_next/static/chunks/71d7a05b14f9f0f4.js +1 -0
  34. karaoke_gen/nextjs_frontend/out/_next/static/chunks/81ac355749ef3302.js +1 -0
  35. karaoke_gen/nextjs_frontend/out/_next/static/chunks/95f7e5934dbb0e5d.js +1 -0
  36. karaoke_gen/nextjs_frontend/out/_next/static/chunks/9bce8f19eaa46940.js +1 -0
  37. karaoke_gen/nextjs_frontend/out/_next/static/chunks/a6dad97d9634a72d.js +1 -0
  38. karaoke_gen/nextjs_frontend/out/_next/static/chunks/a9ed54eed3e14c92.js +2 -0
  39. karaoke_gen/nextjs_frontend/out/_next/static/chunks/b35cd41238ecfb17.js +1 -0
  40. karaoke_gen/nextjs_frontend/out/_next/static/chunks/b5bc3c3d5ebd49eb.js +1 -0
  41. karaoke_gen/nextjs_frontend/out/_next/static/chunks/b5c078c08db5ae32.js +5 -0
  42. karaoke_gen/nextjs_frontend/out/_next/static/chunks/be9c44a178104187.js +1 -0
  43. karaoke_gen/nextjs_frontend/out/_next/static/chunks/c4c840e18cb4861c.js +1 -0
  44. karaoke_gen/nextjs_frontend/out/_next/static/chunks/c645af7d6b65f73e.js +1 -0
  45. karaoke_gen/nextjs_frontend/out/_next/static/chunks/d2c5e2575df784d4.js +1 -0
  46. karaoke_gen/nextjs_frontend/out/_next/static/chunks/d30af02b96d81462.js +1 -0
  47. karaoke_gen/nextjs_frontend/out/_next/static/chunks/d9bdf64f4ec1e9b7.js +7 -0
  48. karaoke_gen/nextjs_frontend/out/_next/static/chunks/dcde6ed684dacd0e.js +5 -0
  49. karaoke_gen/nextjs_frontend/out/_next/static/chunks/e422cbe931246000.js +1 -0
  50. karaoke_gen/nextjs_frontend/out/_next/static/chunks/e483af34fc792d38.js +1 -0
  51. karaoke_gen/nextjs_frontend/out/_next/static/chunks/e57422aad6b897da.js +1 -0
  52. karaoke_gen/nextjs_frontend/out/_next/static/chunks/ef02697fb404726a.js +1 -0
  53. karaoke_gen/nextjs_frontend/out/_next/static/chunks/ff1a16fafef87110.js +1 -0
  54. karaoke_gen/nextjs_frontend/out/_next/static/chunks/turbopack-2d9ca3017a9deedf.js +3 -0
  55. karaoke_gen/nextjs_frontend/out/_next/static/zpw_-rjFIDV5tlPPtnvRI/_buildManifest.js +11 -0
  56. karaoke_gen/nextjs_frontend/out/_next/static/zpw_-rjFIDV5tlPPtnvRI/_clientMiddlewareManifest.json +1 -0
  57. karaoke_gen/nextjs_frontend/out/_next/static/zpw_-rjFIDV5tlPPtnvRI/_ssgManifest.js +1 -0
  58. karaoke_gen/nextjs_frontend/out/_not-found/__next._full.txt +18 -0
  59. karaoke_gen/nextjs_frontend/out/_not-found/__next._head.txt +8 -0
  60. karaoke_gen/nextjs_frontend/out/_not-found/__next._index.txt +9 -0
  61. karaoke_gen/nextjs_frontend/out/_not-found/__next._not-found.__PAGE__.txt +5 -0
  62. karaoke_gen/nextjs_frontend/out/_not-found/__next._not-found.txt +4 -0
  63. karaoke_gen/nextjs_frontend/out/_not-found/__next._tree.txt +2 -0
  64. karaoke_gen/nextjs_frontend/out/_not-found/index.html +1 -0
  65. karaoke_gen/nextjs_frontend/out/_not-found/index.txt +18 -0
  66. karaoke_gen/nextjs_frontend/out/admin/__next._full.txt +25 -0
  67. karaoke_gen/nextjs_frontend/out/admin/__next._head.txt +8 -0
  68. karaoke_gen/nextjs_frontend/out/admin/__next._index.txt +9 -0
  69. karaoke_gen/nextjs_frontend/out/admin/__next._tree.txt +2 -0
  70. karaoke_gen/nextjs_frontend/out/admin/__next.admin.__PAGE__.txt +9 -0
  71. karaoke_gen/nextjs_frontend/out/admin/__next.admin.txt +7 -0
  72. karaoke_gen/nextjs_frontend/out/admin/beta/__next._full.txt +25 -0
  73. karaoke_gen/nextjs_frontend/out/admin/beta/__next._head.txt +8 -0
  74. karaoke_gen/nextjs_frontend/out/admin/beta/__next._index.txt +9 -0
  75. karaoke_gen/nextjs_frontend/out/admin/beta/__next._tree.txt +2 -0
  76. karaoke_gen/nextjs_frontend/out/admin/beta/__next.admin.beta.__PAGE__.txt +9 -0
  77. karaoke_gen/nextjs_frontend/out/admin/beta/__next.admin.beta.txt +4 -0
  78. karaoke_gen/nextjs_frontend/out/admin/beta/__next.admin.txt +7 -0
  79. karaoke_gen/nextjs_frontend/out/admin/beta/index.html +1 -0
  80. karaoke_gen/nextjs_frontend/out/admin/beta/index.txt +25 -0
  81. karaoke_gen/nextjs_frontend/out/admin/index.html +1 -0
  82. karaoke_gen/nextjs_frontend/out/admin/index.txt +25 -0
  83. karaoke_gen/nextjs_frontend/out/admin/jobs/__next._full.txt +25 -0
  84. karaoke_gen/nextjs_frontend/out/admin/jobs/__next._head.txt +8 -0
  85. karaoke_gen/nextjs_frontend/out/admin/jobs/__next._index.txt +9 -0
  86. karaoke_gen/nextjs_frontend/out/admin/jobs/__next._tree.txt +2 -0
  87. karaoke_gen/nextjs_frontend/out/admin/jobs/__next.admin.jobs.__PAGE__.txt +9 -0
  88. karaoke_gen/nextjs_frontend/out/admin/jobs/__next.admin.jobs.txt +4 -0
  89. karaoke_gen/nextjs_frontend/out/admin/jobs/__next.admin.txt +7 -0
  90. karaoke_gen/nextjs_frontend/out/admin/jobs/index.html +1 -0
  91. karaoke_gen/nextjs_frontend/out/admin/jobs/index.txt +25 -0
  92. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next._full.txt +25 -0
  93. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next._head.txt +8 -0
  94. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next._index.txt +9 -0
  95. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next._tree.txt +2 -0
  96. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next.admin.rate-limits.__PAGE__.txt +9 -0
  97. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next.admin.rate-limits.txt +4 -0
  98. karaoke_gen/nextjs_frontend/out/admin/rate-limits/__next.admin.txt +7 -0
  99. karaoke_gen/nextjs_frontend/out/admin/rate-limits/index.html +1 -0
  100. karaoke_gen/nextjs_frontend/out/admin/rate-limits/index.txt +25 -0
  101. karaoke_gen/nextjs_frontend/out/admin/searches/__next._full.txt +25 -0
  102. karaoke_gen/nextjs_frontend/out/admin/searches/__next._head.txt +8 -0
  103. karaoke_gen/nextjs_frontend/out/admin/searches/__next._index.txt +9 -0
  104. karaoke_gen/nextjs_frontend/out/admin/searches/__next._tree.txt +2 -0
  105. karaoke_gen/nextjs_frontend/out/admin/searches/__next.admin.searches.__PAGE__.txt +9 -0
  106. karaoke_gen/nextjs_frontend/out/admin/searches/__next.admin.searches.txt +4 -0
  107. karaoke_gen/nextjs_frontend/out/admin/searches/__next.admin.txt +7 -0
  108. karaoke_gen/nextjs_frontend/out/admin/searches/index.html +1 -0
  109. karaoke_gen/nextjs_frontend/out/admin/searches/index.txt +25 -0
  110. karaoke_gen/nextjs_frontend/out/admin/users/__next._full.txt +25 -0
  111. karaoke_gen/nextjs_frontend/out/admin/users/__next._head.txt +8 -0
  112. karaoke_gen/nextjs_frontend/out/admin/users/__next._index.txt +9 -0
  113. karaoke_gen/nextjs_frontend/out/admin/users/__next._tree.txt +2 -0
  114. karaoke_gen/nextjs_frontend/out/admin/users/__next.admin.txt +7 -0
  115. karaoke_gen/nextjs_frontend/out/admin/users/__next.admin.users.__PAGE__.txt +9 -0
  116. karaoke_gen/nextjs_frontend/out/admin/users/__next.admin.users.txt +4 -0
  117. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next._full.txt +25 -0
  118. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next._head.txt +8 -0
  119. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next._index.txt +9 -0
  120. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next._tree.txt +2 -0
  121. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next.admin.txt +7 -0
  122. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next.admin.users.detail.__PAGE__.txt +9 -0
  123. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next.admin.users.detail.txt +4 -0
  124. karaoke_gen/nextjs_frontend/out/admin/users/detail/__next.admin.users.txt +4 -0
  125. karaoke_gen/nextjs_frontend/out/admin/users/detail/index.html +1 -0
  126. karaoke_gen/nextjs_frontend/out/admin/users/detail/index.txt +25 -0
  127. karaoke_gen/nextjs_frontend/out/admin/users/index.html +1 -0
  128. karaoke_gen/nextjs_frontend/out/admin/users/index.txt +25 -0
  129. karaoke_gen/nextjs_frontend/out/app/__next._full.txt +22 -0
  130. karaoke_gen/nextjs_frontend/out/app/__next._head.txt +8 -0
  131. karaoke_gen/nextjs_frontend/out/app/__next._index.txt +9 -0
  132. karaoke_gen/nextjs_frontend/out/app/__next._tree.txt +2 -0
  133. karaoke_gen/nextjs_frontend/out/app/__next.app.__PAGE__.txt +9 -0
  134. karaoke_gen/nextjs_frontend/out/app/__next.app.txt +4 -0
  135. karaoke_gen/nextjs_frontend/out/app/index.html +1 -0
  136. karaoke_gen/nextjs_frontend/out/app/index.txt +22 -0
  137. karaoke_gen/nextjs_frontend/out/app/jobs/__next._full.txt +19 -0
  138. karaoke_gen/nextjs_frontend/out/app/jobs/__next._head.txt +8 -0
  139. karaoke_gen/nextjs_frontend/out/app/jobs/__next._index.txt +9 -0
  140. karaoke_gen/nextjs_frontend/out/app/jobs/__next._tree.txt +2 -0
  141. karaoke_gen/nextjs_frontend/out/app/jobs/__next.app.jobs.$oc$slug.__PAGE__.txt +6 -0
  142. karaoke_gen/nextjs_frontend/out/app/jobs/__next.app.jobs.$oc$slug.txt +4 -0
  143. karaoke_gen/nextjs_frontend/out/app/jobs/__next.app.jobs.txt +4 -0
  144. karaoke_gen/nextjs_frontend/out/app/jobs/__next.app.txt +4 -0
  145. karaoke_gen/nextjs_frontend/out/app/jobs/index.html +1 -0
  146. karaoke_gen/nextjs_frontend/out/app/jobs/index.txt +19 -0
  147. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next._full.txt +19 -0
  148. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next._head.txt +8 -0
  149. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next._index.txt +9 -0
  150. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next._tree.txt +2 -0
  151. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next.app.jobs.$oc$slug.__PAGE__.txt +6 -0
  152. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next.app.jobs.$oc$slug.txt +4 -0
  153. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next.app.jobs.txt +4 -0
  154. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/__next.app.txt +4 -0
  155. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/index.html +1 -0
  156. karaoke_gen/nextjs_frontend/out/app/jobs/local/instrumental/index.txt +19 -0
  157. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next._full.txt +19 -0
  158. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next._head.txt +8 -0
  159. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next._index.txt +9 -0
  160. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next._tree.txt +2 -0
  161. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next.app.jobs.$oc$slug.__PAGE__.txt +6 -0
  162. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next.app.jobs.$oc$slug.txt +4 -0
  163. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next.app.jobs.txt +4 -0
  164. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/__next.app.txt +4 -0
  165. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/index.html +1 -0
  166. karaoke_gen/nextjs_frontend/out/app/jobs/local/review/index.txt +19 -0
  167. karaoke_gen/nextjs_frontend/out/auth/verify/__next._full.txt +22 -0
  168. karaoke_gen/nextjs_frontend/out/auth/verify/__next._head.txt +8 -0
  169. karaoke_gen/nextjs_frontend/out/auth/verify/__next._index.txt +9 -0
  170. karaoke_gen/nextjs_frontend/out/auth/verify/__next._tree.txt +2 -0
  171. karaoke_gen/nextjs_frontend/out/auth/verify/__next.auth.txt +4 -0
  172. karaoke_gen/nextjs_frontend/out/auth/verify/__next.auth.verify.__PAGE__.txt +9 -0
  173. karaoke_gen/nextjs_frontend/out/auth/verify/__next.auth.verify.txt +4 -0
  174. karaoke_gen/nextjs_frontend/out/auth/verify/index.html +1 -0
  175. karaoke_gen/nextjs_frontend/out/auth/verify/index.txt +22 -0
  176. karaoke_gen/nextjs_frontend/out/index.html +1 -0
  177. karaoke_gen/nextjs_frontend/out/index.txt +22 -0
  178. karaoke_gen/nextjs_frontend/out/manifest.webmanifest +31 -0
  179. karaoke_gen/nextjs_frontend/out/order/success/__next._full.txt +22 -0
  180. karaoke_gen/nextjs_frontend/out/order/success/__next._head.txt +8 -0
  181. karaoke_gen/nextjs_frontend/out/order/success/__next._index.txt +9 -0
  182. karaoke_gen/nextjs_frontend/out/order/success/__next._tree.txt +2 -0
  183. karaoke_gen/nextjs_frontend/out/order/success/__next.order.success.__PAGE__.txt +9 -0
  184. karaoke_gen/nextjs_frontend/out/order/success/__next.order.success.txt +4 -0
  185. karaoke_gen/nextjs_frontend/out/order/success/__next.order.txt +4 -0
  186. karaoke_gen/nextjs_frontend/out/order/success/index.html +1 -0
  187. karaoke_gen/nextjs_frontend/out/order/success/index.txt +22 -0
  188. karaoke_gen/nextjs_frontend/out/payment/success/__next._full.txt +22 -0
  189. karaoke_gen/nextjs_frontend/out/payment/success/__next._head.txt +8 -0
  190. karaoke_gen/nextjs_frontend/out/payment/success/__next._index.txt +9 -0
  191. karaoke_gen/nextjs_frontend/out/payment/success/__next._tree.txt +2 -0
  192. karaoke_gen/nextjs_frontend/out/payment/success/__next.payment.success.__PAGE__.txt +9 -0
  193. karaoke_gen/nextjs_frontend/out/payment/success/__next.payment.success.txt +4 -0
  194. karaoke_gen/nextjs_frontend/out/payment/success/__next.payment.txt +4 -0
  195. karaoke_gen/nextjs_frontend/out/payment/success/index.html +1 -0
  196. karaoke_gen/nextjs_frontend/out/payment/success/index.txt +22 -0
  197. karaoke_gen/nextjs_frontend/out/screenshots/email-action_reminder.png +0 -0
  198. karaoke_gen/nextjs_frontend/out/screenshots/email-beta_welcome.png +0 -0
  199. karaoke_gen/nextjs_frontend/out/screenshots/email-job_completion.png +0 -0
  200. karaoke_gen/nextjs_frontend/out/screenshots/example-output.avif +0 -0
  201. karaoke_gen/nextjs_frontend/out/screenshots/homepage-full.png +0 -0
  202. karaoke_gen/nextjs_frontend/out/screenshots/homepage-hero.png +0 -0
  203. karaoke_gen/nextjs_frontend/out/screenshots/instrumental-review.avif +0 -0
  204. karaoke_gen/nextjs_frontend/out/screenshots/instrumental-review.png +0 -0
  205. karaoke_gen/nextjs_frontend/out/screenshots/job-dashboard.avif +0 -0
  206. karaoke_gen/nextjs_frontend/out/screenshots/lyrics-review.avif +0 -0
  207. karaoke_gen/nextjs_frontend/out/screenshots/lyrics-review.png +0 -0
  208. karaoke_gen/nextjs_frontend/out/sw.js +183 -0
  209. karaoke_gen/utils/cli_args.py +3 -3
  210. karaoke_gen/utils/gen_cli.py +4 -0
  211. karaoke_gen/utils/remote_cli.py +8 -40
  212. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/METADATA +1 -1
  213. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/RECORD +227 -121
  214. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/WHEEL +1 -1
  215. lyrics_transcriber/correction/agentic/agent.py +83 -60
  216. lyrics_transcriber/correction/anchor_sequence.py +48 -3
  217. lyrics_transcriber/correction/corrector.py +92 -58
  218. lyrics_transcriber/review/server.py +165 -33
  219. lyrics_transcriber/utils/tracing.py +214 -0
  220. karaoke_gen/instrumental_review/static/index.html +0 -1721
  221. lyrics_transcriber/frontend/.gitignore +0 -24
  222. lyrics_transcriber/frontend/.yarn/releases/yarn-4.7.0.cjs +0 -935
  223. lyrics_transcriber/frontend/.yarnrc.yml +0 -3
  224. lyrics_transcriber/frontend/README.md +0 -50
  225. lyrics_transcriber/frontend/REPLACE_ALL_FUNCTIONALITY.md +0 -210
  226. lyrics_transcriber/frontend/__init__.py +0 -25
  227. lyrics_transcriber/frontend/e2e/agentic-corrections.spec.ts +0 -207
  228. lyrics_transcriber/frontend/e2e/fixtures/agentic-correction-data.json +0 -226
  229. lyrics_transcriber/frontend/eslint.config.js +0 -28
  230. lyrics_transcriber/frontend/index.html +0 -22
  231. lyrics_transcriber/frontend/package-lock.json +0 -4553
  232. lyrics_transcriber/frontend/package.json +0 -48
  233. lyrics_transcriber/frontend/playwright.config.ts +0 -69
  234. lyrics_transcriber/frontend/public/android-chrome-192x192.png +0 -0
  235. lyrics_transcriber/frontend/public/android-chrome-512x512.png +0 -0
  236. lyrics_transcriber/frontend/src/App.tsx +0 -243
  237. lyrics_transcriber/frontend/src/api.ts +0 -262
  238. lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +0 -111
  239. lyrics_transcriber/frontend/src/components/AddLyricsModal.tsx +0 -114
  240. lyrics_transcriber/frontend/src/components/AgenticCorrectionMetrics.tsx +0 -204
  241. lyrics_transcriber/frontend/src/components/AppHeader.tsx +0 -65
  242. lyrics_transcriber/frontend/src/components/AudioPlayer.tsx +0 -180
  243. lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +0 -175
  244. lyrics_transcriber/frontend/src/components/CorrectionAnnotationModal.tsx +0 -359
  245. lyrics_transcriber/frontend/src/components/CorrectionDetailCard.tsx +0 -281
  246. lyrics_transcriber/frontend/src/components/CorrectionMetrics.tsx +0 -162
  247. lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx +0 -257
  248. lyrics_transcriber/frontend/src/components/EditActionBar.tsx +0 -94
  249. lyrics_transcriber/frontend/src/components/EditModal.tsx +0 -720
  250. lyrics_transcriber/frontend/src/components/EditTimelineSection.tsx +0 -592
  251. lyrics_transcriber/frontend/src/components/EditWordList.tsx +0 -431
  252. lyrics_transcriber/frontend/src/components/FileUpload.tsx +0 -77
  253. lyrics_transcriber/frontend/src/components/FindReplaceModal.tsx +0 -467
  254. lyrics_transcriber/frontend/src/components/Header.tsx +0 -520
  255. lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +0 -1526
  256. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/SyncControls.tsx +0 -216
  257. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +0 -721
  258. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/UpcomingWordsBar.tsx +0 -80
  259. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/index.tsx +0 -999
  260. lyrics_transcriber/frontend/src/components/MetricsDashboard.tsx +0 -51
  261. lyrics_transcriber/frontend/src/components/ModeSelectionModal.tsx +0 -127
  262. lyrics_transcriber/frontend/src/components/ModeSelector.tsx +0 -67
  263. lyrics_transcriber/frontend/src/components/ModelSelector.tsx +0 -23
  264. lyrics_transcriber/frontend/src/components/PreviewVideoSection.tsx +0 -177
  265. lyrics_transcriber/frontend/src/components/ReferenceView.tsx +0 -268
  266. lyrics_transcriber/frontend/src/components/ReplaceAllLyricsModal.tsx +0 -336
  267. lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx +0 -354
  268. lyrics_transcriber/frontend/src/components/SegmentDetailsModal.tsx +0 -64
  269. lyrics_transcriber/frontend/src/components/TimelineEditor.tsx +0 -383
  270. lyrics_transcriber/frontend/src/components/TimingOffsetModal.tsx +0 -131
  271. lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +0 -266
  272. lyrics_transcriber/frontend/src/components/WordDivider.tsx +0 -191
  273. lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx +0 -466
  274. lyrics_transcriber/frontend/src/components/shared/components/SourceSelector.tsx +0 -56
  275. lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +0 -89
  276. lyrics_transcriber/frontend/src/components/shared/constants.ts +0 -30
  277. lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts +0 -180
  278. lyrics_transcriber/frontend/src/components/shared/styles.ts +0 -13
  279. lyrics_transcriber/frontend/src/components/shared/types.js +0 -2
  280. lyrics_transcriber/frontend/src/components/shared/types.ts +0 -135
  281. lyrics_transcriber/frontend/src/components/shared/utils/keyboardHandlers.ts +0 -177
  282. lyrics_transcriber/frontend/src/components/shared/utils/localStorage.ts +0 -78
  283. lyrics_transcriber/frontend/src/components/shared/utils/referenceLineCalculator.ts +0 -75
  284. lyrics_transcriber/frontend/src/components/shared/utils/segmentOperations.ts +0 -360
  285. lyrics_transcriber/frontend/src/components/shared/utils/timingUtils.ts +0 -110
  286. lyrics_transcriber/frontend/src/components/shared/utils/wordUtils.ts +0 -22
  287. lyrics_transcriber/frontend/src/hooks/useManualSync.ts +0 -537
  288. lyrics_transcriber/frontend/src/main.tsx +0 -11
  289. lyrics_transcriber/frontend/src/theme.ts +0 -406
  290. lyrics_transcriber/frontend/src/types/global.d.ts +0 -9
  291. lyrics_transcriber/frontend/src/types.js +0 -2
  292. lyrics_transcriber/frontend/src/types.ts +0 -199
  293. lyrics_transcriber/frontend/src/validation.ts +0 -132
  294. lyrics_transcriber/frontend/src/vite-env.d.ts +0 -1
  295. lyrics_transcriber/frontend/tsconfig.app.json +0 -26
  296. lyrics_transcriber/frontend/tsconfig.json +0 -25
  297. lyrics_transcriber/frontend/tsconfig.node.json +0 -23
  298. lyrics_transcriber/frontend/tsconfig.tsbuildinfo +0 -1
  299. lyrics_transcriber/frontend/update_version.js +0 -11
  300. lyrics_transcriber/frontend/vite.config.d.ts +0 -2
  301. lyrics_transcriber/frontend/vite.config.js +0 -15
  302. lyrics_transcriber/frontend/vite.config.ts +0 -16
  303. lyrics_transcriber/frontend/web_assets/android-chrome-192x192.png +0 -0
  304. lyrics_transcriber/frontend/web_assets/android-chrome-512x512.png +0 -0
  305. lyrics_transcriber/frontend/web_assets/apple-touch-icon.png +0 -0
  306. lyrics_transcriber/frontend/web_assets/assets/index-BSMgOq4Z.js +0 -44465
  307. lyrics_transcriber/frontend/web_assets/assets/index-BSMgOq4Z.js.map +0 -1
  308. lyrics_transcriber/frontend/web_assets/favicon-16x16.png +0 -0
  309. lyrics_transcriber/frontend/web_assets/favicon-32x32.png +0 -0
  310. lyrics_transcriber/frontend/web_assets/favicon.ico +0 -0
  311. lyrics_transcriber/frontend/web_assets/index.html +0 -22
  312. lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.png +0 -0
  313. lyrics_transcriber/frontend/web_assets/nomad-karaoke-logo.svg +0 -5
  314. lyrics_transcriber/frontend/yarn.lock +0 -3711
  315. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/apple-touch-icon.png +0 -0
  316. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/favicon-16x16.png +0 -0
  317. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/favicon-32x32.png +0 -0
  318. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/favicon.ico +0 -0
  319. {lyrics_transcriber/frontend/public → karaoke_gen/nextjs_frontend/out}/nomad-karaoke-logo.svg +0 -0
  320. /lyrics_transcriber/frontend/public/nomad-karaoke-logo.png → /karaoke_gen/nextjs_frontend/out/nomad-logo.png +0 -0
  321. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/entry_points.txt +0 -0
  322. {karaoke_gen-0.105.4.dist-info → karaoke_gen-0.107.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,3 +0,0 @@
1
- nodeLinker: node-modules
2
-
3
- yarnPath: .yarn/releases/yarn-4.7.0.cjs
@@ -1,50 +0,0 @@
1
- # React + TypeScript + Vite
2
-
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
-
5
- Currently, two official plugins are available:
6
-
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
-
10
- ## Expanding the ESLint configuration
11
-
12
- If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13
-
14
- - Configure the top-level `parserOptions` property like this:
15
-
16
- ```js
17
- export default tseslint.config({
18
- languageOptions: {
19
- // other options...
20
- parserOptions: {
21
- project: ['./tsconfig.node.json', './tsconfig.app.json'],
22
- tsconfigRootDir: import.meta.dirname,
23
- },
24
- },
25
- })
26
- ```
27
-
28
- - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
29
- - Optionally add `...tseslint.configs.stylisticTypeChecked`
30
- - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
31
-
32
- ```js
33
- // eslint.config.js
34
- import react from 'eslint-plugin-react'
35
-
36
- export default tseslint.config({
37
- // Set the react version
38
- settings: { react: { version: '18.3' } },
39
- plugins: {
40
- // Add the react plugin
41
- react,
42
- },
43
- rules: {
44
- // other rules...
45
- // Enable its recommended rules
46
- ...react.configs.recommended.rules,
47
- ...react.configs['jsx-runtime'].rules,
48
- },
49
- })
50
- ```
@@ -1,210 +0,0 @@
1
- Please read this doc to understand the "Replace All" modal we implemented in a previous chat: @REPLACE_ALL_FUNCTIONALITY.md
2
-
3
- The primary code for the new modal is here: @ReplaceAllLyricsModal.tsx
4
- but the manual sync functionality relies heavily on @EditTimelineSection.tsx, @useManualSync.ts and @EditActionBar.tsx
5
-
6
- The functionality mostly works but we need to continue refining it and fixing issues until it is good enough for me and other users to use. Please let me know once you've reviewed the above and you're ready for me to explain the first issue.
7
-
8
- # Replace All Lyrics Functionality
9
-
10
- ## Overview
11
-
12
- The "Replace All Lyrics" functionality provides a complete solution for replacing transcribed lyrics when the original transcription quality is too poor to edit word-by-word. This feature allows users to start fresh with clipboard content and manually sync timing for the entire song.
13
-
14
- ## Key Components
15
-
16
- ### 1. ReplaceAllLyricsModal.tsx
17
- - **Location**: `src/components/ReplaceAllLyricsModal.tsx`
18
- - **Purpose**: Standalone modal for replacing all lyrics with clipboard content
19
- - **Design**: Separate from EditModal.tsx to maintain clean separation of concerns
20
-
21
- ### 2. Integration Points
22
- - **useManualSync Hook**: Reuses existing manual sync functionality
23
- - **AudioPlayer Integration**: Leverages global audio controls and duration
24
- - **Types**: Uses existing LyricsSegment and Word types
25
-
26
- ## User Workflow
27
-
28
- ### Phase 1: Input
29
- 1. **Open Modal**: Access via "Replace All Lyrics" button/action
30
- 2. **Paste Content**: Large textarea for pasting lyrics from clipboard
31
- 3. **Real-time Feedback**:
32
- - Line count display
33
- - Word count display
34
- - Preview of how content will be parsed
35
- 4. **Validation**: Ensures content is not empty before proceeding
36
-
37
- ### Phase 2: Manual Sync
38
- 1. **Automatic Conversion**: Each line becomes a LyricsSegment, each word becomes a Word object
39
- 2. **Timeline View**:
40
- - Fixed 30-second zoom window
41
- - Shows entire song duration (0 to audio duration)
42
- - Visual indicators for word positions
43
- 3. **Manual Timing**:
44
- - Spacebar to mark word timings during playback
45
- - Pause/resume functionality for corrections
46
- - Real-time progress tracking
47
- 4. **Progress Panel**:
48
- - Shows all segments with sync status
49
- - Active segment highlighting (blue)
50
- - Completed segments (green) with timing display
51
- - Progress indicators (X/Y words synced)
52
- - Auto-scroll to follow playback
53
-
54
- ## Technical Implementation
55
-
56
- ### Data Structure
57
- ```typescript
58
- // Each line becomes a LyricsSegment
59
- {
60
- id: string,
61
- text: string, // Full line text
62
- start_time: number | null,
63
- end_time: number | null,
64
- words: Word[] // Each word in the line
65
- }
66
-
67
- // Each word becomes a Word object
68
- {
69
- id: string,
70
- text: string, // Individual word
71
- start_time: number | null,
72
- end_time: number | null,
73
- confidence: number // Set to 1.0 for manual entries
74
- }
75
- ```
76
-
77
- ### Modal Layout
78
- - **Full Browser Width**: Uses `maxWidth={false}` and viewport-based calculations
79
- - **Split Layout**:
80
- - Timeline Section: 2/3 width
81
- - Progress Panel: 1/3 width
82
- - **Responsive Design**: Adapts to different screen sizes
83
-
84
- ### Audio Integration
85
- - **Duration Detection**: Uses `window.getAudioDuration()` for accurate song length
86
- - **Playback Control**: Integrates with existing audio controls
87
- - **Auto-cleanup**: Stops audio when canceling sync
88
-
89
- ## Key Features Implemented
90
-
91
- ### 1. Stable Timeline View
92
- - **Fixed Zoom**: Always shows 30-second window
93
- - **Full Song Range**: Timeline spans 0 to full audio duration
94
- - **Prevents Zoom Changes**: Disabled during manual sync to maintain consistency
95
-
96
- ### 2. Manual Sync Enhancement
97
- - **Spacebar Timing**: Press spacebar to mark word timings
98
- - **Pause/Resume**: Alt+P to pause/resume for corrections
99
- - **Visual Feedback**:
100
- - Current word highlighting
101
- - Spacebar press indication
102
- - Progress tracking
103
-
104
- ### 3. Progress Tracking
105
- - **Segment Status**: Visual indicators for sync progress
106
- - **Real-time Updates**: Timing updates as words are synced
107
- - **Auto-scroll**: Follows active segment during sync
108
- - **Completion Status**: Clear visual feedback for completed segments
109
-
110
- ### 4. Error Prevention
111
- - **Input Validation**: Ensures content exists before proceeding
112
- - **Safe Navigation**: Proper cleanup when canceling
113
- - **State Management**: Prevents conflicts with existing edit modals
114
-
115
- ## Bug Fixes Implemented
116
-
117
- ### 1. Manual Sync Issues
118
- - **Problem**: Sync stopping after first spacebar press
119
- - **Solution**: Fixed infinite re-renders in useEffect dependencies
120
- - **Result**: Stable manual sync throughout entire song
121
-
122
- ### 2. Timeline Zoom Problems
123
- - **Problem**: Timeline zooming to single word duration after sync
124
- - **Solution**: Fixed timeRange calculation to always use full song duration
125
- - **Result**: Consistent 30-second view regardless of sync progress
126
-
127
- ### 3. Audio Duration
128
- - **Problem**: Hardcoded duration fallbacks causing inaccurate timelines
129
- - **Solution**: Integration with real audio duration from AudioPlayer
130
- - **Result**: Accurate timeline representation of song length
131
-
132
- ### 4. Keyboard Conflicts
133
- - **Problem**: Multiple keyboard handlers causing conflicts
134
- - **Solution**: Proper handler cleanup and event management
135
- - **Result**: Clean keyboard interaction without conflicts
136
-
137
- ## User Experience Improvements
138
-
139
- ### 1. Visual Feedback
140
- - **Real-time Counts**: Live word/line counting during input
141
- - **Progress Indicators**: Clear visual feedback on sync progress
142
- - **Color Coding**: Blue for active, green for completed segments
143
-
144
- ### 2. Navigation
145
- - **Auto-scroll**: Automatically follows playback position
146
- - **Manual Navigation**: Can manually scroll through segments
147
- - **Status Preservation**: Maintains state during navigation
148
-
149
- ### 3. Error Recovery
150
- - **Pause/Resume**: Ability to pause and correct timing
151
- - **Cancel Support**: Safe cancellation with proper cleanup
152
- - **State Reset**: Clean state management between sessions
153
-
154
- ## Integration with Existing Codebase
155
-
156
- ### 1. Reused Components
157
- - **useManualSync**: Leverages existing manual sync logic
158
- - **Timeline Components**: Reuses timeline visualization
159
- - **Audio Controls**: Integrates with existing audio system
160
-
161
- ### 2. Type Safety
162
- - **TypeScript**: Fully typed implementation
163
- - **Consistent Interfaces**: Uses existing type definitions
164
- - **Validation**: Runtime validation for data integrity
165
-
166
- ### 3. State Management
167
- - **Isolated State**: Doesn't interfere with existing edit functionality
168
- - **Clean Separation**: Separate modal for replace vs. edit operations
169
- - **Proper Cleanup**: Ensures no state leakage between modals
170
-
171
- ## Performance Considerations
172
-
173
- ### 1. Rendering Optimization
174
- - **Memoization**: Strategic use of React.memo and useCallback
175
- - **Efficient Updates**: Minimal re-renders during sync
176
- - **Progressive Loading**: Handles large lyric sets efficiently
177
-
178
- ### 2. Memory Management
179
- - **Cleanup**: Proper cleanup of event listeners and timers
180
- - **State Reset**: Clean state management between sessions
181
- - **Audio Integration**: Efficient audio control integration
182
-
183
- ## Future Enhancement Opportunities
184
-
185
- ### 1. Batch Operations
186
- - **Multi-line Selection**: Select and sync multiple segments at once
187
- - **Timing Adjustment**: Bulk timing adjustments
188
- - **Smart Defaults**: AI-suggested timing based on audio analysis
189
-
190
- ### 2. Import/Export
191
- - **Format Support**: Support for various lyric file formats
192
- - **Backup/Restore**: Save and restore sync sessions
193
- - **Templates**: Predefined timing templates
194
-
195
- ### 3. Advanced Sync
196
- - **Beat Detection**: Automatic beat-based timing suggestions
197
- - **Voice Activity**: Audio analysis for timing hints
198
- - **Collaborative Sync**: Multi-user timing collaboration
199
-
200
- ## Summary
201
-
202
- The "Replace All Lyrics" functionality provides a comprehensive solution for handling poor-quality transcriptions by:
203
-
204
- 1. **Complete Replacement**: Replaces all existing lyrics with fresh clipboard content
205
- 2. **Manual Control**: Gives users full control over timing through manual sync
206
- 3. **Visual Feedback**: Provides clear progress tracking and status indicators
207
- 4. **Stable Interface**: Maintains consistent timeline view throughout the process
208
- 5. **Clean Integration**: Works seamlessly with existing audio and editing systems
209
-
210
- This implementation significantly improves the user experience for cases where starting fresh is more efficient than editing individual words, while maintaining the high-quality timing precision needed for karaoke applications.
@@ -1,25 +0,0 @@
1
- """Frontend module for lyrics transcriber web interface."""
2
-
3
- import os
4
-
5
- # Get the directory containing this file
6
- __frontend_dir__ = os.path.dirname(os.path.abspath(__file__))
7
-
8
- def get_frontend_assets_dir():
9
- """Get the path to the frontend assets directory.
10
-
11
- Returns the web_assets directory if it exists (packaged version),
12
- otherwise returns the dist directory (development version).
13
- """
14
- web_assets_dir = os.path.join(__frontend_dir__, "web_assets")
15
- dist_dir = os.path.join(__frontend_dir__, "dist")
16
-
17
- if os.path.exists(web_assets_dir):
18
- return web_assets_dir
19
- elif os.path.exists(dist_dir):
20
- return dist_dir
21
- else:
22
- raise FileNotFoundError(
23
- "Frontend assets not found. Please build the frontend first with: "
24
- "./scripts/build_frontend.sh"
25
- )
@@ -1,207 +0,0 @@
1
- import { test, expect } from '@playwright/test';
2
- import * as path from 'path';
3
- import { fileURLToPath } from 'url';
4
-
5
- // Get __dirname equivalent in ESM
6
- const __filename = fileURLToPath(import.meta.url);
7
- const __dirname = path.dirname(__filename);
8
-
9
- /**
10
- * E2E tests for the agentic correction workflow in the lyrics transcriber frontend.
11
- *
12
- * These tests verify:
13
- * 1. The UI loads correctly with agentic correction data
14
- * 2. The AgenticCorrectionMetrics panel displays correctly
15
- * 3. Corrected words are highlighted and clickable
16
- * 4. The CorrectionDetailCard shows proper information
17
- */
18
-
19
- // Helper function to load fixture data
20
- async function loadFixtureData(page: import('@playwright/test').Page) {
21
- const fixturePath = path.join(__dirname, 'fixtures', 'agentic-correction-data.json');
22
-
23
- // Create a file chooser promise before clicking
24
- const fileChooserPromise = page.waitForEvent('filechooser');
25
-
26
- // Click the Load File button
27
- await page.getByRole('button', { name: /load file/i }).click();
28
-
29
- // Handle the file chooser
30
- const fileChooser = await fileChooserPromise;
31
- await fileChooser.setFiles(fixturePath);
32
-
33
- // Wait for data to load by asserting expected content appears
34
- await expect(page.getByText('Hello,')).toBeVisible({ timeout: 5000 });
35
- }
36
-
37
- test.describe('Agentic Correction Workflow', () => {
38
- test.beforeEach(async ({ page }) => {
39
- // Navigate to the app
40
- await page.goto('/');
41
-
42
- // Wait for the initial load
43
- await expect(page.getByText('Lyrics Correction Review')).toBeVisible();
44
- });
45
-
46
- test('should load the app in read-only mode', async ({ page }) => {
47
- // Verify read-only mode alert is shown
48
- await expect(page.getByText('Running in read-only mode')).toBeVisible();
49
-
50
- // Verify Load File button is present
51
- await expect(page.getByRole('button', { name: /load file/i })).toBeVisible();
52
- });
53
-
54
- test('should load correction data from JSON file', async ({ page }) => {
55
- await loadFixtureData(page);
56
-
57
- // Verify we're no longer in loading state
58
- await expect(page.getByText('Loading Lyrics Correction Review...')).not.toBeVisible();
59
-
60
- // Verify expected content from fixture is visible
61
- await expect(page.getByText('Hello,')).toBeVisible();
62
- });
63
-
64
- test('should render transcription view after loading data', async ({ page }) => {
65
- await loadFixtureData(page);
66
-
67
- // Wait for transcription content to render
68
- await expect(page.getByText('Hello,')).toBeVisible();
69
-
70
- // Verify the Corrected Transcription header is visible
71
- await expect(page.getByText('Corrected Transcription')).toBeVisible();
72
- });
73
- });
74
-
75
- test.describe('UI Components', () => {
76
- test('should show Load File button on initial load', async ({ page }) => {
77
- await page.goto('/');
78
-
79
- // The Load File button should be visible
80
- const loadButton = page.getByRole('button', { name: /load file/i });
81
- await expect(loadButton).toBeVisible();
82
-
83
- // Should have upload icon
84
- const uploadIcon = page.locator('svg[data-testid="UploadFileIcon"]');
85
- await expect(uploadIcon).toBeVisible();
86
- });
87
-
88
- test('should show read-only mode banner', async ({ page }) => {
89
- await page.goto('/');
90
-
91
- // The read-only alert should be visible
92
- await expect(page.getByRole('alert')).toBeVisible();
93
- await expect(page.getByText(/read-only mode/i)).toBeVisible();
94
- });
95
-
96
- test('should have correction metrics component', async ({ page }) => {
97
- await page.goto('/');
98
-
99
- // The page structure should be there with Paper components
100
- const metricsSection = page.locator('.MuiPaper-root');
101
- await expect(metricsSection.first()).toBeVisible();
102
- });
103
- });
104
-
105
- test.describe('File Upload Flow', () => {
106
- test('should open file dialog when clicking Load File', async ({ page }) => {
107
- await page.goto('/');
108
-
109
- // Set up listener for file chooser
110
- let fileChooserOpened = false;
111
- page.on('filechooser', () => {
112
- fileChooserOpened = true;
113
- });
114
-
115
- // Click the button
116
- const loadButton = page.getByRole('button', { name: /load file/i });
117
- await loadButton.click();
118
-
119
- // Wait for the file chooser event to be processed
120
- await page.waitForEvent('filechooser', { timeout: 5000 }).catch(() => {
121
- // Event already fired
122
- });
123
-
124
- // Verify file chooser was triggered
125
- expect(fileChooserOpened).toBe(true);
126
- });
127
- });
128
-
129
- test.describe('Review Mode', () => {
130
- test.beforeEach(async ({ page }) => {
131
- await page.goto('/');
132
- await expect(page.getByText('Lyrics Correction Review')).toBeVisible();
133
- });
134
-
135
- test('should show Review Mode toggle when agentic data is loaded', async ({ page }) => {
136
- await loadFixtureData(page);
137
-
138
- // Wait for content to load
139
- await expect(page.getByText('Hello,')).toBeVisible();
140
-
141
- // The Review Mode toggle should be visible when agentic corrections are present
142
- // It will appear as "Review Off" chip initially (only in non-read-only mode with agentic data)
143
- // Note: In read-only mode, the toggle won't appear
144
- const reviewChip = page.getByText(/Review Off|Review Mode/i);
145
- const chipCount = await reviewChip.count();
146
-
147
- // Log for debugging purposes (will show in test output)
148
- if (chipCount === 0) {
149
- // Review toggle only shows in edit mode, not read-only mode
150
- // This is expected behavior when loading files in read-only mode
151
- }
152
- });
153
-
154
- test('should show batch actions panel when Review Mode is enabled', async ({ page }) => {
155
- await loadFixtureData(page);
156
-
157
- // Wait for content to load
158
- await expect(page.getByText('Hello,')).toBeVisible();
159
-
160
- // Find the Review Mode toggle (only visible in non-read-only mode)
161
- const reviewToggle = page.getByText(/Review Off/i);
162
-
163
- if (await reviewToggle.isVisible({ timeout: 2000 }).catch(() => false)) {
164
- await reviewToggle.click();
165
-
166
- // Wait for the batch actions panel to appear
167
- await expect(page.getByRole('button', { name: /Accept High Confidence/i })).toBeVisible({ timeout: 5000 });
168
- await expect(page.getByRole('button', { name: /Accept All/i })).toBeVisible();
169
- await expect(page.getByRole('button', { name: /Revert All/i })).toBeVisible();
170
- }
171
- });
172
-
173
- test('should render corrected words with original text preview', async ({ page }) => {
174
- await loadFixtureData(page);
175
-
176
- // Wait for transcription content to load
177
- await expect(page.getByText('Hello,')).toBeVisible();
178
-
179
- // Verify correction-related content is rendered
180
- // The corrected word "now" should be visible (from fixture: "you're" -> "now")
181
- await expect(page.getByText('now')).toBeVisible();
182
- });
183
-
184
- test('should toggle Review Mode on and off', async ({ page }) => {
185
- await loadFixtureData(page);
186
-
187
- // Wait for content to load
188
- await expect(page.getByText('Hello,')).toBeVisible();
189
-
190
- // Find the Review toggle (only visible in non-read-only mode)
191
- const reviewOff = page.getByText(/Review Off/i);
192
-
193
- if (await reviewOff.isVisible({ timeout: 2000 }).catch(() => false)) {
194
- // Click to enable Review Mode
195
- await reviewOff.click();
196
-
197
- // Should now show "Review Mode" label (in filled state)
198
- await expect(page.getByText(/Review Mode/i).first()).toBeVisible();
199
-
200
- // Click to disable Review Mode
201
- await page.getByText(/Review Mode/i).first().click();
202
-
203
- // Should show "Review Off" again
204
- await expect(page.getByText(/Review Off/i)).toBeVisible();
205
- }
206
- });
207
- });