@aigamo/hydrangean-diva 0.0.1-alpha.4 → 0.0.1-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- import { ReactElement } from 'react';
1
+ import { default as React, ReactElement } from 'react';
2
2
  import { PlayQueueStore } from '../stores/PlayQueueStore';
3
3
  interface AddVideoButtonProps {
4
4
  playQueueStore: PlayQueueStore;
5
5
  }
6
- export declare const AddVideoButton: import('react').MemoExoticComponent<({ playQueueStore }: AddVideoButtonProps) => ReactElement>;
6
+ export declare const AddVideoButton: React.MemoExoticComponent<({ playQueueStore }: AddVideoButtonProps) => ReactElement>;
7
7
  export {};
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var S=Object.defineProperty;var w=(n,e,i)=>e in n?S(n,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[e]=i;var p=(n,e,i)=>w(n,typeof e!="symbol"?e+"":e,i);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("@aigamo/nostalgic-diva"),a=require("@elastic/eui"),c=require("@fluentui/react-icons"),h=require("mobx-react-lite"),t=require("react"),O=require("react-sortablejs"),s=require("mobx"),T=require("lodash-es"),F=require("ajv");var u=(n=>(n.Off="Off",n.All="All",n.One="One",n))(u||{});const x=80,M=h.observer(({playerStore:n})=>{const e=g.useNostalgicDiva(),i=t.useCallback(l=>{const m=Number(l.currentTarget.value)/100;n.setPercent(m)},[n]),o=t.useCallback(l=>{l.button===0&&n.setSeeking(!0)},[n]),r=t.useCallback(async l=>{if(l.button===0){const m=Number(l.currentTarget.value)/100;n.setSeeking(!1);const d=await e.getDuration();d!==void 0&&await e.setCurrentTime(d*m)}},[n,e]);return t.createElement(a.EuiRange,{min:0,max:100,step:1e-7,value:n.percent*100,onChange:i,onMouseDown:o,onMouseUp:r,fullWidth:!0,showRange:!0,css:{blockSize:32}})}),A=t.memo(({button:n,isOpen:e,closePopover:i})=>{const[o,r]=t.useState("0"),l=g.useNostalgicDiva();t.useLayoutEffect(()=>{e&&l.getVolume().then(d=>{d!==void 0&&r(Math.floor(d*100).toString())})},[e,l]);const m=t.useCallback(async d=>{r(d.currentTarget.value),await l.setVolume(Number(d.currentTarget.value)/100)},[l]);return t.createElement(a.EuiPopover,{button:n,isOpen:e,closePopover:i,anchorPosition:"upRight"},t.createElement(a.EuiFormRow,null,t.createElement(a.EuiFlexGroup,{responsive:!1,gutterSize:"s",justifyContent:"center",alignItems:"center"},t.createElement(a.EuiButtonIcon,{title:"Mute","aria-label":"Mute",iconType:c.Speaker2Regular,size:"s",iconSize:"l"}),t.createElement(a.EuiRange,{min:0,max:100,step:1,value:o,onChange:m,css:{blockSize:32}}))))}),z=t.memo(({playQueueStore:n,closePopover:e})=>{const i=g.useNostalgicDiva(),o=t.useCallback(async()=>{const E=await i.getCurrentTime();E!==void 0&&await i.setCurrentTime(E-10),e()},[i,e]),r=t.useCallback(async()=>{const E=await i.getCurrentTime();E!==void 0&&await i.setCurrentTime(E+30),e()},[i,e]),l=t.useCallback(async E=>{await i.setPlaybackRate(E),e()},[i,e]),m=t.useCallback(async()=>{n.currentItem!==void 0&&await n.removeItems([n.currentItem]),e()},[n,e]),[d]=t.useState(),v=t.useMemo(()=>[{id:0,items:[{name:"Speed",icon:t.createElement(a.EuiIcon,{type:c.TopSpeedRegular,size:"m"}),panel:1},{name:"Skip back 10 seconds",icon:t.createElement(a.EuiIcon,{type:c.SkipBack10Regular,size:"m"}),onClick:o,disabled:n.isEmpty},{name:"Skip forward 30 seconds",icon:t.createElement(a.EuiIcon,{type:c.SkipForward30Regular,size:"m"}),onClick:r,disabled:n.isEmpty},{isSeparator:!0},{name:"Remove from play queue",icon:t.createElement(a.EuiIcon,{type:c.DismissRegular,size:"m"}),onClick:m,disabled:n.isEmpty}]},{id:1,title:"Speed",items:[.25,.5,.75,1,1.25,1.5,1.75,2].map(E=>({name:E.toString(),onClick:()=>l(E),icon:E===d?"check":"empty"}))}],[n,o,r,m,l,d]);return t.createElement(a.EuiContextMenu,{initialPanelId:0,panels:v})}),B=t.memo(({playQueueStore:n,button:e,isOpen:i,closePopover:o})=>t.createElement(a.EuiPopover,{button:e,isOpen:i,closePopover:o,panelPaddingSize:"none",anchorPosition:"upRight"},t.createElement(z,{playQueueStore:n,closePopover:o}))),N={[u.Off]:c.ArrowRepeatAllOffFilled,[u.All]:c.ArrowRepeatAllFilled,[u.One]:c.ArrowRepeat1Filled},D=h.observer(({playerStore:n,playQueueStore:e})=>{const i=g.useNostalgicDiva(),o=t.useCallback(async()=>{if(e.hasPreviousItem){const r=await i.getCurrentTime();r===void 0||r<5?await e.previous():await i.setCurrentTime(0)}else await i.setCurrentTime(0)},[e,i]);return t.createElement(a.EuiFlexGroup,{responsive:!1,gutterSize:"s",justifyContent:"center",alignItems:"center"},t.createElement(a.EuiButtonIcon,{title:`Shuffle: ${e.shuffle?"On":"Off"}`,"aria-label":`Shuffle: ${e.shuffle?"On":"Off"}`,iconType:e.shuffle?c.ArrowShuffleFilled:c.ArrowShuffleOffFilled,size:"s",iconSize:"l",onClick:e.toggleShuffle,disabled:!0}),t.createElement(a.EuiButtonIcon,{title:"Previous","aria-label":"Previous",iconType:c.PreviousFilled,size:"s",iconSize:"l",onClick:o,disabled:e.isEmpty}),n.playing?t.createElement(a.EuiButtonIcon,{title:"Pause","aria-label":"Pause",iconType:c.PauseFilled,size:"s",iconSize:"l",onClick:()=>i.pause(),disabled:!e.canPlay}):t.createElement(a.EuiButtonIcon,{title:"Play","aria-label":"Play",iconType:c.PlayFilled,size:"s",iconSize:"l",onClick:()=>i.play(),disabled:!e.canPlay}),t.createElement(a.EuiButtonIcon,{title:"Next","aria-label":"Next",iconType:c.NextFilled,size:"s",iconSize:"l",onClick:e.next,disabled:!e.hasNextItem}),t.createElement(a.EuiButtonIcon,{title:`Repeat: ${e.repeat===u.All?"All":e.repeat===u.One?"One":"Off"}`,"aria-label":`Repeat: ${e.repeat===u.All?"All":e.repeat===u.One?"One":"Off"}`,iconType:N[e.repeat],size:"s",iconSize:"l",onClick:e.toggleRepeat}))}),L=t.memo(()=>{const[n,e]=t.useState(!1),i=()=>e(!n);return t.createElement(A,{button:t.createElement(a.EuiButtonIcon,{title:"Volume","aria-label":"Volume",iconType:c.Speaker2Regular,size:"s",iconSize:"l",onClick:i}),isOpen:n,closePopover:()=>e(!1)})}),V=t.memo(({playQueueStore:n})=>{const[e,i]=t.useState(!1),o=()=>i(!e);return t.createElement(B,{playQueueStore:n,button:t.createElement(a.EuiButtonIcon,{title:"More options","aria-label":"More options",iconType:c.MoreHorizontalFilled,size:"s",iconSize:"l",onClick:o}),isOpen:e,closePopover:()=>i(!1)})}),H=t.memo(({playQueueStore:n})=>t.createElement(a.EuiFlexGroup,{responsive:!1,gutterSize:"s",justifyContent:"flexEnd",alignItems:"center"},t.createElement(L,null),t.createElement(V,{playQueueStore:n}))),j=h.observer(({playerStore:n,playQueueStore:e})=>t.createElement(a.EuiBottomBar,{paddingSize:"s"},t.createElement(a.EuiFlexGroup,{direction:"column",gutterSize:"none"},t.createElement(a.EuiFlexItem,null,t.createElement(M,{playerStore:n})),t.createElement(a.EuiFlexItem,null,t.createElement(a.EuiFlexGroup,{responsive:!1},t.createElement(a.EuiFlexItem,{css:{width:"calc(100% / 3)"}}),t.createElement(a.EuiFlexItem,{css:{width:"calc(100% / 3)"}},t.createElement(D,{playerStore:n,playQueueStore:e})),t.createElement(a.EuiFlexItem,{css:{width:"calc(100% / 3)"}},t.createElement(H,{playQueueStore:e}))))))),q=({onCancel:n,onSave:e})=>{const[i,o]=t.useState(""),[r,l]=t.useState(""),[m,d]=t.useState(!1);return React.createElement(a.EuiModal,{onClose:n,initialFocus:"[name=url]"},React.createElement(a.EuiModalHeader,null,React.createElement(a.EuiModalHeaderTitle,null,"Add video")),React.createElement(a.EuiModalBody,null,React.createElement(a.EuiForm,{component:"form"},React.createElement(a.EuiFormRow,{label:"URL"},React.createElement(a.EuiFieldText,{name:"url",value:i,onChange:v=>o(v.target.value)})),React.createElement(a.EuiFormRow,{label:"Title"},React.createElement(a.EuiFieldText,{name:"title",value:r,onChange:v=>l(v.target.value)})))),React.createElement(a.EuiModalFooter,null,React.createElement(a.EuiButtonEmpty,{onClick:n},"Cancel"),React.createElement(a.EuiButton,{type:"submit",onClick:async()=>{try{d(!0),await e({url:i,title:r})}finally{d(!1)}},fill:!0,disabled:i.trim().length===0,isLoading:m},"Save")))};function U(n){return n!==null&&typeof n=="object"&&"title"in n&&typeof n.title=="string"}const $=t.memo(({playQueueStore:n})=>{const[e,i]=t.useState(!1),o=t.useCallback(async r=>{const l=g.findVideoService(r.url);if(l!==void 0){const m=l.extractVideoId(r.url);if(m!==void 0){const v=await(await fetch(`https://noembed.com/embed?url=${encodeURIComponent(r.url)}`)).json();await n.addItems([n.createItem({url:r.url,type:l.type,videoId:m,title:r.title||(U(v)?v.title:m)})])}}i(!1)},[n]);return React.createElement(React.Fragment,null,React.createElement(a.EuiButton,{onClick:()=>i(!0),iconType:c.AddRegular,color:"primary"},"Add video"),e&&React.createElement(q,{onCancel:()=>i(!1),onSave:o}))}),G=h.observer(({playQueueStore:n})=>{const{euiTheme:e}=a.useEuiTheme();return t.createElement(a.EuiTableHeader,{style:{position:"sticky",top:112,zIndex:998,background:e.colors.backgroundBasePlain}},t.createElement(a.EuiTableHeaderCellCheckbox,null,t.createElement(a.EuiCheckbox,{id:"",checked:n.allItemsSelected,onChange:i=>{n.allItemsSelected=i.target.checked}})),t.createElement(a.EuiTableHeaderCell,{width:24}),t.createElement(a.EuiTableHeaderCell,null,"Title"),t.createElement(a.EuiTableHeaderCell,null))}),J=t.memo(({item:n,closePopover:e})=>{const i=t.memo(({onClick:o,...r})=>{const l=t.useCallback(m=>{e(),o==null||o(m)},[o]);return t.createElement(a.EuiContextMenuItem,{...r,onClick:l})});return t.createElement(a.EuiContextMenuPanel,null,t.createElement(i,{icon:t.createElement(a.EuiIcon,{type:""}),onClick:n.playFirst},"Play first"),t.createElement(i,{icon:t.createElement(a.EuiIcon,{type:""}),onClick:n.playNext},"Play next"),t.createElement(i,{icon:t.createElement(a.EuiIcon,{type:c.AddRegular}),onClick:n.addToPlayQueue},"Add to play queue"),t.createElement(a.EuiHorizontalRule,{margin:"none"}),t.createElement(i,{icon:t.createElement(a.EuiIcon,{type:c.ArrowUploadRegular}),onClick:n.moveToTop,disabled:!n.canMoveToTop},"Move to the top"),t.createElement(i,{icon:t.createElement(a.EuiIcon,{type:c.ArrowDownloadRegular}),onClick:n.moveToBottom,disabled:!n.canMoveToBottom},"Move to the bottom"),t.createElement(a.EuiHorizontalRule,{margin:"none"}),t.createElement(i,{icon:t.createElement(a.EuiIcon,{type:""}),onClick:n.removeToTop,disabled:!n.canRemoveToTop},"Remove to the top"),t.createElement(i,{icon:t.createElement(a.EuiIcon,{type:""}),onClick:n.removeOthers,disabled:!n.canRemoveOthers},"Remove others"))}),X=t.memo(({item:n})=>{const[e,i]=t.useState(!1),o=t.useCallback(()=>i(!e),[e]),r=t.useCallback(()=>i(!1),[]);return t.createElement(a.EuiPopover,{button:t.createElement(a.EuiButtonIcon,{title:"More options","aria-label":"More options",iconType:c.MoreHorizontalFilled,size:"s",color:"text",onClick:o}),isOpen:e,closePopover:r,panelPaddingSize:"none",anchorPosition:"leftCenter"},t.createElement(J,{item:n,closePopover:r}))}),W=h.observer(({item:n})=>{const e=g.useNostalgicDiva();return t.createElement(a.EuiTableRowCell,{textOnly:!1,hasActions:!0,align:"right"},t.createElement(a.EuiButton,{iconType:c.PlayRegular,size:"s",onClick:async()=>{n.isCurrent?await e.setCurrentTime(0):n.play()}},"Play"),t.createElement(a.EuiButton,{iconType:c.DismissRegular,size:"s",onClick:n.remove},"Remove"),t.createElement(X,{item:n}))}),Y={Audio:"",Dailymotion:"https://www.dailymotion.com/favicon.ico",Niconico:"https://www.nicovideo.jp/favicon.ico",SoundCloud:"https://soundcloud.com/favicon.ico",Twitch:"https://www.twitch.tv/favicon.ico",Vimeo:"https://vimeo.com/favicon.ico",YouTube:"https://www.youtube.com/favicon.ico"},K=h.observer(({item:n})=>{const e=g.useNostalgicDiva();return t.createElement(a.EuiTableRow,{key:n.id,isSelected:n.isCurrent},t.createElement(a.EuiTableRowCellCheckbox,null,t.createElement(a.EuiCheckbox,{id:n.id.toString(),checked:n.isSelected,onChange:n.toggleSelected})),t.createElement(a.EuiTableRowCell,{textOnly:!1},t.createElement("img",{src:Y[n.type],width:16,height:16,alt:n.type})),t.createElement(a.EuiTableRowCell,null,t.createElement(a.EuiLink,{href:n.url,target:"_blank",external:!0,onClick:()=>e.pause()},n.title)),t.createElement(W,{item:n}))}),Z=h.observer(({playQueueStore:n})=>t.createElement(O.ReactSortable,{tag:"tbody",list:n.items,setList:e=>n.setItems(e)},n.items.map(e=>t.createElement(K,{key:e.id,item:e})))),_=h.observer(({playQueueStore:n})=>t.createElement(a.EuiTable,null,t.createElement(G,{playQueueStore:n}),t.createElement(Z,{playQueueStore:n}))),Q=h.observer(({playQueueStore:n})=>{const[e,i]=t.useState(!1);return React.createElement(React.Fragment,null,e&&React.createElement(a.EuiFlyout,{type:"push",size:"s",onClose:()=>i(!1)},React.createElement("div",{style:{blockSize:"100%"}},React.createElement(a.EuiCodeBlock,{language:"json",overflowHeight:"100%",isCopyable:!0,isVirtualized:!0},JSON.stringify(n.localStorageState,void 0,2)))),React.createElement($,{playQueueStore:n}))}),ee=h.observer(({playerStore:n,playQueueStore:e})=>{const{euiTheme:i}=a.useEuiTheme();return React.createElement(React.Fragment,null,React.createElement(a.EuiFlexGroup,{alignItems:"center",gutterSize:"m",style:{position:"sticky",top:48,zIndex:998,background:i.colors.backgroundBasePlain}},React.createElement(a.EuiFlexItem,{grow:!1},React.createElement(a.EuiButton,{disabled:e.isEmpty||e.selectedItems.length===0,onClick:e.playSelectedItemsNext},"Play next")),React.createElement(a.EuiFlexItem,{grow:!1},React.createElement(a.EuiButton,{iconType:c.AddRegular,onClick:e.addSelectedItems,disabled:e.isEmpty||e.selectedItems.length===0},"Add to play queue")),React.createElement(a.EuiFlexItem,{grow:!1},React.createElement(a.EuiButton,{iconType:c.DismissRegular,onClick:e.removeSelectedItems,disabled:e.isEmpty||e.selectedItems.length===0},"Remove")),React.createElement(a.EuiFlexItem,{grow:!1},React.createElement(a.EuiButton,{iconType:c.DeleteRegular,onClick:e.clear,disabled:e.isEmpty},"Clear")),React.createElement(a.EuiFlexItem,{grow:!0}),React.createElement(a.EuiFlexItem,{grow:!1},React.createElement(Q,{playQueueStore:e}))),!e.isEmpty&&React.createElement(React.Fragment,null,React.createElement(a.EuiSpacer,{size:"l",style:{position:"sticky",top:88,zIndex:998,background:i.colors.backgroundBasePlain}}),React.createElement(_,{playQueueStore:e})))}),te=h.observer(({playerStore:n,playQueueStore:e})=>React.createElement(React.Fragment,null,React.createElement(a.EuiPageTemplate.Header,{pageTitle:"Play queue",rightSideItems:[]}),React.createElement(a.EuiPageTemplate.Section,null,React.createElement(ee,{playerStore:n,playQueueStore:e})))),I={width:16*25,height:9*25},ne=h.observer(({playerStore:n,playQueueStore:e})=>{const i=g.useNostalgicDiva(),o=t.useCallback(async()=>{e.interacted&&await i.play()},[e,i]),r=t.useCallback(async()=>{switch(e.repeat){case u.One:await i.setCurrentTime(0);break;case u.Off:case u.All:if(e.isLastItem)switch(e.repeat){case u.Off:n.onEnded();break;case u.All:e.hasMultipleItems?await e.goToFirst():await i.setCurrentTime(0);break}else await e.next();break}},[e,n,i]),l=t.useMemo(()=>({onLoaded:o,onPlay:n.onPlay,onPause:n.onPause,onEnded:r,onTimeUpdate:n.onTimeUpdate}),[n,o,r]);return React.createElement("div",{css:{position:"fixed",right:0,bottom:x,width:I.width,height:I.height,zIndex:998,backgroundColor:"rgb(39, 39, 39)",display:"flex",flexDirection:"column"}},React.createElement("div",{css:{flexGrow:1,backgroundColor:"black"}},e.currentItem&&React.createElement(g.NostalgicDiva,{src:e.currentItem.url,options:l})))});class C{makeObservable(e,i){return s.makeObservable(e,i)}}const b=class b{constructor(e,i,o){p(this,"id");p(this,"isSelected",!1);this.observableStateProvider=e,this.playQueueStore=i,this.dto=o,this.id=b.nextId++,e.makeObservable(this,{isSelected:s.observable,isCurrent:s.computed,index:s.computed,isFirst:s.computed,isLast:s.computed,canMoveToTop:s.computed,canMoveToBottom:s.computed,canRemoveToTop:s.computed,canRemoveOthers:s.computed,unselect:s.action,toggleSelected:s.action.bound,play:s.action,remove:s.action.bound,playFirst:s.action.bound,playNext:s.action.bound,addToPlayQueue:s.action.bound,moveToTop:s.action.bound,moveToBottom:s.action.bound,removeToTop:s.action.bound,removeOthers:s.action.bound})}static fromDto(e,i,o){return new b(e,i,o)}get url(){return this.dto.url}get type(){return this.dto.type}get videoId(){return this.dto.videoId}get title(){return this.dto.title}get isCurrent(){return this.playQueueStore.currentItem===this}get index(){return this.playQueueStore.items.indexOf(this)}get isFirst(){return this.index===0}get isLast(){return this.index===this.playQueueStore.items.length-1}get canMoveToTop(){return!this.isFirst}get canMoveToBottom(){return!this.isLast}get canRemoveToTop(){return!this.isFirst}get canRemoveOthers(){return this.playQueueStore.hasMultipleItems}clone(){return this.playQueueStore.createItem(this.dto)}unselect(){this.isSelected=!1}toggleSelected(){this.isSelected=!this.isSelected}play(){this.playQueueStore.setCurrentItem(this)}remove(){return this.playQueueStore.removeItems([this])}async playFirst(){await this.playQueueStore.playFirst([this.clone()])}async playNext(){await this.playQueueStore.playNext([this.clone()])}async addToPlayQueue(){await this.playQueueStore.addItems([this.clone()])}moveToTop(){this.playQueueStore.moveItem(this,0)}moveToBottom(){this.playQueueStore.moveItem(this,this.playQueueStore.items.length-1)}removeToTop(){return this.playQueueStore.removeItemsAbove(this)}removeOthers(){return this.playQueueStore.removeOtherItems(this)}};p(b,"nextId",1);let y=b;const f=new F({coerceTypes:!0});function ie(n,e){let i;if(i=f.getSchema(e),i===void 0&&(f.addSchema(n,e),i=f.getSchema(e)),i===void 0||i.schema!==n)throw new Error(`Invalid schema. Expected: '${JSON.stringify(n)}', but got '${JSON.stringify(i==null?void 0:i.schema)}'.`);return i}const ae={type:"object",properties:{version:{type:"string",nullable:!0},repeat:{type:"string",enum:Object.values(u),nullable:!0},shuffle:{type:"boolean",nullable:!0},items:{type:"array",nullable:!0,items:{type:"object",properties:{url:{type:"string"},type:{type:"string"},videoId:{type:"string"},title:{type:"string"}},required:["url","type","videoId","title"]}},currentIndex:{type:"integer",nullable:!0}}},se=ie(ae,"PlayQueueStore");class oe{constructor(e){p(this,"interacted",!1);p(this,"items",[]);p(this,"currentId");p(this,"repeat",u.Off);p(this,"shuffle",!1);this.observableStateProvider=e,e.makeObservable(this,{interacted:s.observable,items:s.observable,currentId:s.observable,repeat:s.observable,shuffle:s.observable,localStorageState:s.computed.struct,isEmpty:s.computed,currentItem:s.computed,canPlay:s.computed,canPause:s.computed,hasMultipleItems:s.computed,currentIndex:s.computed,hasPreviousItem:s.computed,hasNextItem:s.computed,isLastItem:s.computed,selectedItems:s.computed,allItemsSelected:s.computed,selectedItemsOrAllItems:s.computed,setItems:s.action,interact:s.action,clear:s.action.bound,unselectAll:s.action,setCurrentItem:s.action,setNextItems:s.action,clearAndSetItems:s.action,playNext:s.action,playSelectedItemsNext:s.action.bound,addItems:s.action,addSelectedItems:s.action.bound,playFirst:s.action,moveItem:s.action,removeItems:s.action,removeSelectedItems:s.action.bound,removeOtherItems:s.action,removeItemsAbove:s.action,toggleRepeat:s.action.bound,toggleShuffle:s.action.bound,previous:s.action,next:s.action.bound,goToFirst:s.action})}createItem(e){return y.fromDto(this.observableStateProvider,this,e)}get localStorageState(){return{version:"1.0",repeat:this.repeat,shuffle:this.shuffle,items:this.items.map(e=>e.dto),currentIndex:this.currentIndex}}set localStorageState(e){var i;this.repeat=e.repeat??u.Off,this.shuffle=e.shuffle??!1,this.items=((i=e.items)==null?void 0:i.map(o=>this.createItem(o)))??[],this.currentIndex=e.currentIndex}validateLocalStorageState(e){return se(e)}get isEmpty(){return this.items.length===0}get currentItem(){return this.items.find(e=>e.id===this.currentId)}get canPlay(){return this.currentItem!==void 0}get canPause(){return this.currentItem!==void 0}get hasMultipleItems(){return this.items.length>1}get currentIndex(){return this.currentId!==void 0?this.items.findIndex(e=>e.id===this.currentId):void 0}set currentIndex(e){var i;this.currentId=e!==void 0?(i=this.items.at(e))==null?void 0:i.id:void 0}get hasPreviousItem(){return this.hasMultipleItems&&this.currentIndex!==void 0&&this.currentIndex>0}get hasNextItem(){return this.hasMultipleItems&&this.currentIndex!==void 0&&this.currentIndex<this.items.length-1}get isLastItem(){return this.currentIndex!==void 0&&this.currentIndex===this.items.length-1}get selectedItems(){return this.items.filter(e=>e.isSelected)}get allItemsSelected(){return this.selectedItems.length===this.items.length}set allItemsSelected(e){for(const i of this.items)i.isSelected=e}get selectedItemsOrAllItems(){return this.selectedItems.length>0?this.selectedItems:this.items}setItems(e){this.items=e}interact(){this.interacted=!0}clear(){this.interact(),this.currentIndex=void 0,this.items=[]}unselectAll(){for(const e of this.items)e.unselect()}setCurrentItem(e){this.interact(),this.currentId=e==null?void 0:e.id}setNextItems(e){this.currentIndex!==void 0&&this.items.splice(this.currentIndex+1,0,...e)}clearAndSetItems(e){this.clear(),this.setCurrentItem(e[0]),this.setNextItems(e)}async playNext(e){if(this.isEmpty){this.clearAndSetItems(e);return}this.setNextItems(e)}async playSelectedItemsNext(){await this.playNext(this.selectedItemsOrAllItems.map(e=>e.clone())),this.unselectAll()}async addItems(e){if(this.isEmpty){this.clearAndSetItems(e);return}this.items.push(...e)}async addSelectedItems(){await this.addItems(this.selectedItemsOrAllItems.map(e=>e.clone())),this.unselectAll()}async playFirst(e){if(this.isEmpty){this.clearAndSetItems(e);return}const{currentIndex:i}=this;i!==void 0&&(this.interact(),this.items.splice(i,0,...e),this.currentIndex=i)}moveItem(e,i){const o=this.items.splice(this.items.indexOf(e),1)[0];this.items.splice(i,0,o)}async removeItems(e){const{currentItem:i}=this;T.pull(this.items,...e.filter(l=>l!==i));const{currentIndex:o,isLastItem:r}=this;T.pull(this.items,e.find(l=>l===i)),this.currentItem!==i&&(this.interact(),r?await this.goToFirst():this.currentIndex=o)}async removeSelectedItems(){await this.removeItems(this.selectedItemsOrAllItems),this.unselectAll()}async removeOtherItems(e){const i=e.id;return this.removeItems(this.items.filter(o=>o.id!==i))}async removeItemsAbove(e){const i=this.items.indexOf(e);return this.removeItems(this.items.filter((o,r)=>r<i))}toggleRepeat(){switch(this.repeat){case u.Off:this.repeat=u.All;break;case u.All:this.repeat=u.One;break;case u.One:this.repeat=u.Off;break}}toggleShuffle(){this.shuffle=!this.shuffle}async previous(){this.currentIndex!==void 0&&this.hasPreviousItem&&(this.interact(),this.currentIndex--)}async next(){this.currentIndex!==void 0&&this.hasNextItem&&(this.interact(),this.currentIndex++)}async goToFirst(){this.currentIndex!==void 0&&(this.currentIndex=0)}}const R=t.createContext(void 0),re=({children:n})=>{const[e]=t.useState(()=>new oe(new C)),i=g.useNostalgicDiva();return t.useEffect(()=>s.reaction(()=>e.currentItem,async(o,r)=>{o===void 0||r===void 0||o.type===r.type&&o.videoId===r.videoId&&await i.setCurrentTime(0)}),[e,i]),React.createElement(R.Provider,{value:e},n)},k=()=>t.useContext(R),le=h.observer(({children:n})=>{const e=k();return React.createElement(a.EuiPageTemplate,{panelled:!0,style:{minBlockSize:`max(460px, 100vh - ${x}px)`}},n,!e.isEmpty&&React.createElement(a.EuiSpacer,{style:{blockSize:I.height}}))});class ce{constructor(e){p(this,"playing",!1);p(this,"percent",0);p(this,"seeking",!1);e.makeObservable(this,{playing:s.observable,percent:s.observable,seeking:s.observable,setPlaying:s.action,setPercent:s.action,setSeeking:s.action,onPlay:s.action.bound,onPause:s.action.bound,onEnded:s.action.bound,onTimeUpdate:s.action.bound})}setPlaying(e){this.playing=e}setPercent(e){this.percent=e}setSeeking(e){this.seeking=e}onPlay(){this.playing=!0}onPause(){this.playing=!1}onEnded(){this.playing=!1}onTimeUpdate({percent:e}){e!==void 0&&(this.seeking||(this.percent=e))}}const P=t.createContext(void 0),ue=({children:n})=>{const[e]=t.useState(()=>new ce(new C));return React.createElement(P.Provider,{value:e},n)},me=()=>t.useContext(P);class de{makeObservable(e,i){return e}}exports.BottomBar=j;exports.HydrangeanDiva=te;exports.MediaPlayerLayout=le;exports.MiniPlayer=ne;exports.MobXObservableStateProvider=C;exports.ObservableStateProvider=de;exports.PlayQueueStoreProvider=re;exports.PlayerStoreProvider=ue;exports.RepeatMode=u;exports.bottomBarHeight=x;exports.miniPlayerSize=I;exports.usePlayQueueStore=k;exports.usePlayerStore=me;
1
+ "use strict";var w=Object.defineProperty;var O=(n,e,i)=>e in n?w(n,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[e]=i;var p=(n,e,i)=>O(n,typeof e!="symbol"?e+"":e,i);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("@aigamo/nostalgic-diva"),s=require("@elastic/eui"),c=require("@fluentui/react-icons"),h=require("mobx-react-lite"),t=require("react"),F=require("react-sortablejs"),a=require("mobx"),T=require("lodash-es"),R=require("ajv");var u=(n=>(n.Off="Off",n.All="All",n.One="One",n))(u||{});const x=80,M=h.observer(({playerStore:n})=>{const e=g.useNostalgicDiva(),i=t.useCallback(l=>{const m=Number(l.currentTarget.value)/100;n.setPercent(m)},[n]),o=t.useCallback(l=>{l.button===0&&n.setSeeking(!0)},[n]),r=t.useCallback(async l=>{if(l.button===0){const m=Number(l.currentTarget.value)/100;n.setSeeking(!1);const d=await e.getDuration();d!==void 0&&await e.setCurrentTime(d*m)}},[n,e]);return t.createElement(s.EuiRange,{min:0,max:100,step:1e-7,value:n.percent*100,onChange:i,onMouseDown:o,onMouseUp:r,fullWidth:!0,showRange:!0,css:{blockSize:32}})}),A=t.memo(({button:n,isOpen:e,closePopover:i})=>{const[o,r]=t.useState("0"),l=g.useNostalgicDiva();t.useLayoutEffect(()=>{e&&l.getVolume().then(d=>{d!==void 0&&r(Math.floor(d*100).toString())})},[e,l]);const m=t.useCallback(async d=>{r(d.currentTarget.value),await l.setVolume(Number(d.currentTarget.value)/100)},[l]);return t.createElement(s.EuiPopover,{button:n,isOpen:e,closePopover:i,anchorPosition:"upRight"},t.createElement(s.EuiFormRow,null,t.createElement(s.EuiFlexGroup,{responsive:!1,gutterSize:"s",justifyContent:"center",alignItems:"center"},t.createElement(s.EuiButtonIcon,{title:"Mute","aria-label":"Mute",iconType:c.Speaker2Regular,size:"s",iconSize:"l"}),t.createElement(s.EuiRange,{min:0,max:100,step:1,value:o,onChange:m,css:{blockSize:32}}))))}),z=t.memo(({playQueueStore:n,closePopover:e})=>{const i=g.useNostalgicDiva(),o=t.useCallback(async()=>{const E=await i.getCurrentTime();E!==void 0&&await i.setCurrentTime(E-10),e()},[i,e]),r=t.useCallback(async()=>{const E=await i.getCurrentTime();E!==void 0&&await i.setCurrentTime(E+30),e()},[i,e]),l=t.useCallback(async E=>{await i.setPlaybackRate(E),e()},[i,e]),m=t.useCallback(async()=>{n.currentItem!==void 0&&await n.removeItems([n.currentItem]),e()},[n,e]),[d]=t.useState(),v=t.useMemo(()=>[{id:0,items:[{name:"Speed",icon:t.createElement(s.EuiIcon,{type:c.TopSpeedRegular,size:"m"}),panel:1},{name:"Skip back 10 seconds",icon:t.createElement(s.EuiIcon,{type:c.SkipBack10Regular,size:"m"}),onClick:o,disabled:n.isEmpty},{name:"Skip forward 30 seconds",icon:t.createElement(s.EuiIcon,{type:c.SkipForward30Regular,size:"m"}),onClick:r,disabled:n.isEmpty},{isSeparator:!0},{name:"Remove from play queue",icon:t.createElement(s.EuiIcon,{type:c.DismissRegular,size:"m"}),onClick:m,disabled:n.isEmpty}]},{id:1,title:"Speed",items:[.25,.5,.75,1,1.25,1.5,1.75,2].map(E=>({name:E.toString(),onClick:()=>l(E),icon:E===d?"check":"empty"}))}],[n,o,r,m,l,d]);return t.createElement(s.EuiContextMenu,{initialPanelId:0,panels:v})}),B=t.memo(({playQueueStore:n,button:e,isOpen:i,closePopover:o})=>t.createElement(s.EuiPopover,{button:e,isOpen:i,closePopover:o,panelPaddingSize:"none",anchorPosition:"upRight"},t.createElement(z,{playQueueStore:n,closePopover:o}))),N={[u.Off]:c.ArrowRepeatAllOffFilled,[u.All]:c.ArrowRepeatAllFilled,[u.One]:c.ArrowRepeat1Filled},D=h.observer(({playerStore:n,playQueueStore:e})=>{const i=g.useNostalgicDiva(),o=t.useCallback(async()=>{if(e.hasPreviousItem){const r=await i.getCurrentTime();r===void 0||r<5?await e.previous():await i.setCurrentTime(0)}else await i.setCurrentTime(0)},[e,i]);return t.createElement(s.EuiFlexGroup,{responsive:!1,gutterSize:"s",justifyContent:"center",alignItems:"center"},t.createElement(s.EuiButtonIcon,{title:`Shuffle: ${e.shuffle?"On":"Off"}`,"aria-label":`Shuffle: ${e.shuffle?"On":"Off"}`,iconType:e.shuffle?c.ArrowShuffleFilled:c.ArrowShuffleOffFilled,size:"s",iconSize:"l",onClick:e.toggleShuffle,disabled:!0}),t.createElement(s.EuiButtonIcon,{title:"Previous","aria-label":"Previous",iconType:c.PreviousFilled,size:"s",iconSize:"l",onClick:o,disabled:e.isEmpty}),n.playing?t.createElement(s.EuiButtonIcon,{title:"Pause","aria-label":"Pause",iconType:c.PauseFilled,size:"s",iconSize:"l",onClick:()=>i.pause(),disabled:!e.canPlay}):t.createElement(s.EuiButtonIcon,{title:"Play","aria-label":"Play",iconType:c.PlayFilled,size:"s",iconSize:"l",onClick:()=>i.play(),disabled:!e.canPlay}),t.createElement(s.EuiButtonIcon,{title:"Next","aria-label":"Next",iconType:c.NextFilled,size:"s",iconSize:"l",onClick:e.next,disabled:!e.hasNextItem}),t.createElement(s.EuiButtonIcon,{title:`Repeat: ${e.repeat===u.All?"All":e.repeat===u.One?"One":"Off"}`,"aria-label":`Repeat: ${e.repeat===u.All?"All":e.repeat===u.One?"One":"Off"}`,iconType:N[e.repeat],size:"s",iconSize:"l",onClick:e.toggleRepeat}))}),L=t.memo(()=>{const[n,e]=t.useState(!1),i=()=>e(!n);return t.createElement(A,{button:t.createElement(s.EuiButtonIcon,{title:"Volume","aria-label":"Volume",iconType:c.Speaker2Regular,size:"s",iconSize:"l",onClick:i}),isOpen:n,closePopover:()=>e(!1)})}),V=t.memo(({playQueueStore:n})=>{const[e,i]=t.useState(!1),o=()=>i(!e);return t.createElement(B,{playQueueStore:n,button:t.createElement(s.EuiButtonIcon,{title:"More options","aria-label":"More options",iconType:c.MoreHorizontalFilled,size:"s",iconSize:"l",onClick:o}),isOpen:e,closePopover:()=>i(!1)})}),H=t.memo(({playQueueStore:n})=>t.createElement(s.EuiFlexGroup,{responsive:!1,gutterSize:"s",justifyContent:"flexEnd",alignItems:"center"},t.createElement(L,null),t.createElement(V,{playQueueStore:n}))),j=h.observer(({playerStore:n,playQueueStore:e})=>t.createElement(s.EuiBottomBar,{paddingSize:"s"},t.createElement(s.EuiFlexGroup,{direction:"column",gutterSize:"none"},t.createElement(s.EuiFlexItem,null,t.createElement(M,{playerStore:n})),t.createElement(s.EuiFlexItem,null,t.createElement(s.EuiFlexGroup,{responsive:!1},t.createElement(s.EuiFlexItem,{css:{width:"calc(100% / 3)"}}),t.createElement(s.EuiFlexItem,{css:{width:"calc(100% / 3)"}},t.createElement(D,{playerStore:n,playQueueStore:e})),t.createElement(s.EuiFlexItem,{css:{width:"calc(100% / 3)"}},t.createElement(H,{playQueueStore:e}))))))),q=({onCancel:n,onSave:e})=>{const[i,o]=t.useState(""),[r,l]=t.useState(""),[m,d]=t.useState(!1);return t.createElement(s.EuiModal,{onClose:n,initialFocus:"[name=url]"},t.createElement(s.EuiModalHeader,null,t.createElement(s.EuiModalHeaderTitle,null,"Add video")),t.createElement(s.EuiModalBody,null,t.createElement(s.EuiForm,{component:"form"},t.createElement(s.EuiFormRow,{label:"URL"},t.createElement(s.EuiFieldText,{name:"url",value:i,onChange:v=>o(v.target.value)})),t.createElement(s.EuiFormRow,{label:"Title"},t.createElement(s.EuiFieldText,{name:"title",value:r,onChange:v=>l(v.target.value)})))),t.createElement(s.EuiModalFooter,null,t.createElement(s.EuiButtonEmpty,{onClick:n},"Cancel"),t.createElement(s.EuiButton,{type:"submit",onClick:async()=>{try{d(!0),await e({url:i,title:r})}finally{d(!1)}},fill:!0,disabled:i.trim().length===0,isLoading:m},"Save")))};function U(n){return n!==null&&typeof n=="object"&&"title"in n&&typeof n.title=="string"}const $=t.memo(({playQueueStore:n})=>{const[e,i]=t.useState(!1),o=t.useCallback(async r=>{const l=g.findVideoService(r.url);if(l!==void 0){const m=l.extractVideoId(r.url);if(m!==void 0){const v=await(await fetch(`https://noembed.com/embed?url=${encodeURIComponent(r.url)}`)).json();await n.addItems([n.createItem({url:r.url,type:l.type,videoId:m,title:r.title||(U(v)?v.title:m)})])}}i(!1)},[n]);return t.createElement(t.Fragment,null,t.createElement(s.EuiButton,{onClick:()=>i(!0),iconType:c.AddRegular,color:"primary"},"Add video"),e&&t.createElement(q,{onCancel:()=>i(!1),onSave:o}))}),G=h.observer(({playQueueStore:n})=>{const{euiTheme:e}=s.useEuiTheme();return t.createElement(s.EuiTableHeader,{style:{position:"sticky",top:112,zIndex:998,background:e.colors.backgroundBasePlain}},t.createElement(s.EuiTableHeaderCellCheckbox,null,t.createElement(s.EuiCheckbox,{id:"",checked:n.allItemsSelected,onChange:i=>{n.allItemsSelected=i.target.checked}})),t.createElement(s.EuiTableHeaderCell,{width:24}),t.createElement(s.EuiTableHeaderCell,null,"Title"),t.createElement(s.EuiTableHeaderCell,null))}),J=t.memo(({item:n,closePopover:e})=>{const i=t.memo(({onClick:o,...r})=>{const l=t.useCallback(m=>{e(),o==null||o(m)},[o]);return t.createElement(s.EuiContextMenuItem,{...r,onClick:l})});return t.createElement(s.EuiContextMenuPanel,null,t.createElement(i,{icon:t.createElement(s.EuiIcon,{type:""}),onClick:n.playFirst},"Play first"),t.createElement(i,{icon:t.createElement(s.EuiIcon,{type:""}),onClick:n.playNext},"Play next"),t.createElement(i,{icon:t.createElement(s.EuiIcon,{type:c.AddRegular}),onClick:n.addToPlayQueue},"Add to play queue"),t.createElement(s.EuiHorizontalRule,{margin:"none"}),t.createElement(i,{icon:t.createElement(s.EuiIcon,{type:c.ArrowUploadRegular}),onClick:n.moveToTop,disabled:!n.canMoveToTop},"Move to the top"),t.createElement(i,{icon:t.createElement(s.EuiIcon,{type:c.ArrowDownloadRegular}),onClick:n.moveToBottom,disabled:!n.canMoveToBottom},"Move to the bottom"),t.createElement(s.EuiHorizontalRule,{margin:"none"}),t.createElement(i,{icon:t.createElement(s.EuiIcon,{type:""}),onClick:n.removeToTop,disabled:!n.canRemoveToTop},"Remove to the top"),t.createElement(i,{icon:t.createElement(s.EuiIcon,{type:""}),onClick:n.removeOthers,disabled:!n.canRemoveOthers},"Remove others"))}),X=t.memo(({item:n})=>{const[e,i]=t.useState(!1),o=t.useCallback(()=>i(!e),[e]),r=t.useCallback(()=>i(!1),[]);return t.createElement(s.EuiPopover,{button:t.createElement(s.EuiButtonIcon,{title:"More options","aria-label":"More options",iconType:c.MoreHorizontalFilled,size:"s",color:"text",onClick:o}),isOpen:e,closePopover:r,panelPaddingSize:"none",anchorPosition:"leftCenter"},t.createElement(J,{item:n,closePopover:r}))}),W=h.observer(({item:n})=>{const e=g.useNostalgicDiva();return t.createElement(s.EuiTableRowCell,{textOnly:!1,hasActions:!0,align:"right"},t.createElement(s.EuiButton,{iconType:c.PlayRegular,size:"s",onClick:async()=>{n.isCurrent?await e.setCurrentTime(0):n.play()}},"Play"),t.createElement(s.EuiButton,{iconType:c.DismissRegular,size:"s",onClick:n.remove},"Remove"),t.createElement(X,{item:n}))}),Y={Audio:"",Dailymotion:"https://www.dailymotion.com/favicon.ico",Niconico:"https://www.nicovideo.jp/favicon.ico",SoundCloud:"https://soundcloud.com/favicon.ico",Twitch:"https://www.twitch.tv/favicon.ico",Vimeo:"https://vimeo.com/favicon.ico",YouTube:"https://www.youtube.com/favicon.ico"},K=h.observer(({item:n})=>{const e=g.useNostalgicDiva();return t.createElement(s.EuiTableRow,{key:n.id,isSelected:n.isCurrent},t.createElement(s.EuiTableRowCellCheckbox,null,t.createElement(s.EuiCheckbox,{id:n.id.toString(),checked:n.isSelected,onChange:n.toggleSelected})),t.createElement(s.EuiTableRowCell,{textOnly:!1},t.createElement("img",{src:Y[n.type],width:16,height:16,alt:n.type})),t.createElement(s.EuiTableRowCell,null,t.createElement(s.EuiLink,{href:n.url,target:"_blank",external:!0,onClick:()=>e.pause()},n.title)),t.createElement(W,{item:n}))}),Z=h.observer(({playQueueStore:n})=>t.createElement(F.ReactSortable,{tag:"tbody",list:n.items,setList:e=>n.setItems(e)},n.items.map(e=>t.createElement(K,{key:e.id,item:e})))),_=h.observer(({playQueueStore:n})=>t.createElement(s.EuiTable,null,t.createElement(G,{playQueueStore:n}),t.createElement(Z,{playQueueStore:n}))),Q=h.observer(({playQueueStore:n})=>{const[e,i]=t.useState(!1);return t.createElement(t.Fragment,null,e&&t.createElement(s.EuiFlyout,{type:"push",size:"s",onClose:()=>i(!1)},t.createElement("div",{style:{blockSize:"100%"}},t.createElement(s.EuiCodeBlock,{language:"json",overflowHeight:"100%",isCopyable:!0,isVirtualized:!0},JSON.stringify(n.localStorageState,void 0,2)))),t.createElement($,{playQueueStore:n}))}),ee=h.observer(({playerStore:n,playQueueStore:e})=>{const{euiTheme:i}=s.useEuiTheme();return t.createElement(t.Fragment,null,t.createElement(s.EuiFlexGroup,{alignItems:"center",gutterSize:"m",style:{position:"sticky",top:48,zIndex:998,background:i.colors.backgroundBasePlain}},t.createElement(s.EuiFlexItem,{grow:!1},t.createElement(s.EuiButton,{disabled:e.isEmpty||e.selectedItems.length===0,onClick:e.playSelectedItemsNext},"Play next")),t.createElement(s.EuiFlexItem,{grow:!1},t.createElement(s.EuiButton,{iconType:c.AddRegular,onClick:e.addSelectedItems,disabled:e.isEmpty||e.selectedItems.length===0},"Add to play queue")),t.createElement(s.EuiFlexItem,{grow:!1},t.createElement(s.EuiButton,{iconType:c.DismissRegular,onClick:e.removeSelectedItems,disabled:e.isEmpty||e.selectedItems.length===0},"Remove")),t.createElement(s.EuiFlexItem,{grow:!1},t.createElement(s.EuiButton,{iconType:c.DeleteRegular,onClick:e.clear,disabled:e.isEmpty},"Clear")),t.createElement(s.EuiFlexItem,{grow:!0}),t.createElement(s.EuiFlexItem,{grow:!1},t.createElement(Q,{playQueueStore:e}))),!e.isEmpty&&t.createElement(t.Fragment,null,t.createElement(s.EuiSpacer,{size:"l",style:{position:"sticky",top:88,zIndex:998,background:i.colors.backgroundBasePlain}}),t.createElement(_,{playQueueStore:e})))}),te=h.observer(({playerStore:n,playQueueStore:e})=>t.createElement(t.Fragment,null,t.createElement(s.EuiPageTemplate.Header,{pageTitle:"Play queue",rightSideItems:[]}),t.createElement(s.EuiPageTemplate.Section,null,t.createElement(ee,{playerStore:n,playQueueStore:e})))),I={width:16*25,height:9*25},ne=h.observer(({playerStore:n,playQueueStore:e})=>{const i=g.useNostalgicDiva(),o=t.useCallback(async()=>{e.interacted&&await i.play()},[e,i]),r=t.useCallback(async()=>{switch(e.repeat){case u.One:await i.setCurrentTime(0);break;case u.Off:case u.All:if(e.isLastItem)switch(e.repeat){case u.Off:n.onEnded();break;case u.All:e.hasMultipleItems?await e.goToFirst():await i.setCurrentTime(0);break}else await e.next();break}},[e,n,i]),l=t.useMemo(()=>({onLoaded:o,onPlay:n.onPlay,onPause:n.onPause,onEnded:r,onTimeUpdate:n.onTimeUpdate}),[n,o,r]);return t.createElement("div",{css:{position:"fixed",right:0,bottom:x,width:I.width,height:I.height,zIndex:998,backgroundColor:"rgb(39, 39, 39)",display:"flex",flexDirection:"column"}},t.createElement("div",{css:{flexGrow:1,backgroundColor:"black"}},e.currentItem&&t.createElement(g.NostalgicDiva,{src:e.currentItem.url,options:l})))});class C{makeObservable(e,i){return a.makeObservable(e,i)}}const b=class b{constructor(e,i,o){p(this,"id");p(this,"isSelected",!1);this.observableStateProvider=e,this.playQueueStore=i,this.dto=o,this.id=b.nextId++,e.makeObservable(this,{isSelected:a.observable,isCurrent:a.computed,index:a.computed,isFirst:a.computed,isLast:a.computed,canMoveToTop:a.computed,canMoveToBottom:a.computed,canRemoveToTop:a.computed,canRemoveOthers:a.computed,unselect:a.action,toggleSelected:a.action.bound,play:a.action,remove:a.action.bound,playFirst:a.action.bound,playNext:a.action.bound,addToPlayQueue:a.action.bound,moveToTop:a.action.bound,moveToBottom:a.action.bound,removeToTop:a.action.bound,removeOthers:a.action.bound})}static fromDto(e,i,o){return new b(e,i,o)}get url(){return this.dto.url}get type(){return this.dto.type}get videoId(){return this.dto.videoId}get title(){return this.dto.title}get isCurrent(){return this.playQueueStore.currentItem===this}get index(){return this.playQueueStore.items.indexOf(this)}get isFirst(){return this.index===0}get isLast(){return this.index===this.playQueueStore.items.length-1}get canMoveToTop(){return!this.isFirst}get canMoveToBottom(){return!this.isLast}get canRemoveToTop(){return!this.isFirst}get canRemoveOthers(){return this.playQueueStore.hasMultipleItems}clone(){return this.playQueueStore.createItem(this.dto)}unselect(){this.isSelected=!1}toggleSelected(){this.isSelected=!this.isSelected}play(){this.playQueueStore.setCurrentItem(this)}remove(){return this.playQueueStore.removeItems([this])}async playFirst(){await this.playQueueStore.playFirst([this.clone()])}async playNext(){await this.playQueueStore.playNext([this.clone()])}async addToPlayQueue(){await this.playQueueStore.addItems([this.clone()])}moveToTop(){this.playQueueStore.moveItem(this,0)}moveToBottom(){this.playQueueStore.moveItem(this,this.playQueueStore.items.length-1)}removeToTop(){return this.playQueueStore.removeItemsAbove(this)}removeOthers(){return this.playQueueStore.removeOtherItems(this)}};p(b,"nextId",1);let y=b;const f=new R({coerceTypes:!0});function ie(n,e){let i;if(i=f.getSchema(e),i===void 0&&(f.addSchema(n,e),i=f.getSchema(e)),i===void 0||i.schema!==n)throw new Error(`Invalid schema. Expected: '${JSON.stringify(n)}', but got '${JSON.stringify(i==null?void 0:i.schema)}'.`);return i}const se={type:"object",properties:{version:{type:"string",nullable:!0},repeat:{type:"string",enum:Object.values(u),nullable:!0},shuffle:{type:"boolean",nullable:!0},items:{type:"array",nullable:!0,items:{type:"object",properties:{url:{type:"string"},type:{type:"string"},videoId:{type:"string"},title:{type:"string"}},required:["url","type","videoId","title"]}},currentIndex:{type:"integer",nullable:!0}}},ae=ie(se,"PlayQueueStore");class oe{constructor(e){p(this,"interacted",!1);p(this,"items",[]);p(this,"currentId");p(this,"repeat",u.Off);p(this,"shuffle",!1);this.observableStateProvider=e,e.makeObservable(this,{interacted:a.observable,items:a.observable,currentId:a.observable,repeat:a.observable,shuffle:a.observable,localStorageState:a.computed.struct,isEmpty:a.computed,currentItem:a.computed,canPlay:a.computed,canPause:a.computed,hasMultipleItems:a.computed,currentIndex:a.computed,hasPreviousItem:a.computed,hasNextItem:a.computed,isLastItem:a.computed,selectedItems:a.computed,allItemsSelected:a.computed,selectedItemsOrAllItems:a.computed,setItems:a.action,interact:a.action,clear:a.action.bound,unselectAll:a.action,setCurrentItem:a.action,setNextItems:a.action,clearAndSetItems:a.action,playNext:a.action,playSelectedItemsNext:a.action.bound,addItems:a.action,addSelectedItems:a.action.bound,playFirst:a.action,moveItem:a.action,removeItems:a.action,removeSelectedItems:a.action.bound,removeOtherItems:a.action,removeItemsAbove:a.action,toggleRepeat:a.action.bound,toggleShuffle:a.action.bound,previous:a.action,next:a.action.bound,goToFirst:a.action})}createItem(e){return y.fromDto(this.observableStateProvider,this,e)}get localStorageState(){return{version:"1.0",repeat:this.repeat,shuffle:this.shuffle,items:this.items.map(e=>e.dto),currentIndex:this.currentIndex}}set localStorageState(e){var i;this.repeat=e.repeat??u.Off,this.shuffle=e.shuffle??!1,this.items=((i=e.items)==null?void 0:i.map(o=>this.createItem(o)))??[],this.currentIndex=e.currentIndex}validateLocalStorageState(e){return ae(e)}get isEmpty(){return this.items.length===0}get currentItem(){return this.items.find(e=>e.id===this.currentId)}get canPlay(){return this.currentItem!==void 0}get canPause(){return this.currentItem!==void 0}get hasMultipleItems(){return this.items.length>1}get currentIndex(){return this.currentId!==void 0?this.items.findIndex(e=>e.id===this.currentId):void 0}set currentIndex(e){var i;this.currentId=e!==void 0?(i=this.items.at(e))==null?void 0:i.id:void 0}get hasPreviousItem(){return this.hasMultipleItems&&this.currentIndex!==void 0&&this.currentIndex>0}get hasNextItem(){return this.hasMultipleItems&&this.currentIndex!==void 0&&this.currentIndex<this.items.length-1}get isLastItem(){return this.currentIndex!==void 0&&this.currentIndex===this.items.length-1}get selectedItems(){return this.items.filter(e=>e.isSelected)}get allItemsSelected(){return this.selectedItems.length===this.items.length}set allItemsSelected(e){for(const i of this.items)i.isSelected=e}get selectedItemsOrAllItems(){return this.selectedItems.length>0?this.selectedItems:this.items}setItems(e){this.items=e}interact(){this.interacted=!0}clear(){this.interact(),this.currentIndex=void 0,this.items=[]}unselectAll(){for(const e of this.items)e.unselect()}setCurrentItem(e){this.interact(),this.currentId=e==null?void 0:e.id}setNextItems(e){this.currentIndex!==void 0&&this.items.splice(this.currentIndex+1,0,...e)}clearAndSetItems(e){this.clear(),this.setCurrentItem(e[0]),this.setNextItems(e)}async playNext(e){if(this.isEmpty){this.clearAndSetItems(e);return}this.setNextItems(e)}async playSelectedItemsNext(){await this.playNext(this.selectedItemsOrAllItems.map(e=>e.clone())),this.unselectAll()}async addItems(e){if(this.isEmpty){this.clearAndSetItems(e);return}this.items.push(...e)}async addSelectedItems(){await this.addItems(this.selectedItemsOrAllItems.map(e=>e.clone())),this.unselectAll()}async playFirst(e){if(this.isEmpty){this.clearAndSetItems(e);return}const{currentIndex:i}=this;i!==void 0&&(this.interact(),this.items.splice(i,0,...e),this.currentIndex=i)}moveItem(e,i){const o=this.items.splice(this.items.indexOf(e),1)[0];this.items.splice(i,0,o)}async removeItems(e){const{currentItem:i}=this;T.pull(this.items,...e.filter(l=>l!==i));const{currentIndex:o,isLastItem:r}=this;T.pull(this.items,e.find(l=>l===i)),this.currentItem!==i&&(this.interact(),r?await this.goToFirst():this.currentIndex=o)}async removeSelectedItems(){await this.removeItems(this.selectedItemsOrAllItems),this.unselectAll()}async removeOtherItems(e){const i=e.id;return this.removeItems(this.items.filter(o=>o.id!==i))}async removeItemsAbove(e){const i=this.items.indexOf(e);return this.removeItems(this.items.filter((o,r)=>r<i))}toggleRepeat(){switch(this.repeat){case u.Off:this.repeat=u.All;break;case u.All:this.repeat=u.One;break;case u.One:this.repeat=u.Off;break}}toggleShuffle(){this.shuffle=!this.shuffle}async previous(){this.currentIndex!==void 0&&this.hasPreviousItem&&(this.interact(),this.currentIndex--)}async next(){this.currentIndex!==void 0&&this.hasNextItem&&(this.interact(),this.currentIndex++)}async goToFirst(){this.currentIndex!==void 0&&(this.currentIndex=0)}}const k=t.createContext(void 0),re=({children:n})=>{const[e]=t.useState(()=>new oe(new C)),i=g.useNostalgicDiva();return t.useEffect(()=>a.reaction(()=>e.currentItem,async(o,r)=>{o===void 0||r===void 0||o.type===r.type&&o.videoId===r.videoId&&await i.setCurrentTime(0)}),[e,i]),t.createElement(k.Provider,{value:e},n)},P=()=>t.useContext(k),le=h.observer(({children:n})=>{const e=P();return t.createElement(s.EuiPageTemplate,{panelled:!0,style:{minBlockSize:`max(460px, 100vh - ${x}px)`}},n,!e.isEmpty&&t.createElement(s.EuiSpacer,{style:{blockSize:I.height}}))});class ce{constructor(e){p(this,"playing",!1);p(this,"percent",0);p(this,"seeking",!1);e.makeObservable(this,{playing:a.observable,percent:a.observable,seeking:a.observable,setPlaying:a.action,setPercent:a.action,setSeeking:a.action,onPlay:a.action.bound,onPause:a.action.bound,onEnded:a.action.bound,onTimeUpdate:a.action.bound})}setPlaying(e){this.playing=e}setPercent(e){this.percent=e}setSeeking(e){this.seeking=e}onPlay(){this.playing=!0}onPause(){this.playing=!1}onEnded(){this.playing=!1}onTimeUpdate({percent:e}){e!==void 0&&(this.seeking||(this.percent=e))}}const S=t.createContext(void 0),ue=({children:n})=>{const[e]=t.useState(()=>new ce(new C));return t.createElement(S.Provider,{value:e},n)},me=()=>t.useContext(S);class de{makeObservable(e,i){return e}}exports.BottomBar=j;exports.HydrangeanDiva=te;exports.MediaPlayerLayout=le;exports.MiniPlayer=ne;exports.MobXObservableStateProvider=C;exports.ObservableStateProvider=de;exports.PlayQueueStoreProvider=re;exports.PlayerStoreProvider=ue;exports.RepeatMode=u;exports.bottomBarHeight=x;exports.miniPlayerSize=I;exports.usePlayQueueStore=P;exports.usePlayerStore=me;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/features/media-player/stores/RepeatMode.ts","../src/features/media-player/components/BottomBar.tsx","../src/features/media-player/components/AddVideoButton.tsx","../src/features/media-player/components/PlayQueueTable.tsx","../src/features/media-player/components/HydrangeanDiva.tsx","../src/features/media-player/components/MiniPlayer.tsx","../src/features/media-player/stores/MobXObservableStateProvider.ts","../src/features/media-player/stores/PlayQueueItemStore.ts","../src/features/media-player/stores/getOrAddSchema.ts","../src/features/media-player/stores/PlayQueueLocalStorageState.ts","../src/features/media-player/stores/PlayQueueStore.ts","../src/features/media-player/components/PlayQueueStoreContext.tsx","../src/features/media-player/components/MediaPlayerLayout.tsx","../src/features/media-player/stores/PlayerStore.ts","../src/features/media-player/components/PlayerStoreContext.tsx","../src/features/media-player/stores/ObservableStateProvider.ts"],"sourcesContent":["export enum RepeatMode {\n\tOff = 'Off',\n\tAll = 'All',\n\tOne = 'One',\n}\n","import { useNostalgicDiva } from '@aigamo/nostalgic-diva';\nimport {\n\tEuiBottomBar,\n\tEuiButtonIcon,\n\tEuiContextMenu,\n\tEuiContextMenuPanelDescriptor,\n\tEuiFlexGroup,\n\tEuiFlexItem,\n\tEuiFormRow,\n\tEuiIcon,\n\tEuiPopover,\n\tEuiRange,\n\tIconType,\n} from '@elastic/eui';\nimport { _SingleRangeChangeEvent } from '@elastic/eui/src/components/form/range/types';\nimport {\n\tArrowRepeat1Filled,\n\tArrowRepeatAllFilled,\n\tArrowRepeatAllOffFilled,\n\tArrowShuffleFilled,\n\tArrowShuffleOffFilled,\n\tDismissRegular,\n\tMoreHorizontalFilled,\n\tNextFilled,\n\tPauseFilled,\n\tPlayFilled,\n\tPreviousFilled,\n\tSkipBack10Regular,\n\tSkipForward30Regular,\n\tSpeaker2Regular,\n\tTopSpeedRegular,\n} from '@fluentui/react-icons';\nimport { observer } from 'mobx-react-lite';\nimport React, {\n\tmemo,\n\tReactElement,\n\tReactNode,\n\tuseCallback,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseState,\n} from 'react';\n\nimport { PlayerStore } from '@/features/media-player/stores/PlayerStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\nimport { RepeatMode } from '@/features/media-player/stores/RepeatMode';\n\nexport const bottomBarHeight = 80;\n\ninterface SeekBarProps {\n\tplayerStore: PlayerStore;\n}\n\nconst SeekBar = observer(({ playerStore }: SeekBarProps): ReactElement => {\n\tconst diva = useNostalgicDiva();\n\n\tconst handleChange = useCallback(\n\t\t(e: _SingleRangeChangeEvent) => {\n\t\t\tconst percent = Number(e.currentTarget.value) / 100;\n\t\t\tplayerStore.setPercent(percent);\n\t\t},\n\t\t[playerStore],\n\t);\n\n\tconst handleMouseDown = useCallback(\n\t\t(e: React.MouseEvent<HTMLInputElement>) => {\n\t\t\tif (e.button === 0) {\n\t\t\t\tplayerStore.setSeeking(true);\n\t\t\t}\n\t\t},\n\t\t[playerStore],\n\t);\n\n\tconst handleMouseUp = useCallback(\n\t\tasync (e: React.MouseEvent<HTMLInputElement>) => {\n\t\t\tif (e.button === 0) {\n\t\t\t\tconst percent = Number(e.currentTarget.value) / 100;\n\n\t\t\t\tplayerStore.setSeeking(false);\n\n\t\t\t\tconst duration = await diva.getDuration();\n\t\t\t\tif (duration !== undefined) {\n\t\t\t\t\tawait diva.setCurrentTime(duration * percent);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[playerStore, diva],\n\t);\n\n\treturn (\n\t\t<EuiRange\n\t\t\tmin={0}\n\t\t\tmax={100}\n\t\t\tstep={0.0000001}\n\t\t\tvalue={playerStore.percent * 100}\n\t\t\tonChange={handleChange}\n\t\t\tonMouseDown={handleMouseDown}\n\t\t\tonMouseUp={handleMouseUp}\n\t\t\tfullWidth\n\t\t\tshowRange\n\t\t\tcss={{ blockSize: 32 }}\n\t\t/>\n\t);\n});\n\ninterface VolumePopoverProps {\n\tbutton?: NonNullable<ReactNode>;\n\tisOpen: boolean;\n\tclosePopover: () => void;\n}\n\nconst VolumePopover = memo(\n\t({ button, isOpen, closePopover }: VolumePopoverProps): ReactElement => {\n\t\tconst [value, setValue] = useState('0');\n\n\t\tconst diva = useNostalgicDiva();\n\n\t\tuseLayoutEffect(() => {\n\t\t\tif (isOpen) {\n\t\t\t\tvoid diva.getVolume().then((volume) => {\n\t\t\t\t\tif (volume !== undefined) {\n\t\t\t\t\t\tsetValue(Math.floor(volume * 100).toString());\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}, [isOpen, diva]);\n\n\t\tconst handleChange = useCallback(\n\t\t\tasync (e: _SingleRangeChangeEvent): Promise<void> => {\n\t\t\t\tsetValue(e.currentTarget.value);\n\n\t\t\t\tawait diva.setVolume(Number(e.currentTarget.value) / 100);\n\t\t\t},\n\t\t\t[diva],\n\t\t);\n\n\t\treturn (\n\t\t\t<EuiPopover\n\t\t\t\tbutton={button}\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tclosePopover={closePopover}\n\t\t\t\tanchorPosition=\"upRight\"\n\t\t\t>\n\t\t\t\t<EuiFormRow>\n\t\t\t\t\t<EuiFlexGroup\n\t\t\t\t\t\tresponsive={false}\n\t\t\t\t\t\tgutterSize=\"s\"\n\t\t\t\t\t\tjustifyContent=\"center\"\n\t\t\t\t\t\talignItems=\"center\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\t\ttitle=\"Mute\" /* LOC */\n\t\t\t\t\t\t\taria-label=\"Mute\" /* LOC */\n\t\t\t\t\t\t\ticonType={Speaker2Regular}\n\t\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<EuiRange\n\t\t\t\t\t\t\tmin={0}\n\t\t\t\t\t\t\tmax={100}\n\t\t\t\t\t\t\tstep={1}\n\t\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\t\t\tcss={{ blockSize: 32 }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</EuiFlexGroup>\n\t\t\t\t</EuiFormRow>\n\t\t\t</EuiPopover>\n\t\t);\n\t},\n);\n\ninterface MoreOptionsContextMenuProps {\n\tplayQueueStore: PlayQueueStore;\n\tclosePopover: () => void;\n}\n\nconst MoreOptionsContextMenu = memo(\n\t({\n\t\tplayQueueStore,\n\t\tclosePopover,\n\t}: MoreOptionsContextMenuProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\tconst handleClickSkipBack10 = useCallback(async () => {\n\t\t\tconst currentTime = await diva.getCurrentTime();\n\n\t\t\tif (currentTime !== undefined) {\n\t\t\t\tawait diva.setCurrentTime(currentTime - 10);\n\t\t\t}\n\n\t\t\tclosePopover();\n\t\t}, [diva, closePopover]);\n\n\t\tconst handleClickSkipForward30 = useCallback(async () => {\n\t\t\tconst currentTime = await diva.getCurrentTime();\n\n\t\t\tif (currentTime !== undefined) {\n\t\t\t\tawait diva.setCurrentTime(currentTime + 30);\n\t\t\t}\n\n\t\t\tclosePopover();\n\t\t}, [diva, closePopover]);\n\n\t\tconst handleClickPlaybackRate = useCallback(\n\t\t\tasync (playbackRate: number): Promise<void> => {\n\t\t\t\tawait diva.setPlaybackRate(playbackRate);\n\n\t\t\t\tclosePopover();\n\t\t\t},\n\t\t\t[diva, closePopover],\n\t\t);\n\n\t\tconst handleClickRemoveFromPlayQueue =\n\t\t\tuseCallback(async (): Promise<void> => {\n\t\t\t\tif (playQueueStore.currentItem !== undefined) {\n\t\t\t\t\tawait playQueueStore.removeItems([\n\t\t\t\t\t\tplayQueueStore.currentItem,\n\t\t\t\t\t]);\n\t\t\t\t}\n\n\t\t\t\tclosePopover();\n\t\t\t}, [playQueueStore, closePopover]);\n\n\t\tconst [playbackRate] = useState<number>();\n\n\t\tconst panels = useMemo(\n\t\t\t(): EuiContextMenuPanelDescriptor[] => [\n\t\t\t\t{\n\t\t\t\t\tid: 0,\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Speed' /* LOC */,\n\t\t\t\t\t\t\ticon: <EuiIcon type={TopSpeedRegular} size=\"m\" />,\n\t\t\t\t\t\t\tpanel: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Skip back 10 seconds' /* LOC */,\n\t\t\t\t\t\t\ticon: <EuiIcon type={SkipBack10Regular} size=\"m\" />,\n\t\t\t\t\t\t\tonClick: handleClickSkipBack10,\n\t\t\t\t\t\t\tdisabled: playQueueStore.isEmpty,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Skip forward 30 seconds' /* LOC */,\n\t\t\t\t\t\t\ticon: (\n\t\t\t\t\t\t\t\t<EuiIcon type={SkipForward30Regular} size=\"m\" />\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tonClick: handleClickSkipForward30,\n\t\t\t\t\t\t\tdisabled: playQueueStore.isEmpty,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisSeparator: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Remove from play queue' /* LOC */,\n\t\t\t\t\t\t\ticon: <EuiIcon type={DismissRegular} size=\"m\" />,\n\t\t\t\t\t\t\tonClick: handleClickRemoveFromPlayQueue,\n\t\t\t\t\t\t\tdisabled: playQueueStore.isEmpty,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 1,\n\t\t\t\t\ttitle: 'Speed' /* LOC */,\n\t\t\t\t\titems: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n\t\t\t\t\t\t(value) => ({\n\t\t\t\t\t\t\tname: value.toString(),\n\t\t\t\t\t\t\tonClick: (): Promise<void> =>\n\t\t\t\t\t\t\t\thandleClickPlaybackRate(value),\n\t\t\t\t\t\t\ticon: value === playbackRate ? 'check' : 'empty',\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t],\n\t\t\t[\n\t\t\t\tplayQueueStore,\n\t\t\t\thandleClickSkipBack10,\n\t\t\t\thandleClickSkipForward30,\n\t\t\t\thandleClickRemoveFromPlayQueue,\n\t\t\t\thandleClickPlaybackRate,\n\t\t\t\tplaybackRate,\n\t\t\t],\n\t\t);\n\n\t\treturn <EuiContextMenu initialPanelId={0} panels={panels} />;\n\t},\n);\n\ninterface MoreOptionsPopoverProps {\n\tplayQueueStore: PlayQueueStore;\n\tbutton?: NonNullable<ReactNode>;\n\tisOpen: boolean;\n\tclosePopover: () => void;\n}\n\nconst MoreOptionsPopover = memo(\n\t({\n\t\tplayQueueStore,\n\t\tbutton,\n\t\tisOpen,\n\t\tclosePopover,\n\t}: MoreOptionsPopoverProps): ReactElement => {\n\t\treturn (\n\t\t\t<EuiPopover\n\t\t\t\tbutton={button}\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tclosePopover={closePopover}\n\t\t\t\tpanelPaddingSize=\"none\"\n\t\t\t\tanchorPosition=\"upRight\"\n\t\t\t>\n\t\t\t\t<MoreOptionsContextMenu\n\t\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\t\tclosePopover={closePopover}\n\t\t\t\t/>\n\t\t\t</EuiPopover>\n\t\t);\n\t},\n);\n\nconst repeatIconTypes: Record<RepeatMode, IconType> = {\n\t[RepeatMode.Off]: ArrowRepeatAllOffFilled,\n\t[RepeatMode.All]: ArrowRepeatAllFilled,\n\t[RepeatMode.One]: ArrowRepeat1Filled,\n};\n\ninterface BottomBarCenterControlsProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst BottomBarCenterControls = observer(\n\t({\n\t\tplayerStore,\n\t\tplayQueueStore,\n\t}: BottomBarCenterControlsProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\tconst handlePrevious = useCallback(async () => {\n\t\t\tif (playQueueStore.hasPreviousItem) {\n\t\t\t\tconst currentTime = await diva.getCurrentTime();\n\t\t\t\tif (currentTime === undefined || currentTime < 5) {\n\t\t\t\t\tawait playQueueStore.previous();\n\t\t\t\t} else {\n\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t}\n\t\t}, [playQueueStore, diva]);\n\n\t\treturn (\n\t\t\t<EuiFlexGroup\n\t\t\t\tresponsive={false}\n\t\t\t\tgutterSize=\"s\"\n\t\t\t\tjustifyContent=\"center\"\n\t\t\t\talignItems=\"center\"\n\t\t\t>\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle={\n\t\t\t\t\t\t`Shuffle: ${\n\t\t\t\t\t\t\tplayQueueStore.shuffle ? 'On' : 'Off'\n\t\t\t\t\t\t}` /* LOC */\n\t\t\t\t\t}\n\t\t\t\t\taria-label={\n\t\t\t\t\t\t`Shuffle: ${\n\t\t\t\t\t\t\tplayQueueStore.shuffle ? 'On' : 'Off'\n\t\t\t\t\t\t}` /* LOC */\n\t\t\t\t\t}\n\t\t\t\t\ticonType={\n\t\t\t\t\t\tplayQueueStore.shuffle\n\t\t\t\t\t\t\t? ArrowShuffleFilled\n\t\t\t\t\t\t\t: ArrowShuffleOffFilled\n\t\t\t\t\t}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={playQueueStore.toggleShuffle}\n\t\t\t\t\tdisabled /* TODO: remove */\n\t\t\t\t/>\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle=\"Previous\" /* LOC */\n\t\t\t\t\taria-label=\"Previous\" /* LOC */\n\t\t\t\t\ticonType={PreviousFilled}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={handlePrevious}\n\t\t\t\t\tdisabled={playQueueStore.isEmpty}\n\t\t\t\t/>\n\t\t\t\t{playerStore.playing ? (\n\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\ttitle=\"Pause\" /* LOC */\n\t\t\t\t\t\taria-label=\"Pause\" /* LOC */\n\t\t\t\t\t\ticonType={PauseFilled}\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\t\tonClick={(): Promise<void> => diva.pause()}\n\t\t\t\t\t\tdisabled={!playQueueStore.canPlay}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\ttitle=\"Play\" /* LOC */\n\t\t\t\t\t\taria-label=\"Play\" /* LOC */\n\t\t\t\t\t\ticonType={PlayFilled}\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\t\tonClick={(): Promise<void> => diva.play()}\n\t\t\t\t\t\tdisabled={!playQueueStore.canPlay}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle=\"Next\" /* LOC */\n\t\t\t\t\taria-label=\"Next\" /* LOC */\n\t\t\t\t\ticonType={NextFilled}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={playQueueStore.next}\n\t\t\t\t\tdisabled={!playQueueStore.hasNextItem}\n\t\t\t\t/>\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle={\n\t\t\t\t\t\t`Repeat: ${\n\t\t\t\t\t\t\tplayQueueStore.repeat === RepeatMode.All\n\t\t\t\t\t\t\t\t? 'All'\n\t\t\t\t\t\t\t\t: playQueueStore.repeat === RepeatMode.One\n\t\t\t\t\t\t\t\t\t? 'One'\n\t\t\t\t\t\t\t\t\t: 'Off'\n\t\t\t\t\t\t}` /* LOC */\n\t\t\t\t\t}\n\t\t\t\t\taria-label={\n\t\t\t\t\t\t`Repeat: ${\n\t\t\t\t\t\t\tplayQueueStore.repeat === RepeatMode.All\n\t\t\t\t\t\t\t\t? 'All'\n\t\t\t\t\t\t\t\t: playQueueStore.repeat === RepeatMode.One\n\t\t\t\t\t\t\t\t\t? 'One'\n\t\t\t\t\t\t\t\t\t: 'Off'\n\t\t\t\t\t\t}` /* LOC */\n\t\t\t\t\t}\n\t\t\t\t\ticonType={repeatIconTypes[playQueueStore.repeat]}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={playQueueStore.toggleRepeat}\n\t\t\t\t/>\n\t\t\t</EuiFlexGroup>\n\t\t);\n\t},\n);\n\nconst VolumeButton = memo((): ReactElement => {\n\tconst [isVolumePopoverOpen, setIsVolumePopoverOpen] = useState(false);\n\n\tconst toggleVolumePopover = (): void =>\n\t\tsetIsVolumePopoverOpen(!isVolumePopoverOpen);\n\n\treturn (\n\t\t<VolumePopover\n\t\t\tbutton={\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle=\"Volume\" /* LOC */\n\t\t\t\t\taria-label=\"Volume\" /* LOC */\n\t\t\t\t\ticonType={Speaker2Regular}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={toggleVolumePopover}\n\t\t\t\t/>\n\t\t\t}\n\t\t\tisOpen={isVolumePopoverOpen}\n\t\t\tclosePopover={(): void => setIsVolumePopoverOpen(false)}\n\t\t/>\n\t);\n});\n\ninterface MoreOptionsButtonProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst MoreOptionsButton = memo(\n\t({ playQueueStore }: MoreOptionsButtonProps): ReactElement => {\n\t\tconst [isMoreOptionsPopoverOpen, setIsMoreOptionsPopoverOpen] =\n\t\t\tuseState(false);\n\n\t\tconst toggleMoreOptionsPopover = (): void =>\n\t\t\tsetIsMoreOptionsPopoverOpen(!isMoreOptionsPopoverOpen);\n\n\t\treturn (\n\t\t\t<MoreOptionsPopover\n\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\tbutton={\n\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\ttitle=\"More options\" /* LOC */\n\t\t\t\t\t\taria-label=\"More options\" /* LOC */\n\t\t\t\t\t\ticonType={MoreHorizontalFilled}\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\t\tonClick={toggleMoreOptionsPopover}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\tisOpen={isMoreOptionsPopoverOpen}\n\t\t\t\tclosePopover={(): void => setIsMoreOptionsPopoverOpen(false)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\ninterface BottomBarRightControlsProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst BottomBarRightControls = memo(\n\t({ playQueueStore }: BottomBarRightControlsProps): ReactElement => {\n\t\treturn (\n\t\t\t<EuiFlexGroup\n\t\t\t\tresponsive={false}\n\t\t\t\tgutterSize=\"s\"\n\t\t\t\tjustifyContent=\"flexEnd\"\n\t\t\t\talignItems=\"center\"\n\t\t\t>\n\t\t\t\t<VolumeButton />\n\t\t\t\t<MoreOptionsButton playQueueStore={playQueueStore} />\n\t\t\t</EuiFlexGroup>\n\t\t);\n\t},\n);\n\ninterface BottomBarProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const BottomBar = observer(\n\t({ playerStore, playQueueStore }: BottomBarProps): ReactElement => {\n\t\treturn (\n\t\t\t<EuiBottomBar paddingSize=\"s\">\n\t\t\t\t<EuiFlexGroup direction=\"column\" gutterSize=\"none\">\n\t\t\t\t\t<EuiFlexItem>\n\t\t\t\t\t\t<SeekBar playerStore={playerStore} />\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem>\n\t\t\t\t\t\t<EuiFlexGroup responsive={false}>\n\t\t\t\t\t\t\t<EuiFlexItem css={{ width: 'calc(100% / 3)' }} />\n\t\t\t\t\t\t\t<EuiFlexItem css={{ width: 'calc(100% / 3)' }}>\n\t\t\t\t\t\t\t\t<BottomBarCenterControls\n\t\t\t\t\t\t\t\t\tplayerStore={playerStore}\n\t\t\t\t\t\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t\t\t<EuiFlexItem css={{ width: 'calc(100% / 3)' }}>\n\t\t\t\t\t\t\t\t<BottomBarRightControls\n\t\t\t\t\t\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t\t</EuiFlexGroup>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t</EuiFlexGroup>\n\t\t\t</EuiBottomBar>\n\t\t);\n\t},\n);\n","import { findVideoService } from '@aigamo/nostalgic-diva';\nimport {\n\tEuiButton,\n\tEuiButtonEmpty,\n\tEuiFieldText,\n\tEuiForm,\n\tEuiFormRow,\n\tEuiModal,\n\tEuiModalBody,\n\tEuiModalFooter,\n\tEuiModalHeader,\n\tEuiModalHeaderTitle,\n} from '@elastic/eui';\nimport { AddRegular } from '@fluentui/react-icons';\nimport { memo, ReactElement, useCallback, useState } from 'react';\n\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\ninterface AddVideoModalProps {\n\tonCancel: () => void;\n\tonSave: (e: { url: string; title: string }) => Promise<void>;\n}\n\nconst AddVideoModal = ({\n\tonCancel,\n\tonSave,\n}: AddVideoModalProps): ReactElement => {\n\tconst [url, setUrl] = useState('');\n\tconst [title, setTitle] = useState('');\n\tconst [loading, setLoading] = useState(false);\n\n\treturn (\n\t\t<EuiModal onClose={onCancel} initialFocus=\"[name=url]\">\n\t\t\t<EuiModalHeader>\n\t\t\t\t<EuiModalHeaderTitle>Add video{/* LOC */}</EuiModalHeaderTitle>\n\t\t\t</EuiModalHeader>\n\n\t\t\t<EuiModalBody>\n\t\t\t\t<EuiForm component=\"form\">\n\t\t\t\t\t<EuiFormRow label=\"URL\" /* LOC */>\n\t\t\t\t\t\t<EuiFieldText\n\t\t\t\t\t\t\tname=\"url\"\n\t\t\t\t\t\t\tvalue={url}\n\t\t\t\t\t\t\tonChange={(e): void => setUrl(e.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</EuiFormRow>\n\n\t\t\t\t\t<EuiFormRow label=\"Title\">\n\t\t\t\t\t\t<EuiFieldText\n\t\t\t\t\t\t\tname=\"title\"\n\t\t\t\t\t\t\tvalue={title}\n\t\t\t\t\t\t\tonChange={(e): void => setTitle(e.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</EuiFormRow>\n\t\t\t\t</EuiForm>\n\t\t\t</EuiModalBody>\n\n\t\t\t<EuiModalFooter>\n\t\t\t\t<EuiButtonEmpty onClick={onCancel}>\n\t\t\t\t\tCancel{/* LOC */}\n\t\t\t\t</EuiButtonEmpty>\n\n\t\t\t\t<EuiButton\n\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\tonClick={async (): Promise<void> => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tsetLoading(true);\n\n\t\t\t\t\t\t\tawait onSave({ url, title });\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tsetLoading(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t\tfill\n\t\t\t\t\tdisabled={url.trim().length === 0}\n\t\t\t\t\tisLoading={loading}\n\t\t\t\t>\n\t\t\t\t\tSave{/* LOC */}\n\t\t\t\t</EuiButton>\n\t\t\t</EuiModalFooter>\n\t\t</EuiModal>\n\t);\n};\n\ninterface NoembedResult {\n\ttitle: string;\n}\n\nfunction isNoembedResult(value: any): value is NoembedResult {\n\treturn (\n\t\tvalue !== null &&\n\t\ttypeof value === 'object' &&\n\t\t'title' in value &&\n\t\ttypeof value.title === 'string'\n\t);\n}\n\ninterface AddVideoButtonProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const AddVideoButton = memo(\n\t({ playQueueStore }: AddVideoButtonProps): ReactElement => {\n\t\tconst [addVideoModalOpen, setAddVideoModalOpen] = useState(false);\n\n\t\tconst handleSave = useCallback(\n\t\t\tasync (e: { url: string; title: string }): Promise<void> => {\n\t\t\t\tconst videoService = findVideoService(e.url);\n\t\t\t\tif (videoService !== undefined) {\n\t\t\t\t\tconst videoId = videoService.extractVideoId(e.url);\n\t\t\t\t\tif (videoId !== undefined) {\n\t\t\t\t\t\tconst response = await fetch(\n\t\t\t\t\t\t\t`https://noembed.com/embed?url=${encodeURIComponent(\n\t\t\t\t\t\t\t\te.url,\n\t\t\t\t\t\t\t)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst jsonData = await response.json();\n\n\t\t\t\t\t\tawait playQueueStore.addItems([\n\t\t\t\t\t\t\tplayQueueStore.createItem({\n\t\t\t\t\t\t\t\turl: e.url,\n\t\t\t\t\t\t\t\ttype: videoService.type,\n\t\t\t\t\t\t\t\tvideoId: videoId,\n\t\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\t\te.title ||\n\t\t\t\t\t\t\t\t\t(isNoembedResult(jsonData)\n\t\t\t\t\t\t\t\t\t\t? jsonData.title\n\t\t\t\t\t\t\t\t\t\t: videoId),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetAddVideoModalOpen(false);\n\t\t\t},\n\t\t\t[playQueueStore],\n\t\t);\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<EuiButton\n\t\t\t\t\tonClick={(): void => setAddVideoModalOpen(true)}\n\t\t\t\t\ticonType={AddRegular}\n\t\t\t\t\tcolor=\"primary\"\n\t\t\t\t>\n\t\t\t\t\tAdd video{/* LOC */}\n\t\t\t\t</EuiButton>\n\n\t\t\t\t{addVideoModalOpen && (\n\t\t\t\t\t<AddVideoModal\n\t\t\t\t\t\tonCancel={(): void => setAddVideoModalOpen(false)}\n\t\t\t\t\t\tonSave={handleSave}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t);\n\t},\n);\n","import { PlayerType, useNostalgicDiva } from '@aigamo/nostalgic-diva';\nimport {\n\tCommonProps,\n\tEuiButton,\n\tEuiButtonIcon,\n\tEuiCheckbox,\n\tEuiContextMenuItem,\n\tEuiContextMenuItemProps,\n\tEuiContextMenuPanel,\n\tEuiHorizontalRule,\n\tEuiIcon,\n\tEuiLink,\n\tEuiPopover,\n\tEuiTable,\n\tEuiTableHeader,\n\tEuiTableHeaderCell,\n\tEuiTableHeaderCellCheckbox,\n\tEuiTableRow,\n\tEuiTableRowCell,\n\tEuiTableRowCellCheckbox,\n\tuseEuiTheme,\n} from '@elastic/eui';\nimport {\n\tAddRegular,\n\tArrowDownloadRegular,\n\tArrowUploadRegular,\n\tDismissRegular,\n\tMoreHorizontalFilled,\n\tPlayRegular,\n} from '@fluentui/react-icons';\nimport { observer } from 'mobx-react-lite';\nimport React, {\n\tButtonHTMLAttributes,\n\tmemo,\n\tReactElement,\n\tuseCallback,\n\tuseState,\n} from 'react';\nimport { ReactSortable } from 'react-sortablejs';\n\nimport { IPlayQueueItemStore } from '@/features/media-player/stores/IPlayQueueItemStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\ninterface PlayQueueTableHeaderProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst PlayQueueTableHeader = observer(\n\t({ playQueueStore }: PlayQueueTableHeaderProps): ReactElement => {\n\t\tconst { euiTheme } = useEuiTheme();\n\n\t\treturn (\n\t\t\t<EuiTableHeader\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: 'sticky',\n\t\t\t\t\ttop: 48 + 40 + 24,\n\t\t\t\t\tzIndex: 998,\n\t\t\t\t\tbackground: euiTheme.colors.backgroundBasePlain,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<EuiTableHeaderCellCheckbox>\n\t\t\t\t\t<EuiCheckbox\n\t\t\t\t\t\tid=\"\" // TODO\n\t\t\t\t\t\tchecked={playQueueStore.allItemsSelected}\n\t\t\t\t\t\tonChange={(e): void => {\n\t\t\t\t\t\t\tplayQueueStore.allItemsSelected = e.target.checked;\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</EuiTableHeaderCellCheckbox>\n\t\t\t\t<EuiTableHeaderCell width={24} />\n\t\t\t\t<EuiTableHeaderCell>Title{/* LOC */}</EuiTableHeaderCell>\n\t\t\t\t<EuiTableHeaderCell />\n\t\t\t</EuiTableHeader>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableRowContextMenuPanelProps {\n\titem: IPlayQueueItemStore;\n\tclosePopover: () => void;\n}\n\nconst PlayQueueTableRowContextMenuPanel = memo(\n\t({\n\t\titem,\n\t\tclosePopover,\n\t}: PlayQueueTableRowContextMenuPanelProps): ReactElement => {\n\t\tconst ContextMenuItem = memo(\n\t\t\t({\n\t\t\t\tonClick,\n\t\t\t\t...props\n\t\t\t}: CommonProps &\n\t\t\t\tOmit<\n\t\t\t\t\tButtonHTMLAttributes<HTMLButtonElement>,\n\t\t\t\t\t'onClick' | 'disabled' | 'type'\n\t\t\t\t> &\n\t\t\t\tEuiContextMenuItemProps): ReactElement => {\n\t\t\t\tconst handleClick = useCallback(\n\t\t\t\t\t(e: React.MouseEvent) => {\n\t\t\t\t\t\tclosePopover();\n\n\t\t\t\t\t\tonClick?.(e);\n\t\t\t\t\t},\n\t\t\t\t\t[onClick],\n\t\t\t\t);\n\n\t\t\t\treturn <EuiContextMenuItem {...props} onClick={handleClick} />;\n\t\t\t},\n\t\t);\n\n\t\treturn (\n\t\t\t<EuiContextMenuPanel>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type=\"\" />}\n\t\t\t\t\tonClick={item.playFirst}\n\t\t\t\t>\n\t\t\t\t\tPlay first{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type=\"\" />}\n\t\t\t\t\tonClick={item.playNext}\n\t\t\t\t>\n\t\t\t\t\tPlay next{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type={AddRegular} />}\n\t\t\t\t\tonClick={item.addToPlayQueue}\n\t\t\t\t>\n\t\t\t\t\tAdd to play queue{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<EuiHorizontalRule margin=\"none\" />\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type={ArrowUploadRegular} />}\n\t\t\t\t\tonClick={item.moveToTop}\n\t\t\t\t\tdisabled={!item.canMoveToTop}\n\t\t\t\t>\n\t\t\t\t\tMove to the top{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type={ArrowDownloadRegular} />}\n\t\t\t\t\tonClick={item.moveToBottom}\n\t\t\t\t\tdisabled={!item.canMoveToBottom}\n\t\t\t\t>\n\t\t\t\t\tMove to the bottom{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<EuiHorizontalRule margin=\"none\" />\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type=\"\" />}\n\t\t\t\t\tonClick={item.removeToTop}\n\t\t\t\t\tdisabled={!item.canRemoveToTop}\n\t\t\t\t>\n\t\t\t\t\tRemove to the top{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type=\"\" />}\n\t\t\t\t\tonClick={item.removeOthers}\n\t\t\t\t\tdisabled={!item.canRemoveOthers}\n\t\t\t\t>\n\t\t\t\t\tRemove others{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t</EuiContextMenuPanel>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableRowPopoverProps {\n\titem: IPlayQueueItemStore;\n}\n\nconst PlayQueueTableRowPopover = memo(\n\t({ item }: PlayQueueTableRowPopoverProps): ReactElement => {\n\t\tconst [isOpen, setIsOpen] = useState(false);\n\n\t\tconst togglePopover = useCallback(() => setIsOpen(!isOpen), [isOpen]);\n\t\tconst closePopover = useCallback(() => setIsOpen(false), []);\n\n\t\treturn (\n\t\t\t<EuiPopover\n\t\t\t\tbutton={\n\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\ttitle=\"More options\"\n\t\t\t\t\t\taria-label=\"More options\"\n\t\t\t\t\t\ticonType={MoreHorizontalFilled}\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\tcolor=\"text\"\n\t\t\t\t\t\tonClick={togglePopover}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tclosePopover={closePopover}\n\t\t\t\tpanelPaddingSize=\"none\"\n\t\t\t\tanchorPosition=\"leftCenter\"\n\t\t\t>\n\t\t\t\t<PlayQueueTableRowContextMenuPanel\n\t\t\t\t\titem={item}\n\t\t\t\t\tclosePopover={closePopover}\n\t\t\t\t/>\n\t\t\t</EuiPopover>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableRowActionsCellProps {\n\titem: IPlayQueueItemStore;\n}\n\nconst PlayQueueTableRowActionsCell = observer(\n\t({ item }: PlayQueueTableRowActionsCellProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\treturn (\n\t\t\t<EuiTableRowCell textOnly={false} hasActions align=\"right\">\n\t\t\t\t<EuiButton\n\t\t\t\t\ticonType={PlayRegular}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\tonClick={async (): Promise<void> => {\n\t\t\t\t\t\tif (item.isCurrent) {\n\t\t\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\titem.play();\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tPlay{/* LOC */}\n\t\t\t\t</EuiButton>\n\t\t\t\t<EuiButton\n\t\t\t\t\ticonType={DismissRegular}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\tonClick={item.remove}\n\t\t\t\t>\n\t\t\t\t\tRemove{/* LOC */}\n\t\t\t\t</EuiButton>\n\t\t\t\t<PlayQueueTableRowPopover item={item} />\n\t\t\t</EuiTableRowCell>\n\t\t);\n\t},\n);\n\nconst videoServiceIcons: Record<PlayerType, string> = {\n\tAudio: '' /* TODO */,\n\tDailymotion: 'https://www.dailymotion.com/favicon.ico',\n\tNiconico: 'https://www.nicovideo.jp/favicon.ico',\n\tSoundCloud: 'https://soundcloud.com/favicon.ico',\n\tTwitch: 'https://www.twitch.tv/favicon.ico',\n\tVimeo: 'https://vimeo.com/favicon.ico',\n\tYouTube: 'https://www.youtube.com/favicon.ico',\n};\n\ninterface PlayQueueTableRowProps {\n\titem: IPlayQueueItemStore;\n}\n\nconst PlayQueueTableRow = observer(\n\t({ item }: PlayQueueTableRowProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\treturn (\n\t\t\t<EuiTableRow key={item.id} isSelected={item.isCurrent}>\n\t\t\t\t<EuiTableRowCellCheckbox>\n\t\t\t\t\t<EuiCheckbox\n\t\t\t\t\t\tid={item.id.toString() /* TODO */}\n\t\t\t\t\t\tchecked={item.isSelected}\n\t\t\t\t\t\tonChange={item.toggleSelected}\n\t\t\t\t\t/>\n\t\t\t\t</EuiTableRowCellCheckbox>\n\t\t\t\t<EuiTableRowCell textOnly={false}>\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={videoServiceIcons[item.type]}\n\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\theight={16}\n\t\t\t\t\t\talt={item.type /* TODO */}\n\t\t\t\t\t/>\n\t\t\t\t</EuiTableRowCell>\n\t\t\t\t<EuiTableRowCell>\n\t\t\t\t\t<EuiLink\n\t\t\t\t\t\thref={item.url}\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\texternal\n\t\t\t\t\t\tonClick={(): Promise<void> => diva.pause()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{item.title}\n\t\t\t\t\t</EuiLink>\n\t\t\t\t</EuiTableRowCell>\n\t\t\t\t<PlayQueueTableRowActionsCell item={item} />\n\t\t\t</EuiTableRow>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableBodyProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst PlayQueueTableBody = observer(\n\t({ playQueueStore }: PlayQueueTableBodyProps): ReactElement => {\n\t\treturn (\n\t\t\t<ReactSortable\n\t\t\t\ttag=\"tbody\"\n\t\t\t\tlist={playQueueStore.items}\n\t\t\t\tsetList={(items): void => playQueueStore.setItems(items)}\n\t\t\t>\n\t\t\t\t{playQueueStore.items.map((item) => (\n\t\t\t\t\t<PlayQueueTableRow key={item.id} item={item} />\n\t\t\t\t))}\n\t\t\t</ReactSortable>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const PlayQueueTable = observer(\n\t({ playQueueStore }: PlayQueueTableProps): ReactElement => {\n\t\treturn (\n\t\t\t<EuiTable>\n\t\t\t\t<PlayQueueTableHeader playQueueStore={playQueueStore} />\n\t\t\t\t<PlayQueueTableBody playQueueStore={playQueueStore} />\n\t\t\t</EuiTable>\n\t\t);\n\t},\n);\n","import {\n\tEuiButton,\n\tEuiCodeBlock,\n\tEuiFlexGroup,\n\tEuiFlexItem,\n\tEuiFlyout,\n\tEuiPageTemplate,\n\tEuiSpacer,\n\tuseEuiTheme,\n} from '@elastic/eui';\nimport {\n\tAddRegular,\n\tDeleteRegular,\n\tDismissRegular,\n} from '@fluentui/react-icons';\nimport { observer } from 'mobx-react-lite';\nimport { ReactElement, useState } from 'react';\n\nimport { AddVideoButton } from '@/features/media-player/components/AddVideoButton';\nimport { PlayQueueTable } from '@/features/media-player/components/PlayQueueTable';\nimport { PlayerStore } from '@/features/media-player/stores/PlayerStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\ninterface DeveloperToolsButtonProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst DeveloperToolsButton = observer(\n\t({ playQueueStore }: DeveloperToolsButtonProps): ReactElement => {\n\t\tconst [isFlyoutVisible, setIsFlyoutVisible] = useState(false);\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{isFlyoutVisible && (\n\t\t\t\t\t<EuiFlyout\n\t\t\t\t\t\ttype=\"push\"\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\tonClose={(): void => setIsFlyoutVisible(false)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div style={{ blockSize: '100%' }}>\n\t\t\t\t\t\t\t<EuiCodeBlock\n\t\t\t\t\t\t\t\tlanguage=\"json\"\n\t\t\t\t\t\t\t\toverflowHeight=\"100%\"\n\t\t\t\t\t\t\t\tisCopyable\n\t\t\t\t\t\t\t\tisVirtualized\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{JSON.stringify(\n\t\t\t\t\t\t\t\t\tplayQueueStore.localStorageState,\n\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</EuiCodeBlock>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</EuiFlyout>\n\t\t\t\t)}\n\n\t\t\t\t<AddVideoButton playQueueStore={playQueueStore} />\n\t\t\t</>\n\t\t);\n\t},\n);\n\ninterface PlayQueueProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst PlayQueue = observer(\n\t({ playerStore, playQueueStore }: PlayQueueProps): ReactElement => {\n\t\tconst { euiTheme } = useEuiTheme();\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<EuiFlexGroup\n\t\t\t\t\talignItems=\"center\"\n\t\t\t\t\tgutterSize=\"m\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tposition: 'sticky',\n\t\t\t\t\t\ttop: 48,\n\t\t\t\t\t\tzIndex: 998,\n\t\t\t\t\t\tbackground: euiTheme.colors.backgroundBasePlain,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<EuiButton\n\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\tplayQueueStore.isEmpty ||\n\t\t\t\t\t\t\t\tplayQueueStore.selectedItems.length === 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonClick={playQueueStore.playSelectedItemsNext}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tPlay next{/* LOC */}\n\t\t\t\t\t\t</EuiButton>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<EuiButton\n\t\t\t\t\t\t\ticonType={AddRegular}\n\t\t\t\t\t\t\tonClick={playQueueStore.addSelectedItems}\n\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\tplayQueueStore.isEmpty ||\n\t\t\t\t\t\t\t\tplayQueueStore.selectedItems.length === 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tAdd to play queue{/* LOC */}\n\t\t\t\t\t\t</EuiButton>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<EuiButton\n\t\t\t\t\t\t\ticonType={DismissRegular}\n\t\t\t\t\t\t\tonClick={playQueueStore.removeSelectedItems}\n\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\tplayQueueStore.isEmpty ||\n\t\t\t\t\t\t\t\tplayQueueStore.selectedItems.length === 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tRemove{/* LOC */}\n\t\t\t\t\t\t</EuiButton>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<EuiButton\n\t\t\t\t\t\t\ticonType={DeleteRegular}\n\t\t\t\t\t\t\tonClick={playQueueStore.clear}\n\t\t\t\t\t\t\tdisabled={playQueueStore.isEmpty}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tClear{/* LOC */}\n\t\t\t\t\t\t</EuiButton>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem grow={true} />\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<DeveloperToolsButton playQueueStore={playQueueStore} />\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t</EuiFlexGroup>\n\n\t\t\t\t{!playQueueStore.isEmpty && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<EuiSpacer\n\t\t\t\t\t\t\tsize=\"l\"\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: 'sticky',\n\t\t\t\t\t\t\t\ttop: 48 + 40,\n\t\t\t\t\t\t\t\tzIndex: 998,\n\t\t\t\t\t\t\t\tbackground: euiTheme.colors.backgroundBasePlain,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<PlayQueueTable playQueueStore={playQueueStore} />\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</>\n\t\t);\n\t},\n);\n\ninterface HydrangeanDivaProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const HydrangeanDiva = observer(\n\t({ playerStore, playQueueStore }: HydrangeanDivaProps): ReactElement => {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<EuiPageTemplate.Header\n\t\t\t\t\tpageTitle=\"Play queue\" /* LOC */\n\t\t\t\t\trightSideItems={[]}\n\t\t\t\t/>\n\n\t\t\t\t<EuiPageTemplate.Section>\n\t\t\t\t\t<PlayQueue\n\t\t\t\t\t\tplayerStore={playerStore}\n\t\t\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\t\t/>\n\t\t\t\t</EuiPageTemplate.Section>\n\t\t\t</>\n\t\t);\n\t},\n);\n","import {\n\tNostalgicDiva,\n\tPlayerOptions,\n\tuseNostalgicDiva,\n} from '@aigamo/nostalgic-diva';\nimport { observer } from 'mobx-react-lite';\nimport { ReactElement, useCallback, useMemo } from 'react';\n\nimport { bottomBarHeight } from '@/features/media-player/components/BottomBar';\nimport { PlayerStore } from '@/features/media-player/stores/PlayerStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\nimport { RepeatMode } from '@/features/media-player/stores/RepeatMode';\n\nexport const miniPlayerSize = {\n\twidth: 16 * 25,\n\theight: 9 * 25,\n} as const;\n\ninterface MiniPlayerProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const MiniPlayer = observer(\n\t({ playerStore, playQueueStore }: MiniPlayerProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\tconst handleLoaded = useCallback(async (): Promise<void> => {\n\t\t\tif (!playQueueStore.interacted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait diva.play();\n\t\t}, [playQueueStore, diva]);\n\n\t\tconst handleEnded = useCallback(async (): Promise<void> => {\n\t\t\tswitch (playQueueStore.repeat) {\n\t\t\t\tcase RepeatMode.One:\n\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase RepeatMode.Off:\n\t\t\t\tcase RepeatMode.All:\n\t\t\t\t\tif (playQueueStore.isLastItem) {\n\t\t\t\t\t\tswitch (playQueueStore.repeat) {\n\t\t\t\t\t\t\tcase RepeatMode.Off:\n\t\t\t\t\t\t\t\tplayerStore.onEnded();\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase RepeatMode.All:\n\t\t\t\t\t\t\t\tif (playQueueStore.hasMultipleItems) {\n\t\t\t\t\t\t\t\t\tawait playQueueStore.goToFirst();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait playQueueStore.next();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}, [playQueueStore, playerStore, diva]);\n\n\t\tconst options = useMemo(\n\t\t\t(): PlayerOptions => ({\n\t\t\t\tonLoaded: handleLoaded,\n\t\t\t\tonPlay: playerStore.onPlay,\n\t\t\t\tonPause: playerStore.onPause,\n\t\t\t\tonEnded: handleEnded,\n\t\t\t\tonTimeUpdate: playerStore.onTimeUpdate,\n\t\t\t}),\n\t\t\t[playerStore, handleLoaded, handleEnded],\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tcss={{\n\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\tright: 0,\n\t\t\t\t\tbottom: bottomBarHeight,\n\t\t\t\t\twidth: miniPlayerSize.width,\n\t\t\t\t\theight: miniPlayerSize.height,\n\t\t\t\t\tzIndex: 998,\n\t\t\t\t\tbackgroundColor: 'rgb(39, 39, 39)',\n\t\t\t\t\tdisplay: 'flex',\n\t\t\t\t\tflexDirection: 'column',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div css={{ flexGrow: 1, backgroundColor: 'black' }}>\n\t\t\t\t\t{playQueueStore.currentItem && (\n\t\t\t\t\t\t<NostalgicDiva\n\t\t\t\t\t\t\tsrc={playQueueStore.currentItem.url}\n\t\t\t\t\t\t\toptions={options}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t},\n);\n","import { AnnotationsMap, makeObservable } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\n\nexport class MobXObservableStateProvider implements IObservableStateProvider {\n\tmakeObservable<\n\t\tT extends object,\n\t\tAdditionalKeys extends PropertyKey = never,\n\t>(target: T, annotations?: AnnotationsMap<T, AdditionalKeys>): T {\n\t\treturn makeObservable(target, annotations);\n\t}\n}\n","import { PlayerType } from '@aigamo/nostalgic-diva';\nimport { action, computed, observable } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\nimport {\n\tIPlayQueueItemStore,\n\tPlayQueueItemDto,\n} from '@/features/media-player/stores/IPlayQueueItemStore';\nimport { IPlayQueueStore } from '@/features/media-player/stores/IPlayQueueStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\nexport class PlayQueueItemStore implements IPlayQueueItemStore {\n\tstatic nextId = 1;\n\n\treadonly id: number;\n\tisSelected = false;\n\n\tconstructor(\n\t\treadonly observableStateProvider: IObservableStateProvider,\n\t\treadonly playQueueStore: IPlayQueueStore,\n\t\treadonly dto: PlayQueueItemDto,\n\t) {\n\t\tthis.id = PlayQueueItemStore.nextId++;\n\n\t\tobservableStateProvider.makeObservable(this, {\n\t\t\tisSelected: observable,\n\t\t\tisCurrent: computed,\n\t\t\tindex: computed,\n\t\t\tisFirst: computed,\n\t\t\tisLast: computed,\n\t\t\tcanMoveToTop: computed,\n\t\t\tcanMoveToBottom: computed,\n\t\t\tcanRemoveToTop: computed,\n\t\t\tcanRemoveOthers: computed,\n\t\t\tunselect: action,\n\t\t\ttoggleSelected: action.bound,\n\t\t\tplay: action,\n\t\t\tremove: action.bound,\n\t\t\tplayFirst: action.bound,\n\t\t\tplayNext: action.bound,\n\t\t\taddToPlayQueue: action.bound,\n\t\t\tmoveToTop: action.bound,\n\t\t\tmoveToBottom: action.bound,\n\t\t\tremoveToTop: action.bound,\n\t\t\tremoveOthers: action.bound,\n\t\t});\n\t}\n\n\tstatic fromDto(\n\t\tobservableStateProvider: IObservableStateProvider,\n\t\tplayQueueStore: PlayQueueStore,\n\t\tdto: PlayQueueItemDto,\n\t): IPlayQueueItemStore {\n\t\treturn new PlayQueueItemStore(\n\t\t\tobservableStateProvider,\n\t\t\tplayQueueStore,\n\t\t\tdto,\n\t\t);\n\t}\n\n\tget url(): string {\n\t\treturn this.dto.url;\n\t}\n\n\tget type(): PlayerType {\n\t\treturn this.dto.type;\n\t}\n\n\tget videoId(): string {\n\t\treturn this.dto.videoId;\n\t}\n\n\tget title(): string {\n\t\treturn this.dto.title;\n\t}\n\n\tget isCurrent(): boolean {\n\t\treturn this.playQueueStore.currentItem === this;\n\t}\n\n\tget index(): number {\n\t\treturn this.playQueueStore.items.indexOf(this);\n\t}\n\n\tget isFirst(): boolean {\n\t\treturn this.index === 0;\n\t}\n\n\tget isLast(): boolean {\n\t\treturn this.index === this.playQueueStore.items.length - 1;\n\t}\n\n\tget canMoveToTop(): boolean {\n\t\treturn !this.isFirst;\n\t}\n\n\tget canMoveToBottom(): boolean {\n\t\treturn !this.isLast;\n\t}\n\n\tget canRemoveToTop(): boolean {\n\t\treturn !this.isFirst;\n\t}\n\n\tget canRemoveOthers(): boolean {\n\t\treturn this.playQueueStore.hasMultipleItems;\n\t}\n\n\tclone(): IPlayQueueItemStore {\n\t\treturn this.playQueueStore.createItem(this.dto);\n\t}\n\n\tunselect(): void {\n\t\tthis.isSelected = false;\n\t}\n\n\ttoggleSelected(): void {\n\t\tthis.isSelected = !this.isSelected;\n\t}\n\n\tplay(): void {\n\t\tthis.playQueueStore.setCurrentItem(this);\n\t}\n\n\tremove(): Promise<void> {\n\t\treturn this.playQueueStore.removeItems([this]);\n\t}\n\n\tasync playFirst(): Promise<void> {\n\t\tawait this.playQueueStore.playFirst([this.clone()]);\n\t}\n\n\tasync playNext(): Promise<void> {\n\t\tawait this.playQueueStore.playNext([this.clone()]);\n\t}\n\n\tasync addToPlayQueue(): Promise<void> {\n\t\tawait this.playQueueStore.addItems([this.clone()]);\n\t}\n\n\tmoveToTop(): void {\n\t\tthis.playQueueStore.moveItem(this, 0);\n\t}\n\n\tmoveToBottom(): void {\n\t\tthis.playQueueStore.moveItem(\n\t\t\tthis,\n\t\t\tthis.playQueueStore.items.length - 1,\n\t\t);\n\t}\n\n\tremoveToTop(): Promise<void> {\n\t\treturn this.playQueueStore.removeItemsAbove(this);\n\t}\n\n\tremoveOthers(): Promise<void> {\n\t\treturn this.playQueueStore.removeOtherItems(this);\n\t}\n}\n","import Ajv, { JSONSchemaType, ValidateFunction } from 'ajv';\n\nconst ajv = new Ajv({\n\tcoerceTypes: true,\n});\n\nexport function getOrAddSchema<T>(\n\tschema: JSONSchemaType<T>,\n\tkeyRef: string,\n): ValidateFunction<T> {\n\t// https://ajv.js.org/guide/managing-schemas.html#pre-adding-all-schemas-vs-adding-on-demand\n\tlet validate: ValidateFunction<T> | undefined;\n\tvalidate = ajv.getSchema(keyRef);\n\tif (validate === undefined) {\n\t\tajv.addSchema(schema, keyRef);\n\t\tvalidate = ajv.getSchema(keyRef);\n\t}\n\n\tif (validate === undefined || validate.schema !== schema) {\n\t\tthrow new Error(\n\t\t\t`Invalid schema. Expected: '${JSON.stringify(\n\t\t\t\tschema,\n\t\t\t)}', but got '${JSON.stringify(validate?.schema)}'.`,\n\t\t);\n\t}\n\n\treturn validate;\n}\n","import { JSONSchemaType } from 'ajv';\n\nimport { getOrAddSchema } from '@/features/media-player/stores/getOrAddSchema';\nimport { PlayQueueItemDto } from '@/features/media-player/stores/IPlayQueueItemStore';\nimport { RepeatMode } from '@/features/media-player/stores/RepeatMode';\n\nexport interface PlayQueueLocalStorageState {\n\tversion?: '1.0';\n\trepeat?: RepeatMode;\n\tshuffle?: boolean;\n\titems?: PlayQueueItemDto[];\n\tcurrentIndex?: number;\n}\n\nconst PlayQueueLocalStorageStateSchema: JSONSchemaType<PlayQueueLocalStorageState> =\n\t{\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tversion: {\n\t\t\t\ttype: 'string',\n\t\t\t\tnullable: true,\n\t\t\t},\n\t\t\trepeat: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: Object.values(RepeatMode),\n\t\t\t\tnullable: true,\n\t\t\t},\n\t\t\tshuffle: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tnullable: true,\n\t\t\t},\n\t\t\titems: {\n\t\t\t\ttype: 'array',\n\t\t\t\tnullable: true,\n\t\t\t\titems: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\turl: {\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttype: {\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvideoId: {\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttitle: {\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\trequired: ['url', 'type', 'videoId', 'title'],\n\t\t\t\t},\n\t\t\t},\n\t\t\tcurrentIndex: {\n\t\t\t\ttype: 'integer',\n\t\t\t\tnullable: true,\n\t\t\t},\n\t\t},\n\t};\n\nexport const validatePlayQueueLocalStorageState = getOrAddSchema(\n\tPlayQueueLocalStorageStateSchema,\n\t'PlayQueueStore',\n);\n","import { LocalStorageStateStore } from '@aigamo/route-sphere';\nimport { pull } from 'lodash-es';\nimport { action, computed, observable } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\nimport {\n\tIPlayQueueItemStore,\n\tPlayQueueItemDto,\n} from '@/features/media-player/stores/IPlayQueueItemStore';\nimport { IPlayQueueStore } from '@/features/media-player/stores/IPlayQueueStore';\nimport { PlayQueueItemStore } from '@/features/media-player/stores/PlayQueueItemStore';\nimport {\n\tPlayQueueLocalStorageState,\n\tvalidatePlayQueueLocalStorageState,\n} from '@/features/media-player/stores/PlayQueueLocalStorageState';\nimport { RepeatMode } from '@/features/media-player/stores/RepeatMode';\n\nexport class PlayQueueStore\n\timplements\n\t\tIPlayQueueStore,\n\t\tLocalStorageStateStore<PlayQueueLocalStorageState>\n{\n\tinteracted = false;\n\titems: IPlayQueueItemStore[] = [];\n\tcurrentId: number | undefined;\n\trepeat = RepeatMode.Off;\n\tshuffle = false;\n\n\tconstructor(readonly observableStateProvider: IObservableStateProvider) {\n\t\tobservableStateProvider.makeObservable(this, {\n\t\t\tinteracted: observable,\n\t\t\titems: observable,\n\t\t\tcurrentId: observable,\n\t\t\trepeat: observable,\n\t\t\tshuffle: observable,\n\t\t\tlocalStorageState: computed.struct,\n\t\t\tisEmpty: computed,\n\t\t\tcurrentItem: computed,\n\t\t\tcanPlay: computed,\n\t\t\tcanPause: computed,\n\t\t\thasMultipleItems: computed,\n\t\t\tcurrentIndex: computed,\n\t\t\thasPreviousItem: computed,\n\t\t\thasNextItem: computed,\n\t\t\tisLastItem: computed,\n\t\t\tselectedItems: computed,\n\t\t\tallItemsSelected: computed,\n\t\t\tselectedItemsOrAllItems: computed,\n\t\t\tsetItems: action,\n\t\t\tinteract: action,\n\t\t\tclear: action.bound,\n\t\t\tunselectAll: action,\n\t\t\tsetCurrentItem: action,\n\t\t\tsetNextItems: action,\n\t\t\tclearAndSetItems: action,\n\t\t\tplayNext: action,\n\t\t\tplaySelectedItemsNext: action.bound,\n\t\t\taddItems: action,\n\t\t\taddSelectedItems: action.bound,\n\t\t\tplayFirst: action,\n\t\t\tmoveItem: action,\n\t\t\tremoveItems: action,\n\t\t\tremoveSelectedItems: action.bound,\n\t\t\tremoveOtherItems: action,\n\t\t\tremoveItemsAbove: action,\n\t\t\ttoggleRepeat: action.bound,\n\t\t\ttoggleShuffle: action.bound,\n\t\t\tprevious: action,\n\t\t\tnext: action.bound,\n\t\t\tgoToFirst: action,\n\t\t});\n\t}\n\n\tcreateItem(dto: PlayQueueItemDto): IPlayQueueItemStore {\n\t\treturn PlayQueueItemStore.fromDto(\n\t\t\tthis.observableStateProvider,\n\t\t\tthis,\n\t\t\tdto,\n\t\t);\n\t}\n\n\tget localStorageState(): PlayQueueLocalStorageState {\n\t\treturn {\n\t\t\tversion: '1.0',\n\t\t\trepeat: this.repeat,\n\t\t\tshuffle: this.shuffle,\n\t\t\titems: this.items.map((item) => item.dto),\n\t\t\tcurrentIndex: this.currentIndex,\n\t\t};\n\t}\n\tset localStorageState(value: PlayQueueLocalStorageState) {\n\t\tthis.repeat = value.repeat ?? RepeatMode.Off;\n\t\tthis.shuffle = value.shuffle ?? false;\n\t\tthis.items = value.items?.map((item) => this.createItem(item)) ?? [];\n\t\tthis.currentIndex = value.currentIndex;\n\t}\n\n\tvalidateLocalStorageState(\n\t\tlocalStorageState: any,\n\t): localStorageState is PlayQueueLocalStorageState {\n\t\treturn validatePlayQueueLocalStorageState(localStorageState);\n\t}\n\n\tget isEmpty(): boolean {\n\t\treturn this.items.length === 0;\n\t}\n\n\tget currentItem(): IPlayQueueItemStore | undefined {\n\t\treturn this.items.find((item) => item.id === this.currentId);\n\t}\n\n\tget canPlay(): boolean {\n\t\treturn this.currentItem !== undefined;\n\t}\n\n\tget canPause(): boolean {\n\t\treturn this.currentItem !== undefined;\n\t}\n\n\tget hasMultipleItems(): boolean {\n\t\treturn this.items.length > 1;\n\t}\n\n\tget currentIndex(): number | undefined {\n\t\treturn this.currentId !== undefined\n\t\t\t? this.items.findIndex((item) => item.id === this.currentId)\n\t\t\t: undefined;\n\t}\n\tset currentIndex(value: number | undefined) {\n\t\tthis.currentId =\n\t\t\tvalue !== undefined ? this.items.at(value)?.id : undefined;\n\t}\n\n\tget hasPreviousItem(): boolean {\n\t\treturn (\n\t\t\tthis.hasMultipleItems &&\n\t\t\tthis.currentIndex !== undefined &&\n\t\t\tthis.currentIndex > 0\n\t\t);\n\t}\n\n\tget hasNextItem(): boolean {\n\t\treturn (\n\t\t\tthis.hasMultipleItems &&\n\t\t\tthis.currentIndex !== undefined &&\n\t\t\tthis.currentIndex < this.items.length - 1\n\t\t);\n\t}\n\n\tget isLastItem(): boolean {\n\t\treturn (\n\t\t\tthis.currentIndex !== undefined &&\n\t\t\tthis.currentIndex === this.items.length - 1\n\t\t);\n\t}\n\n\tget selectedItems(): IPlayQueueItemStore[] {\n\t\treturn this.items.filter((item) => item.isSelected);\n\t}\n\n\tget allItemsSelected(): boolean {\n\t\treturn this.selectedItems.length === this.items.length;\n\t}\n\tset allItemsSelected(value: boolean) {\n\t\tfor (const item of this.items) {\n\t\t\titem.isSelected = value;\n\t\t}\n\t}\n\n\tget selectedItemsOrAllItems(): IPlayQueueItemStore[] {\n\t\treturn this.selectedItems.length > 0 ? this.selectedItems : this.items;\n\t}\n\n\tsetItems(value: IPlayQueueItemStore[]): void {\n\t\tthis.items = value;\n\t}\n\n\tinteract(): void {\n\t\tthis.interacted = true;\n\t}\n\n\tclear(): void {\n\t\tthis.interact();\n\n\t\tthis.currentIndex = undefined;\n\t\tthis.items = [];\n\t}\n\n\tunselectAll(): void {\n\t\tfor (const item of this.items) {\n\t\t\titem.unselect();\n\t\t}\n\t}\n\n\tsetCurrentItem(item: IPlayQueueItemStore | undefined): void {\n\t\tthis.interact();\n\n\t\tthis.currentId = item?.id;\n\t}\n\n\tsetNextItems(items: IPlayQueueItemStore[]): void {\n\t\tif (this.currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.items.splice(this.currentIndex + 1, 0, ...items);\n\t}\n\n\tclearAndSetItems(items: IPlayQueueItemStore[]): void {\n\t\tthis.clear();\n\n\t\tthis.setCurrentItem(items[0]);\n\n\t\tthis.setNextItems(items);\n\t}\n\n\tasync playNext(items: IPlayQueueItemStore[]): Promise<void> {\n\t\tif (this.isEmpty) {\n\t\t\tthis.clearAndSetItems(items);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setNextItems(items);\n\t}\n\n\tasync playSelectedItemsNext(): Promise<void> {\n\t\tawait this.playNext(\n\t\t\tthis.selectedItemsOrAllItems.map((item) => item.clone()),\n\t\t);\n\n\t\tthis.unselectAll();\n\t}\n\n\tasync addItems(items: IPlayQueueItemStore[]): Promise<void> {\n\t\tif (this.isEmpty) {\n\t\t\tthis.clearAndSetItems(items);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.items.push(...items);\n\t}\n\n\tasync addSelectedItems(): Promise<void> {\n\t\tawait this.addItems(\n\t\t\tthis.selectedItemsOrAllItems.map((item) => item.clone()),\n\t\t);\n\n\t\tthis.unselectAll();\n\t}\n\n\tasync playFirst(items: IPlayQueueItemStore[]): Promise<void> {\n\t\tif (this.isEmpty) {\n\t\t\tthis.clearAndSetItems(items);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { currentIndex } = this;\n\t\tif (currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.interact();\n\n\t\tthis.items.splice(currentIndex, 0, ...items);\n\t\tthis.currentIndex = currentIndex;\n\t}\n\n\tmoveItem(item: IPlayQueueItemStore, index: number): void {\n\t\tconst element = this.items.splice(this.items.indexOf(item), 1)[0];\n\t\tthis.items.splice(index, 0, element);\n\t}\n\n\tasync removeItems(items: IPlayQueueItemStore[]): Promise<void> {\n\t\t// Note: We need to remove the current (if any) and other (previous and/or next) items separately,\n\t\t// so that the current index can be set properly even if the current item was removed.\n\n\t\t// Capture the current item.\n\t\tconst { currentItem } = this;\n\n\t\t// First, remove items that are not equal to the current one.\n\t\tpull(this.items, ...items.filter((item) => item !== currentItem));\n\n\t\t// Capture the current index.\n\t\tconst { currentIndex, isLastItem } = this;\n\n\t\t// Then, remove the current item if any.\n\t\tpull(\n\t\t\tthis.items,\n\t\t\titems.find((item) => item === currentItem),\n\t\t);\n\n\t\t// If the current item differs from the captured one, then it means that the current item was removed from the play queue.\n\t\tif (this.currentItem !== currentItem) {\n\t\t\tthis.interact();\n\n\t\t\tif (isLastItem) {\n\t\t\t\t// Start over the playlist from the beginning.\n\t\t\t\tawait this.goToFirst();\n\t\t\t} else {\n\t\t\t\t// Set the current index to the captured one.\n\t\t\t\tthis.currentIndex = currentIndex;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync removeSelectedItems(): Promise<void> {\n\t\tawait this.removeItems(this.selectedItemsOrAllItems);\n\n\t\tthis.unselectAll();\n\t}\n\n\tasync removeOtherItems(item: IPlayQueueItemStore): Promise<void> {\n\t\tconst itemId = item.id;\n\t\treturn this.removeItems(\n\t\t\tthis.items.filter((item) => item.id !== itemId),\n\t\t);\n\t}\n\n\tasync removeItemsAbove(item: IPlayQueueItemStore): Promise<void> {\n\t\tconst itemIndex = this.items.indexOf(item);\n\t\treturn this.removeItems(\n\t\t\tthis.items.filter((_, index) => index < itemIndex),\n\t\t);\n\t}\n\n\ttoggleRepeat(): void {\n\t\tswitch (this.repeat) {\n\t\t\tcase RepeatMode.Off:\n\t\t\t\tthis.repeat = RepeatMode.All;\n\t\t\t\tbreak;\n\t\t\tcase RepeatMode.All:\n\t\t\t\tthis.repeat = RepeatMode.One;\n\t\t\t\tbreak;\n\t\t\tcase RepeatMode.One:\n\t\t\t\tthis.repeat = RepeatMode.Off;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\ttoggleShuffle(): void {\n\t\tthis.shuffle = !this.shuffle;\n\t}\n\n\tasync previous(): Promise<void> {\n\t\tif (this.currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.hasPreviousItem) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.interact();\n\n\t\tthis.currentIndex--;\n\t}\n\n\tasync next(): Promise<void> {\n\t\tif (this.currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.hasNextItem) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.interact();\n\n\t\tthis.currentIndex++;\n\t}\n\n\tasync goToFirst(): Promise<void> {\n\t\tif (this.currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.currentIndex = 0;\n\t}\n}\n","import { useNostalgicDiva } from '@aigamo/nostalgic-diva';\nimport { reaction } from 'mobx';\nimport {\n\tcreateContext,\n\tReactElement,\n\tReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseState,\n} from 'react';\n\nimport { MobXObservableStateProvider } from '@/features/media-player/stores/MobXObservableStateProvider';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\n// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\nconst PlayQueueStoreContext = createContext<PlayQueueStore>(undefined!);\n\ninterface PlayQueueStoreProviderProps {\n\tchildren?: ReactNode;\n}\n\nexport const PlayQueueStoreProvider = ({\n\tchildren,\n}: PlayQueueStoreProviderProps): ReactElement => {\n\tconst [playQueueStore] = useState(\n\t\t() => new PlayQueueStore(new MobXObservableStateProvider()),\n\t);\n\n\tconst diva = useNostalgicDiva();\n\n\tuseEffect(() => {\n\t\treturn reaction(\n\t\t\t() => playQueueStore.currentItem,\n\t\t\tasync (currentItem, previousItem) => {\n\t\t\t\tif (currentItem === undefined || previousItem === undefined) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tcurrentItem.type === previousItem.type &&\n\t\t\t\t\tcurrentItem.videoId === previousItem.videoId\n\t\t\t\t) {\n\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t}, [playQueueStore, diva]);\n\n\treturn (\n\t\t<PlayQueueStoreContext.Provider value={playQueueStore}>\n\t\t\t{children}\n\t\t</PlayQueueStoreContext.Provider>\n\t);\n};\n\nexport const usePlayQueueStore = (): PlayQueueStore => {\n\treturn useContext(PlayQueueStoreContext);\n};\n","import { EuiPageTemplate, EuiSpacer } from '@elastic/eui';\nimport { observer } from 'mobx-react-lite';\nimport { ReactElement, ReactNode } from 'react';\n\nimport { bottomBarHeight } from '@/features/media-player/components/BottomBar';\nimport { miniPlayerSize } from '@/features/media-player/components/MiniPlayer';\nimport { usePlayQueueStore } from '@/features/media-player/components/PlayQueueStoreContext';\n\ninterface MediaPlayerLayoutProps {\n\tchildren?: ReactNode;\n}\n\nexport const MediaPlayerLayout = observer(\n\t({ children }: MediaPlayerLayoutProps): ReactElement => {\n\t\tconst playQueueStore = usePlayQueueStore();\n\n\t\treturn (\n\t\t\t<EuiPageTemplate\n\t\t\t\tpanelled\n\t\t\t\tstyle={{\n\t\t\t\t\tminBlockSize: `max(460px, 100vh - ${bottomBarHeight}px)`,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{children}\n\n\t\t\t\t{!playQueueStore.isEmpty && (\n\t\t\t\t\t<EuiSpacer style={{ blockSize: miniPlayerSize.height }} />\n\t\t\t\t)}\n\t\t\t</EuiPageTemplate>\n\t\t);\n\t},\n);\n","import { TimeEvent } from '@aigamo/nostalgic-diva';\nimport { action, observable } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\n\nexport class PlayerStore {\n\tplaying = false;\n\tpercent = 0;\n\tseeking = false;\n\n\tconstructor(observableStateProvider: IObservableStateProvider) {\n\t\tobservableStateProvider.makeObservable(this, {\n\t\t\tplaying: observable,\n\t\t\tpercent: observable,\n\t\t\tseeking: observable,\n\t\t\tsetPlaying: action,\n\t\t\tsetPercent: action,\n\t\t\tsetSeeking: action,\n\t\t\tonPlay: action.bound,\n\t\t\tonPause: action.bound,\n\t\t\tonEnded: action.bound,\n\t\t\tonTimeUpdate: action.bound,\n\t\t});\n\t}\n\n\tsetPlaying(value: boolean): void {\n\t\tthis.playing = value;\n\t}\n\n\tsetPercent(value: number): void {\n\t\tthis.percent = value;\n\t}\n\n\tsetSeeking(value: boolean): void {\n\t\tthis.seeking = value;\n\t}\n\n\tonPlay(): void {\n\t\tthis.playing = true;\n\t}\n\n\tonPause(): void {\n\t\tthis.playing = false;\n\t}\n\n\tonEnded(): void {\n\t\tthis.playing = false;\n\t}\n\n\tonTimeUpdate({ percent }: TimeEvent): void {\n\t\tif (percent !== undefined) {\n\t\t\tif (!this.seeking) {\n\t\t\t\tthis.percent = percent;\n\t\t\t}\n\t\t}\n\n\t\t// TODO\n\t}\n}\n","import {\n\tcreateContext,\n\tReactElement,\n\tReactNode,\n\tuseContext,\n\tuseState,\n} from 'react';\n\nimport { MobXObservableStateProvider } from '@/features/media-player/stores/MobXObservableStateProvider';\nimport { PlayerStore } from '@/features/media-player/stores/PlayerStore';\n\n// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\nconst PlayerStoreContext = createContext<PlayerStore>(undefined!);\n\ninterface PlayerStoreProviderProps {\n\tchildren?: ReactNode;\n}\n\nexport const PlayerStoreProvider = ({\n\tchildren,\n}: PlayerStoreProviderProps): ReactElement => {\n\tconst [playerStore] = useState(\n\t\t() => new PlayerStore(new MobXObservableStateProvider()),\n\t);\n\n\treturn (\n\t\t<PlayerStoreContext.Provider value={playerStore}>\n\t\t\t{children}\n\t\t</PlayerStoreContext.Provider>\n\t);\n};\n\nexport const usePlayerStore = (): PlayerStore => {\n\treturn useContext(PlayerStoreContext);\n};\n","import { AnnotationsMap } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\n\nexport class ObservableStateProvider implements IObservableStateProvider {\n\tmakeObservable<\n\t\tT extends object,\n\t\tAdditionalKeys extends PropertyKey = never,\n\t>(target: T, annotations?: AnnotationsMap<T, AdditionalKeys>): T {\n\t\treturn target;\n\t}\n}\n"],"names":["RepeatMode","bottomBarHeight","SeekBar","observer","playerStore","diva","useNostalgicDiva","handleChange","useCallback","e","percent","handleMouseDown","handleMouseUp","duration","React","EuiRange","VolumePopover","memo","button","isOpen","closePopover","value","setValue","useState","useLayoutEffect","volume","EuiPopover","EuiFormRow","EuiFlexGroup","EuiButtonIcon","Speaker2Regular","MoreOptionsContextMenu","playQueueStore","handleClickSkipBack10","currentTime","handleClickSkipForward30","handleClickPlaybackRate","playbackRate","handleClickRemoveFromPlayQueue","panels","useMemo","EuiIcon","TopSpeedRegular","SkipBack10Regular","SkipForward30Regular","DismissRegular","EuiContextMenu","MoreOptionsPopover","repeatIconTypes","ArrowRepeatAllOffFilled","ArrowRepeatAllFilled","ArrowRepeat1Filled","BottomBarCenterControls","handlePrevious","ArrowShuffleFilled","ArrowShuffleOffFilled","PreviousFilled","PauseFilled","PlayFilled","NextFilled","VolumeButton","isVolumePopoverOpen","setIsVolumePopoverOpen","toggleVolumePopover","MoreOptionsButton","isMoreOptionsPopoverOpen","setIsMoreOptionsPopoverOpen","toggleMoreOptionsPopover","MoreHorizontalFilled","BottomBarRightControls","BottomBar","EuiBottomBar","EuiFlexItem","AddVideoModal","onCancel","onSave","url","setUrl","title","setTitle","loading","setLoading","EuiModal","EuiModalHeader","EuiModalHeaderTitle","EuiModalBody","EuiForm","EuiFieldText","EuiModalFooter","EuiButtonEmpty","EuiButton","isNoembedResult","AddVideoButton","addVideoModalOpen","setAddVideoModalOpen","handleSave","videoService","findVideoService","videoId","jsonData","AddRegular","PlayQueueTableHeader","euiTheme","useEuiTheme","EuiTableHeader","EuiTableHeaderCellCheckbox","EuiCheckbox","EuiTableHeaderCell","PlayQueueTableRowContextMenuPanel","item","ContextMenuItem","onClick","props","handleClick","EuiContextMenuItem","EuiContextMenuPanel","EuiHorizontalRule","ArrowUploadRegular","ArrowDownloadRegular","PlayQueueTableRowPopover","setIsOpen","togglePopover","PlayQueueTableRowActionsCell","EuiTableRowCell","PlayRegular","videoServiceIcons","PlayQueueTableRow","EuiTableRow","EuiTableRowCellCheckbox","EuiLink","PlayQueueTableBody","ReactSortable","items","PlayQueueTable","EuiTable","DeveloperToolsButton","isFlyoutVisible","setIsFlyoutVisible","EuiFlyout","EuiCodeBlock","PlayQueue","DeleteRegular","EuiSpacer","HydrangeanDiva","EuiPageTemplate","miniPlayerSize","MiniPlayer","handleLoaded","handleEnded","options","NostalgicDiva","MobXObservableStateProvider","target","annotations","makeObservable","_PlayQueueItemStore","observableStateProvider","dto","__publicField","observable","computed","action","PlayQueueItemStore","ajv","Ajv","getOrAddSchema","schema","keyRef","validate","PlayQueueLocalStorageStateSchema","validatePlayQueueLocalStorageState","PlayQueueStore","_a","localStorageState","currentIndex","index","element","currentItem","pull","isLastItem","itemId","itemIndex","_","PlayQueueStoreContext","createContext","PlayQueueStoreProvider","children","useEffect","reaction","previousItem","usePlayQueueStore","useContext","MediaPlayerLayout","PlayerStore","PlayerStoreContext","PlayerStoreProvider","usePlayerStore","ObservableStateProvider"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/features/media-player/stores/RepeatMode.ts","../src/features/media-player/components/BottomBar.tsx","../src/features/media-player/components/AddVideoButton.tsx","../src/features/media-player/components/PlayQueueTable.tsx","../src/features/media-player/components/HydrangeanDiva.tsx","../src/features/media-player/components/MiniPlayer.tsx","../src/features/media-player/stores/MobXObservableStateProvider.ts","../src/features/media-player/stores/PlayQueueItemStore.ts","../src/features/media-player/stores/getOrAddSchema.ts","../src/features/media-player/stores/PlayQueueLocalStorageState.ts","../src/features/media-player/stores/PlayQueueStore.ts","../src/features/media-player/components/PlayQueueStoreContext.tsx","../src/features/media-player/components/MediaPlayerLayout.tsx","../src/features/media-player/stores/PlayerStore.ts","../src/features/media-player/components/PlayerStoreContext.tsx","../src/features/media-player/stores/ObservableStateProvider.ts"],"sourcesContent":["export enum RepeatMode {\n\tOff = 'Off',\n\tAll = 'All',\n\tOne = 'One',\n}\n","import { useNostalgicDiva } from '@aigamo/nostalgic-diva';\nimport {\n\tEuiBottomBar,\n\tEuiButtonIcon,\n\tEuiContextMenu,\n\tEuiContextMenuPanelDescriptor,\n\tEuiFlexGroup,\n\tEuiFlexItem,\n\tEuiFormRow,\n\tEuiIcon,\n\tEuiPopover,\n\tEuiRange,\n\tIconType,\n} from '@elastic/eui';\nimport { _SingleRangeChangeEvent } from '@elastic/eui/src/components/form/range/types';\nimport {\n\tArrowRepeat1Filled,\n\tArrowRepeatAllFilled,\n\tArrowRepeatAllOffFilled,\n\tArrowShuffleFilled,\n\tArrowShuffleOffFilled,\n\tDismissRegular,\n\tMoreHorizontalFilled,\n\tNextFilled,\n\tPauseFilled,\n\tPlayFilled,\n\tPreviousFilled,\n\tSkipBack10Regular,\n\tSkipForward30Regular,\n\tSpeaker2Regular,\n\tTopSpeedRegular,\n} from '@fluentui/react-icons';\nimport { observer } from 'mobx-react-lite';\nimport React, {\n\tmemo,\n\tReactElement,\n\tReactNode,\n\tuseCallback,\n\tuseLayoutEffect,\n\tuseMemo,\n\tuseState,\n} from 'react';\n\nimport { PlayerStore } from '@/features/media-player/stores/PlayerStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\nimport { RepeatMode } from '@/features/media-player/stores/RepeatMode';\n\nexport const bottomBarHeight = 80;\n\ninterface SeekBarProps {\n\tplayerStore: PlayerStore;\n}\n\nconst SeekBar = observer(({ playerStore }: SeekBarProps): ReactElement => {\n\tconst diva = useNostalgicDiva();\n\n\tconst handleChange = useCallback(\n\t\t(e: _SingleRangeChangeEvent) => {\n\t\t\tconst percent = Number(e.currentTarget.value) / 100;\n\t\t\tplayerStore.setPercent(percent);\n\t\t},\n\t\t[playerStore],\n\t);\n\n\tconst handleMouseDown = useCallback(\n\t\t(e: React.MouseEvent<HTMLInputElement>) => {\n\t\t\tif (e.button === 0) {\n\t\t\t\tplayerStore.setSeeking(true);\n\t\t\t}\n\t\t},\n\t\t[playerStore],\n\t);\n\n\tconst handleMouseUp = useCallback(\n\t\tasync (e: React.MouseEvent<HTMLInputElement>) => {\n\t\t\tif (e.button === 0) {\n\t\t\t\tconst percent = Number(e.currentTarget.value) / 100;\n\n\t\t\t\tplayerStore.setSeeking(false);\n\n\t\t\t\tconst duration = await diva.getDuration();\n\t\t\t\tif (duration !== undefined) {\n\t\t\t\t\tawait diva.setCurrentTime(duration * percent);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[playerStore, diva],\n\t);\n\n\treturn (\n\t\t<EuiRange\n\t\t\tmin={0}\n\t\t\tmax={100}\n\t\t\tstep={0.0000001}\n\t\t\tvalue={playerStore.percent * 100}\n\t\t\tonChange={handleChange}\n\t\t\tonMouseDown={handleMouseDown}\n\t\t\tonMouseUp={handleMouseUp}\n\t\t\tfullWidth\n\t\t\tshowRange\n\t\t\tcss={{ blockSize: 32 }}\n\t\t/>\n\t);\n});\n\ninterface VolumePopoverProps {\n\tbutton?: NonNullable<ReactNode>;\n\tisOpen: boolean;\n\tclosePopover: () => void;\n}\n\nconst VolumePopover = memo(\n\t({ button, isOpen, closePopover }: VolumePopoverProps): ReactElement => {\n\t\tconst [value, setValue] = useState('0');\n\n\t\tconst diva = useNostalgicDiva();\n\n\t\tuseLayoutEffect(() => {\n\t\t\tif (isOpen) {\n\t\t\t\tvoid diva.getVolume().then((volume) => {\n\t\t\t\t\tif (volume !== undefined) {\n\t\t\t\t\t\tsetValue(Math.floor(volume * 100).toString());\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}, [isOpen, diva]);\n\n\t\tconst handleChange = useCallback(\n\t\t\tasync (e: _SingleRangeChangeEvent): Promise<void> => {\n\t\t\t\tsetValue(e.currentTarget.value);\n\n\t\t\t\tawait diva.setVolume(Number(e.currentTarget.value) / 100);\n\t\t\t},\n\t\t\t[diva],\n\t\t);\n\n\t\treturn (\n\t\t\t<EuiPopover\n\t\t\t\tbutton={button}\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tclosePopover={closePopover}\n\t\t\t\tanchorPosition=\"upRight\"\n\t\t\t>\n\t\t\t\t<EuiFormRow>\n\t\t\t\t\t<EuiFlexGroup\n\t\t\t\t\t\tresponsive={false}\n\t\t\t\t\t\tgutterSize=\"s\"\n\t\t\t\t\t\tjustifyContent=\"center\"\n\t\t\t\t\t\talignItems=\"center\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\t\ttitle=\"Mute\" /* LOC */\n\t\t\t\t\t\t\taria-label=\"Mute\" /* LOC */\n\t\t\t\t\t\t\ticonType={Speaker2Regular}\n\t\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<EuiRange\n\t\t\t\t\t\t\tmin={0}\n\t\t\t\t\t\t\tmax={100}\n\t\t\t\t\t\t\tstep={1}\n\t\t\t\t\t\t\tvalue={value}\n\t\t\t\t\t\t\tonChange={handleChange}\n\t\t\t\t\t\t\tcss={{ blockSize: 32 }}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</EuiFlexGroup>\n\t\t\t\t</EuiFormRow>\n\t\t\t</EuiPopover>\n\t\t);\n\t},\n);\n\ninterface MoreOptionsContextMenuProps {\n\tplayQueueStore: PlayQueueStore;\n\tclosePopover: () => void;\n}\n\nconst MoreOptionsContextMenu = memo(\n\t({\n\t\tplayQueueStore,\n\t\tclosePopover,\n\t}: MoreOptionsContextMenuProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\tconst handleClickSkipBack10 = useCallback(async () => {\n\t\t\tconst currentTime = await diva.getCurrentTime();\n\n\t\t\tif (currentTime !== undefined) {\n\t\t\t\tawait diva.setCurrentTime(currentTime - 10);\n\t\t\t}\n\n\t\t\tclosePopover();\n\t\t}, [diva, closePopover]);\n\n\t\tconst handleClickSkipForward30 = useCallback(async () => {\n\t\t\tconst currentTime = await diva.getCurrentTime();\n\n\t\t\tif (currentTime !== undefined) {\n\t\t\t\tawait diva.setCurrentTime(currentTime + 30);\n\t\t\t}\n\n\t\t\tclosePopover();\n\t\t}, [diva, closePopover]);\n\n\t\tconst handleClickPlaybackRate = useCallback(\n\t\t\tasync (playbackRate: number): Promise<void> => {\n\t\t\t\tawait diva.setPlaybackRate(playbackRate);\n\n\t\t\t\tclosePopover();\n\t\t\t},\n\t\t\t[diva, closePopover],\n\t\t);\n\n\t\tconst handleClickRemoveFromPlayQueue =\n\t\t\tuseCallback(async (): Promise<void> => {\n\t\t\t\tif (playQueueStore.currentItem !== undefined) {\n\t\t\t\t\tawait playQueueStore.removeItems([\n\t\t\t\t\t\tplayQueueStore.currentItem,\n\t\t\t\t\t]);\n\t\t\t\t}\n\n\t\t\t\tclosePopover();\n\t\t\t}, [playQueueStore, closePopover]);\n\n\t\tconst [playbackRate] = useState<number>();\n\n\t\tconst panels = useMemo(\n\t\t\t(): EuiContextMenuPanelDescriptor[] => [\n\t\t\t\t{\n\t\t\t\t\tid: 0,\n\t\t\t\t\titems: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Speed' /* LOC */,\n\t\t\t\t\t\t\ticon: <EuiIcon type={TopSpeedRegular} size=\"m\" />,\n\t\t\t\t\t\t\tpanel: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Skip back 10 seconds' /* LOC */,\n\t\t\t\t\t\t\ticon: <EuiIcon type={SkipBack10Regular} size=\"m\" />,\n\t\t\t\t\t\t\tonClick: handleClickSkipBack10,\n\t\t\t\t\t\t\tdisabled: playQueueStore.isEmpty,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Skip forward 30 seconds' /* LOC */,\n\t\t\t\t\t\t\ticon: (\n\t\t\t\t\t\t\t\t<EuiIcon type={SkipForward30Regular} size=\"m\" />\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tonClick: handleClickSkipForward30,\n\t\t\t\t\t\t\tdisabled: playQueueStore.isEmpty,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tisSeparator: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: 'Remove from play queue' /* LOC */,\n\t\t\t\t\t\t\ticon: <EuiIcon type={DismissRegular} size=\"m\" />,\n\t\t\t\t\t\t\tonClick: handleClickRemoveFromPlayQueue,\n\t\t\t\t\t\t\tdisabled: playQueueStore.isEmpty,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: 1,\n\t\t\t\t\ttitle: 'Speed' /* LOC */,\n\t\t\t\t\titems: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2].map(\n\t\t\t\t\t\t(value) => ({\n\t\t\t\t\t\t\tname: value.toString(),\n\t\t\t\t\t\t\tonClick: (): Promise<void> =>\n\t\t\t\t\t\t\t\thandleClickPlaybackRate(value),\n\t\t\t\t\t\t\ticon: value === playbackRate ? 'check' : 'empty',\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t],\n\t\t\t[\n\t\t\t\tplayQueueStore,\n\t\t\t\thandleClickSkipBack10,\n\t\t\t\thandleClickSkipForward30,\n\t\t\t\thandleClickRemoveFromPlayQueue,\n\t\t\t\thandleClickPlaybackRate,\n\t\t\t\tplaybackRate,\n\t\t\t],\n\t\t);\n\n\t\treturn <EuiContextMenu initialPanelId={0} panels={panels} />;\n\t},\n);\n\ninterface MoreOptionsPopoverProps {\n\tplayQueueStore: PlayQueueStore;\n\tbutton?: NonNullable<ReactNode>;\n\tisOpen: boolean;\n\tclosePopover: () => void;\n}\n\nconst MoreOptionsPopover = memo(\n\t({\n\t\tplayQueueStore,\n\t\tbutton,\n\t\tisOpen,\n\t\tclosePopover,\n\t}: MoreOptionsPopoverProps): ReactElement => {\n\t\treturn (\n\t\t\t<EuiPopover\n\t\t\t\tbutton={button}\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tclosePopover={closePopover}\n\t\t\t\tpanelPaddingSize=\"none\"\n\t\t\t\tanchorPosition=\"upRight\"\n\t\t\t>\n\t\t\t\t<MoreOptionsContextMenu\n\t\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\t\tclosePopover={closePopover}\n\t\t\t\t/>\n\t\t\t</EuiPopover>\n\t\t);\n\t},\n);\n\nconst repeatIconTypes: Record<RepeatMode, IconType> = {\n\t[RepeatMode.Off]: ArrowRepeatAllOffFilled,\n\t[RepeatMode.All]: ArrowRepeatAllFilled,\n\t[RepeatMode.One]: ArrowRepeat1Filled,\n};\n\ninterface BottomBarCenterControlsProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst BottomBarCenterControls = observer(\n\t({\n\t\tplayerStore,\n\t\tplayQueueStore,\n\t}: BottomBarCenterControlsProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\tconst handlePrevious = useCallback(async () => {\n\t\t\tif (playQueueStore.hasPreviousItem) {\n\t\t\t\tconst currentTime = await diva.getCurrentTime();\n\t\t\t\tif (currentTime === undefined || currentTime < 5) {\n\t\t\t\t\tawait playQueueStore.previous();\n\t\t\t\t} else {\n\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t}\n\t\t}, [playQueueStore, diva]);\n\n\t\treturn (\n\t\t\t<EuiFlexGroup\n\t\t\t\tresponsive={false}\n\t\t\t\tgutterSize=\"s\"\n\t\t\t\tjustifyContent=\"center\"\n\t\t\t\talignItems=\"center\"\n\t\t\t>\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle={\n\t\t\t\t\t\t`Shuffle: ${\n\t\t\t\t\t\t\tplayQueueStore.shuffle ? 'On' : 'Off'\n\t\t\t\t\t\t}` /* LOC */\n\t\t\t\t\t}\n\t\t\t\t\taria-label={\n\t\t\t\t\t\t`Shuffle: ${\n\t\t\t\t\t\t\tplayQueueStore.shuffle ? 'On' : 'Off'\n\t\t\t\t\t\t}` /* LOC */\n\t\t\t\t\t}\n\t\t\t\t\ticonType={\n\t\t\t\t\t\tplayQueueStore.shuffle\n\t\t\t\t\t\t\t? ArrowShuffleFilled\n\t\t\t\t\t\t\t: ArrowShuffleOffFilled\n\t\t\t\t\t}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={playQueueStore.toggleShuffle}\n\t\t\t\t\tdisabled /* TODO: remove */\n\t\t\t\t/>\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle=\"Previous\" /* LOC */\n\t\t\t\t\taria-label=\"Previous\" /* LOC */\n\t\t\t\t\ticonType={PreviousFilled}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={handlePrevious}\n\t\t\t\t\tdisabled={playQueueStore.isEmpty}\n\t\t\t\t/>\n\t\t\t\t{playerStore.playing ? (\n\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\ttitle=\"Pause\" /* LOC */\n\t\t\t\t\t\taria-label=\"Pause\" /* LOC */\n\t\t\t\t\t\ticonType={PauseFilled}\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\t\tonClick={(): Promise<void> => diva.pause()}\n\t\t\t\t\t\tdisabled={!playQueueStore.canPlay}\n\t\t\t\t\t/>\n\t\t\t\t) : (\n\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\ttitle=\"Play\" /* LOC */\n\t\t\t\t\t\taria-label=\"Play\" /* LOC */\n\t\t\t\t\t\ticonType={PlayFilled}\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\t\tonClick={(): Promise<void> => diva.play()}\n\t\t\t\t\t\tdisabled={!playQueueStore.canPlay}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle=\"Next\" /* LOC */\n\t\t\t\t\taria-label=\"Next\" /* LOC */\n\t\t\t\t\ticonType={NextFilled}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={playQueueStore.next}\n\t\t\t\t\tdisabled={!playQueueStore.hasNextItem}\n\t\t\t\t/>\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle={\n\t\t\t\t\t\t`Repeat: ${\n\t\t\t\t\t\t\tplayQueueStore.repeat === RepeatMode.All\n\t\t\t\t\t\t\t\t? 'All'\n\t\t\t\t\t\t\t\t: playQueueStore.repeat === RepeatMode.One\n\t\t\t\t\t\t\t\t\t? 'One'\n\t\t\t\t\t\t\t\t\t: 'Off'\n\t\t\t\t\t\t}` /* LOC */\n\t\t\t\t\t}\n\t\t\t\t\taria-label={\n\t\t\t\t\t\t`Repeat: ${\n\t\t\t\t\t\t\tplayQueueStore.repeat === RepeatMode.All\n\t\t\t\t\t\t\t\t? 'All'\n\t\t\t\t\t\t\t\t: playQueueStore.repeat === RepeatMode.One\n\t\t\t\t\t\t\t\t\t? 'One'\n\t\t\t\t\t\t\t\t\t: 'Off'\n\t\t\t\t\t\t}` /* LOC */\n\t\t\t\t\t}\n\t\t\t\t\ticonType={repeatIconTypes[playQueueStore.repeat]}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={playQueueStore.toggleRepeat}\n\t\t\t\t/>\n\t\t\t</EuiFlexGroup>\n\t\t);\n\t},\n);\n\nconst VolumeButton = memo((): ReactElement => {\n\tconst [isVolumePopoverOpen, setIsVolumePopoverOpen] = useState(false);\n\n\tconst toggleVolumePopover = (): void =>\n\t\tsetIsVolumePopoverOpen(!isVolumePopoverOpen);\n\n\treturn (\n\t\t<VolumePopover\n\t\t\tbutton={\n\t\t\t\t<EuiButtonIcon\n\t\t\t\t\ttitle=\"Volume\" /* LOC */\n\t\t\t\t\taria-label=\"Volume\" /* LOC */\n\t\t\t\t\ticonType={Speaker2Regular}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\tonClick={toggleVolumePopover}\n\t\t\t\t/>\n\t\t\t}\n\t\t\tisOpen={isVolumePopoverOpen}\n\t\t\tclosePopover={(): void => setIsVolumePopoverOpen(false)}\n\t\t/>\n\t);\n});\n\ninterface MoreOptionsButtonProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst MoreOptionsButton = memo(\n\t({ playQueueStore }: MoreOptionsButtonProps): ReactElement => {\n\t\tconst [isMoreOptionsPopoverOpen, setIsMoreOptionsPopoverOpen] =\n\t\t\tuseState(false);\n\n\t\tconst toggleMoreOptionsPopover = (): void =>\n\t\t\tsetIsMoreOptionsPopoverOpen(!isMoreOptionsPopoverOpen);\n\n\t\treturn (\n\t\t\t<MoreOptionsPopover\n\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\tbutton={\n\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\ttitle=\"More options\" /* LOC */\n\t\t\t\t\t\taria-label=\"More options\" /* LOC */\n\t\t\t\t\t\ticonType={MoreHorizontalFilled}\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\ticonSize=\"l\"\n\t\t\t\t\t\tonClick={toggleMoreOptionsPopover}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\tisOpen={isMoreOptionsPopoverOpen}\n\t\t\t\tclosePopover={(): void => setIsMoreOptionsPopoverOpen(false)}\n\t\t\t/>\n\t\t);\n\t},\n);\n\ninterface BottomBarRightControlsProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst BottomBarRightControls = memo(\n\t({ playQueueStore }: BottomBarRightControlsProps): ReactElement => {\n\t\treturn (\n\t\t\t<EuiFlexGroup\n\t\t\t\tresponsive={false}\n\t\t\t\tgutterSize=\"s\"\n\t\t\t\tjustifyContent=\"flexEnd\"\n\t\t\t\talignItems=\"center\"\n\t\t\t>\n\t\t\t\t<VolumeButton />\n\t\t\t\t<MoreOptionsButton playQueueStore={playQueueStore} />\n\t\t\t</EuiFlexGroup>\n\t\t);\n\t},\n);\n\ninterface BottomBarProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const BottomBar = observer(\n\t({ playerStore, playQueueStore }: BottomBarProps): ReactElement => {\n\t\treturn (\n\t\t\t<EuiBottomBar paddingSize=\"s\">\n\t\t\t\t<EuiFlexGroup direction=\"column\" gutterSize=\"none\">\n\t\t\t\t\t<EuiFlexItem>\n\t\t\t\t\t\t<SeekBar playerStore={playerStore} />\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem>\n\t\t\t\t\t\t<EuiFlexGroup responsive={false}>\n\t\t\t\t\t\t\t<EuiFlexItem css={{ width: 'calc(100% / 3)' }} />\n\t\t\t\t\t\t\t<EuiFlexItem css={{ width: 'calc(100% / 3)' }}>\n\t\t\t\t\t\t\t\t<BottomBarCenterControls\n\t\t\t\t\t\t\t\t\tplayerStore={playerStore}\n\t\t\t\t\t\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t\t\t<EuiFlexItem css={{ width: 'calc(100% / 3)' }}>\n\t\t\t\t\t\t\t\t<BottomBarRightControls\n\t\t\t\t\t\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t\t</EuiFlexGroup>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t</EuiFlexGroup>\n\t\t\t</EuiBottomBar>\n\t\t);\n\t},\n);\n","import { findVideoService } from '@aigamo/nostalgic-diva';\nimport {\n\tEuiButton,\n\tEuiButtonEmpty,\n\tEuiFieldText,\n\tEuiForm,\n\tEuiFormRow,\n\tEuiModal,\n\tEuiModalBody,\n\tEuiModalFooter,\n\tEuiModalHeader,\n\tEuiModalHeaderTitle,\n} from '@elastic/eui';\nimport { AddRegular } from '@fluentui/react-icons';\nimport React, { memo, ReactElement, useCallback, useState } from 'react';\n\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\ninterface AddVideoModalProps {\n\tonCancel: () => void;\n\tonSave: (e: { url: string; title: string }) => Promise<void>;\n}\n\nconst AddVideoModal = ({\n\tonCancel,\n\tonSave,\n}: AddVideoModalProps): ReactElement => {\n\tconst [url, setUrl] = useState('');\n\tconst [title, setTitle] = useState('');\n\tconst [loading, setLoading] = useState(false);\n\n\treturn (\n\t\t<EuiModal onClose={onCancel} initialFocus=\"[name=url]\">\n\t\t\t<EuiModalHeader>\n\t\t\t\t<EuiModalHeaderTitle>Add video{/* LOC */}</EuiModalHeaderTitle>\n\t\t\t</EuiModalHeader>\n\n\t\t\t<EuiModalBody>\n\t\t\t\t<EuiForm component=\"form\">\n\t\t\t\t\t<EuiFormRow label=\"URL\" /* LOC */>\n\t\t\t\t\t\t<EuiFieldText\n\t\t\t\t\t\t\tname=\"url\"\n\t\t\t\t\t\t\tvalue={url}\n\t\t\t\t\t\t\tonChange={(e): void => setUrl(e.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</EuiFormRow>\n\n\t\t\t\t\t<EuiFormRow label=\"Title\">\n\t\t\t\t\t\t<EuiFieldText\n\t\t\t\t\t\t\tname=\"title\"\n\t\t\t\t\t\t\tvalue={title}\n\t\t\t\t\t\t\tonChange={(e): void => setTitle(e.target.value)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</EuiFormRow>\n\t\t\t\t</EuiForm>\n\t\t\t</EuiModalBody>\n\n\t\t\t<EuiModalFooter>\n\t\t\t\t<EuiButtonEmpty onClick={onCancel}>\n\t\t\t\t\tCancel{/* LOC */}\n\t\t\t\t</EuiButtonEmpty>\n\n\t\t\t\t<EuiButton\n\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\tonClick={async (): Promise<void> => {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tsetLoading(true);\n\n\t\t\t\t\t\t\tawait onSave({ url, title });\n\t\t\t\t\t\t} finally {\n\t\t\t\t\t\t\tsetLoading(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t\tfill\n\t\t\t\t\tdisabled={url.trim().length === 0}\n\t\t\t\t\tisLoading={loading}\n\t\t\t\t>\n\t\t\t\t\tSave{/* LOC */}\n\t\t\t\t</EuiButton>\n\t\t\t</EuiModalFooter>\n\t\t</EuiModal>\n\t);\n};\n\ninterface NoembedResult {\n\ttitle: string;\n}\n\nfunction isNoembedResult(value: any): value is NoembedResult {\n\treturn (\n\t\tvalue !== null &&\n\t\ttypeof value === 'object' &&\n\t\t'title' in value &&\n\t\ttypeof value.title === 'string'\n\t);\n}\n\ninterface AddVideoButtonProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const AddVideoButton = memo(\n\t({ playQueueStore }: AddVideoButtonProps): ReactElement => {\n\t\tconst [addVideoModalOpen, setAddVideoModalOpen] = useState(false);\n\n\t\tconst handleSave = useCallback(\n\t\t\tasync (e: { url: string; title: string }): Promise<void> => {\n\t\t\t\tconst videoService = findVideoService(e.url);\n\t\t\t\tif (videoService !== undefined) {\n\t\t\t\t\tconst videoId = videoService.extractVideoId(e.url);\n\t\t\t\t\tif (videoId !== undefined) {\n\t\t\t\t\t\tconst response = await fetch(\n\t\t\t\t\t\t\t`https://noembed.com/embed?url=${encodeURIComponent(\n\t\t\t\t\t\t\t\te.url,\n\t\t\t\t\t\t\t)}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst jsonData = await response.json();\n\n\t\t\t\t\t\tawait playQueueStore.addItems([\n\t\t\t\t\t\t\tplayQueueStore.createItem({\n\t\t\t\t\t\t\t\turl: e.url,\n\t\t\t\t\t\t\t\ttype: videoService.type,\n\t\t\t\t\t\t\t\tvideoId: videoId,\n\t\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\t\te.title ||\n\t\t\t\t\t\t\t\t\t(isNoembedResult(jsonData)\n\t\t\t\t\t\t\t\t\t\t? jsonData.title\n\t\t\t\t\t\t\t\t\t\t: videoId),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetAddVideoModalOpen(false);\n\t\t\t},\n\t\t\t[playQueueStore],\n\t\t);\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<EuiButton\n\t\t\t\t\tonClick={(): void => setAddVideoModalOpen(true)}\n\t\t\t\t\ticonType={AddRegular}\n\t\t\t\t\tcolor=\"primary\"\n\t\t\t\t>\n\t\t\t\t\tAdd video{/* LOC */}\n\t\t\t\t</EuiButton>\n\n\t\t\t\t{addVideoModalOpen && (\n\t\t\t\t\t<AddVideoModal\n\t\t\t\t\t\tonCancel={(): void => setAddVideoModalOpen(false)}\n\t\t\t\t\t\tonSave={handleSave}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</>\n\t\t);\n\t},\n);\n","import { PlayerType, useNostalgicDiva } from '@aigamo/nostalgic-diva';\nimport {\n\tCommonProps,\n\tEuiButton,\n\tEuiButtonIcon,\n\tEuiCheckbox,\n\tEuiContextMenuItem,\n\tEuiContextMenuItemProps,\n\tEuiContextMenuPanel,\n\tEuiHorizontalRule,\n\tEuiIcon,\n\tEuiLink,\n\tEuiPopover,\n\tEuiTable,\n\tEuiTableHeader,\n\tEuiTableHeaderCell,\n\tEuiTableHeaderCellCheckbox,\n\tEuiTableRow,\n\tEuiTableRowCell,\n\tEuiTableRowCellCheckbox,\n\tuseEuiTheme,\n} from '@elastic/eui';\nimport {\n\tAddRegular,\n\tArrowDownloadRegular,\n\tArrowUploadRegular,\n\tDismissRegular,\n\tMoreHorizontalFilled,\n\tPlayRegular,\n} from '@fluentui/react-icons';\nimport { observer } from 'mobx-react-lite';\nimport React, {\n\tButtonHTMLAttributes,\n\tmemo,\n\tReactElement,\n\tuseCallback,\n\tuseState,\n} from 'react';\nimport { ReactSortable } from 'react-sortablejs';\n\nimport { IPlayQueueItemStore } from '@/features/media-player/stores/IPlayQueueItemStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\ninterface PlayQueueTableHeaderProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst PlayQueueTableHeader = observer(\n\t({ playQueueStore }: PlayQueueTableHeaderProps): ReactElement => {\n\t\tconst { euiTheme } = useEuiTheme();\n\n\t\treturn (\n\t\t\t<EuiTableHeader\n\t\t\t\tstyle={{\n\t\t\t\t\tposition: 'sticky',\n\t\t\t\t\ttop: 48 + 40 + 24,\n\t\t\t\t\tzIndex: 998,\n\t\t\t\t\tbackground: euiTheme.colors.backgroundBasePlain,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<EuiTableHeaderCellCheckbox>\n\t\t\t\t\t<EuiCheckbox\n\t\t\t\t\t\tid=\"\" // TODO\n\t\t\t\t\t\tchecked={playQueueStore.allItemsSelected}\n\t\t\t\t\t\tonChange={(e): void => {\n\t\t\t\t\t\t\tplayQueueStore.allItemsSelected = e.target.checked;\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t</EuiTableHeaderCellCheckbox>\n\t\t\t\t<EuiTableHeaderCell width={24} />\n\t\t\t\t<EuiTableHeaderCell>Title{/* LOC */}</EuiTableHeaderCell>\n\t\t\t\t<EuiTableHeaderCell />\n\t\t\t</EuiTableHeader>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableRowContextMenuPanelProps {\n\titem: IPlayQueueItemStore;\n\tclosePopover: () => void;\n}\n\nconst PlayQueueTableRowContextMenuPanel = memo(\n\t({\n\t\titem,\n\t\tclosePopover,\n\t}: PlayQueueTableRowContextMenuPanelProps): ReactElement => {\n\t\tconst ContextMenuItem = memo(\n\t\t\t({\n\t\t\t\tonClick,\n\t\t\t\t...props\n\t\t\t}: CommonProps &\n\t\t\t\tOmit<\n\t\t\t\t\tButtonHTMLAttributes<HTMLButtonElement>,\n\t\t\t\t\t'onClick' | 'disabled' | 'type'\n\t\t\t\t> &\n\t\t\t\tEuiContextMenuItemProps): ReactElement => {\n\t\t\t\tconst handleClick = useCallback(\n\t\t\t\t\t(e: React.MouseEvent) => {\n\t\t\t\t\t\tclosePopover();\n\n\t\t\t\t\t\tonClick?.(e);\n\t\t\t\t\t},\n\t\t\t\t\t[onClick],\n\t\t\t\t);\n\n\t\t\t\treturn <EuiContextMenuItem {...props} onClick={handleClick} />;\n\t\t\t},\n\t\t);\n\n\t\treturn (\n\t\t\t<EuiContextMenuPanel>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type=\"\" />}\n\t\t\t\t\tonClick={item.playFirst}\n\t\t\t\t>\n\t\t\t\t\tPlay first{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type=\"\" />}\n\t\t\t\t\tonClick={item.playNext}\n\t\t\t\t>\n\t\t\t\t\tPlay next{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type={AddRegular} />}\n\t\t\t\t\tonClick={item.addToPlayQueue}\n\t\t\t\t>\n\t\t\t\t\tAdd to play queue{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<EuiHorizontalRule margin=\"none\" />\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type={ArrowUploadRegular} />}\n\t\t\t\t\tonClick={item.moveToTop}\n\t\t\t\t\tdisabled={!item.canMoveToTop}\n\t\t\t\t>\n\t\t\t\t\tMove to the top{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type={ArrowDownloadRegular} />}\n\t\t\t\t\tonClick={item.moveToBottom}\n\t\t\t\t\tdisabled={!item.canMoveToBottom}\n\t\t\t\t>\n\t\t\t\t\tMove to the bottom{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<EuiHorizontalRule margin=\"none\" />\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type=\"\" />}\n\t\t\t\t\tonClick={item.removeToTop}\n\t\t\t\t\tdisabled={!item.canRemoveToTop}\n\t\t\t\t>\n\t\t\t\t\tRemove to the top{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t\t<ContextMenuItem\n\t\t\t\t\ticon={<EuiIcon type=\"\" />}\n\t\t\t\t\tonClick={item.removeOthers}\n\t\t\t\t\tdisabled={!item.canRemoveOthers}\n\t\t\t\t>\n\t\t\t\t\tRemove others{/* LOC */}\n\t\t\t\t</ContextMenuItem>\n\t\t\t</EuiContextMenuPanel>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableRowPopoverProps {\n\titem: IPlayQueueItemStore;\n}\n\nconst PlayQueueTableRowPopover = memo(\n\t({ item }: PlayQueueTableRowPopoverProps): ReactElement => {\n\t\tconst [isOpen, setIsOpen] = useState(false);\n\n\t\tconst togglePopover = useCallback(() => setIsOpen(!isOpen), [isOpen]);\n\t\tconst closePopover = useCallback(() => setIsOpen(false), []);\n\n\t\treturn (\n\t\t\t<EuiPopover\n\t\t\t\tbutton={\n\t\t\t\t\t<EuiButtonIcon\n\t\t\t\t\t\ttitle=\"More options\"\n\t\t\t\t\t\taria-label=\"More options\"\n\t\t\t\t\t\ticonType={MoreHorizontalFilled}\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\tcolor=\"text\"\n\t\t\t\t\t\tonClick={togglePopover}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\tisOpen={isOpen}\n\t\t\t\tclosePopover={closePopover}\n\t\t\t\tpanelPaddingSize=\"none\"\n\t\t\t\tanchorPosition=\"leftCenter\"\n\t\t\t>\n\t\t\t\t<PlayQueueTableRowContextMenuPanel\n\t\t\t\t\titem={item}\n\t\t\t\t\tclosePopover={closePopover}\n\t\t\t\t/>\n\t\t\t</EuiPopover>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableRowActionsCellProps {\n\titem: IPlayQueueItemStore;\n}\n\nconst PlayQueueTableRowActionsCell = observer(\n\t({ item }: PlayQueueTableRowActionsCellProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\treturn (\n\t\t\t<EuiTableRowCell textOnly={false} hasActions align=\"right\">\n\t\t\t\t<EuiButton\n\t\t\t\t\ticonType={PlayRegular}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\tonClick={async (): Promise<void> => {\n\t\t\t\t\t\tif (item.isCurrent) {\n\t\t\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\titem.play();\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\tPlay{/* LOC */}\n\t\t\t\t</EuiButton>\n\t\t\t\t<EuiButton\n\t\t\t\t\ticonType={DismissRegular}\n\t\t\t\t\tsize=\"s\"\n\t\t\t\t\tonClick={item.remove}\n\t\t\t\t>\n\t\t\t\t\tRemove{/* LOC */}\n\t\t\t\t</EuiButton>\n\t\t\t\t<PlayQueueTableRowPopover item={item} />\n\t\t\t</EuiTableRowCell>\n\t\t);\n\t},\n);\n\nconst videoServiceIcons: Record<PlayerType, string> = {\n\tAudio: '' /* TODO */,\n\tDailymotion: 'https://www.dailymotion.com/favicon.ico',\n\tNiconico: 'https://www.nicovideo.jp/favicon.ico',\n\tSoundCloud: 'https://soundcloud.com/favicon.ico',\n\tTwitch: 'https://www.twitch.tv/favicon.ico',\n\tVimeo: 'https://vimeo.com/favicon.ico',\n\tYouTube: 'https://www.youtube.com/favicon.ico',\n};\n\ninterface PlayQueueTableRowProps {\n\titem: IPlayQueueItemStore;\n}\n\nconst PlayQueueTableRow = observer(\n\t({ item }: PlayQueueTableRowProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\treturn (\n\t\t\t<EuiTableRow key={item.id} isSelected={item.isCurrent}>\n\t\t\t\t<EuiTableRowCellCheckbox>\n\t\t\t\t\t<EuiCheckbox\n\t\t\t\t\t\tid={item.id.toString() /* TODO */}\n\t\t\t\t\t\tchecked={item.isSelected}\n\t\t\t\t\t\tonChange={item.toggleSelected}\n\t\t\t\t\t/>\n\t\t\t\t</EuiTableRowCellCheckbox>\n\t\t\t\t<EuiTableRowCell textOnly={false}>\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={videoServiceIcons[item.type]}\n\t\t\t\t\t\twidth={16}\n\t\t\t\t\t\theight={16}\n\t\t\t\t\t\talt={item.type /* TODO */}\n\t\t\t\t\t/>\n\t\t\t\t</EuiTableRowCell>\n\t\t\t\t<EuiTableRowCell>\n\t\t\t\t\t<EuiLink\n\t\t\t\t\t\thref={item.url}\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\texternal\n\t\t\t\t\t\tonClick={(): Promise<void> => diva.pause()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{item.title}\n\t\t\t\t\t</EuiLink>\n\t\t\t\t</EuiTableRowCell>\n\t\t\t\t<PlayQueueTableRowActionsCell item={item} />\n\t\t\t</EuiTableRow>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableBodyProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst PlayQueueTableBody = observer(\n\t({ playQueueStore }: PlayQueueTableBodyProps): ReactElement => {\n\t\treturn (\n\t\t\t<ReactSortable\n\t\t\t\ttag=\"tbody\"\n\t\t\t\tlist={playQueueStore.items}\n\t\t\t\tsetList={(items): void => playQueueStore.setItems(items)}\n\t\t\t>\n\t\t\t\t{playQueueStore.items.map((item) => (\n\t\t\t\t\t<PlayQueueTableRow key={item.id} item={item} />\n\t\t\t\t))}\n\t\t\t</ReactSortable>\n\t\t);\n\t},\n);\n\ninterface PlayQueueTableProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const PlayQueueTable = observer(\n\t({ playQueueStore }: PlayQueueTableProps): ReactElement => {\n\t\treturn (\n\t\t\t<EuiTable>\n\t\t\t\t<PlayQueueTableHeader playQueueStore={playQueueStore} />\n\t\t\t\t<PlayQueueTableBody playQueueStore={playQueueStore} />\n\t\t\t</EuiTable>\n\t\t);\n\t},\n);\n","import {\n\tEuiButton,\n\tEuiCodeBlock,\n\tEuiFlexGroup,\n\tEuiFlexItem,\n\tEuiFlyout,\n\tEuiPageTemplate,\n\tEuiSpacer,\n\tuseEuiTheme,\n} from '@elastic/eui';\nimport {\n\tAddRegular,\n\tDeleteRegular,\n\tDismissRegular,\n} from '@fluentui/react-icons';\nimport { observer } from 'mobx-react-lite';\nimport React, { ReactElement, useState } from 'react';\n\nimport { AddVideoButton } from '@/features/media-player/components/AddVideoButton';\nimport { PlayQueueTable } from '@/features/media-player/components/PlayQueueTable';\nimport { PlayerStore } from '@/features/media-player/stores/PlayerStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\ninterface DeveloperToolsButtonProps {\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst DeveloperToolsButton = observer(\n\t({ playQueueStore }: DeveloperToolsButtonProps): ReactElement => {\n\t\tconst [isFlyoutVisible, setIsFlyoutVisible] = useState(false);\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{isFlyoutVisible && (\n\t\t\t\t\t<EuiFlyout\n\t\t\t\t\t\ttype=\"push\"\n\t\t\t\t\t\tsize=\"s\"\n\t\t\t\t\t\tonClose={(): void => setIsFlyoutVisible(false)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div style={{ blockSize: '100%' }}>\n\t\t\t\t\t\t\t<EuiCodeBlock\n\t\t\t\t\t\t\t\tlanguage=\"json\"\n\t\t\t\t\t\t\t\toverflowHeight=\"100%\"\n\t\t\t\t\t\t\t\tisCopyable\n\t\t\t\t\t\t\t\tisVirtualized\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{JSON.stringify(\n\t\t\t\t\t\t\t\t\tplayQueueStore.localStorageState,\n\t\t\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</EuiCodeBlock>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</EuiFlyout>\n\t\t\t\t)}\n\n\t\t\t\t<AddVideoButton playQueueStore={playQueueStore} />\n\t\t\t</>\n\t\t);\n\t},\n);\n\ninterface PlayQueueProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nconst PlayQueue = observer(\n\t({ playerStore, playQueueStore }: PlayQueueProps): ReactElement => {\n\t\tconst { euiTheme } = useEuiTheme();\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<EuiFlexGroup\n\t\t\t\t\talignItems=\"center\"\n\t\t\t\t\tgutterSize=\"m\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tposition: 'sticky',\n\t\t\t\t\t\ttop: 48,\n\t\t\t\t\t\tzIndex: 998,\n\t\t\t\t\t\tbackground: euiTheme.colors.backgroundBasePlain,\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<EuiButton\n\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\tplayQueueStore.isEmpty ||\n\t\t\t\t\t\t\t\tplayQueueStore.selectedItems.length === 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tonClick={playQueueStore.playSelectedItemsNext}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tPlay next{/* LOC */}\n\t\t\t\t\t\t</EuiButton>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<EuiButton\n\t\t\t\t\t\t\ticonType={AddRegular}\n\t\t\t\t\t\t\tonClick={playQueueStore.addSelectedItems}\n\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\tplayQueueStore.isEmpty ||\n\t\t\t\t\t\t\t\tplayQueueStore.selectedItems.length === 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tAdd to play queue{/* LOC */}\n\t\t\t\t\t\t</EuiButton>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<EuiButton\n\t\t\t\t\t\t\ticonType={DismissRegular}\n\t\t\t\t\t\t\tonClick={playQueueStore.removeSelectedItems}\n\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\tplayQueueStore.isEmpty ||\n\t\t\t\t\t\t\t\tplayQueueStore.selectedItems.length === 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tRemove{/* LOC */}\n\t\t\t\t\t\t</EuiButton>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<EuiButton\n\t\t\t\t\t\t\ticonType={DeleteRegular}\n\t\t\t\t\t\t\tonClick={playQueueStore.clear}\n\t\t\t\t\t\t\tdisabled={playQueueStore.isEmpty}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tClear{/* LOC */}\n\t\t\t\t\t\t</EuiButton>\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t\t<EuiFlexItem grow={true} />\n\t\t\t\t\t<EuiFlexItem grow={false}>\n\t\t\t\t\t\t<DeveloperToolsButton playQueueStore={playQueueStore} />\n\t\t\t\t\t</EuiFlexItem>\n\t\t\t\t</EuiFlexGroup>\n\n\t\t\t\t{!playQueueStore.isEmpty && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<EuiSpacer\n\t\t\t\t\t\t\tsize=\"l\"\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\tposition: 'sticky',\n\t\t\t\t\t\t\t\ttop: 48 + 40,\n\t\t\t\t\t\t\t\tzIndex: 998,\n\t\t\t\t\t\t\t\tbackground: euiTheme.colors.backgroundBasePlain,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t<PlayQueueTable playQueueStore={playQueueStore} />\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t</>\n\t\t);\n\t},\n);\n\ninterface HydrangeanDivaProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const HydrangeanDiva = observer(\n\t({ playerStore, playQueueStore }: HydrangeanDivaProps): ReactElement => {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<EuiPageTemplate.Header\n\t\t\t\t\tpageTitle=\"Play queue\" /* LOC */\n\t\t\t\t\trightSideItems={[]}\n\t\t\t\t/>\n\n\t\t\t\t<EuiPageTemplate.Section>\n\t\t\t\t\t<PlayQueue\n\t\t\t\t\t\tplayerStore={playerStore}\n\t\t\t\t\t\tplayQueueStore={playQueueStore}\n\t\t\t\t\t/>\n\t\t\t\t</EuiPageTemplate.Section>\n\t\t\t</>\n\t\t);\n\t},\n);\n","import {\n\tNostalgicDiva,\n\tPlayerOptions,\n\tuseNostalgicDiva,\n} from '@aigamo/nostalgic-diva';\nimport { observer } from 'mobx-react-lite';\nimport React, { ReactElement, useCallback, useMemo } from 'react';\n\nimport { bottomBarHeight } from '@/features/media-player/components/BottomBar';\nimport { PlayerStore } from '@/features/media-player/stores/PlayerStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\nimport { RepeatMode } from '@/features/media-player/stores/RepeatMode';\n\nexport const miniPlayerSize = {\n\twidth: 16 * 25,\n\theight: 9 * 25,\n} as const;\n\ninterface MiniPlayerProps {\n\tplayerStore: PlayerStore;\n\tplayQueueStore: PlayQueueStore;\n}\n\nexport const MiniPlayer = observer(\n\t({ playerStore, playQueueStore }: MiniPlayerProps): ReactElement => {\n\t\tconst diva = useNostalgicDiva();\n\n\t\tconst handleLoaded = useCallback(async (): Promise<void> => {\n\t\t\tif (!playQueueStore.interacted) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tawait diva.play();\n\t\t}, [playQueueStore, diva]);\n\n\t\tconst handleEnded = useCallback(async (): Promise<void> => {\n\t\t\tswitch (playQueueStore.repeat) {\n\t\t\t\tcase RepeatMode.One:\n\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase RepeatMode.Off:\n\t\t\t\tcase RepeatMode.All:\n\t\t\t\t\tif (playQueueStore.isLastItem) {\n\t\t\t\t\t\tswitch (playQueueStore.repeat) {\n\t\t\t\t\t\t\tcase RepeatMode.Off:\n\t\t\t\t\t\t\t\tplayerStore.onEnded();\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase RepeatMode.All:\n\t\t\t\t\t\t\t\tif (playQueueStore.hasMultipleItems) {\n\t\t\t\t\t\t\t\t\tawait playQueueStore.goToFirst();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait playQueueStore.next();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}, [playQueueStore, playerStore, diva]);\n\n\t\tconst options = useMemo(\n\t\t\t(): PlayerOptions => ({\n\t\t\t\tonLoaded: handleLoaded,\n\t\t\t\tonPlay: playerStore.onPlay,\n\t\t\t\tonPause: playerStore.onPause,\n\t\t\t\tonEnded: handleEnded,\n\t\t\t\tonTimeUpdate: playerStore.onTimeUpdate,\n\t\t\t}),\n\t\t\t[playerStore, handleLoaded, handleEnded],\n\t\t);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tcss={{\n\t\t\t\t\tposition: 'fixed',\n\t\t\t\t\tright: 0,\n\t\t\t\t\tbottom: bottomBarHeight,\n\t\t\t\t\twidth: miniPlayerSize.width,\n\t\t\t\t\theight: miniPlayerSize.height,\n\t\t\t\t\tzIndex: 998,\n\t\t\t\t\tbackgroundColor: 'rgb(39, 39, 39)',\n\t\t\t\t\tdisplay: 'flex',\n\t\t\t\t\tflexDirection: 'column',\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<div css={{ flexGrow: 1, backgroundColor: 'black' }}>\n\t\t\t\t\t{playQueueStore.currentItem && (\n\t\t\t\t\t\t<NostalgicDiva\n\t\t\t\t\t\t\tsrc={playQueueStore.currentItem.url}\n\t\t\t\t\t\t\toptions={options}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t},\n);\n","import { AnnotationsMap, makeObservable } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\n\nexport class MobXObservableStateProvider implements IObservableStateProvider {\n\tmakeObservable<\n\t\tT extends object,\n\t\tAdditionalKeys extends PropertyKey = never,\n\t>(target: T, annotations?: AnnotationsMap<T, AdditionalKeys>): T {\n\t\treturn makeObservable(target, annotations);\n\t}\n}\n","import { PlayerType } from '@aigamo/nostalgic-diva';\nimport { action, computed, observable } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\nimport {\n\tIPlayQueueItemStore,\n\tPlayQueueItemDto,\n} from '@/features/media-player/stores/IPlayQueueItemStore';\nimport { IPlayQueueStore } from '@/features/media-player/stores/IPlayQueueStore';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\nexport class PlayQueueItemStore implements IPlayQueueItemStore {\n\tstatic nextId = 1;\n\n\treadonly id: number;\n\tisSelected = false;\n\n\tconstructor(\n\t\treadonly observableStateProvider: IObservableStateProvider,\n\t\treadonly playQueueStore: IPlayQueueStore,\n\t\treadonly dto: PlayQueueItemDto,\n\t) {\n\t\tthis.id = PlayQueueItemStore.nextId++;\n\n\t\tobservableStateProvider.makeObservable(this, {\n\t\t\tisSelected: observable,\n\t\t\tisCurrent: computed,\n\t\t\tindex: computed,\n\t\t\tisFirst: computed,\n\t\t\tisLast: computed,\n\t\t\tcanMoveToTop: computed,\n\t\t\tcanMoveToBottom: computed,\n\t\t\tcanRemoveToTop: computed,\n\t\t\tcanRemoveOthers: computed,\n\t\t\tunselect: action,\n\t\t\ttoggleSelected: action.bound,\n\t\t\tplay: action,\n\t\t\tremove: action.bound,\n\t\t\tplayFirst: action.bound,\n\t\t\tplayNext: action.bound,\n\t\t\taddToPlayQueue: action.bound,\n\t\t\tmoveToTop: action.bound,\n\t\t\tmoveToBottom: action.bound,\n\t\t\tremoveToTop: action.bound,\n\t\t\tremoveOthers: action.bound,\n\t\t});\n\t}\n\n\tstatic fromDto(\n\t\tobservableStateProvider: IObservableStateProvider,\n\t\tplayQueueStore: PlayQueueStore,\n\t\tdto: PlayQueueItemDto,\n\t): IPlayQueueItemStore {\n\t\treturn new PlayQueueItemStore(\n\t\t\tobservableStateProvider,\n\t\t\tplayQueueStore,\n\t\t\tdto,\n\t\t);\n\t}\n\n\tget url(): string {\n\t\treturn this.dto.url;\n\t}\n\n\tget type(): PlayerType {\n\t\treturn this.dto.type;\n\t}\n\n\tget videoId(): string {\n\t\treturn this.dto.videoId;\n\t}\n\n\tget title(): string {\n\t\treturn this.dto.title;\n\t}\n\n\tget isCurrent(): boolean {\n\t\treturn this.playQueueStore.currentItem === this;\n\t}\n\n\tget index(): number {\n\t\treturn this.playQueueStore.items.indexOf(this);\n\t}\n\n\tget isFirst(): boolean {\n\t\treturn this.index === 0;\n\t}\n\n\tget isLast(): boolean {\n\t\treturn this.index === this.playQueueStore.items.length - 1;\n\t}\n\n\tget canMoveToTop(): boolean {\n\t\treturn !this.isFirst;\n\t}\n\n\tget canMoveToBottom(): boolean {\n\t\treturn !this.isLast;\n\t}\n\n\tget canRemoveToTop(): boolean {\n\t\treturn !this.isFirst;\n\t}\n\n\tget canRemoveOthers(): boolean {\n\t\treturn this.playQueueStore.hasMultipleItems;\n\t}\n\n\tclone(): IPlayQueueItemStore {\n\t\treturn this.playQueueStore.createItem(this.dto);\n\t}\n\n\tunselect(): void {\n\t\tthis.isSelected = false;\n\t}\n\n\ttoggleSelected(): void {\n\t\tthis.isSelected = !this.isSelected;\n\t}\n\n\tplay(): void {\n\t\tthis.playQueueStore.setCurrentItem(this);\n\t}\n\n\tremove(): Promise<void> {\n\t\treturn this.playQueueStore.removeItems([this]);\n\t}\n\n\tasync playFirst(): Promise<void> {\n\t\tawait this.playQueueStore.playFirst([this.clone()]);\n\t}\n\n\tasync playNext(): Promise<void> {\n\t\tawait this.playQueueStore.playNext([this.clone()]);\n\t}\n\n\tasync addToPlayQueue(): Promise<void> {\n\t\tawait this.playQueueStore.addItems([this.clone()]);\n\t}\n\n\tmoveToTop(): void {\n\t\tthis.playQueueStore.moveItem(this, 0);\n\t}\n\n\tmoveToBottom(): void {\n\t\tthis.playQueueStore.moveItem(\n\t\t\tthis,\n\t\t\tthis.playQueueStore.items.length - 1,\n\t\t);\n\t}\n\n\tremoveToTop(): Promise<void> {\n\t\treturn this.playQueueStore.removeItemsAbove(this);\n\t}\n\n\tremoveOthers(): Promise<void> {\n\t\treturn this.playQueueStore.removeOtherItems(this);\n\t}\n}\n","import Ajv, { JSONSchemaType, ValidateFunction } from 'ajv';\n\nconst ajv = new Ajv({\n\tcoerceTypes: true,\n});\n\nexport function getOrAddSchema<T>(\n\tschema: JSONSchemaType<T>,\n\tkeyRef: string,\n): ValidateFunction<T> {\n\t// https://ajv.js.org/guide/managing-schemas.html#pre-adding-all-schemas-vs-adding-on-demand\n\tlet validate: ValidateFunction<T> | undefined;\n\tvalidate = ajv.getSchema(keyRef);\n\tif (validate === undefined) {\n\t\tajv.addSchema(schema, keyRef);\n\t\tvalidate = ajv.getSchema(keyRef);\n\t}\n\n\tif (validate === undefined || validate.schema !== schema) {\n\t\tthrow new Error(\n\t\t\t`Invalid schema. Expected: '${JSON.stringify(\n\t\t\t\tschema,\n\t\t\t)}', but got '${JSON.stringify(validate?.schema)}'.`,\n\t\t);\n\t}\n\n\treturn validate;\n}\n","import { JSONSchemaType } from 'ajv';\n\nimport { getOrAddSchema } from '@/features/media-player/stores/getOrAddSchema';\nimport { PlayQueueItemDto } from '@/features/media-player/stores/IPlayQueueItemStore';\nimport { RepeatMode } from '@/features/media-player/stores/RepeatMode';\n\nexport interface PlayQueueLocalStorageState {\n\tversion?: '1.0';\n\trepeat?: RepeatMode;\n\tshuffle?: boolean;\n\titems?: PlayQueueItemDto[];\n\tcurrentIndex?: number;\n}\n\nconst PlayQueueLocalStorageStateSchema: JSONSchemaType<PlayQueueLocalStorageState> =\n\t{\n\t\ttype: 'object',\n\t\tproperties: {\n\t\t\tversion: {\n\t\t\t\ttype: 'string',\n\t\t\t\tnullable: true,\n\t\t\t},\n\t\t\trepeat: {\n\t\t\t\ttype: 'string',\n\t\t\t\tenum: Object.values(RepeatMode),\n\t\t\t\tnullable: true,\n\t\t\t},\n\t\t\tshuffle: {\n\t\t\t\ttype: 'boolean',\n\t\t\t\tnullable: true,\n\t\t\t},\n\t\t\titems: {\n\t\t\t\ttype: 'array',\n\t\t\t\tnullable: true,\n\t\t\t\titems: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\turl: {\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttype: {\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t},\n\t\t\t\t\t\tvideoId: {\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttitle: {\n\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\trequired: ['url', 'type', 'videoId', 'title'],\n\t\t\t\t},\n\t\t\t},\n\t\t\tcurrentIndex: {\n\t\t\t\ttype: 'integer',\n\t\t\t\tnullable: true,\n\t\t\t},\n\t\t},\n\t};\n\nexport const validatePlayQueueLocalStorageState = getOrAddSchema(\n\tPlayQueueLocalStorageStateSchema,\n\t'PlayQueueStore',\n);\n","import { LocalStorageStateStore } from '@aigamo/route-sphere';\nimport { pull } from 'lodash-es';\nimport { action, computed, observable } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\nimport {\n\tIPlayQueueItemStore,\n\tPlayQueueItemDto,\n} from '@/features/media-player/stores/IPlayQueueItemStore';\nimport { IPlayQueueStore } from '@/features/media-player/stores/IPlayQueueStore';\nimport { PlayQueueItemStore } from '@/features/media-player/stores/PlayQueueItemStore';\nimport {\n\tPlayQueueLocalStorageState,\n\tvalidatePlayQueueLocalStorageState,\n} from '@/features/media-player/stores/PlayQueueLocalStorageState';\nimport { RepeatMode } from '@/features/media-player/stores/RepeatMode';\n\nexport class PlayQueueStore\n\timplements\n\t\tIPlayQueueStore,\n\t\tLocalStorageStateStore<PlayQueueLocalStorageState>\n{\n\tinteracted = false;\n\titems: IPlayQueueItemStore[] = [];\n\tcurrentId: number | undefined;\n\trepeat = RepeatMode.Off;\n\tshuffle = false;\n\n\tconstructor(readonly observableStateProvider: IObservableStateProvider) {\n\t\tobservableStateProvider.makeObservable(this, {\n\t\t\tinteracted: observable,\n\t\t\titems: observable,\n\t\t\tcurrentId: observable,\n\t\t\trepeat: observable,\n\t\t\tshuffle: observable,\n\t\t\tlocalStorageState: computed.struct,\n\t\t\tisEmpty: computed,\n\t\t\tcurrentItem: computed,\n\t\t\tcanPlay: computed,\n\t\t\tcanPause: computed,\n\t\t\thasMultipleItems: computed,\n\t\t\tcurrentIndex: computed,\n\t\t\thasPreviousItem: computed,\n\t\t\thasNextItem: computed,\n\t\t\tisLastItem: computed,\n\t\t\tselectedItems: computed,\n\t\t\tallItemsSelected: computed,\n\t\t\tselectedItemsOrAllItems: computed,\n\t\t\tsetItems: action,\n\t\t\tinteract: action,\n\t\t\tclear: action.bound,\n\t\t\tunselectAll: action,\n\t\t\tsetCurrentItem: action,\n\t\t\tsetNextItems: action,\n\t\t\tclearAndSetItems: action,\n\t\t\tplayNext: action,\n\t\t\tplaySelectedItemsNext: action.bound,\n\t\t\taddItems: action,\n\t\t\taddSelectedItems: action.bound,\n\t\t\tplayFirst: action,\n\t\t\tmoveItem: action,\n\t\t\tremoveItems: action,\n\t\t\tremoveSelectedItems: action.bound,\n\t\t\tremoveOtherItems: action,\n\t\t\tremoveItemsAbove: action,\n\t\t\ttoggleRepeat: action.bound,\n\t\t\ttoggleShuffle: action.bound,\n\t\t\tprevious: action,\n\t\t\tnext: action.bound,\n\t\t\tgoToFirst: action,\n\t\t});\n\t}\n\n\tcreateItem(dto: PlayQueueItemDto): IPlayQueueItemStore {\n\t\treturn PlayQueueItemStore.fromDto(\n\t\t\tthis.observableStateProvider,\n\t\t\tthis,\n\t\t\tdto,\n\t\t);\n\t}\n\n\tget localStorageState(): PlayQueueLocalStorageState {\n\t\treturn {\n\t\t\tversion: '1.0',\n\t\t\trepeat: this.repeat,\n\t\t\tshuffle: this.shuffle,\n\t\t\titems: this.items.map((item) => item.dto),\n\t\t\tcurrentIndex: this.currentIndex,\n\t\t};\n\t}\n\tset localStorageState(value: PlayQueueLocalStorageState) {\n\t\tthis.repeat = value.repeat ?? RepeatMode.Off;\n\t\tthis.shuffle = value.shuffle ?? false;\n\t\tthis.items = value.items?.map((item) => this.createItem(item)) ?? [];\n\t\tthis.currentIndex = value.currentIndex;\n\t}\n\n\tvalidateLocalStorageState(\n\t\tlocalStorageState: any,\n\t): localStorageState is PlayQueueLocalStorageState {\n\t\treturn validatePlayQueueLocalStorageState(localStorageState);\n\t}\n\n\tget isEmpty(): boolean {\n\t\treturn this.items.length === 0;\n\t}\n\n\tget currentItem(): IPlayQueueItemStore | undefined {\n\t\treturn this.items.find((item) => item.id === this.currentId);\n\t}\n\n\tget canPlay(): boolean {\n\t\treturn this.currentItem !== undefined;\n\t}\n\n\tget canPause(): boolean {\n\t\treturn this.currentItem !== undefined;\n\t}\n\n\tget hasMultipleItems(): boolean {\n\t\treturn this.items.length > 1;\n\t}\n\n\tget currentIndex(): number | undefined {\n\t\treturn this.currentId !== undefined\n\t\t\t? this.items.findIndex((item) => item.id === this.currentId)\n\t\t\t: undefined;\n\t}\n\tset currentIndex(value: number | undefined) {\n\t\tthis.currentId =\n\t\t\tvalue !== undefined ? this.items.at(value)?.id : undefined;\n\t}\n\n\tget hasPreviousItem(): boolean {\n\t\treturn (\n\t\t\tthis.hasMultipleItems &&\n\t\t\tthis.currentIndex !== undefined &&\n\t\t\tthis.currentIndex > 0\n\t\t);\n\t}\n\n\tget hasNextItem(): boolean {\n\t\treturn (\n\t\t\tthis.hasMultipleItems &&\n\t\t\tthis.currentIndex !== undefined &&\n\t\t\tthis.currentIndex < this.items.length - 1\n\t\t);\n\t}\n\n\tget isLastItem(): boolean {\n\t\treturn (\n\t\t\tthis.currentIndex !== undefined &&\n\t\t\tthis.currentIndex === this.items.length - 1\n\t\t);\n\t}\n\n\tget selectedItems(): IPlayQueueItemStore[] {\n\t\treturn this.items.filter((item) => item.isSelected);\n\t}\n\n\tget allItemsSelected(): boolean {\n\t\treturn this.selectedItems.length === this.items.length;\n\t}\n\tset allItemsSelected(value: boolean) {\n\t\tfor (const item of this.items) {\n\t\t\titem.isSelected = value;\n\t\t}\n\t}\n\n\tget selectedItemsOrAllItems(): IPlayQueueItemStore[] {\n\t\treturn this.selectedItems.length > 0 ? this.selectedItems : this.items;\n\t}\n\n\tsetItems(value: IPlayQueueItemStore[]): void {\n\t\tthis.items = value;\n\t}\n\n\tinteract(): void {\n\t\tthis.interacted = true;\n\t}\n\n\tclear(): void {\n\t\tthis.interact();\n\n\t\tthis.currentIndex = undefined;\n\t\tthis.items = [];\n\t}\n\n\tunselectAll(): void {\n\t\tfor (const item of this.items) {\n\t\t\titem.unselect();\n\t\t}\n\t}\n\n\tsetCurrentItem(item: IPlayQueueItemStore | undefined): void {\n\t\tthis.interact();\n\n\t\tthis.currentId = item?.id;\n\t}\n\n\tsetNextItems(items: IPlayQueueItemStore[]): void {\n\t\tif (this.currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.items.splice(this.currentIndex + 1, 0, ...items);\n\t}\n\n\tclearAndSetItems(items: IPlayQueueItemStore[]): void {\n\t\tthis.clear();\n\n\t\tthis.setCurrentItem(items[0]);\n\n\t\tthis.setNextItems(items);\n\t}\n\n\tasync playNext(items: IPlayQueueItemStore[]): Promise<void> {\n\t\tif (this.isEmpty) {\n\t\t\tthis.clearAndSetItems(items);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.setNextItems(items);\n\t}\n\n\tasync playSelectedItemsNext(): Promise<void> {\n\t\tawait this.playNext(\n\t\t\tthis.selectedItemsOrAllItems.map((item) => item.clone()),\n\t\t);\n\n\t\tthis.unselectAll();\n\t}\n\n\tasync addItems(items: IPlayQueueItemStore[]): Promise<void> {\n\t\tif (this.isEmpty) {\n\t\t\tthis.clearAndSetItems(items);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.items.push(...items);\n\t}\n\n\tasync addSelectedItems(): Promise<void> {\n\t\tawait this.addItems(\n\t\t\tthis.selectedItemsOrAllItems.map((item) => item.clone()),\n\t\t);\n\n\t\tthis.unselectAll();\n\t}\n\n\tasync playFirst(items: IPlayQueueItemStore[]): Promise<void> {\n\t\tif (this.isEmpty) {\n\t\t\tthis.clearAndSetItems(items);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { currentIndex } = this;\n\t\tif (currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.interact();\n\n\t\tthis.items.splice(currentIndex, 0, ...items);\n\t\tthis.currentIndex = currentIndex;\n\t}\n\n\tmoveItem(item: IPlayQueueItemStore, index: number): void {\n\t\tconst element = this.items.splice(this.items.indexOf(item), 1)[0];\n\t\tthis.items.splice(index, 0, element);\n\t}\n\n\tasync removeItems(items: IPlayQueueItemStore[]): Promise<void> {\n\t\t// Note: We need to remove the current (if any) and other (previous and/or next) items separately,\n\t\t// so that the current index can be set properly even if the current item was removed.\n\n\t\t// Capture the current item.\n\t\tconst { currentItem } = this;\n\n\t\t// First, remove items that are not equal to the current one.\n\t\tpull(this.items, ...items.filter((item) => item !== currentItem));\n\n\t\t// Capture the current index.\n\t\tconst { currentIndex, isLastItem } = this;\n\n\t\t// Then, remove the current item if any.\n\t\tpull(\n\t\t\tthis.items,\n\t\t\titems.find((item) => item === currentItem),\n\t\t);\n\n\t\t// If the current item differs from the captured one, then it means that the current item was removed from the play queue.\n\t\tif (this.currentItem !== currentItem) {\n\t\t\tthis.interact();\n\n\t\t\tif (isLastItem) {\n\t\t\t\t// Start over the playlist from the beginning.\n\t\t\t\tawait this.goToFirst();\n\t\t\t} else {\n\t\t\t\t// Set the current index to the captured one.\n\t\t\t\tthis.currentIndex = currentIndex;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync removeSelectedItems(): Promise<void> {\n\t\tawait this.removeItems(this.selectedItemsOrAllItems);\n\n\t\tthis.unselectAll();\n\t}\n\n\tasync removeOtherItems(item: IPlayQueueItemStore): Promise<void> {\n\t\tconst itemId = item.id;\n\t\treturn this.removeItems(\n\t\t\tthis.items.filter((item) => item.id !== itemId),\n\t\t);\n\t}\n\n\tasync removeItemsAbove(item: IPlayQueueItemStore): Promise<void> {\n\t\tconst itemIndex = this.items.indexOf(item);\n\t\treturn this.removeItems(\n\t\t\tthis.items.filter((_, index) => index < itemIndex),\n\t\t);\n\t}\n\n\ttoggleRepeat(): void {\n\t\tswitch (this.repeat) {\n\t\t\tcase RepeatMode.Off:\n\t\t\t\tthis.repeat = RepeatMode.All;\n\t\t\t\tbreak;\n\t\t\tcase RepeatMode.All:\n\t\t\t\tthis.repeat = RepeatMode.One;\n\t\t\t\tbreak;\n\t\t\tcase RepeatMode.One:\n\t\t\t\tthis.repeat = RepeatMode.Off;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\ttoggleShuffle(): void {\n\t\tthis.shuffle = !this.shuffle;\n\t}\n\n\tasync previous(): Promise<void> {\n\t\tif (this.currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.hasPreviousItem) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.interact();\n\n\t\tthis.currentIndex--;\n\t}\n\n\tasync next(): Promise<void> {\n\t\tif (this.currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.hasNextItem) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.interact();\n\n\t\tthis.currentIndex++;\n\t}\n\n\tasync goToFirst(): Promise<void> {\n\t\tif (this.currentIndex === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.currentIndex = 0;\n\t}\n}\n","import { useNostalgicDiva } from '@aigamo/nostalgic-diva';\nimport { reaction } from 'mobx';\nimport React, {\n\tcreateContext,\n\tReactElement,\n\tReactNode,\n\tuseContext,\n\tuseEffect,\n\tuseState,\n} from 'react';\n\nimport { MobXObservableStateProvider } from '@/features/media-player/stores/MobXObservableStateProvider';\nimport { PlayQueueStore } from '@/features/media-player/stores/PlayQueueStore';\n\n// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\nconst PlayQueueStoreContext = createContext<PlayQueueStore>(undefined!);\n\ninterface PlayQueueStoreProviderProps {\n\tchildren?: ReactNode;\n}\n\nexport const PlayQueueStoreProvider = ({\n\tchildren,\n}: PlayQueueStoreProviderProps): ReactElement => {\n\tconst [playQueueStore] = useState(\n\t\t() => new PlayQueueStore(new MobXObservableStateProvider()),\n\t);\n\n\tconst diva = useNostalgicDiva();\n\n\tuseEffect(() => {\n\t\treturn reaction(\n\t\t\t() => playQueueStore.currentItem,\n\t\t\tasync (currentItem, previousItem) => {\n\t\t\t\tif (currentItem === undefined || previousItem === undefined) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tcurrentItem.type === previousItem.type &&\n\t\t\t\t\tcurrentItem.videoId === previousItem.videoId\n\t\t\t\t) {\n\t\t\t\t\tawait diva.setCurrentTime(0);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\t}, [playQueueStore, diva]);\n\n\treturn (\n\t\t<PlayQueueStoreContext.Provider value={playQueueStore}>\n\t\t\t{children}\n\t\t</PlayQueueStoreContext.Provider>\n\t);\n};\n\nexport const usePlayQueueStore = (): PlayQueueStore => {\n\treturn useContext(PlayQueueStoreContext);\n};\n","import { EuiPageTemplate, EuiSpacer } from '@elastic/eui';\nimport { observer } from 'mobx-react-lite';\nimport React, { ReactElement, ReactNode } from 'react';\n\nimport { bottomBarHeight } from '@/features/media-player/components/BottomBar';\nimport { miniPlayerSize } from '@/features/media-player/components/MiniPlayer';\nimport { usePlayQueueStore } from '@/features/media-player/components/PlayQueueStoreContext';\n\ninterface MediaPlayerLayoutProps {\n\tchildren?: ReactNode;\n}\n\nexport const MediaPlayerLayout = observer(\n\t({ children }: MediaPlayerLayoutProps): ReactElement => {\n\t\tconst playQueueStore = usePlayQueueStore();\n\n\t\treturn (\n\t\t\t<EuiPageTemplate\n\t\t\t\tpanelled\n\t\t\t\tstyle={{\n\t\t\t\t\tminBlockSize: `max(460px, 100vh - ${bottomBarHeight}px)`,\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{children}\n\n\t\t\t\t{!playQueueStore.isEmpty && (\n\t\t\t\t\t<EuiSpacer style={{ blockSize: miniPlayerSize.height }} />\n\t\t\t\t)}\n\t\t\t</EuiPageTemplate>\n\t\t);\n\t},\n);\n","import { TimeEvent } from '@aigamo/nostalgic-diva';\nimport { action, observable } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\n\nexport class PlayerStore {\n\tplaying = false;\n\tpercent = 0;\n\tseeking = false;\n\n\tconstructor(observableStateProvider: IObservableStateProvider) {\n\t\tobservableStateProvider.makeObservable(this, {\n\t\t\tplaying: observable,\n\t\t\tpercent: observable,\n\t\t\tseeking: observable,\n\t\t\tsetPlaying: action,\n\t\t\tsetPercent: action,\n\t\t\tsetSeeking: action,\n\t\t\tonPlay: action.bound,\n\t\t\tonPause: action.bound,\n\t\t\tonEnded: action.bound,\n\t\t\tonTimeUpdate: action.bound,\n\t\t});\n\t}\n\n\tsetPlaying(value: boolean): void {\n\t\tthis.playing = value;\n\t}\n\n\tsetPercent(value: number): void {\n\t\tthis.percent = value;\n\t}\n\n\tsetSeeking(value: boolean): void {\n\t\tthis.seeking = value;\n\t}\n\n\tonPlay(): void {\n\t\tthis.playing = true;\n\t}\n\n\tonPause(): void {\n\t\tthis.playing = false;\n\t}\n\n\tonEnded(): void {\n\t\tthis.playing = false;\n\t}\n\n\tonTimeUpdate({ percent }: TimeEvent): void {\n\t\tif (percent !== undefined) {\n\t\t\tif (!this.seeking) {\n\t\t\t\tthis.percent = percent;\n\t\t\t}\n\t\t}\n\n\t\t// TODO\n\t}\n}\n","import React, {\n\tcreateContext,\n\tReactElement,\n\tReactNode,\n\tuseContext,\n\tuseState,\n} from 'react';\n\nimport { MobXObservableStateProvider } from '@/features/media-player/stores/MobXObservableStateProvider';\nimport { PlayerStore } from '@/features/media-player/stores/PlayerStore';\n\n// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\nconst PlayerStoreContext = createContext<PlayerStore>(undefined!);\n\ninterface PlayerStoreProviderProps {\n\tchildren?: ReactNode;\n}\n\nexport const PlayerStoreProvider = ({\n\tchildren,\n}: PlayerStoreProviderProps): ReactElement => {\n\tconst [playerStore] = useState(\n\t\t() => new PlayerStore(new MobXObservableStateProvider()),\n\t);\n\n\treturn (\n\t\t<PlayerStoreContext.Provider value={playerStore}>\n\t\t\t{children}\n\t\t</PlayerStoreContext.Provider>\n\t);\n};\n\nexport const usePlayerStore = (): PlayerStore => {\n\treturn useContext(PlayerStoreContext);\n};\n","import { AnnotationsMap } from 'mobx';\n\nimport { IObservableStateProvider } from '@/features/media-player/stores/IObservableStateProvider';\n\nexport class ObservableStateProvider implements IObservableStateProvider {\n\tmakeObservable<\n\t\tT extends object,\n\t\tAdditionalKeys extends PropertyKey = never,\n\t>(target: T, annotations?: AnnotationsMap<T, AdditionalKeys>): T {\n\t\treturn target;\n\t}\n}\n"],"names":["RepeatMode","bottomBarHeight","SeekBar","observer","playerStore","diva","useNostalgicDiva","handleChange","useCallback","e","percent","handleMouseDown","handleMouseUp","duration","React","EuiRange","VolumePopover","memo","button","isOpen","closePopover","value","setValue","useState","useLayoutEffect","volume","EuiPopover","EuiFormRow","EuiFlexGroup","EuiButtonIcon","Speaker2Regular","MoreOptionsContextMenu","playQueueStore","handleClickSkipBack10","currentTime","handleClickSkipForward30","handleClickPlaybackRate","playbackRate","handleClickRemoveFromPlayQueue","panels","useMemo","EuiIcon","TopSpeedRegular","SkipBack10Regular","SkipForward30Regular","DismissRegular","EuiContextMenu","MoreOptionsPopover","repeatIconTypes","ArrowRepeatAllOffFilled","ArrowRepeatAllFilled","ArrowRepeat1Filled","BottomBarCenterControls","handlePrevious","ArrowShuffleFilled","ArrowShuffleOffFilled","PreviousFilled","PauseFilled","PlayFilled","NextFilled","VolumeButton","isVolumePopoverOpen","setIsVolumePopoverOpen","toggleVolumePopover","MoreOptionsButton","isMoreOptionsPopoverOpen","setIsMoreOptionsPopoverOpen","toggleMoreOptionsPopover","MoreHorizontalFilled","BottomBarRightControls","BottomBar","EuiBottomBar","EuiFlexItem","AddVideoModal","onCancel","onSave","url","setUrl","title","setTitle","loading","setLoading","EuiModal","EuiModalHeader","EuiModalHeaderTitle","EuiModalBody","EuiForm","EuiFieldText","EuiModalFooter","EuiButtonEmpty","EuiButton","isNoembedResult","AddVideoButton","addVideoModalOpen","setAddVideoModalOpen","handleSave","videoService","findVideoService","videoId","jsonData","AddRegular","PlayQueueTableHeader","euiTheme","useEuiTheme","EuiTableHeader","EuiTableHeaderCellCheckbox","EuiCheckbox","EuiTableHeaderCell","PlayQueueTableRowContextMenuPanel","item","ContextMenuItem","onClick","props","handleClick","EuiContextMenuItem","EuiContextMenuPanel","EuiHorizontalRule","ArrowUploadRegular","ArrowDownloadRegular","PlayQueueTableRowPopover","setIsOpen","togglePopover","PlayQueueTableRowActionsCell","EuiTableRowCell","PlayRegular","videoServiceIcons","PlayQueueTableRow","EuiTableRow","EuiTableRowCellCheckbox","EuiLink","PlayQueueTableBody","ReactSortable","items","PlayQueueTable","EuiTable","DeveloperToolsButton","isFlyoutVisible","setIsFlyoutVisible","EuiFlyout","EuiCodeBlock","PlayQueue","DeleteRegular","EuiSpacer","HydrangeanDiva","EuiPageTemplate","miniPlayerSize","MiniPlayer","handleLoaded","handleEnded","options","NostalgicDiva","MobXObservableStateProvider","target","annotations","makeObservable","_PlayQueueItemStore","observableStateProvider","dto","__publicField","observable","computed","action","PlayQueueItemStore","ajv","Ajv","getOrAddSchema","schema","keyRef","validate","PlayQueueLocalStorageStateSchema","validatePlayQueueLocalStorageState","PlayQueueStore","_a","localStorageState","currentIndex","index","element","currentItem","pull","isLastItem","itemId","itemIndex","_","PlayQueueStoreContext","createContext","PlayQueueStoreProvider","children","useEffect","reaction","previousItem","usePlayQueueStore","useContext","MediaPlayerLayout","PlayerStore","PlayerStoreContext","PlayerStoreProvider","usePlayerStore","ObservableStateProvider"],"mappings":"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"}