peertube-plugin-transposer-connector
Version:
Transposer connector is a PeerTube language tool plugin to transcribe and translate with Whisper
2 lines (1 loc) • 14.3 kB
JavaScript
async function w({registerClientRoute:b,peertubeHelpers:d}){let{notifier:g}=d;function a(){return window.location.origin}function l(t){var u=window.location.href;t=t.replace(/[\[\]]/g,"\\$&");var s=new RegExp("[?&]"+t+"(=([^&#]*)|&|#|$)"),p=s.exec(u);return p?p[2]?decodeURIComponent(p[2].replace(/\+/g," ")):"":null}b({route:"/transposer/translation/edit",onMount:({rootEl:t})=>{t.innerHTML=s();function u(n,i,o){console.log(n),console.log(i),console.log(o);let f=new Blob([o],{type:"text/vtt"}),c=new FormData;c.append("captionfile",f,"".concat(n,"_").concat(i,".vtt")),fetch("".concat(a(),"/api/v1/videos/").concat(n,"/captions/").concat(i),{method:"PUT",body:c,headers:d.getAuthHeader()}).then(r=>{if(!r.ok)throw new Error("Failed to save changes: ".concat(r.status," ").concat(r.statusText));g.success("Changes saved successfully."),window.open("".concat(a(),"/p/transposer/translate?videoId=").concat(n),"_self")}).catch(r=>{g.error("Error saving changes: ".concat(r)),console.error("Error saving changes:",r)})}function s(){return'\n <div id="plugincontainer">\n <h1>Translation Edit Language</h1>\n <button id="saveTranslationEdit">Save changes</button>\n <button id="backButton">Back</button>\n <br>\n <br>\n <textarea id="textArea" style="width: 100%; height: 590px; overflow-y: auto;"></textarea>\n </div>'}t.querySelector("#backButton").addEventListener("click",()=>{console.log("back button clicked");let n=l("videoId");window.open("".concat(a(),"/p/transposer/translate?videoId=").concat(n),"_self")});function m(){var n=l("videoId"),i=l("lang");if(n==null){console.log("No Video Id in query param"),window.open("".concat(a(),"/p/transposer"),"_self");return}if(i==null){console.log("No language in query param");return}fetch("".concat(a(),"/api/v1/videos/").concat(n,"/captions"),{method:"GET",headers:d.getAuthHeader()}).then(o=>{if(!o.ok)throw new Error("Failed to fetch captions: ".concat(o.status," ").concat(o.statusText));return o.json()}).then(o=>{if(o.total==0)throw new Error("No captions available yet.");let f=o.data,c=!1;if(f.forEach(r=>{if(r.language.id===i){c=!0;let h="".concat(a()).concat(r.captionPath);fetch(h).then(e=>{if(!e.ok)throw new Error("Failed to fetch VTT file: ".concat(e.status," ").concat(e.statusText));return e.text()}).then(e=>{document.getElementById("textArea").value=e}).catch(e=>{console.error("Error fetching VTT file:",e)})}}),!c)throw new Error("Language not found")})}t.querySelector("#saveTranslationEdit").addEventListener("click",()=>{let n=l("videoId"),i=l("lang"),o=document.getElementById("textArea").value;if(!o){g.error("Caption text is empty.");return}u(n,i,o)});function x(){return'\n #plugincontainer {\n max-width: 100%;\n padding: 20px;\n position: relative;\n } \n \n #plugincontainer h1 {\n color: var(--mainColor);\n }\n \n #plugincontainer #formcontainer {\n display: flex;\n flex-wrap: wrap;\n }\n \n #plugincontainer .modifyButton,\n #plugincontainer .saveButton, \n #plugincontainer .cancelButton, \n #plugincontainer .deleteButton {\n cursor: pointer;\n padding: 20px;\n }\n \n #plugincontainer input, \n #plugincontainer textarea,\n #plugincontainer select {\n display: block;\n font-size: 16px;\n padding: var(--input-y-padding, 8px) var(--input-x-padding, 12px);\n width: 100%;\n max-width: 100%;\n color: var(--input-fg, #000);\n background-color: var(--input-bg, #fff);\n border: 1px solid var(--input-border-color, #ccc);\n border-radius: var(--input-border-radius, 4px);\n line-height: 24px;\n transition: background-color 0.3s ease;\n }\n \n #plugincontainer p {\n font-size: 18px;\n }\n \n #plugincontainer table {\n width: 100%;\n border-collapse: collapse;\n margin: 25px 0;\n font-size: 0.9em;\n min-width: 130px;\n min-height: 130px;\n }\n \n #plugincontainer table tr {\n text-align: left;\n }\n \n #plugincontainer table th,\n #plugincontainer table td {\n padding: 12px 15px;\n border-bottom: 1px solid var(--inputPlaceholderColor, #ccc);\n }\n \n #plugincontainer table th {\n background-color: var(--greyBackgroundColor, #f8f9fa);\n color: var(--mainForegroundColor);\n }\n \n /* General button styling */\n #plugincontainer button {\n color: var(--on-primary, var(--mainForegroundColor));\n background-color: var(--primary, var(--mainColor));\n border: 1px solid var(--primary, var(--mainColor));\n padding: var(--input-y-padding, 8px) var(--input-x-padding, 12px);\n border-radius: 4px;\n cursor: pointer;\n transition: background-color 0.3s;\n vertical-align: top;\n }\n \n /* Top-level action buttons */\n #plugincontainer > button {\n width: auto;\n min-width: 100px;\n margin-right: 10px;\n }\n \n /* Table buttons */\n #plugincontainer td button {\n width: auto;\n min-width: 80px;\n margin: 0 5px;\n }\n \n #plugincontainer button:hover {\n background-color: var(--secondaryColor);\n }\n \n #plugincontainer button:disabled {\n background-color: var(--greyBackgroundColor, #cccccc);\n color: var(--greyForegroundColor, #666666);\n cursor: not-allowed;\n }\n \n /* Action buttons like in the video list */\n #plugincontainer .action-button {\n position: relative;\n width: 56px;\n height: 56px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-width: unset;\n padding: 8px;\n }\n \n #plugincontainer .action-button.success {\n background-color: var(--primary, var(--mainColor));\n border-color: var(--primary, var(--mainColor));\n }\n \n #plugincontainer .action-button.not-triggered {\n background-color: var(--greyBackgroundColor, #f8f9fa);\n border-color: var(--greyForegroundColor, #ccc);\n color: var(--greyForegroundColor, #666);\n }\n \n #plugincontainer .action-button svg {\n width: 24px;\n height: 24px;\n margin-bottom: 6px;\n fill: var(--on-primary, var(--mainForegroundColor));\n stroke: var(--on-primary, var(--mainForegroundColor));\n }\n \n #plugincontainer .action-button.not-triggered svg {\n fill: var(--greyForegroundColor, #666);\n stroke: var(--greyForegroundColor, #666);\n }\n \n /* Specialized button styles */\n #plugincontainer .translate-field-btn {\n background-color: var(--greyBackgroundColor, #6c757d);\n font-size: 0.8em;\n width: auto;\n padding: 2px 5px;\n margin-left: 5px;\n min-width: unset;\n }\n \n #plugincontainer .translate-field-btn:hover {\n background-color: var(--secondaryColor, #5a6268);\n }\n \n #plugincontainer #triggerDetail {\n background-color: var(--primary, var(--mainColor));\n border: 1px solid var(--primary, var(--mainColor));\n border-radius: 4px;\n padding: 6px;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n \n #plugincontainer #triggerDetail svg {\n fill: var(--on-primary, var(--mainForegroundColor));\n stroke: var(--on-primary, var(--mainForegroundColor));\n }\n \n #plugincontainer .edit-icon path {\n stroke: var(--on-primary, var(--mainForegroundColor));\n }\n \n /* Rest of the styles remain the same */\n #plugincontainer #pageButtonsContainer {\n margin: 15px 0;\n text-align: center;\n }\n \n #plugincontainer #confirmationBox {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background-color: var(--primary, var(--mainColor));\n padding: 20px;\n border-radius: 5px;\n }\n \n #plugincontainer #confirmationBox p {\n margin-bottom: 20px;\n color: var(--on-primary, var(--mainForegroundColor));\n }\n \n #plugincontainer #confirmationBox button {\n margin-right: 10px;\n padding: 8px 16px;\n border: none;\n border-radius: 3px;\n background-color: var(--on-primary, var(--mainForegroundColor));\n color: var(--primary, var(--mainColor));\n cursor: pointer;\n }\n \n #plugincontainer .page-button {\n background-color: var(--primary, var(--mainColor));\n min-width: unset;\n width: auto;\n }\n \n #plugincontainer .current-page-button {\n background-color: var(--secondaryColor);\n }\n \n /* Action buttons and Header Styles */\n #plugincontainer .action-column-header {\n padding: 0;\n }\n \n #plugincontainer .action-headers-container {\n display: flex;\n justify-content: space-between;\n width: 100%;\n }\n \n #plugincontainer .action-header {\n flex: 1;\n text-align: center;\n font-size: 0.9em;\n font-weight: bold;\n padding: 8px 4px;\n white-space: nowrap;\n }\n \n #plugincontainer .action-buttons-row {\n display: flex;\n justify-content: space-between;\n width: 100%;\n }\n \n #plugincontainer .action-cell {\n flex: 1;\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 4px;\n }\n \n #plugincontainer .action-button.label-xl {\n font-size: 90%;\n padding: var(--input-y-padding) calc(var(--input-x-padding) / 2) !important;\n }\n \n #plugincontainer .counter-label {\n font-size: 0.75em;\n margin-top: 4px;\n text-align: center;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n \n /* Language notice styles */\n #plugincontainer .language-notice {\n margin: 10px 0;\n padding: 10px;\n border-radius: 4px;\n }\n \n #plugincontainer .language-notice.success {\n background-color: #e6ffe6;\n border: 1px solid #b3ffb3;\n }\n \n #plugincontainer .language-notice.warning {\n background-color: #fff8e6;\n border: 1px solid #ffe0b3;\n }\n \n #plugincontainer .language-notice p {\n margin: 0;\n font-size: 14px;\n }\n \n /* Field container styles */\n #plugincontainer .field-container {\n display: flex;\n align-items: center;\n width: 100%;\n }\n \n #plugincontainer .field-container input,\n #plugincontainer .field-container textarea {\n flex: 1;\n min-width: 200px;\n }\n \n /* Modal styles */\n #plugincontainer .modal {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0,0,0,0.5);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n }\n \n #plugincontainer .modal-content {\n background-color: var(--backgroundPrimary, white);\n padding: 20px;\n border-radius: 5px;\n width: 400px;\n text-align: center;\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n }\n \n #plugincontainer .modal-content h3 {\n margin-top: 0;\n color: var(--primary, var(--mainColor));\n }\n \n #plugincontainer .modal-content button {\n margin: 10px;\n padding: 10px 15px;\n min-width: 100px;\n }\n \n /* For the translation status colors */\n #plugincontainer input[style*="background-color: #e6ffe6"],\n #plugincontainer textarea[style*="background-color: #e6ffe6"] {\n background-color: #e6ffe6 !important;\n }\n \n #plugincontainer input[style*="background-color: #ffe6e6"],\n #plugincontainer textarea[style*="background-color: #ffe6e6"] {\n background-color: #ffe6e6 !important;\n }\n \n #plugincontainer input[style*="background-color: #fff8e6"],\n #plugincontainer textarea[style*="background-color: #fff8e6"] {\n background-color: #fff8e6 !important;\n }\n '}function v(){m();let n=document.createElement("style");n.innerHTML=x(),t.appendChild(n)}v()}})}export{w as register};