ソースを参照

improve archi + handle controls

Niemes 1 年間 前
コミット
2fbbae83e6
5 ファイル変更531 行追加265 行削除
  1. 8 42
      assets/dom/renderers/FullDomeRenderer.js
  2. 81 0
      assets/js/domUtils.js
  3. 206 0
      assets/js/player.js
  4. 220 132
      assets/js/playlist.js
  5. 16 91
      renderer.js

+ 8 - 42
assets/dom/renderers/FullDomeRenderer.js

@@ -3,7 +3,9 @@
  *   https://github.com/spite/THREE.CubemapToEquirectangular
  */
 
-import {initPlaylist} from '../../js/playlist.js'
+let initDom = function() {
+    startAnimation()
+}
 
 const inchesToMeters     = 0.0254;
 const feetToMeters       = 0.3048;
@@ -205,44 +207,6 @@ function setupScene(scene) {
     var geometry = new THREE.SphereBufferGeometry( RendererConfig.dome.radius, 60, 40 );
     geometry.scale( -1, 1, 1 );
 
-    window.videoPlayer = document.createElement('video');
-    window.videoPlayer.id = "window.videoPlayerplayer"
-    window.videoPlayer.width  = 1024;
-    window.videoPlayer.height =  640;
-    window.videoPlayer.loop = false;
-    window.videoPlayer.loopPlaylist = true
-    window.videoPlayer.muted  = true;
-
-    window.videoPlayer.src = "./assets/preview.mp4";
-    window.videoPlayer.setAttribute( 'webkit-playsinline', 'webkit-playsinline' );
-    window.videoPlayer.setAttribute( 'playsinline', 'playsinline' );
-    window.videoPlayer.setAttribute( 'crossorigin', 'anonymous' );
-    window.videoPlayer.play();
-
-    window.curVideo = 0;
-    
-    window.videoPlayer.onended = function () {
-        let playlistVideos = window.playlist.el.getElementsByTagName("li")
-
-        if (playlistVideos.length !== 0) {
-            window.curVideo++;
-            // go to next video in the playlist
-            if (window.curVideo < playlistVideos.length) {
-                // console.log("try to switch no next video", playlistVideos[window.curVideo]);
-                window.videoPlayer.src = playlistVideos[window.curVideo].getAttribute('path');
-                window.videoPlayer.play()
-            }
-            // last video of the playlist loop back to the begining.
-            else if (window.curVideo == playlistVideos.length && window.videoPlayer.loopPlaylist){
-                window.curVideo = 0;
-                window.videoPlayer.src = playlistVideos[window.curVideo].getAttribute('path');
-                window.videoPlayer.play()
-            }
-        } else {
-            window.curVideo = 0
-            window.videoPlayer.play()
-        }
-    }
     // iOS require the video to start muted in order for it to autoplay, so we use a click
     // to enable the sound.
     // document.getElementsByTagName("canvas")[0].addEventListener("click",
@@ -363,7 +327,9 @@ if(window.onRendererReady) {
 }
 
 window.onload = function () {
-    initPlaylist()
-    startAnimation()
+    // initPlaylist()
+    // startAnimation()
     window.onWindowResize(true)
-};
+};
+
+export {initDom}

+ 81 - 0
assets/js/domUtils.js

