@@ -9,8 +9,11 @@ export type video = {
99
1010const store : { [ key : string ] : video } = { } ;
1111const queue : string [ ] = [ ] ;
12- let queuepos = 0 ;
12+ let queuepos = - 1 ;
13+ let popupel : HTMLElement = null ;
1314let queueel : HTMLElement = null ;
15+ let titleel : HTMLElement = null ;
16+ let quenoel : HTMLElement = null ;
1417
1518export async function addToStore ( name : string , length : string , thumbnail : string , title : string , creator : string ) : Promise < void > ;
1619export async function addToStore ( name : string ) : Promise < void > ;
@@ -20,83 +23,143 @@ export async function addToStore(name: string, ...args: any[]) {
2023 const [ length , thumbnail , title , creator ] = args . length === 4 ? args : await requestData ( name ) ;
2124 store [ name ] = { length, thumbnail, title, creator } ;
2225}
26+ export const isEmptyQueue = ( ) => queue . length === 0 ;
2327export const enqueue = ( name : string , pos ?: number ) => {
2428 if ( ! store [ name ] )
2529 throw "Not in store!" ;
2630 if ( pos !== undefined )
2731 queue . splice ( pos , 0 , name ) ;
2832 else
2933 queue . splice ( queue . length , 0 , name ) ;
30- console . log ( queue ) ;
34+ popupel . classList . remove ( 'hidden' ) ;
35+ calcBottom ( popupel . classList . contains ( 'down' ) ) ;
3136} ;
3237export const enqueueNow = ( name : string ) => {
3338 if ( ! name )
3439 throw "Not in store!" ;
35- queue . splice ( queuepos + 1 , 0 , name ) ;
36- console . log ( queue ) ;
40+ if ( queue [ queuepos ] !== name && queue [ queuepos + 1 ] !== name )
41+ enqueue ( name , queuepos + 1 ) ;
3742}
3843export const removeFromQueue = ( index : number ) => {
44+ console . log ( index , queuepos , queue ) ;
45+ if ( index < 0 || index >= queue . length ) return ;
46+ if ( queue . length === 1 ) return clearQueue ( ) ;
3947 queue . splice ( index , 1 ) ;
40- console . log ( queue ) ;
48+ if ( queuepos >= 0 && index <= queuepos ) {
49+ -- queuepos ;
50+ updateText ( ) ;
51+ }
4152}
42- export const gotoQueue = ( index : number ) => {
53+ export const gotoQueue = ( index : number , go = true ) => {
54+ console . log ( index , queue ) ;
55+ if ( index < 0 || index >= queue . length ) return ;
4356 queueel ?. children [ queuepos ] ?. classList . remove ( 'playing' ) ;
4457 queuepos = index ;
45- const url = `/videos/${ queue [ index ] } ` ;
46- // trick router into accepting my url without reloading page
47- window . history . pushState ( null , null , url ) ;
48- window . history . pushState ( null , null , url ) ;
49- window . history . back ( ) ;
58+ if ( go ) {
59+ const url = `/videos/${ queue [ index ] } ` ;
60+ // trick router into accepting my url without reloading page
61+ // if previously tricked, need to undo that (to avoid broken history)
62+ if ( history . state ?. fake === true )
63+ window . history . back ( ) ;
64+ setTimeout ( ( ) => {
65+ window . history . pushState ( { fake : true } , null , url ) ;
66+ window . dispatchEvent ( new PopStateEvent ( "popstate" ) ) ;
67+ } , 0 ) ;
68+ }
5069 queueel ?. children [ index ] ?. classList . add ( 'playing' ) ;
51- console . log ( queuepos ) ;
70+ updateText ( ) ;
5271}
5372export const gotoNextInQueue = ( ) => gotoQueue ( queuepos + 1 ) ;
73+ export const clearQueue = ( ) => {
74+ queuepos = - 1 ;
75+ queue . splice ( 0 , queue . length ) ;
76+ clearText ( ) ;
77+ popupel . classList . add ( 'hidden' ) ;
78+ setTimeout ( ( ) => popupel . classList . remove ( 'down' ) , 0 ) ;
79+ } ;
80+ export const toggleQueue = ( ) => calcBottom ( popupel . classList . toggle ( 'down' ) ) ;
5481
5582
5683export const init = ( ) => {
5784 // remove existing elements from extension reload
58- Array . from ( document . querySelectorAll ( '.enhancer-queue' ) ) . forEach ( e => e . remove ( ) ) ;
85+ Array . from ( document . querySelectorAll ( '.enhancer-queue' ) ) . forEach ( n => n . remove ( ) ) ;
5986
6087 const q = document . createElement ( 'div' ) ;
61- q . className = 'enhancer-queue' ;
88+ popupel = q ;
89+ q . className = 'enhancer-queue hidden' ;
6290 q . innerHTML = `
63- <div class="top"></div>
64- <div class="elements"></div>
91+ <div class="enhancer-queue-inner">
92+ <div class="top">
93+ <div class="current"><span class="title">Nothing to play</span><span class="no">-</span> / <span class="of">0</span></div>
94+ <div class="close">×</div>
95+ </div>
96+ <div class="elements"></div>
97+ </div>
6598 ` ;
66- const e = q . querySelector ( '.elements' ) as HTMLElement ;
99+ const e : HTMLElement = q . querySelector ( '.elements' ) ;
67100 queueel = e ;
68- document . body . appendChild ( q ) ;
101+ const o : HTMLElement = q . querySelector ( '.of' ) ;
102+ titleel = q . querySelector ( '.title' ) ;
103+ quenoel = q . querySelector ( '.no' ) ;
104+ document . body . append ( q ) ;
69105
70106 queue . splice = ( start : number , count : number , ...elements : string [ ] ) => {
71107 start = start < 0 ? queue . length - start : start ;
72108 start = start < 0 ? 0 : start > queue . length ? queue . length : start ;
73109 const end = start + count > queue . length ? queue . length : start + count ;
74110 let s = start > 0 ? e . children [ start - 1 ] : null ;
75- for ( let i = start ; i < end ; i ++ )
111+ for ( let i = end - 1 ; i >= start ; i -- )
76112 e . children [ i ] . remove ( ) ;
77113 for ( let el of elements ) {
78114 const node = insertChild ( el ) ;
79- s = s === null ? e . appendChild ( node ) : ( s . after ( node ) , node ) ;
115+ s === null ? e . firstChild === null ? e . append ( node ) : e . firstChild . before ( node ) : s . after ( node ) ;
116+ s = node ;
80117 }
81- return Array . prototype . splice . call ( queue , start , count , ...elements ) ;
118+ const del = Array . prototype . splice . call ( queue , start , count , ...elements ) ;
119+ o . textContent = `${ queue . length } ` ;
120+ return del ;
82121 } ;
83122 e . addEventListener ( 'click' , clickElements ) ;
123+ q . querySelector ( '.top' ) . addEventListener ( 'click' , toggleQueue ) ;
124+ q . querySelector ( '.close' ) . addEventListener ( 'click' , clearQueue ) ;
84125 window . addEventListener ( 'message' , msg ) ;
85126} ;
86127const clickElements = ( e : MouseEvent ) => {
87128 const el = ( e . target as HTMLElement ) . closest ( '.element' ) ;
88129 if ( el === null )
89130 return ;
90131 e . preventDefault ( ) ;
91- const i = Array . from ( el . parentElement . children ) . findIndex ( e => e . isSameNode ( el ) ) ;
92- gotoQueue ( i ) ;
132+ const i = Array . from ( el . parentElement . children ) . findIndex ( n => n . isSameNode ( el ) ) ;
133+ if ( i === - 1 )
134+ return ;
135+ const r = ( e . target as HTMLElement ) . closest ( '.r' ) ;
136+ if ( r === null )
137+ gotoQueue ( i ) ;
138+ else
139+ removeFromQueue ( i ) ;
93140} ;
94141const msg = ( e : MessageEvent ) => {
95142 if ( e . origin !== "https://player.zype.com" && e . origin !== "http://player.zype.com" )
96143 return ;
97- const m = JSON . parse ( e . data ) ;
98- if ( m . event === "zype:complete" ) gotoNextInQueue ( ) ;
99- }
144+ try {
145+ const m = JSON . parse ( e . data ) ;
146+ if ( m . event === "zype:complete" ) gotoNextInQueue ( ) ;
147+ } catch { }
148+ } ;
149+ const updateText = ( ) => {
150+ titleel . textContent = store [ queue [ queuepos ] ] ?. title ;
151+ quenoel . textContent = queuepos >= 0 ? `${ queuepos + 1 } ` : '-' ;
152+ } ;
153+ const clearText = ( ) => {
154+ titleel . textContent = 'Nothing to play' ;
155+ quenoel . textContent = '-' ;
156+ } ;
157+ const calcBottom = ( down : boolean ) => {
158+ if ( down )
159+ popupel . style . bottom = `-${ queueel . getBoundingClientRect ( ) . height } px` ;
160+ else
161+ popupel . style . bottom = '' ;
162+ } ;
100163
101164
102165type thumb = {
@@ -144,6 +207,7 @@ const insertChild = (name: string): HTMLElement => {
144207 <span class="title">${ store [ name ] . title } </span>
145208 <span class="creator">${ store [ name ] . creator } • ${ store [ name ] . length } </span>
146209 </div>
210+ <div class="remove"><span class="r">🗑</span></div>
147211 ` ;
148212 return n ;
149213} ;
0 commit comments