From 9795d5856e706f8d91f271f8765f20fcaf7da0a4 Mon Sep 17 00:00:00 2001 From: sergiotarxz Date: Thu, 21 Jan 2021 23:18:21 +0100 Subject: [PATCH] feat: Spitting on a new theme while the Jorge theme goes stable and solving some errors. --- peertube-dl-web.conf | 3 +- themes/default/public/dist/css/index.css | 390 +++++++++++------- .../public/dist/css/index.css | 252 +++++++++++ .../public/dist/img/peertube-dl-logo.png | Bin 0 -> 3701 bytes .../new_look_default/public/dist/index.html | 69 ++++ themes/new_look_default/public/package.json | 13 + .../public/src/application.js | 106 +++++ themes/new_look_default/public/src/index.js | 10 + .../public/src/view/download_form.js | 35 ++ .../public/src/view/format_selector.js | 87 ++++ .../public/src/view/loading_modal.js | 25 ++ .../public/src/view/poping_notice.js | 56 +++ .../public/src/view/video_container.js | 112 +++++ .../new_look_default/public/webpack.config.js | 10 + 14 files changed, 1012 insertions(+), 156 deletions(-) create mode 100644 themes/new_look_default/public/dist/css/index.css create mode 100644 themes/new_look_default/public/dist/img/peertube-dl-logo.png create mode 100644 themes/new_look_default/public/dist/index.html create mode 100644 themes/new_look_default/public/package.json create mode 100644 themes/new_look_default/public/src/application.js create mode 100644 themes/new_look_default/public/src/index.js create mode 100644 themes/new_look_default/public/src/view/download_form.js create mode 100644 themes/new_look_default/public/src/view/format_selector.js create mode 100644 themes/new_look_default/public/src/view/loading_modal.js create mode 100644 themes/new_look_default/public/src/view/poping_notice.js create mode 100644 themes/new_look_default/public/src/view/video_container.js create mode 100644 themes/new_look_default/public/webpack.config.js diff --git a/peertube-dl-web.conf b/peertube-dl-web.conf index 71f81e1..3c317df 100644 --- a/peertube-dl-web.conf +++ b/peertube-dl-web.conf @@ -5,5 +5,6 @@ clients => 3, proxy => 1, pid_file => $ENV{PIDFILE} || '/var/run/peertube-dl-web.pid', - } + }, + theme => 'new_look_default', }; diff --git a/themes/default/public/dist/css/index.css b/themes/default/public/dist/css/index.css index d5545f8..87c0190 100644 --- a/themes/default/public/dist/css/index.css +++ b/themes/default/public/dist/css/index.css @@ -1,194 +1,274 @@ body { - height: 98vh; - - display: flex; - flex-flow: column; - align-items: center; - justify-content: center; - - background-color: #111827; + height: 99.9%; + margin: 0; + padding: 0; } -.application-container { - display: flex; - flex-flow: column; - align-items: center; - justify-content: center; - - border-radius: 0.3rem; - - background-color: #1f2937; - - padding: 1.5rem 3rem 1.5rem 3rem; +a { + color: blue; } -.application-container form { - display: flex; - flex-flow: column; - justify-content: center; - - width: 100%; - padding: 1rem; +a:hover,a:focus { + text-decoration: underline; } -.application-container h2 { - color: #ffffff; - font-weight: 400; - font-size: 1.6rem; -} - -.application-container input { - padding: 1rem; - - color: #ffffff; - background-color: #374151; - - border-radius: 0.2rem; - border: 1px solid transparent; -} - -.application-container button { - margin-top: 1rem; - - color: #ffffff; - font-weight: bold; - - background-color: #059669; - - border-radius: 0.2rem; - border: 1px solid transparent; - - padding: 0.5rem 1rem 0.5rem 1rem; -} - -.application-container button, -.application-container input { - font-size: 0.9rem; -} - -.application-container.active { - display: flex; -} - -#poping-notice { - position: absolute; - display: none; - padding: 3rem; - border-radius: 0.3rem; - background-color: #374151; - color: white; -} - -#poping-notice-content a { - text-decoration: none; - color: #10b981; -} - -#poping-notice-container-bar { - display: flex; - justify-content: center; -} - -#close-poping-notice { - background-color: #059669; - padding: 0.5rem 5rem 0.5rem 5rem; - border-radius: 0.3rem; - text-decoration: none; - font-weight: bolder; - color: white; +#video { + width: 100%; + margin: 3px; } #modal-video-container { - position: absolute; - display: none; + display: none; + background: white; + position: fixed; + top: 50%; + left: 50%; + height: 100%; + width: 100%; + transform: translate(-50%, -50%); + border: black 1px solid; +} - height: 100vh; - width: 100%; - - flex-flow: column; - align-items: center; - - background-color: #111827; +#modal-video-container.active { + display: block; } .video-container-bar { - width: 95%; - height: 2rem; - padding: 1rem; - display: flex; - justify-content: end; + display: flex; + justify-content: right; } -.video-container-bar a { - padding: 1rem; - border-radius: 0.3rem; - - display: flex; - align-items: center; - justify-content: center; - - background-color: #dc2626; +#close-and-reset-video-container { + margin-top: 0.25rem; + margin-right: 0.25rem; + border: 1px solid black; } -#modal-video-container > #block { - display: flex; - flex-flow: column; - align-items: center; - justify-content: center; +#close-and-reset-video-container:hover,#close-and-reset-video-container:focus { + background: black; + color: white; } #download-video-container { - padding: 2rem; - - display: flex; - align-items: center; - justify-content: center; + margin: 10px; + justify-content: center; } -#download-video-prepare, -#download-video { - display: none; - border-radius: 0.3rem; - background-color: #059669; - text-decoration: none; - color: white; - user-select: none; - cursor: pointer; +#download-video-container a { + display: none; + padding-left: 5px; + padding-right: 5px; + padding-top: 5px; + padding-bottom: 5px; + width: 100%; + background: #0a0; + border-radius: 5px; + font-size: 30px; + color: white; + height: 30px; } -#download-video-loading.active { - height: 2rem; +#download-video-container a.active { + display: block; } -#download-video-container a.active, -#download-video-loading.active { - display: block; - padding: 0.5rem 2rem 0.5rem 2rem; +#download-video-container a embed { + height: 30px; } -#modal-loading, -#modal-format-selector { - display: none; +#video-container { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + height: 100%; } -#poping-notice.active, -#modal-video-container.active { - --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), - 0 4px 6px -2px rgba(0, 0, 0, 0.05); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), - var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +.block { + display: block; } +.application-container { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + text-align: center; + height: 100%; + background: #000; + color: white; +} + +#download-form { + display: flex; + justify-content: center; + flex-direction: column; +} + +#download-form-button { + margin-top: 5px; + height: 50px; + font-size: 1.5rem; + background: #fff; + color: black; + border: none; +} + +h2 { + font-size: 2rem; +} + +#modal-loading { + display: none; + position: fixed; + top: 50%; + left: 50%; + height: 100%; + width: 100%; + transform: translate(-50%, -50%); + border: black 1px solid; + justify-content: right; + align-items: center; +} + +#modal-loading.active { + display: flex; +} + +#modal-loading embed { + width: 10%; +} + +#poping-notice { + display: none; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border: black 1px solid; + width: 91%; + background: white; + padding: 10px; + border-radius: 15px; + max-height: 95%; + overflow-y: scroll; +} + #poping-notice.active { - display: block; + display: block; } -#modal-video-container.active { - display: flex; +#poping-notice-container-bar { + display: flex; + justify-content: center; + font-size: 5rem; } -@media (min-width: 812px) { - #poping-notice { - width: 40%; - } +#close-poping-notice { + width: 150px; + height: 150px; + align-items: center; + display: flex; + text-align: center; + justify-content: center; + border-radius: 50%; + background: #0f0; + color: black; + text-decoration: none; +} + +#close-poping-notice:hover,#close-poping-notice:focus { + background: black; + color: white; +} + +#modal-format-selector { + display: none; + background: white; + position: fixed; + top: 50%; + left: 50%; + height: 100%; + width: 100%; + transform: translate(-50%, -50%); + border: black 1px solid; + flex-direction: column; + overflow-y: scroll; +} + +#modal-format-selector.active { + display: flex; +} + +#modal-format-selector > h2 { + text-align: center; +} + +#modal-format-selector > p { + margin-left: 2rem; +} + +#modal-format-selector .format-list { + box-sizing: border-box; + background: #fff; + margin: 2rem; +} + +#close-modal-format-selector { + margin-top: 0.50rem; + margin-right: 0.50rem; + border: 1px solid black; + background: grey; + color: white; + width: 25px; + height: 25px; + text-align: center; + font-size: 20px; + font-weight: bold; +} + +#close-modal-format-selector:hover,#close-modal-format-selector:focus { + background: black; +} + +.format-list > div { + width: 100%; + display: grid; + grid-auto-columns: 50%; + grid-template-areas: "a a"; +} + +.format-list > div > a { + border: 1px solid black; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + padding-right: 5%; + padding-left: 5%; + text-decoration: none; + color: black; + background: #eee; + overflow-wrap: anywhere; +} + +.format-list > div > a:hover { + background: black; + color: white; +} + +.format-list > div > a:after { + padding-bottom: 100%; + display: block; + content: ""; +} + +div.video-formats a { + background: #f00; +} + +@media (min-width: 668px) { + #poping-notice { + width: 629px; + } } diff --git a/themes/new_look_default/public/dist/css/index.css b/themes/new_look_default/public/dist/css/index.css new file mode 100644 index 0000000..2ddd890 --- /dev/null +++ b/themes/new_look_default/public/dist/css/index.css @@ -0,0 +1,252 @@ +body { + height: 98vh; + + display: flex; + flex-flow: column; + align-items: center; + justify-content: center; + + background-color: #111827; +} + +.application-container { + display: flex; + flex-flow: column; + align-items: center; + justify-content: center; + + border-radius: 0.3rem; + + background-color: #1f2937; + + padding: 1.5rem 3rem 1.5rem 3rem; +} + +.application-container form { + display: flex; + flex-flow: column; + justify-content: center; + + width: 100%; + padding: 1rem; +} + +.application-container h2 { + color: #ffffff; + font-weight: 400; + font-size: 1.6rem; +} + +.application-container input { + padding: 1rem; + + color: #ffffff; + background-color: #374151; + + border-radius: 0.2rem; + border: 1px solid transparent; +} + +.application-container button { + margin-top: 1rem; + + color: #ffffff; + font-weight: bold; + + background-color: #059669; + + border-radius: 0.2rem; + border: 1px solid transparent; + + padding: 0.5rem 1rem 0.5rem 1rem; +} + +.application-container button:hover,.application-container button:focus { + background-color: #059; +} + +.application-container button, +.application-container input { + font-size: 0.9rem; +} + +.application-container.active { + display: flex; +} + +#poping-notice { + position: absolute; + display: none; + padding: 3rem; + border-radius: 0.3rem; + background-color: #374151; + color: white; +} + +#poping-notice-content a { + text-decoration: none; + color: #10b981; +} + +#poping-notice-content a:hover,#poping-notice-content a:focus { + color: #0ae; +} + +#poping-notice-container-bar { + display: flex; + justify-content: center; +} + +#close-poping-notice { + background-color: #059669; + padding: 0.5rem 5rem 0.5rem 5rem; + border-radius: 0.3rem; + text-decoration: none; + font-weight: bolder; + color: white; +} + +#close-poping-notice:hover,#close-poping-notice:focus { + background-color: #059; +} + +#modal-video-container { + position: absolute; + display: none; + + height: 100vh; + width: 100%; + + flex-flow: column; + align-items: center; + + background-color: #111827; +} + +.video-container-bar { + width: 95%; + height: 2rem; + padding: 1rem; + display: flex; + justify-content: end; +} + +.video-container-bar a { + padding: 1rem; + border-radius: 0.3rem; + + display: flex; + align-items: center; + justify-content: center; + + background-color: #dc2626; +} + +.video-container-bar a:hover,.video-container-bar a:focus { + color: white; + background-color: grey; +} + + +#modal-video-container > #block { + display: flex; + flex-flow: column; + align-items: center; + justify-content: center; +} + +#download-video-container { + padding: 2rem; + + display: flex; + align-items: center; + justify-content: center; +} + +.button-download { + display: none; + border-radius: 0.3rem; + background-color: #059669; + text-decoration: none; + color: white; + user-select: none; + cursor: pointer; + height: 30px; + padding: 0 2rem; +} + +.button-download:hover,.button-download:focus { + background-color: #059; +} + +.button-download embed { + height: 100%; +} + +#download-video-loading.active { + height: 2rem; +} + +#download-video-container .button-download.active { + display: flex; + align-items: center; +} + +#modal-loading, +#modal-format-selector { + display: none; +} + +#poping-notice.active, +#modal-video-container.active { + --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), + 0 4px 6px -2px rgba(0, 0, 0, 0.05); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), + var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +#poping-notice.active { + display: block; +} + +#modal-video-container.active { + display: flex; +} + +#modal-loading { + display: none; + position: fixed; + top: 50%; + left: 50%; + height: 100%; + width: 100%; + transform: translate(-50%, -50%); + border: black 1px solid; + justify-content: right; + align-items: center; +} + +#modal-loading.active { + display: flex; +} + +#modal-loading embed { + width: 10%; +} + +#video { + width: 100%; +} + +#video-container { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; +} + +@media (min-width: 812px) { + #poping-notice { + width: 40%; + } +} diff --git a/themes/new_look_default/public/dist/img/peertube-dl-logo.png b/themes/new_look_default/public/dist/img/peertube-dl-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f884590d368d1e60c6f1f908c147f1c285b44caa GIT binary patch literal 3701 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 NSl?W)Oy^4YKLD4{YIXns literal 0 HcmV?d00001 diff --git a/themes/new_look_default/public/dist/index.html b/themes/new_look_default/public/dist/index.html new file mode 100644 index 0000000..215e5b7 --- /dev/null +++ b/themes/new_look_default/public/dist/index.html @@ -0,0 +1,69 @@ + + + + + + + + +
+

Peertube-dl Web Application

+
+ + +
+
+ + + +
+
+

This webpage is free as in freedom software, it is offered to you with the hope it will be useful, but without any warranty, + you can find the source code at my gitea with docs to setup your own + webpage like this, this software is licensed under the AGPLv3 license which means you MUST convey the source code in a human readable form + if you distribute this software or use it as an service to users of service or distributees.

+ +

I hope that if you find a non supported url which should be supported, a bug, or a feature you would like this webpage to have you file an issue in + https://gitea.sergiotarxz.freemyip.com/sergiotarxz/Peertube-dl/issues + to help this software improve since I find tracking users a pretty bad way to discover bugs and potential good features.

+ +

This webpage may load third party resources depending on the url you give to it which may put cookies in your browser, you are + encouraged to frecuently delete your browser cookies to avoid those third parties tracking you on internet, Firefox offers you an + option to delete cookies as soon as you close the browser which may be a good idea to enable in the orwellian internet of today.

+
+
+ X +
+
+ + diff --git a/themes/new_look_default/public/package.json b/themes/new_look_default/public/package.json new file mode 100644 index 0000000..3edd723 --- /dev/null +++ b/themes/new_look_default/public/package.json @@ -0,0 +1,13 @@ +{ + "name": "default-theme", + "version": "1.0.0", + "private": true, + "license": "MIT", + "scripts": { + "build": "webpack" + }, + "dependencies": { + "webpack": "^5.15.0", + "webpack-cli": "^4.3.1" + } +} diff --git a/themes/new_look_default/public/src/application.js b/themes/new_look_default/public/src/application.js new file mode 100644 index 0000000..2509e11 --- /dev/null +++ b/themes/new_look_default/public/src/application.js @@ -0,0 +1,106 @@ +"use strict"; + +import { PopingNotice } from './view/poping_notice.js'; +import { DownloadForm } from './view/download_form.js'; +import { LoadingModal } from './view/loading_modal.js'; +import { VideoContainer } from './view/video_container.js'; +import { FormatSelector } from './view/format_selector.js'; + +class Application { + constructor() { + this.poping_notice = new PopingNotice(); + this.download_form = new DownloadForm(this.onDownloadFormGot.bind(this)); + this.loading_modal = new LoadingModal(); + this.video_container = new VideoContainer(); + this.format_selector = new FormatSelector(); + } + + init() { + this.popingNotice.setVisible(true); + } + + onDownloadFormGot(url) { + this.dispatchURL(url); + } + + dispatchURL(url, format) { + this.loadingModal.setVisible(true); + let error_str; + let success = this.queryAPI(url, format).then( (response) => { + if ( response.options !== undefined && response.options.list_formats !== undefined && response.options.list_formats ) { + if ( response.formats === undefined + || response.formats.audio_formats === undefined + || response.formats.video_formats === undefined ) { + throw 'Format object is not valid.'; + } + this.formatSelector.prepareFormatSelector( + response.title, response.description, + response.formats.audio_formats, response.formats.video_formats, + ( id ) => { + this.loadingModal.setVisible(true); + this.dispatchURL(url, id); + }); + this.formatSelector.setVisible(true); + this.loadingModal.setVisible(false); + } else { + this.videoContainer.onCanPlay(this.onCanPlayVideoContainer.bind(this)); + this.videoContainer.setURLVideo(response.url); + this.videoContainer.setFilename(response.filename); + } + }).catch( (error) => { + error_str = error.toString(); + this.loadingModal.setVisible(false); + let input_url = document.createElement('a'); + input_url.href = url; + input_url.innerText = url; + let issues_url = document.createElement('a'); + issues_url.href = 'https://gitea.sergiotarxz.freemyip.com/sergiotarxz/Peertube-dl/issues'; + issues_url.innerText = 'here'; + this.popingNotice.setMessage( [ 'The url ', input_url, ' is not supported, the error was: ', error_str , ' if you think this is an error, report it ', issues_url, '.' ]); + this.popingNotice.setVisible(true); +}); + } + + onCanPlayVideoContainer() { + this.videoContainer.setVisible(true); + this.loadingModal.setVisible(false); + } + + async queryAPI(url, format) { + let request = { url: url }; + if (format !== undefined) + request.format = format; + const response = await fetch('/api', { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(request), + }); + return response.json(); + } + + get formatSelector() { + return this.format_selector; + } + + get videoContainer() { + return this.video_container; + } + + get downloadForm() { + return this.download_form; + } + + get popingNotice() { + return this.poping_notice; + } + + get loadingModal() { + return this.loading_modal; + } +} + +export { Application }; diff --git a/themes/new_look_default/public/src/index.js b/themes/new_look_default/public/src/index.js new file mode 100644 index 0000000..6ea3341 --- /dev/null +++ b/themes/new_look_default/public/src/index.js @@ -0,0 +1,10 @@ +"use strict"; + +import { Application } from './application.js'; + +window.addEventListener('load', (event) => { + let application = new Application(); + application.init(); +}); + + diff --git a/themes/new_look_default/public/src/view/download_form.js b/themes/new_look_default/public/src/view/download_form.js new file mode 100644 index 0000000..74f1e55 --- /dev/null +++ b/themes/new_look_default/public/src/view/download_form.js @@ -0,0 +1,35 @@ +"use strict"; + +class DownloadForm { + constructor(callback) { + this.query_selector = '#download-form'; + this.callback = (event) => { + event.preventDefault(); + callback(this.downloadFormUrl.value); + }; + this.addEventListeners(); + } + + addEventListeners() { + this.downloadFormButton.addEventListener('click', this.callback); + this.element.addEventListener('submit', this.callback); + } + + get downloadFormButton() { + return this.element.querySelector('#download-form-button'); + } + + get downloadFormUrl() { + return this.element.querySelector('#download-form-url'); + } + + get querySelector() { + return this.query_selector; + } + + get element() { + return document.querySelector(this.querySelector); + } +} + +export { DownloadForm }; diff --git a/themes/new_look_default/public/src/view/format_selector.js b/themes/new_look_default/public/src/view/format_selector.js new file mode 100644 index 0000000..c9e9665 --- /dev/null +++ b/themes/new_look_default/public/src/view/format_selector.js @@ -0,0 +1,87 @@ +"use strict"; + +class FormatSelector { + constructor() { + this.query_selector = '#modal-format-selector'; + this.addEventListeners(); + } + + appendFormat(container, object, is_video, callback) { + let a = document.createElement('a'); + if ( is_video ) { + a.innerText = 'Id: ' + object.id + "\n" + + 'Format: ' + object.mimeType + "\n" + + 'QualityLabel: ' + object.qualityLabel + "p\n" + + 'Bitrate: ' + object.bitrate + "\n" + + ( + ( object.audioSampleRate !== undefined ) ? + 'AudioSampleRate: ' + object.audioSampleRate + ".\n" : + "No audio." + ); + } else { + a.innerText = 'Id: ' + object.id + "\n" + + 'Format: ' + object.mimeType + "\n" + + 'AudioSampleRate: ' + object.audioSampleRate + "\n" + + 'Bitrate: ' + object.bitrate + ".\n"; + } + a.addEventListener( 'click', (event) => { + callback(object.id); + }); + container.appendChild(a); + } + + prepareFormatSelector(title, description, audio_formats, video_formats, callback) { + this.titleFormatSelector.innerText = title; + this.descriptionFormatSelector.innerText = description; + this.videoFormats.innerHTML = ''; + this.audioFormats.innerHTML = ''; + for ( let x of audio_formats) { + this.appendFormat(this.audioFormats, x, false, callback); + } + for ( let x of video_formats ) { + this.appendFormat(this.videoFormats, x, true, callback); + } + } + + setVisible(option) { + if (option) { + this.element.classList.add('active'); + } else { + this.element.classList.remove('active'); + } + } + + addEventListeners() { + this.closeFormatSelector.addEventListener('click', (event) => { this.setVisible(false); }); + } + + get videoFormats() { + return this.element.querySelector('.video-formats'); + } + + get audioFormats() { + return this.element.querySelector('.audio-formats'); + } + + get titleFormatSelector() { + return this.element.querySelector('h2'); + } + + get descriptionFormatSelector() { + return this.element.querySelector('p'); + } + + get closeFormatSelector() { + return this.element.querySelector('#close-modal-format-selector'); + } + + get element() { + return document.querySelector(this.querySelector); + } + + get querySelector() { + return this.query_selector; + } +} + +export { FormatSelector }; diff --git a/themes/new_look_default/public/src/view/loading_modal.js b/themes/new_look_default/public/src/view/loading_modal.js new file mode 100644 index 0000000..10ae7bc --- /dev/null +++ b/themes/new_look_default/public/src/view/loading_modal.js @@ -0,0 +1,25 @@ +"use strict"; + +class LoadingModal { + constructor() { + this.query_selector = '#modal-loading'; + } + + setVisible(option) { + if (option) { + this.element.classList.add('active'); + } else { + this.element.classList.remove('active'); + } + } + + get element() { + return document.querySelector(this.querySelector); + } + + get querySelector() { + return this.query_selector; + } +} + +export { LoadingModal }; diff --git a/themes/new_look_default/public/src/view/poping_notice.js b/themes/new_look_default/public/src/view/poping_notice.js new file mode 100644 index 0000000..69156af --- /dev/null +++ b/themes/new_look_default/public/src/view/poping_notice.js @@ -0,0 +1,56 @@ +"use strict"; + +class PopingNotice { + constructor() { + this.query_selector = '#poping-notice'; + this.closePopingNotice.addEventListener('click', (event) => { + this.setVisible(false); + }); + } + + setVisible(option) { + if (option) { + this.element.classList.add('active'); + } else { + this.element.classList.remove('active'); + } + } + + setMessage(message) { + if (!message instanceof Array) + throw 'Message is not instance of Array.'; + let p = document.createElement('p'); + for (let node of message) { + if (typeof node === "string" + || node instanceof String) { + node = document.createTextNode(node); + p.appendChild(node); + } else if ( node instanceof Node) { + p.appendChild(node); + } else { + throw ('Node is not a instance of Node nor a String'); + } + } + this.popingNoticeContent.innerHTML = ''; + this.popingNoticeContent.appendChild(p); + + } + + get querySelector() { + return this.query_selector; + } + + get element() { + return document.querySelector(this.querySelector); + } + + get popingNoticeContent() { + return this.element.querySelector('#poping-notice-content'); + } + + get closePopingNotice() { + return this.element.querySelector('#close-poping-notice'); + } +} + +export { PopingNotice }; diff --git a/themes/new_look_default/public/src/view/video_container.js b/themes/new_look_default/public/src/view/video_container.js new file mode 100644 index 0000000..99caaa6 --- /dev/null +++ b/themes/new_look_default/public/src/view/video_container.js @@ -0,0 +1,112 @@ +"use strict"; + +class VideoContainer { + constructor() { + this.query_selector = '#modal-video-container'; + this.addEventListeners(); + } + + setVisible(option) { + if (option) { + this.element.classList.add('active'); + } else { + this.element.classList.remove('active'); + this.downloadVideoPrepare.classList.add('active'); + this.downloadVideoLoading.classList.remove('active'); + this.downloadVideo.classList.remove('active'); + } + } + + addEventListeners() { + this.downloadVideoPrepare.addEventListener('click', this.downloadPrepareHandler.bind(this)); + this.closeAndResetVideoContainer.addEventListener('click', (event) => { + this.setVisible(false); + }); + } + + downloadPrepareHandler(event) { + this.downloadVideoPrepare.classList.remove('active'); + this.downloadVideoLoading.classList.add('active'); + this.generateBlobVideo(this.URLVideo).then( blob => { + this.downloadVideo.href = URL.createObjectURL(blob); + this.downloadVideo.download = this.filename; + this.downloadVideoLoading.classList.remove('active'); + this.downloadVideo.classList.add('active'); + }); + + } + + async generateBlobVideo(url) { + const blob = await fetch(url, { mode: 'cors', }) + .then(res => res.blob()) + .catch( err => this.generateBlobVideoByProxy(url) ); + return blob; + } + + async generateBlobVideoByProxy(url) { + const blob = await fetch( '/proxy_to_get', { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({url: url}), + } + ).then(res => res.blob()); + return blob; + } + + onCanPlay(callback) { + video.addEventListener('canplay', (event) => { + callback(); + }); + } + + setURLVideo(url) { + this.url_video = url; + video.src = url; + } + + setFilename(filename) { + this.filename = filename; + } + + get closeAndResetVideoContainer() { + return this.element.querySelector('#close-and-reset-video-container'); + } + + get downloadVideo() { + return this.element.querySelector('#download-video'); + } + + get URLVideo() { + return this.url_video; + } + + get closeAndResetVideoContainer() { + return this.element.querySelector('#close-and-reset-video-container'); + } + + get downloadVideoLoading() { + return this.element.querySelector('#download-video-loading'); + } + + get downloadVideoPrepare() { + return this.element.querySelector('#download-video-prepare'); + } + + get video() { + return this.element.querySelector('#video'); + } + + get element() { + return document.querySelector(this.querySelector); + } + + get querySelector() { + return this.query_selector; + } +} + +export { VideoContainer }; diff --git a/themes/new_look_default/public/webpack.config.js b/themes/new_look_default/public/webpack.config.js new file mode 100644 index 0000000..bc82144 --- /dev/null +++ b/themes/new_look_default/public/webpack.config.js @@ -0,0 +1,10 @@ +const path = require('path'); + +module.exports = { + entry: './src/index.js', + devtool: 'source-map', + output: { + filename: 'peertube-dl-web.js', + path: path.resolve(__dirname, 'dist/js'), + }, +};