@@ -0,0 +1,81 @@
+// control panel hide/show
+// shortcuts 
+
+
+let domUtils = function () {
+    let optionPanel = document.getElementById('panel')
+    let progres = document.getElementById('controls')
+
+
+    function hidepanel(bool) {
+        if (!bool) {
+            optionPanel.style.right = "15px"
+            optionPanel.style.opacity = 1
+            progres.style.opacity = 1
+        } else {
+            optionPanel.style.right = "-315px"
+            optionPanel.style.opacity = 0
+            progres.style.opacity = 0
+        }
+    }
+
+    function miam(mess, type, duration = 1000, pos = "top-left") {
+        bulmaToast.toast({
+            message: mess,
+            type: type,
+            dismissible: true,
+            duration: duration,
+            position: pos,
+            "single": false,
+            // animate: { in: 'fadeIn', out: 'fadeOut' }
+        })
+    }
+
+    document.addEventListener("keydown", function (event) {
+        // console.log("event.key", event.key)
+        let usedKeys = ["p", " ", "m"]
+
+        if (usedKeys.indexOf(event.key) !== -1) { // touche - debug info
+            event.preventDefault();
+
+            if (event.key == "m") { // m for muted
+                if (!videoPlayer.muted) videoPlayer.muted = true
+                else videoPlayer.muted = false
+                // notif("success", "mute", videoPlayer.muted)
+                miam(videoPlayer.muted ? "Mute" : "Unmute", 'is-primary')
+            }
+
+            if (event.key == " ") { // space for pause
+                if (!videoPlayer.paused) {
+                    videoPlayer.pause()
+                    miam('Video Paused.', 'is-primary')
+                }
+                else {
+                    videoPlayer.play()
+                    miam('Video is playing.', 'is-primary')
+                }
+
+            }
+
+            if (event.key === "p") { // P for panel
+                event.preventDefault();
+                if (optionPanel.style.opacity == 0) hidepanel(false)
+                else hidepanel(true)
+            }
+        }
+    });
+
+    function centerVideo(){
+        let wrapLoca = document.getElementById('wrap')
+    
+        wrapLoca.style.left = `calc(50vw - ${wrapLoca.offsetWidth / 2}px)`
+        wrapLoca.style.top = `calc(50vh - ${wrapLoca.offsetHeight / 2}px)`
+        localStorage.setItem('playerTop', wrapLoca.style.top);
+        localStorage.setItem('playerLeft', wrapLoca.style.left);
+    }
+
+    miam("Press 'P' to open the Menu.", 'is-info', 4000, "top-center")
+}
+
+
+export { domUtils };

+ 206 - 0
assets/js/player.js

