From dcb67c58cef0ccdc4c368ab24cf7b11b7e327775 Mon Sep 17 00:00:00 2001 From: railsjack Date: Sat, 26 Oct 2019 07:11:00 +0800 Subject: [PATCH] Update --- index.html | 12 +- main-process/communication/async-msg.js | 5 - main-process/communication/sync-msg.js | 5 - main-process/drop_dir.js | 37 +++ main-process/main-process.rar | Bin 0 -> 15832 bytes main-process/menus/application-menu.js | 240 --------------- main-process/menus/context-menu.js | 23 -- main-process/menus/shortcuts.js | 16 - main-process/native-ui/dialogs/error.js | 5 - main-process/native-ui/dialogs/information.js | 13 - main-process/native-ui/dialogs/open-file.js | 11 - main-process/native-ui/dialogs/save.js | 13 - main-process/native-ui/drag/codeIcon.png | Bin 6339 -> 0 bytes main-process/native-ui/drag/drag.js | 10 - main-process/native-ui/tray/iconTemplate.png | Bin 446 -> 0 bytes .../native-ui/tray/iconTemplate@2x.png | Bin 1060 -> 0 bytes main-process/native-ui/tray/tray.js | 28 -- .../native-ui/tray/windows-icon@2x.png | Bin 2537 -> 0 bytes main-process/system/app-information.js | 5 - main-process/system/protocol-handler.js | 14 - player/components/bootstrap.js | 85 ++++++ player/components/helper.js | 37 +++ player/components/player.js | 55 ++++ player/components/seekbar.js | 36 +++ player/components/tutorial_list.js | 99 ++++++ player/custom.js | 287 ------------------ player/index.js | 6 + utils/create_tutorial_list.js | 62 ++++ 28 files changed, 424 insertions(+), 680 deletions(-) delete mode 100644 main-process/communication/async-msg.js delete mode 100644 main-process/communication/sync-msg.js create mode 100644 main-process/drop_dir.js create mode 100644 main-process/main-process.rar delete mode 100644 main-process/menus/application-menu.js delete mode 100644 main-process/menus/context-menu.js delete mode 100644 main-process/menus/shortcuts.js delete mode 100644 main-process/native-ui/dialogs/error.js delete mode 100644 main-process/native-ui/dialogs/information.js delete mode 100644 main-process/native-ui/dialogs/open-file.js delete mode 100644 main-process/native-ui/dialogs/save.js delete mode 100644 main-process/native-ui/drag/codeIcon.png delete mode 100644 main-process/native-ui/drag/drag.js delete mode 100644 main-process/native-ui/tray/iconTemplate.png delete mode 100644 main-process/native-ui/tray/iconTemplate@2x.png delete mode 100644 main-process/native-ui/tray/tray.js delete mode 100644 main-process/native-ui/tray/windows-icon@2x.png delete mode 100644 main-process/system/app-information.js delete mode 100644 main-process/system/protocol-handler.js create mode 100644 player/components/bootstrap.js create mode 100644 player/components/helper.js create mode 100644 player/components/player.js create mode 100644 player/components/seekbar.js create mode 100644 player/components/tutorial_list.js delete mode 100644 player/custom.js create mode 100644 player/index.js create mode 100644 utils/create_tutorial_list.js diff --git a/index.html b/index.html index 6e42114..47e3ae9 100644 --- a/index.html +++ b/index.html @@ -2,12 +2,13 @@ - React Native Tutorial + Tutorial Player - + + - +
@@ -31,9 +32,10 @@
+ + - - + \ No newline at end of file diff --git a/main-process/communication/async-msg.js b/main-process/communication/async-msg.js deleted file mode 100644 index 50b2b3e..0000000 --- a/main-process/communication/async-msg.js +++ /dev/null @@ -1,5 +0,0 @@ -const {ipcMain} = require('electron') - -ipcMain.on('asynchronous-message', (event, arg) => { - event.sender.send('asynchronous-reply', 'pong') -}) diff --git a/main-process/communication/sync-msg.js b/main-process/communication/sync-msg.js deleted file mode 100644 index fcdd680..0000000 --- a/main-process/communication/sync-msg.js +++ /dev/null @@ -1,5 +0,0 @@ -const {ipcMain} = require('electron') - -ipcMain.on('synchronous-message', (event, arg) => { - event.returnValue = 'pong' -}) diff --git a/main-process/drop_dir.js b/main-process/drop_dir.js new file mode 100644 index 0000000..6afd9c0 --- /dev/null +++ b/main-process/drop_dir.js @@ -0,0 +1,37 @@ +const { ipcMain } = require("electron"); +const fs = require("fs"); +const path = require("path"); + +const createTutorialList = require("../utils/create_tutorial_list"); + +ipcMain.on("Request", (event, dirPath) => { + if (!fs.existsSync(dirPath)) { + event.sender.send("Response", { + code: 400, + reason: "NOEXITS", + content: "The file/directory does not exist" + }); + } else if (!fs.lstatSync(dirPath).isDirectory()) { + event.sender.send("Response", { + code: 401, + reason: "NOTDIR", + content: "The file is not a directory" + }); + } else if( path.basename(dirPath).match(/[^a-zA-Z0-9_\-\.\'\"\& ]+/g) !== null ) { + event.sender.send("Response", { + code: 300, + reason: "INVALID_DIRNAME", + content: "The directory name is invalid", + data: path.basename(dirPath) + }); + } else { + createTutorialList(dirPath, (data) => { + event.sender.send("Response", { + code: 201, + reason: "CREATED", + content: "The list is created successfully!", + data: data + }); + }); + } +}); diff --git a/main-process/main-process.rar b/main-process/main-process.rar new file mode 100644 index 0000000000000000000000000000000000000000..37330c73718b49ca85f00bd5166b7029921726d8 GIT binary patch literal 15832 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 TkMIA_tayAkbtO=6Frfbh&M%vO literal 0 HcmV?d00001 diff --git a/main-process/menus/application-menu.js b/main-process/menus/application-menu.js deleted file mode 100644 index b543889..0000000 --- a/main-process/menus/application-menu.js +++ /dev/null @@ -1,240 +0,0 @@ -const {BrowserWindow, Menu, app, shell, dialog} = require('electron') - -let template = [{ - label: 'Edit', - submenu: [{ - label: 'Undo', - accelerator: 'CmdOrCtrl+Z', - role: 'undo' - }, { - label: 'Redo', - accelerator: 'Shift+CmdOrCtrl+Z', - role: 'redo' - }, { - type: 'separator' - }, { - label: 'Cut', - accelerator: 'CmdOrCtrl+X', - role: 'cut' - }, { - label: 'Copy', - accelerator: 'CmdOrCtrl+C', - role: 'copy' - }, { - label: 'Paste', - accelerator: 'CmdOrCtrl+V', - role: 'paste' - }, { - label: 'Select All', - accelerator: 'CmdOrCtrl+A', - role: 'selectall' - }] -}, { - label: 'View', - submenu: [{ - label: 'Reload', - accelerator: 'CmdOrCtrl+R', - click: (item, focusedWindow) => { - if (focusedWindow) { - // on reload, start fresh and close any old - // open secondary windows - if (focusedWindow.id === 1) { - BrowserWindow.getAllWindows().forEach(win => { - if (win.id > 1) win.close() - }) - } - focusedWindow.reload() - } - } - }, { - label: 'Toggle Full Screen', - accelerator: (() => { - if (process.platform === 'darwin') { - return 'Ctrl+Command+F' - } else { - return 'F11' - } - })(), - click: (item, focusedWindow) => { - if (focusedWindow) { - focusedWindow.setFullScreen(!focusedWindow.isFullScreen()) - } - } - }, { - label: 'Toggle Developer Tools', - accelerator: (() => { - if (process.platform === 'darwin') { - return 'Alt+Command+I' - } else { - return 'Ctrl+Shift+I' - } - })(), - click: (item, focusedWindow) => { - if (focusedWindow) { - focusedWindow.toggleDevTools() - } - } - }, { - type: 'separator' - }, { - label: 'App Menu Demo', - click: function (item, focusedWindow) { - if (focusedWindow) { - const options = { - type: 'info', - title: 'Application Menu Demo', - buttons: ['Ok'], - message: 'This demo is for the Menu section, showing how to create a clickable menu item in the application menu.' - } - dialog.showMessageBox(focusedWindow, options, function () {}) - } - } - }] -}, { - label: 'Window', - role: 'window', - submenu: [{ - label: 'Minimize', - accelerator: 'CmdOrCtrl+M', - role: 'minimize' - }, { - label: 'Close', - accelerator: 'CmdOrCtrl+W', - role: 'close' - }, { - type: 'separator' - }, { - label: 'Reopen Window', - accelerator: 'CmdOrCtrl+Shift+T', - enabled: false, - key: 'reopenMenuItem', - click: () => { - app.emit('activate') - } - }] -}, { - label: 'Help', - role: 'help', - submenu: [{ - label: 'Learn More', - click: () => { - shell.openExternal('http://electron.atom.io') - } - }] -}] - -function addUpdateMenuItems (items, position) { - if (process.mas) return - - const version = app.getVersion() - let updateItems = [{ - label: `Version ${version}`, - enabled: false - }, { - label: 'Checking for Update', - enabled: false, - key: 'checkingForUpdate' - }, { - label: 'Check for Update', - visible: false, - key: 'checkForUpdate', - click: () => { - require('electron').autoUpdater.checkForUpdates() - } - }, { - label: 'Restart and Install Update', - enabled: true, - visible: false, - key: 'restartToUpdate', - click: () => { - require('electron').autoUpdater.quitAndInstall() - } - }] - - items.splice.apply(items, [position, 0].concat(updateItems)) -} - -function findReopenMenuItem () { - const menu = Menu.getApplicationMenu() - if (!menu) return - - let reopenMenuItem - menu.items.forEach(item => { - if (item.submenu) { - item.submenu.items.forEach(item => { - if (item.key === 'reopenMenuItem') { - reopenMenuItem = item - } - }) - } - }) - return reopenMenuItem -} - -if (process.platform === 'darwin') { - const name = app.getName() - template.unshift({ - label: name, - submenu: [{ - label: `About ${name}`, - role: 'about' - }, { - type: 'separator' - }, { - label: 'Services', - role: 'services', - submenu: [] - }, { - type: 'separator' - }, { - label: `Hide ${name}`, - accelerator: 'Command+H', - role: 'hide' - }, { - label: 'Hide Others', - accelerator: 'Command+Alt+H', - role: 'hideothers' - }, { - label: 'Show All', - role: 'unhide' - }, { - type: 'separator' - }, { - label: 'Quit', - accelerator: 'Command+Q', - click: () => { - app.quit() - } - }] - }) - - // Window menu. - template[3].submenu.push({ - type: 'separator' - }, { - label: 'Bring All to Front', - role: 'front' - }) - - addUpdateMenuItems(template[0].submenu, 1) -} - -if (process.platform === 'win32') { - const helpMenu = template[template.length - 1].submenu - addUpdateMenuItems(helpMenu, 0) -} - -app.on('ready', () => { - const menu = Menu.buildFromTemplate(template) - Menu.setApplicationMenu(menu) -}) - -app.on('browser-window-created', () => { - let reopenMenuItem = findReopenMenuItem() - if (reopenMenuItem) reopenMenuItem.enabled = false -}) - -app.on('window-all-closed', () => { - let reopenMenuItem = findReopenMenuItem() - if (reopenMenuItem) reopenMenuItem.enabled = true -}) diff --git a/main-process/menus/context-menu.js b/main-process/menus/context-menu.js deleted file mode 100644 index ebb321c..0000000 --- a/main-process/menus/context-menu.js +++ /dev/null @@ -1,23 +0,0 @@ -const { - BrowserWindow, - Menu, - MenuItem, - ipcMain, - app -} = require('electron') - -const menu = new Menu() -menu.append(new MenuItem({ label: 'Hello' })) -menu.append(new MenuItem({ type: 'separator' })) -menu.append(new MenuItem({ label: 'Electron', type: 'checkbox', checked: true })) - -app.on('browser-window-created', (event, win) => { - win.webContents.on('context-menu', (e, params) => { - menu.popup(win, params.x, params.y) - }) -}) - -ipcMain.on('show-context-menu', (event) => { - const win = BrowserWindow.fromWebContents(event.sender) - menu.popup(win) -}) diff --git a/main-process/menus/shortcuts.js b/main-process/menus/shortcuts.js deleted file mode 100644 index 656da46..0000000 --- a/main-process/menus/shortcuts.js +++ /dev/null @@ -1,16 +0,0 @@ -const {app, dialog, globalShortcut} = require('electron') - -app.on('ready', () => { - globalShortcut.register('CommandOrControl+Alt+K', () => { - dialog.showMessageBox({ - type: 'info', - message: 'Success!', - detail: 'You pressed the registered global shortcut keybinding.', - buttons: ['OK'] - }) - }) -}) - -app.on('will-quit', () => { - globalShortcut.unregisterAll() -}) diff --git a/main-process/native-ui/dialogs/error.js b/main-process/native-ui/dialogs/error.js deleted file mode 100644 index 4ed0843..0000000 --- a/main-process/native-ui/dialogs/error.js +++ /dev/null @@ -1,5 +0,0 @@ -const {ipcMain, dialog} = require('electron') - -ipcMain.on('open-error-dialog', (event) => { - dialog.showErrorBox('An Error Message', 'Demonstrating an error message.') -}) diff --git a/main-process/native-ui/dialogs/information.js b/main-process/native-ui/dialogs/information.js deleted file mode 100644 index 5054a1d..0000000 --- a/main-process/native-ui/dialogs/information.js +++ /dev/null @@ -1,13 +0,0 @@ -const {ipcMain, dialog} = require('electron') - -ipcMain.on('open-information-dialog', (event) => { - const options = { - type: 'info', - title: 'Information', - message: "This is an information dialog. Isn't it nice?", - buttons: ['Yes', 'No'] - } - dialog.showMessageBox(options, (index) => { - event.sender.send('information-dialog-selection', index) - }) -}) diff --git a/main-process/native-ui/dialogs/open-file.js b/main-process/native-ui/dialogs/open-file.js deleted file mode 100644 index 1aaf375..0000000 --- a/main-process/native-ui/dialogs/open-file.js +++ /dev/null @@ -1,11 +0,0 @@ -const {ipcMain, dialog} = require('electron') - -ipcMain.on('open-file-dialog', (event) => { - dialog.showOpenDialog({ - properties: ['openFile', 'openDirectory'] - }, (files) => { - if (files) { - event.sender.send('selected-directory', files) - } - }) -}) diff --git a/main-process/native-ui/dialogs/save.js b/main-process/native-ui/dialogs/save.js deleted file mode 100644 index b10ed3f..0000000 --- a/main-process/native-ui/dialogs/save.js +++ /dev/null @@ -1,13 +0,0 @@ -const {ipcMain, dialog} = require('electron') - -ipcMain.on('save-dialog', (event) => { - const options = { - title: 'Save an Image', - filters: [ - { name: 'Images', extensions: ['jpg', 'png', 'gif'] } - ] - } - dialog.showSaveDialog(options, (filename) => { - event.sender.send('saved-file', filename) - }) -}) diff --git a/main-process/native-ui/drag/codeIcon.png b/main-process/native-ui/drag/codeIcon.png deleted file mode 100644 index 2dd68b6b8926c5ab8f0f25d3ce854386d68adf0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6339 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 diff --git a/main-process/native-ui/drag/drag.js b/main-process/native-ui/drag/drag.js deleted file mode 100644 index 1e46f0c..0000000 --- a/main-process/native-ui/drag/drag.js +++ /dev/null @@ -1,10 +0,0 @@ -const {ipcMain} = require('electron') -const path = require('path') - -ipcMain.on('ondragstart', (event, filepath) => { - const iconName = 'codeIcon.png' - event.sender.startDrag({ - file: filepath, - icon: path.join(__dirname, iconName) - }) -}) diff --git a/main-process/native-ui/tray/iconTemplate.png b/main-process/native-ui/tray/iconTemplate.png deleted file mode 100644 index d56c5086993c4c2b28540f49872f4230649fc223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 446 zcmV;v0YUzWP)r z;2k-*QRgNuFbDH#Dt`tAQ1s$s>rpLbO;j9M%})ty8C{|aenUnCRa@;ln`J?K!)Lx-vhy(obWl>SZ~2H~4Hy;`9U oG3-N!>tE3-m(YvGq00W`3t5U%48luTaR2}S07*qoM6N<$g1KnJfB*mh diff --git a/main-process/native-ui/tray/iconTemplate@2x.png b/main-process/native-ui/tray/iconTemplate@2x.png deleted file mode 100644 index bd3064409281d19f18b71d3c04cd6fd6e6ffc08e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1060 zcmV+<1l#+GP)5iybulX zf|TpA(lk-h_Ms}I>F}b1AqaxD2{A>27+O=zQZq5$_V;tvy4`o*eNOKt?mzjRwbr-3 zHLvyUQ&#r)>Os>LupG?StJ*Ny4frQuz8rF^LGBiX2JetO2Xg}Er^7Q)FB-@wuKoxd z4SCByLL;abEo77jfkmX7z)5@o^`@qbB+7I*IEnY5PAYX~uh2t#XbTVFJe-3=P)uE^ z*aHV)FbseTZ~!hso%AkV8^M)iF(cK>%akX;O1KQaf$i3Y)VvG$9R@%Rr7z4RYQGL1 zPQuPybrrOR=CBS_KkyYe;rNFUhSgbomOhRkh<_d|PkI1P@`32NzcEOzLMveXXadeFxm`2~7GmX=}E&s8TijDq%g zNn^~f4wX%!A(2ice=F2)Aoa49(kLn&=;M^r3&H+t%KoVMQ>gS(MH%6~2Rn01r$MQg zL-iw-^J|;sg<|#ZYr(!WTH@ugygeA-4(Uszo59uW1n!pw1C1cBuFzm_s*&Y;;LFIAvD`_x8xH;%6qCF65zK|GV>yi7*AO+1 zjD3C=4OwY3j4MIM6Eqz;m>s9(v00}UfEU_HpN69Hj0_a>!Oo3rHD*jXDJN`z$&yEKHdOQ@otWj6v<;-- zpmFOz3FT9yuR~s4qQU+=jpBfV5{+h&uY#*E0qUxTIJ%Qt>)JrSRp1Wvwvf;V8qAtpqq5oIW5Yld>L!o)fUe*PJm(E5q89=5|$KaXYgC>yHhZz0_ef>5pg0_%W?5{(pc%IZ3aST2M+b@Oc?|2+c2j8n_ z_$)+?Bx8eR&<-lWH$ENygw0?;dIN0xA{+N!`yQ<2+T1)lS0aFt%J5pW5t8wF2Q1|}!qad?@0j^@3@V?9xn0000 { - const iconName = process.platform === 'win32' ? 'windows-icon.png' : 'iconTemplate.png' - const iconPath = path.join(__dirname, iconName) - appIcon = new Tray(iconPath) - - const contextMenu = Menu.buildFromTemplate([{ - label: 'Remove', - click: () => { - event.sender.send('tray-removed') - } - }]) - - appIcon.setToolTip('Electron Demo in the tray.') - appIcon.setContextMenu(contextMenu) -}) - -ipcMain.on('remove-tray', () => { - appIcon.destroy() -}) - -app.on('window-all-closed', () => { - if (appIcon) appIcon.destroy() -}) diff --git a/main-process/native-ui/tray/windows-icon@2x.png b/main-process/native-ui/tray/windows-icon@2x.png deleted file mode 100644 index 463f37405774428033ae3e70c483d52b4bfe0a74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2537 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 diff --git a/main-process/system/app-information.js b/main-process/system/app-information.js deleted file mode 100644 index 6b3290d..0000000 --- a/main-process/system/app-information.js +++ /dev/null @@ -1,5 +0,0 @@ -const {app, ipcMain} = require('electron') - -ipcMain.on('get-app-path', (event) => { - event.sender.send('got-app-path', app.getAppPath()) -}) diff --git a/main-process/system/protocol-handler.js b/main-process/system/protocol-handler.js deleted file mode 100644 index c290e1e..0000000 --- a/main-process/system/protocol-handler.js +++ /dev/null @@ -1,14 +0,0 @@ -const {app, dialog} = require('electron') -const path = require('path') - -if (process.defaultApp) { - if (process.argv.length >= 2) { - app.setAsDefaultProtocolClient('electron-api-demos', process.execPath, [path.resolve(process.argv[1])]) - } -} else { - app.setAsDefaultProtocolClient('electron-api-demos') -} - -app.on('open-url', (event, url) => { - dialog.showErrorBox('Welcome Back', `You arrived from: ${url}`) -}) diff --git a/player/components/bootstrap.js b/player/components/bootstrap.js new file mode 100644 index 0000000..44e15d4 --- /dev/null +++ b/player/components/bootstrap.js @@ -0,0 +1,85 @@ +class BootStrap { + onReady = callback => { + if (typeof callback === "function") { + var onceCalled = false; + document.addEventListener("DOMContentLoaded", function(event) { + if (!onceCalled) { + onceCalled = true; + callback(event); + } + }); + document.onreadystatechange = function(event) { + if (document.readyState == "interactive") { + if (!onceCalled) { + onceCalled = true; + callback(event); + } + } + }; + } + }; + + loadComponents = async event => { + const { ipcRenderer } = require("electron"); + let selectDir = ""; + document.addEventListener("dragover", e => { + e.preventDefault(); + }); + document.addEventListener("drop", e => { + e.preventDefault(); + if (e.dataTransfer.files.length === 1) { + selectDir = e.dataTransfer.files[0].path; + ipcRenderer.send("Request", selectDir); + } else { + alert("You can drop only 1 directory at once."); + } + return false; + }); + + ipcRenderer.on("Response", (event, response) => { + if (response.code !== 201) { + alert(response.content); + } else { + if (selectDir != "") { + Helper.setConf("list_dir", selectDir); + Helper.setConf("currentTime", 0); + Helper.setConf("playedIndex", 0); + } + alert(response.content); + location.reload(); + } + }); + + const tutorialList = new TutorialList(); + const player = new Player(); + + await tutorialList.load(); + + tutorialList.bindEvents("change", e => { + Helper.setConf("currentTime", 0); + player.play(tutorialList.selectedValue()); + Helper.setConf("playedIndex", tutorialList.getIndex()); + }); + + player.bindEvents("onended", args => { + Helper.setConf("currentTime", 0); + let nextIndex = tutorialList.getIndex() + 1; + if (nextIndex < tutorialList.length()) { + tutorialList.setIndex(nextIndex); + player.play(tutorialList.selectedValue(), true); + } + }); + + let playedIndex; + if ((playedIndex = Helper.getConf("playedIndex"))) { + tutorialList.setIndex(parseInt(playedIndex)); + player.play(tutorialList.selectedValue(), false); + } + }; + + initialize = () => { + this.onReady(this.loadComponents); + }; +} + +module.exports = new BootStrap(); diff --git a/player/components/helper.js b/player/components/helper.js new file mode 100644 index 0000000..f61fcac --- /dev/null +++ b/player/components/helper.js @@ -0,0 +1,37 @@ +module.exports = class Helper { + static validateTitle = title => { + var ret = title; + ret = ret.replace(/\.vtt/gi, ""); + return ret.replace(/\-/gi, " "); + }; + + static loadScript = async path => { + let script = document.createElement("script"); + script.src = path; + document.getElementsByTagName("head")[0].appendChild(script); + return new Promise((resolve, eject) => { + script.onload = () => resolve(); + script.onerror = () => eject(); + }); + }; + + static getListDir = () => { + const cached_list_dir = Helper.getConf("list_dir"); + return cached_list_dir; + }; + + static getHumanTitle = path => { + let ret = path.replace(/[\\\/]/g, " > "); + ret = ret.replace(/\.mp4/g, ""); + ret = ret.replace(/\.vtt/g, ""); + return ret.replace(/[^A-Za-z0-9\.\>]/g, " "); + }; + + static getConf = key => { + return localStorage.getItem(key); + }; + + static setConf = (key, value) => { + localStorage.setItem(key, value); + }; +}; diff --git a/player/components/player.js b/player/components/player.js new file mode 100644 index 0000000..b40614d --- /dev/null +++ b/player/components/player.js @@ -0,0 +1,55 @@ +module.exports = class Player { + constructor() { + this.playerUI = document.getElementById("video_player"); + this.captionUI = document.getElementById("playerCaption"); + this.titleUI = document.getElementById("video_title"); + + return; + new MediaElementPlayer(this.playerUI, { + stretching: "auto", + pluginPath: "player/media-elements/build/", + success: function(media) { + var renderer = document.getElementById(media.id + "-rendername"); + + media.addEventListener("loadedmetadata", function() {}); + + media.addEventListener("error", function(e) {}); + } + }); + } + + bindEvents = (evName, callback) => { + this.playerUI[evName] = callback; + }; + + play = (index, auto_play = true) => { + if (index === 0) { + return; + } + var base_dir = Helper.getListDir(); + this.playerUI.preload = true; + this.playerUI.src = base_dir + "/" + mp4_files[index]; + this.captionUI.src = base_dir + "/" + vtt_files[index]; + this.playerUI.textTracks[0].mode = "showing"; + this.titleUI.innerText = Helper.getHumanTitle(mp4_files[index]); + + this.playerUI.ontimeupdate = () => { + if (this.playerUI.currentTime > 0) { + Helper.setConf("currentTime", this.playerUI.currentTime); + } + }; + + this.playerUI.focus(); + + if (auto_play) { + this.playerUI.play(); + } else { + setTimeout(() => { + var currentTime; + if ((currentTime = Helper.getConf("currentTime"))) { + this.playerUI.currentTime = parseFloat(currentTime); + } + }, 1000); + } + }; +}; diff --git a/player/components/seekbar.js b/player/components/seekbar.js new file mode 100644 index 0000000..b67a4e3 --- /dev/null +++ b/player/components/seekbar.js @@ -0,0 +1,36 @@ +module.exports = class Seekbar { + constructor() { + this.UI = document.getElementById("seekbar"); + this.posUI = document.getElementById("seekbar_pos"); + this.UI.ontimeupdate = function() { + var percentage = (vid.currentTime / vid.duration) * 100; + $("#custom-seekbar span").css("width", percentage + "%"); + }; + + this.drag_started = false; + + this.posUI.onmousedown = e => { + console.log("onmousedown..."); + this.drag_started = true; + }; + this.UI.onmousemove = e => { + if (this.drag_started) { + console.log("onmousemove..."); + this.posUI.style.left = e.pageX; + } + }; + this.UI.onmouseup = e => { + console.log("onmouseup..."); + this.drag_started = false; + }; + this.posUI.onmouseup = e => { + console.log("onmouseup..."); + this.drag_started = false; + }; + } + + bindEvents = (evName, callback) => { + this.UI.addEventListener(evName, callback); + this.UI[evName] = callback; + }; +}; diff --git a/player/components/tutorial_list.js b/player/components/tutorial_list.js new file mode 100644 index 0000000..9e4fca6 --- /dev/null +++ b/player/components/tutorial_list.js @@ -0,0 +1,99 @@ +module.exports = class TutorialList { + constructor() { + this.UI = document.getElementById("tutorialList"); + this.selectorButton = document.getElementById("selectListBtn"); + this.selectorButton.addEventListener("click", e => { + this.setDir(); + }); + } + + bindEvents = (evName, callback) => { + this.UI.addEventListener(evName, callback); + }; + + load = async () => { + var cached_list_dir = Helper.getListDir(); + if (cached_list_dir) { + await Helper.loadScript(cached_list_dir + "/list_mp4.js"); + await Helper.loadScript(cached_list_dir + "/list_vtt.js"); + + await this.loadOptionTags(); + } + return new Promise((resolve, eject) => { + resolve(); + }); + }; + + setIndex = index => { + this.UI.selectedIndex = index; + }; + + getIndex = () => this.UI.selectedIndex; + length = () => this.UI.options.length; + + selectedValue = () => { + if (this.UI.options[this.UI.selectedIndex]) { + return this.UI.options[this.UI.selectedIndex].value; + } else { + return 0; + } + }; + + setDir = function() { + // const win = require('electron').remote.getCurrentWindow(); + // win.setFullScreen(true); + // return; + const app = require("electron").remote.app; + var basepath = Helper.getListDir() || app.getAppPath(); + const dialog = require("electron").remote.dialog; + const list_dir = dialog.showOpenDialog(null, { + properties: ["openDirectory"], + defaultPath: basepath + }); + if (list_dir) { + Helper.setConf("list_dir", list_dir); + } + load(); + }; + + clearHtml = function() { + this.UI.innerHTML = ""; + }; + + loadOptionTags = () => { + this.clearHtml(); + + let temp_vtt_file_dir = ""; + let optionNode; + + optionNode = document.createElement("option"); + optionNode.value = ""; + optionNode.innerHTML = "Select a video to play"; + this.UI.appendChild(optionNode); + + for (var k in vtt_files) { + var vtt_file = vtt_files[k]; + var vtt_file_dir = vtt_file.split(/\//gi)[0]; + + if (vtt_file.indexOf("/") > -1 && vtt_file_dir != temp_vtt_file_dir) { + optionNode = document.createElement("optgroup"); + optionNode.label = Helper.validateTitle(vtt_file_dir); + this.UI.appendChild(optionNode); + } + + optionNode = document.createElement("option"); + optionNode.value = k; + if (vtt_file.indexOf("/") > -1){ + optionNode.innerHTML = Helper.validateTitle( + vtt_file.replace(vtt_file_dir + "/", "   ") + ); + } else { + optionNode.innerHTML = vtt_file; + } + this.UI.appendChild(optionNode); + temp_vtt_file_dir = vtt_file_dir; + } + + this.UI.appendChild(optionNode); + }; +}; diff --git a/player/custom.js b/player/custom.js deleted file mode 100644 index 3b3b466..0000000 --- a/player/custom.js +++ /dev/null @@ -1,287 +0,0 @@ -document.ready = (callback) => { - if (typeof callback === 'function') { - var onceCalled = false - document.addEventListener("DOMContentLoaded", function (event) { - if (!onceCalled) { - onceCalled = true - callback(event) - } - }) - document.onreadystatechange = function (event) { - if (document.readyState == "interactive") { - if (!onceCalled) { - onceCalled = true - callback(event) - } - } - } - } -} - -class Helper { - static validateTitle = (title) => { - var ret = title - ret = ret.replace(/\.vtt/gi, '') - return ret.replace(/\-/gi, ' ') - } - - static loadScript = async (path) => { - let script = document.createElement('script') - script.src = path - document.getElementsByTagName('head')[0].appendChild(script) - return new Promise((resolve, eject) => { - script.onload = () => resolve() - script.onerror = () => eject() - }) - } - - static getListDir = () => { - const cached_list_dir = Helper.getConf('list_dir') - return cached_list_dir - } - - static getHumanTitle = (path) => { - let ret = path.replace(/[\\\/]/g, ' > ') - ret = ret.replace(/\.mp4/g, '') - ret = ret.replace(/\.vtt/g, '') - return ret.replace(/[^A-Za-z0-9\.\>]/g, ' ') - } - - static getConf = (key) => { - return localStorage.getItem(key) - } - - static setConf = (key, value) => { - localStorage.setItem(key, value) - } - -} - - -class Player { - - constructor() { - this.playerUI = document.getElementById('video_player') - this.captionUI = document.getElementById('playerCaption') - this.titleUI = document.getElementById('video_title') - - return; - new MediaElementPlayer(this.playerUI, { - stretching: 'auto', - pluginPath: 'player/media-elements/build/', - success: function (media) { - var renderer = document.getElementById(media.id + '-rendername'); - - media.addEventListener('loadedmetadata', function () { - - }); - - media.addEventListener('error', function (e) { - - }); - } - }); - - } - - bindEvents = (evName, callback) => { - this.playerUI[evName] = callback - } - - play = (index, auto_play = true) => { - if (index === 0) { - return - } - var base_dir = Helper.getListDir() - this.playerUI.preload = true - this.playerUI.src = base_dir + '/' + mp4_files[index] - this.captionUI.src = base_dir + '/' + vtt_files[index] - this.playerUI.textTracks[0].mode = 'showing' - this.titleUI.innerText = Helper.getHumanTitle(mp4_files[index]) - - this.playerUI.ontimeupdate = () => { - if (this.playerUI.currentTime > 0) { - Helper.setConf('currentTime', this.playerUI.currentTime) - } - } - - this.playerUI.focus() - - if (auto_play) { - this.playerUI.play() - } else { - setTimeout(() => { - var currentTime - if (currentTime = Helper.getConf('currentTime')) { - this.playerUI.currentTime = parseFloat(currentTime) - } - }, 1000) - } - } -} - - -class TutorialList { - - constructor() { - this.UI = document.getElementById('tutorialList') - this.selectorButton = document.getElementById('selectListBtn') - this.selectorButton.addEventListener('click', (e) => { - this.setDir() - }) - } - - bindEvents = (evName, callback) => { - this.UI.addEventListener(evName, callback) - } - - load = async () => { - var cached_list_dir = Helper.getListDir() - if (cached_list_dir) { - await Helper.loadScript(cached_list_dir + '/list_mp4.js') - await Helper.loadScript(cached_list_dir + '/list_vtt.js') - - await this.loadOptionTags() - } - return new Promise((resolve, eject) => { resolve() }) - } - - setIndex = (index) => { - this.UI.selectedIndex = index - } - - getIndex = () => this.UI.selectedIndex - length = () => this.UI.options.length - - selectedValue = () => { - if (this.UI.options[this.UI.selectedIndex]) { - return this.UI.options[this.UI.selectedIndex].value - } else { - return 0 - } - } - - setDir = function () { - // const win = require('electron').remote.getCurrentWindow(); - // win.setFullScreen(true); - // return; - const app = require('electron').remote.app - var basepath = Helper.getListDir() || app.getAppPath() - const dialog = require('electron').remote.dialog - const list_dir = dialog.showOpenDialog(null, { - properties: ['openDirectory'], - defaultPath: basepath - }) - if (list_dir) { - Helper.setConf('list_dir', list_dir) - } - load() - } - - clearHtml = function () { - this.UI.innerHTML = '' - } - - loadOptionTags = () => { - - this.clearHtml() - - let temp_vtt_file_dir = '' - let optionNode - - optionNode = document.createElement('option') - optionNode.value = '' - optionNode.innerHTML = "Select a video to play" - this.UI.appendChild(optionNode) - - for (var k in vtt_files) { - var vtt_file = vtt_files[k] - var vtt_file_dir = vtt_file.split(/\//gi)[0] - - if (vtt_file_dir != temp_vtt_file_dir) { - optionNode = document.createElement('optgroup') - optionNode.label = Helper.validateTitle(vtt_file_dir) - this.UI.appendChild(optionNode) - } - - optionNode = document.createElement('option') - optionNode.value = k - optionNode.innerHTML = Helper.validateTitle(vtt_file.replace(vtt_file_dir + "/", '   ')) - this.UI.appendChild(optionNode) - temp_vtt_file_dir = vtt_file_dir - } - - this.UI.appendChild(optionNode) - } -} - -class Seekbar { - - constructor() { - this.UI = document.getElementById("seekbar"); - this.posUI = document.getElementById("seekbar_pos"); - this.UI.ontimeupdate = function () { - var percentage = (vid.currentTime / vid.duration) * 100; - $("#custom-seekbar span").css("width", percentage + "%"); - }; - - this.drag_started = false; - - this.posUI.onmousedown = (e) => { - console.log('onmousedown...'); - this.drag_started = true; - }; - this.UI.onmousemove = (e) => { - if (this.drag_started) { - console.log('onmousemove...'); - this.posUI.style.left = e.pageX; - } - }; - this.UI.onmouseup = (e) => { - console.log('onmouseup...'); - this.drag_started = false; - }; - this.posUI.onmouseup = (e) => { - console.log('onmouseup...'); - this.drag_started = false; - }; - } - - - bindEvents = (evName, callback) => { - this.UI.addEventListener(evName, callback) - this.UI[evName] = callback - } - -}; - - -document.ready(async (event) => { - - const tutorialList = new TutorialList() - const player = new Player() - - await tutorialList.load() - - tutorialList.bindEvents('change', (e) => { - Helper.setConf('currentTime', 0) - player.play(tutorialList.selectedValue()) - Helper.setConf('playedIndex', tutorialList.getIndex()) - }) - - player.bindEvents('onended', (args) => { - Helper.setConf('currentTime', 0) - let nextIndex = tutorialList.getIndex() + 1 - if (nextIndex < tutorialList.length()) { - tutorialList.setIndex(nextIndex) - player.play(tutorialList.selectedValue(), true) - } - }) - - if (playedIndex = Helper.getConf('playedIndex')) { - tutorialList.setIndex(parseInt(playedIndex)) - player.play(tutorialList.selectedValue(), false) - } - -}) - diff --git a/player/index.js b/player/index.js new file mode 100644 index 0000000..c5ff564 --- /dev/null +++ b/player/index.js @@ -0,0 +1,6 @@ +const Helper = require("./player/components/helper"); +const Player = require("./player/components/player"); +const TutorialList = require("./player/components/tutorial_list"); +const Bootstrap = require("./player/components/bootstrap"); + +Bootstrap.initialize(); diff --git a/utils/create_tutorial_list.js b/utils/create_tutorial_list.js new file mode 100644 index 0000000..b7cc927 --- /dev/null +++ b/utils/create_tutorial_list.js @@ -0,0 +1,62 @@ +const glob = require("glob"); +const path = require("path"); +const fs = require("fs"); + +function writeListFile(arrList, varName, fileName, dirPath) { + let newArrList = arrList.map(function(item) { + return item.replace(dirPath + "/", ""); + }); + let content = newArrList.join('",\n"'); + content = "var " + varName + ' = [\n"' + content + '"\n];'; + fs.writeFileSync(dirPath + "/" + fileName, content); +} + +function naturalSort(myArray) { + var collator = new Intl.Collator(undefined, { + numeric: true, + sensitivity: "base" + }); + return myArray.sort(collator.compare); +} + +function validateVTT(mp4_files, vtt_files) { + var new_vtt_files = []; + for( var i = 0; i < mp4_files.length; i++ ) { + var mp4_file = mp4_files[i]; + var vtt_file = mp4_file.substr(0, mp4_file.length - 4) + ".vtt"; + var srt_file = mp4_file.substr(0, mp4_file.length - 4) + ".srt"; + if (vtt_files.indexOf(vtt_file) > -1) { + new_vtt_files.push(vtt_file); + } else if (vtt_files.indexOf(srt_file) > -1) { + new_vtt_files.push(srt_file); + } else { + new_vtt_files.push(vtt_file); + } + } + return new_vtt_files; +} + +module.exports = (dirPath, cb) => { + let mp4_files = glob.sync(path.join(dirPath, "/**/*.mp4")); + let vtt_files = glob.sync(path.join(dirPath, "/**/*.vtt")); + let srt_files = glob.sync(path.join(dirPath, "/**/*.srt")); + + if ( vtt_files.length < srt_files.length ) { + vtt_files = srt_files; + } + + mp4_files = naturalSort(mp4_files); + + vtt_files = validateVTT(mp4_files, vtt_files); + + const newDirPath = dirPath.replace(/\\/g, "/"); + writeListFile(mp4_files, "mp4_files", "list_mp4.js", newDirPath); + + if (vtt_files.length > 0) { + writeListFile(vtt_files, "vtt_files", "list_vtt.js", newDirPath); + } else { + writeListFile([], "vtt_files", "list_vtt.js", newDirPath); + } + + cb({ result: true }); +};