xrfragment/src/3rd/js/plugin/frontend/$files.js

122 lines
3.2 KiB
JavaScript

// reactive component for displaying the menu
filesComponent = (el) => new Proxy({
html: (data) => `
<style type="text/css">
#messages .msg.ui #files div {
border:none;
padding:0;
border-radius:0;
margin:0;
box-shadow:none;
}
.msg.ui #files{
min-width:415px;
}
</style>
<div class="ui envelope">
<div class="msg ui">
<div>
<div id="files">
<i class="gg-close-o" id="close" onclick="$files.remove()"></i>
<br>
<div class="tab-frame">
${data.tabs.map( (t) =>
` <input type="radio" name="tab" id="${t.id}" ${t.id == "localFiles" ? 'checked="checked"' : '' }>
<label for="${t.id}">${t.name}</label>
`
).join('')
}
<br><br><br>
<div class="tab">
<div id="localFilesTab">
<button id="localOpen" onclick="$files.fileLoaders()" ><i class="gg-software-upload"></i> open experience</button>
<br>
<button id="localSave" onclick="frontend.download()"><i class="gg-software-download"></i> save current</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`,
tabs: [
{name: "offline", id: "localFiles"}
],
show: false,
$localFiles: $localFiles = el.querySelector("#localFiles"),
toggle(state){
this.show = state !== undefined ? state : !this.show
},
remove(){
el.parent.remove(el)
},
init(opts){
this.decorateFileButton()
// create HTML element
el.innerHTML = this.html(this)
for( i in this ) el[i] = this[i]
this.toggle(this.show) // trigger visibility
document.querySelector("#messages").appendChild(el);
// setup input listeners
(['click']).map( (e) => el.addEventListener(e, (ev) => this[e] && this[e](ev.target.id,ev) ) )
// signal ready
setTimeout( () => {
document.dispatchEvent( new CustomEvent("$files:ready", {detail: {$files:this,xrf}}) )
},100)
return this
},
decorateFileButton: function(){
// rename button
document.querySelector("#load").setAttribute("value","3D file")
// decorate fileLoaders
window.frontend.fileLoaders = ( (fileLoaders) => {
this.fileLoaders = fileLoaders
return () => this.toggle()
})( window.frontend.fileLoaders )
},
click(id,e){
switch(id){
case "icon":
case "more": return this.toggle(); break;
}
}
},
{
get(me,k,v){ return me[k] },
set(me,k,v){
me[k] = v
switch( k ){
case "show":{
el.style.display = v ? '' : 'none';
if( v ) $chat.visible = true
break;
}
case "tabs":{
el.innerHTML = $files.html($files)
break;
}
}
},
renderButtons: (data) => `${data.buttons.join('')}`
})
// reactify component!
document.addEventListener('$chat:ready', (e) => {
window.$files = filesComponent( document.createElement('div') ).init(e.detail)
})