@@ -0,0 +1,206 @@
+import { Playlist } from './playlist.js'
+
+let baseClass = "button is-small is-light"
+let clactive = baseClass + " is-link"
+let currentPlaylist = []
+
+class MainPlayer {
+    constructor() {
+
+        this.playlist = new Playlist()
+        this.config = {
+            currentIndex: 0,
+            loop: () => localStorage.getItem('loop'),
+        }
+
+        this.button = {
+            play: document.getElementById("play"),
+            pause: document.getElementById("pause"),
+            loop: document.getElementById("loop")
+        }
+        this.controls = {
+            play: (elem, act) => {
+                window.videoPlayer.play()
+                if (!act) {
+                    elem.className = clactive
+                    this.button.pause.className = baseClass
+                    this.button.pause.setAttribute('active', "false")
+                } else {
+                    elem.className = baseClass
+                    document.getElementById("pause").className = baseClass
+                }
+            },
+            pause: (elem, act) => {
+                window.videoPlayer.pause()
+                if (!act) {
+                    elem.className = clactive
+                    this.button.play.className = baseClass
+                    this.button.play.setAttribute('active', "false")
+                } else {
+                    elem.className = baseClass
+                    document.getElementById("play").className = clactive
+                }
+            },
+            previous: (elem) => {
+        
+            },
+            next: (elem) => {
+        
+            },
+            loop: (elem, act) => {
+                let swap = act ? false : true
+                elem.setAttribute('active', swap)
+                localStorage.setItem('loop', swap);
+
+                console.log("swap", swap)
+                if (swap) elem.className = clactive
+                else elem.className = baseClass
+            }
+        }
+
+        this.ctrlPlayer = (cmd, srcElem) => {
+            let active = srcElem.getAttribute("active") == "false" ? false : true
+            this.controls[cmd](srcElem, active)
+        },
+
+        this.addVideo = function () {
+
+            const dialogConfig = {
+                title: 'Select video files',
+                buttonLabel: 'Validate Selection',
+                filters: [
+                    { name: 'Movies', extensions: ['mkv', 'avi', 'mp4', "m4v", "webm", "ogv"] }
+                ],
+                properties: ['openFile', 'multiSelections']
+            };
+
+            electron.openDialog('showOpenDialog', dialogConfig)
+                .then((result) => {
+                    window.videoPlayer.src = result?.filePaths[0]
+                    window.videoPlayer.play()
+
+                    createPlaylist(result.filePaths)
+                })
+                .catch((err) => { console.log("err", err) })
+        }
+
+
+        this.createPlaylist = function (list) {
+            let playlist = document.getElementById('playlist')
+            let emptyFlag = document.getElementById('emptyFlag')
+
+            emptyFlag.style.display = "none"
+
+            list?.forEach((source) => {
+                currentPlaylist.push(source)
+                localStorage.setItem('playlist', currentPlaylist.join("|"));
+                let pathfull = source.split("/")
+                let filename = pathfull[pathfull.length - 1]
+
+                let videoNeo = document.createElement('li')
+                let delButton = document.createElement('button')
+                delButton.className = "delete is-small"
+
+                delButton.addEventListener('dblclick', function (event) {
+                    console.log("db click")
+                    removeVideo(event.srcElement.parentNode)
+                });
+
+                videoNeo.innerHTML = `<span class="hand">  </span>${filename}`
+                videoNeo.setAttribute("path", source);
+                videoNeo.setAttribute("index", playlist.getElementsByTagName('li').length);
+                videoNeo.appendChild(delButton)
+
+                videoNeo.onclick = () => {
+                    videoPlayer.src = videoNeo.getAttribute('path')
+                    window.curVideo = videoNeo.getAttribute('index')
+                    window.videoPlayer.play()
+                }
+                playlist.appendChild(videoNeo)
+                // console.log("window.playlist", window.playlist);
+            })
+        },
+
+        this.removeVideo = function (val) {
+            var emptyFlag = document.getElementById('emptyFlag')
+            var listElements = document.getElementById("playlist");
+            let sourcePath = val.getAttribute("path")
+            let sourceIndex = currentPlaylist.indexOf(sourcePath)
+            listElements.removeChild(val);
+
+            if (sourceIndex !== -1) {
+                currentPlaylist.splice(sourceIndex, 1);
+            }
+
+            // If playlist is empty
+            if (listElements.childElementCount == 1) {
+                emptyFlag.style.display = "flex"
+                window.videoPlayer.pause()
+                window.videoPlayer.src = "./assets/preview.mp4";
+                window.videoPlayer.play()
+            }
+            //update playlist cache 
+            localStorage.setItem('playlist', currentPlaylist.join("|"));
+        },
+
+        this.initPlayer = function() {
+            window.videoPlayer = document.createElement('video');
+            window.videoPlayer.id = "window.videoPlayerplayer"
+            window.videoPlayer.width = 1024;
+            window.videoPlayer.height = 640;
+            window.videoPlayer.loop = false;
+            window.videoPlayer.muted = true;
+
+            window.videoPlayer.src = "./assets/preview.mp4";
+            window.videoPlayer.setAttribute('webkit-playsinline', 'webkit-playsinline');
+            window.videoPlayer.setAttribute('playsinline', 'playsinline');
+            window.videoPlayer.setAttribute('crossorigin', 'anonymous');
+            window.videoPlayer.play();
+
+            window.curVideo = 0;
+            
+            let self = this
+            window.videoPlayer.onended = function () {
+                let playlistVideos = window.playlist.el.getElementsByTagName("li")
+                let looping = self.config.loop()
+
+                if (playlistVideos.length !== 0) {
+                    window.curVideo++;
+                    console.log("looping", looping)
+                    console.log("window.curVideo", window.curVideo, playlistVideos.length, window.curVideo < playlistVideos.length - 1)
+
+                    // go to next video in the playlist
+                    if (window.curVideo < playlistVideos.length) {
+                        // console.log("try to switch no next video", playlistVideos[window.curVideo]);
+                        window.videoPlayer.src = playlistVideos[window.curVideo].getAttribute('path');
+                        window.videoPlayer.play()
+                    }
+                    // last video of the playlist loop back to the begining.
+                    else if (window.curVideo >= playlistVideos.length - 1&& looping == "true") {
+                        console.log("is looping ? !", looping)
+                        window.curVideo = 0;
+                        window.videoPlayer.src = playlistVideos[window.curVideo].getAttribute('path');
+                        window.videoPlayer.play()
+                    } else {
+                        console.log("playlist end")
+                        window.curVideo = 0
+                    }
+                } else {
+                    window.curVideo = 0
+                    window.videoPlayer.play()
+                }
+            }
+            console.log("init loop", this.config.loop())
+            this.button.loop.setAttribute('active', this.config.loop() ? "true" : "false")
+
+            console.log("test loop", this.config.loop() == "true" ? clactive : baseClass)
+            this.button.loop.className = ""
+            this.button.loop.className = this.config.loop() == "true" ? clactive : baseClass
+
+            console.log("className = ", this.button.loop.className)
+        }
+        
+    }
+}
+
+export { MainPlayer };

