xrfragment-haxe/src/3rd/js/plugin/remotestorage/remotestorage.js

257 lines
7.9 KiB
JavaScript
Raw Normal View History

2025-05-09 18:19:10 +02:00
// this demonstrates the remotestorage aframe component
// reactive component for displaying the menu
remoteStorageComponent = (el) => new Proxy({
2025-05-14 09:48:33 +02:00
html: (data) => (`
2025-05-09 18:19:10 +02:00
<style type="text/css">
2025-05-14 09:48:33 +02:00
body #files .rs-button-big{
background: #FFF;
box-shadow: none;
border: 1px solid #CCC;
padding: 10px 0px 49px 10px;
}
#files .rs-button{
background:#CCC;
2025-05-09 18:19:10 +02:00
}
2025-05-15 18:48:49 +02:00
#files input {
min-width:345px;
}
#files #buttons select,
#files #buttons button{
width:255px;
max-width:unset;
}
#files #listing{
margin-bottom:15px;
}
#files #delete{
display: none;
transform: translate(10px, 5px);
}
#links{
display:none
}
2025-05-09 18:19:10 +02:00
</style>
<div id="remoteFilesTab">
<div id="rswidget"></div>
2025-05-14 09:48:33 +02:00
<br>
<div id="buttons" style="display:none">
2025-05-15 18:48:49 +02:00
<select id="listing" alt="your files"></select>
<i class="gg-close-o" id="delete" alt="delete" onclick="$remotestorage.remove()"></i>
<a href="https://inspektor.5apps.com/?path=%2Fwebxr%2F" target="_blank" style="margin-left:15px">manage files</a>
<br>
<button onclick="$remotestorage.savePrivate()"><i class="gg-software-download"></i> save experience</button>
2025-05-14 09:48:33 +02:00
<br>
2025-05-15 18:48:49 +02:00
<button onclick="$remotestorage.savePublic()" ><i class="gg-globe-alt"></i> publish online</button>
2025-05-14 09:48:33 +02:00
<br>
2025-05-15 18:48:49 +02:00
<div id="links">
<br>
<div><i class="gg-link"></i>&nbsp;&nbsp;&nbsp;3D file</div>
<input type="text" value='' id="file">
<br>
<div><i class="gg-link"></i>&nbsp;&nbsp;&nbsp;3D file in webviewer</div>
<input type="text" value='' id="webviewer">
</div>
2025-05-14 09:48:33 +02:00
</div>
2025-05-09 18:19:10 +02:00
</div>
2025-05-14 09:48:33 +02:00
`),
2025-05-09 18:19:10 +02:00
2025-05-14 09:48:33 +02:00
connected: false,
2025-05-15 18:48:49 +02:00
$listing: false,
$links: false,
2025-05-09 18:19:10 +02:00
init(opts){
// create HTML element
2025-05-15 18:48:49 +02:00
$files.tabs = $files.tabs.concat({id:"remoteFiles", name: "remote storage"})
2025-05-14 09:48:33 +02:00
el.innerHTML = this.html(this)
2025-05-09 18:19:10 +02:00
el.className = "tab"
document.querySelector("#files .tab-frame").appendChild(el);
2025-05-15 18:48:49 +02:00
// setup references
this.$listing = document.querySelector('#files .tab-frame select#listing');
this.$links = document.querySelector('#files .tab-frame #links');
2025-05-09 18:19:10 +02:00
// setup input listeners
(['click']).map( (e) => el.addEventListener(e, (ev) => typeof this[e] == 'function' && this[e](ev.target.id,ev) ) )
2025-05-15 18:48:49 +02:00
2025-05-09 18:19:10 +02:00
// signal ready
setTimeout( () => {
document.dispatchEvent( new CustomEvent("remotestorage:ready", {detail: {$files:this,xrf}}) )
},100)
this.loadScript( () => this.initRemoteStorage() )
return this
},
loadScript(cb){
let el = document.createElement("script")
el.setAttribute("defer","")
el.src = "https://unpkg.com/remotestoragejs@2.0.0-beta.7/release/remotestorage.js"
document.head.appendChild(el)
el = document.createElement("script")
el.src = "https://unpkg.com/remotestorage-widget@1.6.0/build/widget.js"
el.addEventListener('load', () => setTimeout(cb,2000) )
document.head.appendChild(el)
},
initRemoteStorage(){
let apis = {
dropbox: "4jc8nx1lbarp472"
}
2025-05-14 09:48:33 +02:00
const modules = []
2025-05-15 18:48:49 +02:00
if( typeof WebXR != undefined ){
modules.push(WebXR) // defined in remotestorage-module-webXRF.js
2025-05-14 09:48:33 +02:00
}
window.remoteStorage = new RemoteStorage({logging: true, modules })
2025-05-09 18:19:10 +02:00
if( Object.keys(apis).length ) remoteStorage.setApiKeys(apis)
2025-05-15 18:48:49 +02:00
remoteStorage.on('not-connected', (e) => { this.connected = false })
remoteStorage.on('ready', (e) => { })
remoteStorage.on('connected', (e) => {
this.connected = true
// force open dialog and click remote-tab
frontend.$topbar.toggle(true)
$files.toggle(true)
document.querySelector("#files input#remoteFiles").click()
2025-05-09 18:19:10 +02:00
2025-05-15 18:48:49 +02:00
this.updateFiles()
})
remoteStorage.access.claim( `webxr`, 'rw'); // our data dir
remoteStorage.caching.enable( `/webxr/` ) // local-first, remotestorage-second
remoteStorage.caching.enable( `/public/webxr/` ) // local-first, remotestorage-second
2025-05-09 18:19:10 +02:00
// create widget
let opts = {}
opts.modalBackdrop = false
2025-05-14 09:48:33 +02:00
opts.leaveOpen = true
2025-05-09 18:19:10 +02:00
widget = new window.Widget(window.remoteStorage, opts)
widget.attach( "rswidget" );
},
2025-05-15 18:48:49 +02:00
savePrivate(){
frontend.download( (data,filename) => {
filename = prompt('save-as filename', filename)
remoteStorage.webxr.add(data,{public:false,filename,mimetype: 'model/glb-binary'})
.then( () => window.notify(`saved webxr/${filename} to remote storage`) )
.catch( (e) => {
console.error(e)
window.notify(`failed to save webxr/${filename} to remote storage`,{status:'error'})
})
})
},
savePublic(){
frontend.download( (data,filename) => {
filename = prompt('save-as filename', filename)
opts = {public:true,filename,mimetype: 'model/glb-binary'}
remoteStorage.webxr.add(data,opts)
.then( (res) => {
window.notify(`saved webxr/${filename} to remote storage`)
const link = opts.client.storage.remote.href + opts.client.base + filename
const linkWebView = document.location.href.replace(/(\?|#).*/,'') + `?${link}`
this.$links.querySelector("#file").value = link
this.$links.querySelector("#webviewer").value = linkWebView
this.$links.style.display = 'block'
})
.catch( (e) => {
console.error(e)
window.notify(`failed to save webxr/${filename} to remote storage`,{status:'error'})
})
})
},
openPrivate(file){
if( !confirm(`teleport to ${file} on your remotestorage?`) ) return
remoteStorage.webxr.getFile(file)
.then( (res) => {
for( var i in xrf.loaders ){
if( file.replace(/.*\./).match(i) ){
xrf.navigator.URI.file = '' // bypass cached file (easy refresh same file for testing)
xrf.navigator.to(file,null, (new xrf.loaders[i]()), res.data)
return
}
}
throw 'unknown filetype: '+file
})
.catch( (e) => {
console.error(e)
window.notify("could not load webxr/"+file)
})
},
remove(){
const currentFile = el.querySelector('select#listing').value
if( confirm("remove "+currentFile+" from remote storage?") ){
remoteStorage.webxr.remove(currentFile)
.then( () => {
window.notify(`removed webxr/${filename} from remote storage`)
this.updateFiles()
})
.catch( (e) => {
console.error(e)
window.notify(`could not webxr/${filename} from remote storage`,{status:'error'})
})
}
},
updateFiles(){
remoteStorage.webxr.getListing()
.then( (listing) => {
this.$listing.innerHTML = '' // empty
const addOption = (value,text) => {
let opt = document.createElement("option")
opt.text = text
opt.value = value
this.$listing.appendChild(opt)
}
addOption("","--- your experiences ---")
for( let file in listing ){
if( file.match(/\.(glb|gltf|usd|obj|col|fbx)$/) ) addOption(file,file)
}
// autoload selection
if( !this.updateFiles.autoload ){ // run once
this.$listing.addEventListener('change', () => {
if( this.$listing.options.selectedIndex > 0 ) this.openPrivate(this.$listing.value)
document.querySelector("#delete").style.display = this.$listing.options.selectedIndex == 0 ? "none" : "inline-block"
this.$links.style.display = 'none'
})
this.updateFiles.autoload = true
}
})
},
2025-05-09 18:19:10 +02:00
click(id,e){
2025-05-14 09:48:33 +02:00
//switch(id){
// case "more": return this.toggle(); break;
//}
2025-05-09 18:19:10 +02:00
}
},
{
get(me,k,v){ return me[k] },
set(me,k,v){
me[k] = v
2025-05-14 09:48:33 +02:00
switch( k ){
case 'connected': el.querySelector("#buttons").style.display = v ? 'block' : 'none'; break;
}
2025-05-09 18:19:10 +02:00
},
})
// reactify component!
document.addEventListener('$files:ready', (e) => {
window.$remotestorage = remoteStorageComponent( document.createElement('div') ).init(e.detail)
})