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,268 +0,0 @@
1
- import { useMemo } from 'react'
2
- import { Paper, Typography, Box, IconButton } from '@mui/material'
3
- import { ReferenceViewProps } from './shared/types'
4
- import { calculateReferenceLinePositions } from './shared/utils/referenceLineCalculator'
5
- import { SourceSelector } from './shared/components/SourceSelector'
6
- import { HighlightedText } from './shared/components/HighlightedText'
7
- import { TranscriptionWordPosition } from './shared/types'
8
- import { getWordsFromIds } from './shared/utils/wordUtils'
9
- import ContentCopyIcon from '@mui/icons-material/ContentCopy'
10
- import { styled } from '@mui/material/styles'
11
-
12
- const SegmentControls = styled(Box)({
13
- display: 'flex',
14
- alignItems: 'center',
15
- gap: '2px',
16
- paddingTop: '1px',
17
- paddingRight: '4px'
18
- })
19
-
20
- const TextContainer = styled(Box)({
21
- flex: 1,
22
- minWidth: 0,
23
- })
24
-
25
- export default function ReferenceView({
26
- referenceSources,
27
- anchors,
28
- onElementClick,
29
- onWordClick,
30
- flashingType,
31
- corrected_segments,
32
- currentSource,
33
- onSourceChange,
34
- highlightInfo,
35
- mode,
36
- gaps,
37
- corrections,
38
- onAddLyrics
39
- }: ReferenceViewProps) {
40
- // Get available sources from referenceSources object
41
- const availableSources = useMemo(() =>
42
- Object.keys(referenceSources),
43
- [referenceSources]
44
- )
45
-
46
- // Ensure we always have a valid currentSource
47
- const effectiveCurrentSource = useMemo(() =>
48
- currentSource || (availableSources.length > 0 ? availableSources[0] : ''),
49
- [currentSource, availableSources]
50
- )
51
-
52
- // Create word positions for the reference view
53
- const referenceWordPositions = useMemo(() => {
54
- const positions: TranscriptionWordPosition[] = [];
55
- const allPositions = new Map<number, TranscriptionWordPosition[]>();
56
-
57
- // Map anchor words
58
- anchors?.forEach(anchor => {
59
- const position = anchor.reference_positions[effectiveCurrentSource];
60
- if (position === undefined) return;
61
-
62
- if (!allPositions.has(position)) {
63
- allPositions.set(position, []);
64
- }
65
-
66
- const referenceWords = getWordsFromIds(
67
- referenceSources[effectiveCurrentSource].segments,
68
- anchor.reference_word_ids[effectiveCurrentSource] || []
69
- );
70
-
71
- referenceWords.forEach(word => {
72
- const wordPosition: TranscriptionWordPosition = {
73
- word: {
74
- id: word.id,
75
- text: word.text,
76
- start_time: word.start_time ?? undefined,
77
- end_time: word.end_time ?? undefined
78
- },
79
- type: 'anchor',
80
- sequence: anchor,
81
- isInRange: true
82
- };
83
- allPositions.get(position)!.push(wordPosition);
84
- });
85
- });
86
-
87
- // Map gap words
88
- gaps?.forEach(gap => {
89
- const precedingAnchor = gap.preceding_anchor_id ?
90
- anchors?.find(a => a.id === gap.preceding_anchor_id) :
91
- undefined;
92
- const followingAnchor = gap.following_anchor_id ?
93
- anchors?.find(a => a.id === gap.following_anchor_id) :
94
- undefined;
95
-
96
- const position = precedingAnchor?.reference_positions[effectiveCurrentSource] ??
97
- followingAnchor?.reference_positions[effectiveCurrentSource];
98
-
99
- if (position === undefined) return;
100
-
101
- const gapPosition = precedingAnchor ? position + 1 : position - 1;
102
-
103
- if (!allPositions.has(gapPosition)) {
104
- allPositions.set(gapPosition, []);
105
- }
106
-
107
- const referenceWords = getWordsFromIds(
108
- referenceSources[effectiveCurrentSource].segments,
109
- gap.reference_word_ids[effectiveCurrentSource] || []
110
- );
111
-
112
- referenceWords.forEach(word => {
113
- // Find if this word has a correction
114
- const isWordCorrected = corrections?.some(correction =>
115
- correction.reference_positions?.[effectiveCurrentSource]?.toString() === word.id &&
116
- gap.transcribed_word_ids.includes(correction.word_id)
117
- );
118
-
119
- const wordPosition: TranscriptionWordPosition = {
120
- word: {
121
- id: word.id,
122
- text: word.text,
123
- start_time: word.start_time ?? undefined,
124
- end_time: word.end_time ?? undefined
125
- },
126
- type: 'gap',
127
- sequence: gap,
128
- isInRange: true,
129
- isCorrected: isWordCorrected
130
- };
131
- allPositions.get(gapPosition)!.push(wordPosition);
132
- });
133
- });
134
-
135
- // Sort by position and flatten
136
- Array.from(allPositions.entries())
137
- .sort(([a], [b]) => a - b)
138
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
139
- .forEach(([_, words]) => {
140
- positions.push(...words);
141
- });
142
-
143
- return positions;
144
- }, [anchors, gaps, effectiveCurrentSource, referenceSources, corrections]);
145
-
146
- const { linePositions } = useMemo(() =>
147
- calculateReferenceLinePositions(
148
- corrected_segments,
149
- anchors,
150
- effectiveCurrentSource
151
- ),
152
- [corrected_segments, anchors, effectiveCurrentSource]
153
- )
154
-
155
- // Create a mapping of reference words to their corrections
156
- const referenceCorrections = useMemo(() => {
157
- const correctionMap = new Map<string, string>();
158
-
159
- corrections?.forEach(correction => {
160
- const referencePosition = correction.reference_positions?.[effectiveCurrentSource];
161
- if (referencePosition !== undefined) {
162
- correctionMap.set(referencePosition.toString(), correction.corrected_word);
163
- }
164
- });
165
-
166
- return correctionMap;
167
- }, [corrections, effectiveCurrentSource]);
168
-
169
- // Get the segments for the current source
170
- const currentSourceSegments = referenceSources[effectiveCurrentSource]?.segments || [];
171
-
172
- // Helper function to copy text to clipboard
173
- const copyToClipboard = (text: string) => {
174
- navigator.clipboard.writeText(text);
175
- };
176
-
177
- // Helper function to copy all reference text from current source
178
- const copyAllReferenceText = () => {
179
- const allText = currentSourceSegments
180
- .map(segment => segment.words.map(w => w.text).join(' '))
181
- .join('\n');
182
- copyToClipboard(allText);
183
- };
184
-
185
- return (
186
- <Paper sx={{ p: 0.8, position: 'relative' }}>
187
- <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 0.5 }}>
188
- <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
189
- <Typography variant="h6" sx={{ fontSize: '0.9rem', mb: 0 }}>
190
- Reference Lyrics
191
- </Typography>
192
- <IconButton
193
- size="small"
194
- onClick={copyAllReferenceText}
195
- sx={{
196
- padding: '2px',
197
- height: '20px',
198
- width: '20px',
199
- minHeight: '20px',
200
- minWidth: '20px'
201
- }}
202
- title="Copy all reference lyrics"
203
- >
204
- <ContentCopyIcon sx={{ fontSize: '1rem' }} />
205
- </IconButton>
206
- </Box>
207
- <SourceSelector
208
- availableSources={availableSources}
209
- currentSource={effectiveCurrentSource}
210
- onSourceChange={onSourceChange}
211
- onAddLyrics={onAddLyrics}
212
- />
213
- </Box>
214
- <Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.2 }}>
215
- {currentSourceSegments.map((segment, index) => (
216
- <Box
217
- key={index}
218
- sx={{
219
- display: 'flex',
220
- alignItems: 'flex-start',
221
- width: '100%',
222
- mb: 0,
223
- '&:hover': {
224
- backgroundColor: (theme) => theme.palette.action.hover
225
- }
226
- }}
227
- >
228
- <SegmentControls>
229
- <IconButton
230
- size="small"
231
- onClick={() => copyToClipboard(segment.words.map(w => w.text).join(' '))}
232
- sx={{
233
- padding: '1px',
234
- height: '18px',
235
- width: '18px',
236
- minHeight: '18px',
237
- minWidth: '18px'
238
- }}
239
- >
240
- <ContentCopyIcon sx={{ fontSize: '0.9rem' }} />
241
- </IconButton>
242
- </SegmentControls>
243
- <TextContainer>
244
- <HighlightedText
245
- wordPositions={referenceWordPositions.filter(wp =>
246
- segment.words.some(w => w.id === wp.word.id)
247
- )}
248
- segments={[segment]}
249
- anchors={anchors}
250
- onElementClick={onElementClick}
251
- onWordClick={onWordClick}
252
- flashingType={flashingType}
253
- highlightInfo={highlightInfo}
254
- mode={mode}
255
- isReference={true}
256
- currentSource={effectiveCurrentSource}
257
- linePositions={linePositions}
258
- referenceCorrections={referenceCorrections}
259
- gaps={gaps}
260
- preserveSegments={true}
261
- />
262
- </TextContainer>
263
- </Box>
264
- ))}
265
- </Box>
266
- </Paper>
267
- )
268
- }
@@ -1,336 +0,0 @@
1
- import {
2
- Dialog,
3
- DialogTitle,
4
- DialogContent,
5
- DialogActions,
6
- IconButton,
7
- Box,
8
- Button,
9
- Typography,
10
- TextField
11
- } from '@mui/material'
12
- import CloseIcon from '@mui/icons-material/Close'
13
- import ContentPasteIcon from '@mui/icons-material/ContentPaste'
14
- import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh'
15
- import ArrowBackIcon from '@mui/icons-material/ArrowBack'
16
- import { LyricsSegment, Word } from '../types'
17
- import { useState, useEffect, useCallback, useMemo } from 'react'
18
- import { nanoid } from 'nanoid'
19
- import ModeSelectionModal from './ModeSelectionModal'
20
- import LyricsSynchronizer from './LyricsSynchronizer'
21
-
22
- // Augment window type for audio functions
23
- declare global {
24
- interface Window {
25
- getAudioDuration?: () => number;
26
- toggleAudioPlayback?: () => void;
27
- isAudioPlaying?: boolean;
28
- }
29
- }
30
-
31
- type ModalMode = 'selection' | 'replace' | 'resync'
32
-
33
- interface ReplaceAllLyricsModalProps {
34
- open: boolean
35
- onClose: () => void
36
- onSave: (newSegments: LyricsSegment[]) => void
37
- onPlaySegment?: (startTime: number) => void
38
- currentTime?: number
39
- setModalSpacebarHandler: (handler: (() => (e: KeyboardEvent) => void) | undefined) => void
40
- existingSegments?: LyricsSegment[] // Current segments for re-sync mode
41
- }
42
-
43
- export default function ReplaceAllLyricsModal({
44
- open,
45
- onClose,
46
- onSave,
47
- onPlaySegment,
48
- currentTime = 0,
49
- setModalSpacebarHandler,
50
- existingSegments = []
51
- }: ReplaceAllLyricsModalProps) {
52
- const [mode, setMode] = useState<ModalMode>('selection')
53
- const [inputText, setInputText] = useState('')
54
- const [newSegments, setNewSegments] = useState<LyricsSegment[]>([])
55
-
56
- // Reset state when modal opens
57
- useEffect(() => {
58
- if (open) {
59
- setMode('selection')
60
- setInputText('')
61
- setNewSegments([])
62
- }
63
- }, [open])
64
-
65
- // Parse the input text to get line and word counts
66
- const parseInfo = useMemo(() => {
67
- if (!inputText.trim()) return { lines: 0, words: 0 }
68
-
69
- const lines = inputText.trim().split('\n').filter(line => line.trim().length > 0)
70
- const totalWords = lines.reduce((count, line) => {
71
- return count + line.trim().split(/\s+/).length
72
- }, 0)
73
-
74
- return { lines: lines.length, words: totalWords }
75
- }, [inputText])
76
-
77
- // Process the input text into segments and words
78
- const processLyrics = useCallback(() => {
79
- if (!inputText.trim()) return
80
-
81
- const lines = inputText.trim().split('\n').filter(line => line.trim().length > 0)
82
- const segments: LyricsSegment[] = []
83
-
84
- lines.forEach((line) => {
85
- const words = line.trim().split(/\s+/).filter(word => word.length > 0)
86
- const segmentWords: Word[] = words.map((wordText) => ({
87
- id: nanoid(),
88
- text: wordText,
89
- start_time: null,
90
- end_time: null,
91
- confidence: 1.0,
92
- created_during_correction: true
93
- }))
94
-
95
- segments.push({
96
- id: nanoid(),
97
- text: line.trim(),
98
- words: segmentWords,
99
- start_time: null,
100
- end_time: null
101
- })
102
- })
103
-
104
- setNewSegments(segments)
105
- setMode('resync') // Go to synchronizer with the new segments
106
- }, [inputText])
107
-
108
- // Handle paste from clipboard
109
- const handlePasteFromClipboard = useCallback(async () => {
110
- try {
111
- const text = await navigator.clipboard.readText()
112
- setInputText(text)
113
- } catch (error) {
114
- console.error('Failed to read from clipboard:', error)
115
- alert('Failed to read from clipboard. Please paste manually.')
116
- }
117
- }, [])
118
-
119
- // Handle modal close
120
- const handleClose = useCallback(() => {
121
- setMode('selection')
122
- setInputText('')
123
- setNewSegments([])
124
- onClose()
125
- }, [onClose])
126
-
127
- // Handle save from synchronizer
128
- const handleSave = useCallback((segments: LyricsSegment[]) => {
129
- onSave(segments)
130
- handleClose()
131
- }, [onSave, handleClose])
132
-
133
- // Handle mode selection
134
- const handleSelectReplace = useCallback(() => {
135
- setMode('replace')
136
- }, [])
137
-
138
- const handleSelectResync = useCallback(() => {
139
- setMode('resync')
140
- }, [])
141
-
142
- // Handle back to selection
143
- const handleBackToSelection = useCallback(() => {
144
- setMode('selection')
145
- setInputText('')
146
- setNewSegments([])
147
- }, [])
148
-
149
- // Determine which segments to use for synchronizer
150
- const segmentsForSync = mode === 'resync' && newSegments.length > 0
151
- ? newSegments
152
- : existingSegments
153
-
154
- // Check if we have existing lyrics
155
- const hasExistingLyrics = existingSegments.length > 0 &&
156
- existingSegments.some(s => s.words.length > 0)
157
-
158
- return (
159
- <>
160
- {/* Mode Selection Modal */}
161
- <ModeSelectionModal
162
- open={open && mode === 'selection'}
163
- onClose={handleClose}
164
- onSelectReplace={handleSelectReplace}
165
- onSelectResync={handleSelectResync}
166
- hasExistingLyrics={hasExistingLyrics}
167
- />
168
-
169
- {/* Replace All Lyrics Modal (Paste Phase) */}
170
- <Dialog
171
- open={open && mode === 'replace'}
172
- onClose={handleClose}
173
- maxWidth="md"
174
- fullWidth
175
- PaperProps={{
176
- sx: {
177
- height: '80vh',
178
- maxHeight: '80vh'
179
- }
180
- }}
181
- >
182
- <DialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
183
- <IconButton onClick={handleBackToSelection} size="small">
184
- <ArrowBackIcon />
185
- </IconButton>
186
- <Box sx={{ flex: 1 }}>
187
- Replace All Lyrics
188
- </Box>
189
- <IconButton onClick={handleClose} sx={{ ml: 'auto' }}>
190
- <CloseIcon />
191
- </IconButton>
192
- </DialogTitle>
193
-
194
- <DialogContent
195
- dividers
196
- sx={{
197
- display: 'flex',
198
- flexDirection: 'column',
199
- flexGrow: 1,
200
- overflow: 'hidden'
201
- }}
202
- >
203
- <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2, height: '100%' }}>
204
- <Typography variant="h6" gutterBottom>
205
- Paste your new lyrics below:
206
- </Typography>
207
-
208
- <Typography variant="body2" color="text.secondary" gutterBottom>
209
- Each line will become a separate segment. Words will be separated by spaces.
210
- </Typography>
211
-
212
- <Box sx={{ display: 'flex', gap: 2, mb: 2 }}>
213
- <Button
214
- variant="outlined"
215
- onClick={handlePasteFromClipboard}
216
- startIcon={<ContentPasteIcon />}
217
- size="small"
218
- >
219
- Paste from Clipboard
220
- </Button>
221
- <Typography variant="body2" sx={{
222
- alignSelf: 'center',
223
- color: 'text.secondary',
224
- fontWeight: 'medium'
225
- }}>
226
- {parseInfo.lines} lines, {parseInfo.words} words
227
- </Typography>
228
- </Box>
229
-
230
- <TextField
231
- multiline
232
- rows={15}
233
- value={inputText}
234
- onChange={(e) => setInputText(e.target.value)}
235
- placeholder="Paste your lyrics here...&#10;Each line will become a segment&#10;Words will be separated by spaces"
236
- sx={{
237
- flexGrow: 1,
238
- '& .MuiInputBase-root': {
239
- height: '100%',
240
- alignItems: 'flex-start'
241
- }
242
- }}
243
- />
244
- </Box>
245
- </DialogContent>
246
-
247
- <DialogActions>
248
- <Button onClick={handleClose} color="inherit">
249
- Cancel
250
- </Button>
251
- <Button
252
- variant="contained"
253
- onClick={processLyrics}
254
- disabled={!inputText.trim()}
255
- startIcon={<AutoFixHighIcon />}
256
- >
257
- Continue to Sync
258
- </Button>
259
- </DialogActions>
260
- </Dialog>
261
-
262
- {/* Synchronizer Modal */}
263
- <Dialog
264
- open={open && mode === 'resync'}
265
- onClose={handleClose}
266
- maxWidth={false}
267
- fullWidth
268
- PaperProps={{
269
- sx: {
270
- height: '90vh',
271
- margin: '5vh 2vw',
272
- maxWidth: 'calc(100vw - 4vw)',
273
- width: 'calc(100vw - 4vw)'
274
- }
275
- }}
276
- >
277
- <DialogTitle sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
278
- <IconButton onClick={handleBackToSelection} size="small">
279
- <ArrowBackIcon />
280
- </IconButton>
281
- <Box sx={{ flex: 1 }}>
282
- {newSegments.length > 0 ? 'Sync New Lyrics' : 'Re-sync Existing Lyrics'}
283
- </Box>
284
- <IconButton onClick={handleClose} sx={{ ml: 'auto' }}>
285
- <CloseIcon />
286
- </IconButton>
287
- </DialogTitle>
288
-
289
- <DialogContent
290
- dividers
291
- sx={{
292
- display: 'flex',
293
- flexDirection: 'column',
294
- flexGrow: 1,
295
- overflow: 'hidden',
296
- p: 2
297
- }}
298
- >
299
- {segmentsForSync.length > 0 ? (
300
- <LyricsSynchronizer
301
- segments={segmentsForSync}
302
- currentTime={currentTime}
303
- onPlaySegment={onPlaySegment}
304
- onSave={handleSave}
305
- onCancel={handleClose}
306
- setModalSpacebarHandler={setModalSpacebarHandler}
307
- />
308
- ) : (
309
- <Box sx={{
310
- display: 'flex',
311
- flexDirection: 'column',
312
- alignItems: 'center',
313
- justifyContent: 'center',
314
- height: '100%',
315
- gap: 2
316
- }}>
317
- <Typography variant="h6" color="text.secondary">
318
- No lyrics to sync
319
- </Typography>
320
- <Typography variant="body2" color="text.secondary">
321
- Go back and paste new lyrics, or close this modal.
322
- </Typography>
323
- <Button
324
- variant="outlined"
325
- onClick={handleBackToSelection}
326
- startIcon={<ArrowBackIcon />}
327
- >
328
- Back to Selection
329
- </Button>
330
- </Box>
331
- )}
332
- </DialogContent>
333
- </Dialog>
334
- </>
335
- )
336
- }