+ 220 - 132
assets/js/playlist.js

@@ -1,141 +1,229 @@
 
 
-let initPlaylist = function() {
-    
-    let el = document.getElementById('playlist')
-
-    window.playlist = new Sortable(el, {
-        group: "videos",  // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
-        sort: true,  // sorting inside list
-        delay: 0, // time in milliseconds to define when the sorting should start
-        delayOnTouchOnly: false, // only delay if user is using touch
-        touchStartThreshold: 0, // px, how many pixels the point should move before cancelling a delayed drag event
-        store: null,  // @see Store
-        animation: 150,  // ms, animation speed moving items when sorting, `0` — without animation
-        easing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples.
-        handle: ".hand",  // Drag handle selector within list items
-        // filter: ".ignore-elements",  // Selectors that do not lead to dragging (String or Function)
-        preventOnFilter: true, // Call `event.preventDefault()` when triggered `filter`
-        // draggable: ".item",  // Specifies which items inside the element should be draggable
-
-        dataIdAttr: 'data-id', // HTML attribute that is used by the `toArray()` method
-
-        ghostClass: "sortable-ghost",  // Class name for the drop placeholder
-        chosenClass: "sortable-chosen",  // Class name for the chosen item
-        dragClass: "sortable-drag",  // Class name for the dragging item
-
-        swapThreshold: 1, // Threshold of the swap zone
-        invertSwap: false, // Will always use inverted swap zone if set to true
-        invertedSwapThreshold: 1, // Threshold of the inverted swap zone (will be set to swapThreshold value by default)
-        direction: 'horizontal', // Direction of Sortable (will be detected automatically if not given)
-
-        forceFallback: false,  // ignore the HTML5 DnD behaviour and force the fallback to kick in
-
-        fallbackClass: "sortable-fallback",  // Class name for the cloned DOM Element when using forceFallback
-        fallbackOnBody: false,  // Appends the cloned DOM Element into the Document's Body
-        fallbackTolerance: 0, // Specify in pixels how far the mouse should move before it's considered as a drag.
-
-        removeCloneOnHide: true, // Remove the clone element when it is not showing, rather than just hiding it
-        emptyInsertThreshold: 5, // px, distance mouse must be from empty sortable to insert drag element into it
-
-
-        setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
-            dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
-        },
-
-        // Element is chosen
-        onChoose: function (/**Event*/evt) {
-            evt.oldIndex;  // element index within parent
-        },
-
-        // Element is unchosen
-        onUnchoose: function(/**Event*/evt) {
-            // same properties as onEnd
-        },
-
-        // Element dragging started
-        onStart: function (/**Event*/evt) {
-            evt.oldIndex;  // element index within parent
-        },
+let currentPlaylist = []
+class Playlist {
+    constructor(){
 
-        // Element dragging ended
-        onEnd: function (/**Event*/evt) {
-            var itemEl = evt.item;  // dragged HTMLElement
-            evt.to;    // target list
-            evt.from;  // previous list
-            evt.oldIndex;  // element's old index within old parent
-            evt.newIndex;  // element's new index within new parent
-            evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
-            evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
-            evt.clone // the clone element
-            evt.pullMode;  // when item is in another sortable: `"clone"` if cloning, `true` if moving
-        },
-
-        // Element is dropped into the list from another list
-        onAdd: function (/**Event*/evt) {
-            // same properties as onEnd
-            console.log("vidéo Ajouté", evt)
-        },
-
-        // Changed sorting within list
-        onUpdate: function (/**Event*/evt) {
-            // same properties as onEnd
-            console.log("Update VidéoList", evt);
-        },
-
-        // Called by any change to the list (add / update / remove)
-        onSort: function (/**Event*/evt) {
-            // same properties as onEnd
-        },
-
-        // Element is removed from the list into another list
-        onRemove: function (/**Event*/evt) {
-            // same properties as onEnd
-        },
-
-        // Attempt to drag a filtered element
-        onFilter: function (/**Event*/evt) {
-            var itemEl = evt.item;  // HTMLElement receiving the `mousedown|tapstart` event.
-        },
-
-        // Event when you move an item in the list or between lists
-        onMove: function (/**Event*/evt, /**Event*/originalEvent) {
-            // Example: https://jsbin.com/nawahef/edit?js,output
-            evt.dragged; // dragged HTMLElement
-            evt.draggedRect; // DOMRect {left, top, right, bottom}
-            evt.related; // HTMLElement on which have guided
-            evt.relatedRect; // DOMRect
-            evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default
-            originalEvent.clientY; // mouse position
-            // return false; — for cancel
-            // return -1; — insert before target
-            // return 1; — insert after target
-            // return true; — keep default insertion point based on the direction
-            // return void; — keep default insertion point based on the direction
-        },
-
-        // Called when creating a clone of element
-        onClone: function (/**Event*/evt) {
-            var origEl = evt.item;
-            var cloneEl = evt.clone;
-        },
+        let self = this
+        this.addVideo = function(){
+    
+            const dialogConfig = {
+                title: 'Select video files',
+                buttonLabel: 'Validate Selection',
+                filters: [
+                    { name: 'Movies', extensions: ['mkv', 'avi', 'mp4', "m4v", "webm", "ogv"] }
+                ],
+                properties: ['openFile', 'multiSelections']
+            };
+            
+            electron.openDialog('showOpenDialog', dialogConfig)
+            .then( (result) => {
+                window.videoPlayer.src = result?.filePaths[0]
+                window.videoPlayer.play()
+        
+                self.createPlaylist(result.filePaths)
+            })
+            .catch( (err) => {console.log("err", err)})
+        
+        }
 
-        // Called when dragging element changes position
-        onChange: function(evt) {
-            evt.newIndex // most likely why this event is used is to get the dragging element's current index
-            // same properties as onEnd
-            // console.log("change", evt.oldIndex, evt.newIndex);
-            if (evt.oldIndex == window.curVideo) {
-                window.curVideo = evt.newIndex
+        this.createPlaylist = function(list){
+            let playlist = document.getElementById('playlist')
+            let emptyFlag = document.getElementById('emptyFlag')
+        
+            emptyFlag.style.display = "none"
+        
+            list?.forEach( (source) => {
+                currentPlaylist.push(source)
+                localStorage.setItem('playlist', currentPlaylist.join("|"));
+                let pathfull = source.split("/")
+                let filename = pathfull[pathfull.length - 1]
+        
+                let videoNeo = document.createElement('li')
+                let delButton = document.createElement('button')
+                delButton.className = "delete is-small"
+        
+                delButton.addEventListener('click', function (event) {
+                    console.log("db click")
+                    self.removeVideo(event.srcElement.parentNode)
+                });
+        
+                videoNeo.innerHTML = `<span class="hand">  </span>${filename}`
+                videoNeo.setAttribute("path", source);
+                videoNeo.setAttribute("index", playlist.getElementsByTagName('li').length);
+                videoNeo.appendChild(delButton)
+        
+                videoNeo.addEventListener('dblclick', function (event) {
+                    videoPlayer.src = videoNeo.getAttribute('path')
+                    window.curVideo = videoNeo.getAttribute('index')
+                    window.videoPlayer.play()
+                });
+        
+                playlist.appendChild(videoNeo)
+                // console.log("window.playlist", window.playlist);
+            })
+        }
+        
+        this.removeVideo = function(val) {
+            var emptyFlag = document.getElementById('emptyFlag')
+            var listElements = document.getElementById("playlist");
+            let sourcePath = val.getAttribute("path")
+            let sourceIndex = currentPlaylist.indexOf(sourcePath)
+            listElements.removeChild(val);
+            
+            if ( sourceIndex !== -1) {
+                currentPlaylist.splice(sourceIndex,1);
             }
-            let currentPlaylist = window.playlist.el.getElementsByTagName("li")
-                
-            for (let index = 0; index < currentPlaylist.length; index++) {
-                const element = currentPlaylist[index];
-                element.setAttribute('index', index)
+        
+            // If playlist is empty
+            if (listElements.childElementCount == 1) {
+                emptyFlag.style.display = "flex"
+                window.videoPlayer.pause()
+                window.videoPlayer.src = "./assets/preview.mp4";
+                window.videoPlayer.play()
             }
+            //update playlist cache 
+            localStorage.setItem('playlist', currentPlaylist.join("|"));
+        }
+
+        this.initPlaylist = function() {
+    
+            let el = document.getElementById('playlist')
+        
+            window.playlist = new Sortable(el, {
+                group: "videos",  // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
+                sort: true,  // sorting inside list
+                delay: 0, // time in milliseconds to define when the sorting should start
+                delayOnTouchOnly: false, // only delay if user is using touch
+                touchStartThreshold: 0, // px, how many pixels the point should move before cancelling a delayed drag event
+                store: null,  // @see Store
+                animation: 150,  // ms, animation speed moving items when sorting, `0` — without animation
+                easing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples.
+                handle: ".hand",  // Drag handle selector within list items
+                // filter: ".ignore-elements",  // Selectors that do not lead to dragging (String or Function)
+                preventOnFilter: true, // Call `event.preventDefault()` when triggered `filter`
+                // draggable: ".item",  // Specifies which items inside the element should be draggable
+        
+                dataIdAttr: 'data-id', // HTML attribute that is used by the `toArray()` method
+        
+                ghostClass: "sortable-ghost",  // Class name for the drop placeholder
+                chosenClass: "sortable-chosen",  // Class name for the chosen item
+                dragClass: "sortable-drag",  // Class name for the dragging item
+        
+                swapThreshold: 1, // Threshold of the swap zone
+                invertSwap: false, // Will always use inverted swap zone if set to true
+                invertedSwapThreshold: 1, // Threshold of the inverted swap zone (will be set to swapThreshold value by default)
+                direction: 'horizontal', // Direction of Sortable (will be detected automatically if not given)
+        
+                forceFallback: false,  // ignore the HTML5 DnD behaviour and force the fallback to kick in
+        
+                fallbackClass: "sortable-fallback",  // Class name for the cloned DOM Element when using forceFallback
+                fallbackOnBody: false,  // Appends the cloned DOM Element into the Document's Body
+                fallbackTolerance: 0, // Specify in pixels how far the mouse should move before it's considered as a drag.
+        
+                removeCloneOnHide: true, // Remove the clone element when it is not showing, rather than just hiding it
+                emptyInsertThreshold: 5, // px, distance mouse must be from empty sortable to insert drag element into it
+        
+        
+                setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
+                    dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
+                },
+        
+                // Element is chosen
+                onChoose: function (/**Event*/evt) {
+                    evt.oldIndex;  // element index within parent
+                },
+        
+                // Element is unchosen
+                onUnchoose: function(/**Event*/evt) {
+                    // same properties as onEnd
+                },
+        
+                // Element dragging started
+                onStart: function (/**Event*/evt) {
+                    evt.oldIndex;  // element index within parent
+                },
+        
+                // Element dragging ended
+                onEnd: function (/**Event*/evt) {
+                    var itemEl = evt.item;  // dragged HTMLElement
+                    evt.to;    // target list
+                    evt.from;  // previous list
+                    evt.oldIndex;  // element's old index within old parent
+                    evt.newIndex;  // element's new index within new parent
+                    evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
+                    evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
+                    evt.clone // the clone element
+                    evt.pullMode;  // when item is in another sortable: `"clone"` if cloning, `true` if moving
+                },
+        
+                // Element is dropped into the list from another list
+                onAdd: function (/**Event*/evt) {
+                    // same properties as onEnd
+                    console.log("vidéo Ajouté", evt)
+                },
+        
+                // Changed sorting within list
+                onUpdate: function (/**Event*/evt) {
+                    // same properties as onEnd
+                    console.log("Update VidéoList", evt);
+                },
+        
+                // Called by any change to the list (add / update / remove)
+                onSort: function (/**Event*/evt) {
+                    // same properties as onEnd
+                },
+        
+                // Element is removed from the list into another list
+                onRemove: function (/**Event*/evt) {
+                    // same properties as onEnd
+                },
+        
+                // Attempt to drag a filtered element
+                onFilter: function (/**Event*/evt) {
+                    var itemEl = evt.item;  // HTMLElement receiving the `mousedown|tapstart` event.
+                },
+        
+                // Event when you move an item in the list or between lists
+                onMove: function (/**Event*/evt, /**Event*/originalEvent) {
+                    // Example: https://jsbin.com/nawahef/edit?js,output
+                    evt.dragged; // dragged HTMLElement
+                    evt.draggedRect; // DOMRect {left, top, right, bottom}
+                    evt.related; // HTMLElement on which have guided
+                    evt.relatedRect; // DOMRect
+                    evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default
+                    originalEvent.clientY; // mouse position
+                    // return false; — for cancel
+                    // return -1; — insert before target
+                    // return 1; — insert after target
+                    // return true; — keep default insertion point based on the direction
+                    // return void; — keep default insertion point based on the direction
+                },
+        
+                // Called when creating a clone of element
+                onClone: function (/**Event*/evt) {
+                    var origEl = evt.item;
+                    var cloneEl = evt.clone;
+                },
+        
+                // Called when dragging element changes position
+                onChange: function(evt) {
+                    evt.newIndex // most likely why this event is used is to get the dragging element's current index
+                    // same properties as onEnd
+                    // console.log("change", evt.oldIndex, evt.newIndex);
+                    if (evt.oldIndex == window.curVideo) {
+                        window.curVideo = evt.newIndex
+                    }
+                    let currentPlaylist = window.playlist.el.getElementsByTagName("li")
+                        
+                    for (let index = 0; index < currentPlaylist.length; index++) {
+                        const element = currentPlaylist[index];
+                        element.setAttribute('index', index)
+                    }
+                }
+            });
         }
-    });
+    }
 }
 
-export { initPlaylist };
+export { Playlist };

+ 16 - 91
renderer.js

@@ -4,103 +4,28 @@
 // `nodeIntegration` is turned off. Use `preload.js` to
 // selectively enable features needed in the rendering
 // process.
-
-function centerVideo(){
-    let wrapLoca = document.getElementById('wrap')
-
-    wrapLoca.style.left = `calc(50vw - ${wrapLoca.offsetWidth / 2}px)`
-    wrapLoca.style.top = `calc(50vh - ${wrapLoca.offsetHeight / 2}px)`
-    localStorage.setItem('playerTop', wrapLoca.style.top);
-    localStorage.setItem('playerLeft', wrapLoca.style.left);
-    // console.log("new location save", wrapLoca.style.left, wrapLoca.style.top)
-}
-
-let currentPlaylist = []
-function addVideo(){
-    
-    const dialogConfig = {
-        title: 'Select video files',
-        buttonLabel: 'Validate Selection',
-        filters: [
-            { name: 'Movies', extensions: ['mkv', 'avi', 'mp4', "m4v", "webm", "ogv"] }
-        ],
-        properties: ['openFile', 'multiSelections']
-    };
-    
-    electron.openDialog('showOpenDialog', dialogConfig)
-    .then( (result) => {
-        window.videoPlayer.src = result?.filePaths[0]
-        window.videoPlayer.play()
-
-        createPlaylist(result.filePaths)
-    })
-    .catch( (err) => {console.log("err", err)})
-
-}
-
-function createPlaylist(list){
-    let playlist = document.getElementById('playlist')
-    let emptyFlag = document.getElementById('emptyFlag')
-
-    emptyFlag.style.display = "none"
-
-    list?.forEach( (source) => {
-        currentPlaylist.push(source)
-        localStorage.setItem('playlist', currentPlaylist.join("|"));
-        let pathfull = source.split("/")
-        let filename = pathfull[pathfull.length - 1]
-
-        let videoNeo = document.createElement('li')
-        let delButton = document.createElement('button')
-        delButton.className = "delete is-small"
-
-        delButton.addEventListener('dblclick', function (event) {
-            console.log("db click")
-            removeVideo(event.srcElement.parentNode)
-        });
-
-        videoNeo.innerHTML = `<span class="hand">  </span>${filename}`
-        videoNeo.setAttribute("path", source);
-        videoNeo.setAttribute("index", playlist.getElementsByTagName('li').length);
-        videoNeo.appendChild(delButton)
-
-        videoNeo.onclick = () => {
-            videoPlayer.src = videoNeo.getAttribute('path')
-            window.curVideo = videoNeo.getAttribute('index')
-            window.videoPlayer.play()
-        }
-        playlist.appendChild(videoNeo)
-        // console.log("window.playlist", window.playlist);
-    })
-}
-
-function removeVideo(val) {
-    var emptyFlag = document.getElementById('emptyFlag')
-    var listElements = document.getElementById("playlist");
-    let sourcePath = val.getAttribute("path")
-    let sourceIndex = currentPlaylist.indexOf(sourcePath)
-    listElements.removeChild(val);
+// Init player
+    // init playlist
+    // init DomRenderer
+    // domUtils
     
-    if ( sourceIndex !== -1) {
-        currentPlaylist.splice(sourceIndex,1);
-    }
+import { domUtils } from './assets/js/domUtils.js'
+import { MainPlayer } from './assets/js/player.js'
+import { initDom } from './assets/dom/renderers/FullDomeRenderer.js'
 
-    // If playlist is empty
-    if (listElements.childElementCount == 1) {
-        emptyFlag.style.display = "flex"
-        window.videoPlayer.pause()
-        window.videoPlayer.src = "./assets/preview.mp4";
-        window.videoPlayer.play()
-    }
-    //update playlist cache 
-    localStorage.setItem('playlist', currentPlaylist.join("|"));
-}
+domUtils()
 
+let player = new MainPlayer()
+player.playlist.initPlaylist()
+player.initPlayer()
+initDom()
 
+window.player = player
+window.control = player.ctrlPlayer
 
-// Init playlist
 document.addEventListener('DOMContentLoaded', ()=> {
     let lastPlaylist = localStorage.getItem('playlist').split("|")
-    if (lastPlaylist.length > 0) createPlaylist(lastPlaylist)
+    if (lastPlaylist.length > 0) player.playlist.createPlaylist(lastPlaylist)
 }, false);
 
+