wip: remotestorage
This commit is contained in:
parent
076a6ca86a
commit
52f79a44c5
7 changed files with 358 additions and 85 deletions
|
|
@ -86,6 +86,7 @@
|
|||
<script src="./../../../dist/xrfragment.plugin.matrix.js"></script> <!-- matrix connectivity -->
|
||||
<script src="./../../../dist/xrfragment.plugin.network.js"></script> <!-- matrix and webrtc chat/scene examples -->
|
||||
<script src="./../../../dist/xrfragment.plugin.editor.js"></script> <!-- basic editor example -->
|
||||
<script src="./../../../dist/xrfragment.plugin.remotestorage.js"></script><!-- basic remotestorage example -->
|
||||
<script src="./../../../dist/xrfragment.plugin.frontend.css.js"></script> <!-- basic menu interface css -->
|
||||
<script src="./../../../dist/xrfragment.plugin.frontend.js"></script> <!-- basic menu interface -->
|
||||
|
||||
|
|
|
|||
3
make
3
make
|
|
@ -123,10 +123,11 @@ build(){
|
|||
cp src/3rd/js/plugin/frontend/\$editor.js dist/xrfragment.plugin.editor.js
|
||||
|
||||
cp src/3rd/js/plugin/frontend/css.js dist/xrfragment.plugin.frontend.css.js
|
||||
jscat src/3rd/js/plugin/frontend/{snackbar,accessibility,\$menu,frontend,chatcommand/*,joystick,tab-to-href,remotestorage}.js > dist/xrfragment.plugin.frontend.js
|
||||
jscat src/3rd/js/plugin/frontend/{snackbar,accessibility,\$menu,\$files,frontend,chatcommand/*,joystick,tab-to-href}.js > dist/xrfragment.plugin.frontend.js
|
||||
|
||||
jscat src/3rd/js/plugin/matrix/{matrix-crdt,matrix}.js > dist/xrfragment.plugin.matrix.js
|
||||
jscat src/3rd/js/plugin/p2p/{trystero-torrent.min,trystero}.js > dist/xrfragment.plugin.p2p.js
|
||||
jscat src/3rd/js/plugin/remotestorage/*.js > dist/xrfragment.plugin.remotestorage.js
|
||||
|
||||
# all in one
|
||||
cat dist/aframe.min.js dist/aframe-blink-controls.min.js dist/xrfragment.aframe.js > dist/xrfragment.aframe.all.js
|
||||
|
|
|
|||
113
src/3rd/js/plugin/frontend/$files.js
Normal file
113
src/3rd/js/plugin/frontend/$files.js
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
|
||||
// reactive component for displaying the menu
|
||||
filesComponent = (el) => new Proxy({
|
||||
|
||||
html: (data) => `
|
||||
<style type="text/css">
|
||||
#messages .msg.ui, #messages .msg.ui #files div {
|
||||
border:none;
|
||||
padding:0;
|
||||
margin:0;
|
||||
box-shadow:none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="ui envelope">
|
||||
<div class="msg ui">
|
||||
<div>
|
||||
<div id="files">
|
||||
<i class="gg-close-o" id="close" onclick="$files.visible = false"></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>
|
||||
<div class="tab">
|
||||
<div id="localFilesTab">
|
||||
<button id="uploadFile" ><i class="gg-software-upload"></i> upload</button>
|
||||
<button id="downloadfile"><i class="gg-software-download"></i> download</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
||||
tabs: [
|
||||
{name: "local files", id: "localFiles"}
|
||||
],
|
||||
|
||||
show: false,
|
||||
$localFiles: $localFiles = el.querySelector("#localFiles"),
|
||||
|
||||
toggle(state){
|
||||
this.show = state !== undefined ? state : !this.show
|
||||
},
|
||||
|
||||
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.fileLoader = 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)
|
||||
})
|
||||
|
|
@ -740,6 +740,7 @@ document.head.innerHTML += `
|
|||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-right:5px;
|
||||
transform: scale(var(--ggs,1)) translate(3px,3px);
|
||||
width: 16px;
|
||||
height: 6px;
|
||||
|
|
@ -847,5 +848,47 @@ document.head.innerHTML += `
|
|||
left: -11px;
|
||||
top: -2px
|
||||
}
|
||||
|
||||
.gg-software-upload {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-right:5px;
|
||||
transform: scale(var(--ggs, 1));
|
||||
width: 16px;
|
||||
height: 6px;
|
||||
border: 2px solid;
|
||||
border-top: 0;
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
.gg-software-upload::after {
|
||||
content: "";
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-left: 2px solid;
|
||||
border-top: 2px solid;
|
||||
transform: rotate(45deg);
|
||||
left: 2px;
|
||||
bottom: 4px;
|
||||
}
|
||||
.gg-software-upload::before {
|
||||
content: "";
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
border-radius: 3px;
|
||||
width: 2px;
|
||||
height: 10px;
|
||||
background: currentColor;
|
||||
left: 5px;
|
||||
bottom: 3px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
`
|
||||
|
|
|
|||
94
src/3rd/js/plugin/frontend/filedialog.js
Normal file
94
src/3rd/js/plugin/frontend/filedialog.js
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
// reactive component for displaying the menu
|
||||
filesComponent = (el) => new Proxy({
|
||||
|
||||
html: `
|
||||
<div class="ui envelope">
|
||||
<div class="msg ui">
|
||||
<div>
|
||||
<div id="files">
|
||||
<i class="gg-close-o" id="close" onclick="$files.visible = false"></i>
|
||||
<br>
|
||||
<div class="tab-frame">
|
||||
<input type="radio" name="tab" id="login" checked="">
|
||||
<label for="login">local files</label>
|
||||
|
||||
<div class="tab">
|
||||
<div id="localFiles"><div><div>
|
||||
<a class="badge ruler">Peer2Peer</a><br>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td>nickname</td>
|
||||
<td>
|
||||
<input type="text" id="nickname" placeholder="your nickname" maxlength="18" onkeydown="trystero.nickname = this.value">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div></div>
|
||||
<table>
|
||||
<tbody><tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button id="connect" onclick="network.connect( $connections )">📡 Connect!</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
||||
collapsed: false,
|
||||
$localFiles: $localFiles = el.querySelector("#localFiles"),
|
||||
|
||||
toggle(state){
|
||||
this.collapsed = state !== undefined ? state : !this.collapsed
|
||||
},
|
||||
|
||||
init(opts){
|
||||
el.innerHTML = this.html
|
||||
document.querySelector("#messages").appendChild(el);
|
||||
(['click']).map( (e) => el.addEventListener(e, (ev) => this[e] && this[e](ev.target.id,ev) ) )
|
||||
setTimeout( () => {
|
||||
document.dispatchEvent( new CustomEvent("$files:ready", {detail: {$files:this,xrf}}) )
|
||||
},100)
|
||||
return this
|
||||
},
|
||||
|
||||
click(id,e){
|
||||
switch(id){
|
||||
case "icon":
|
||||
case "more": return this.toggle(); break;
|
||||
}
|
||||
this.toggle(false)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
get(me,k,v){ return me[k] },
|
||||
|
||||
set(me,k,v){
|
||||
me[k] = v
|
||||
switch( k ){
|
||||
case "buttons": el.querySelector("#buttons").innerHTML = this.renderButtons(me);
|
||||
document.dispatchEvent( new CustomEvent("$menu:buttons:render", {detail: el.querySelector('.menu') }) )
|
||||
break;
|
||||
case "collapsed":
|
||||
el.querySelector("#buttons").style.display = me.collapsed ? 'block' : 'none'
|
||||
frontend.emit('$menu:collapse', v)
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
renderButtons: (data) => `${data.buttons.join('')}`
|
||||
|
||||
})
|
||||
|
||||
// reactify component!
|
||||
document.addEventListener('frontend:ready', (e) => {
|
||||
window.$files = filesComponent( document.createElement('div') ).init(e.detail)
|
||||
})
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
// this demonstrates the remotestorage aframe component
|
||||
|
||||
|
||||
document.addEventListener('frontend:ready', (e) => {
|
||||
|
||||
function 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)
|
||||
}
|
||||
|
||||
function addStyles(){
|
||||
let el = document.createElement('style')
|
||||
el.type = 'text/css'
|
||||
el.innerHTML = `
|
||||
|
||||
#remotestorage-widget {
|
||||
left: 0;
|
||||
position: fixed;
|
||||
display:block;
|
||||
}
|
||||
body.menu #remotestorage-widget{
|
||||
top: 50px;
|
||||
}
|
||||
body #remotestorage-widget {
|
||||
top: 0px;
|
||||
}
|
||||
`
|
||||
document.head.appendChild(el)
|
||||
}
|
||||
|
||||
function addButtons(){
|
||||
const $widget = document.querySelector(".rs-widget")
|
||||
debugger
|
||||
|
||||
const $btnLoad = document.createElement('button')
|
||||
const $btnSave = document.createElement('button')
|
||||
$btnLoad.innerText = 'load'
|
||||
$btnSave.innerText = 'save'
|
||||
$widget.appendChild($btnLoad)
|
||||
$widget.appendChild($btnSave)
|
||||
}
|
||||
|
||||
function init(){
|
||||
let apis = {}
|
||||
window.remoteStorage = new RemoteStorage({logging: true })
|
||||
if( Object.keys(apis).length ) remoteStorage.setApiKeys(apis)
|
||||
|
||||
remoteStorage.on('connected', (e) => { console.log("connected") } )
|
||||
//remoteStorage.on('network-offline', (e) => this.el.sceneEl.emit('remoteStorage.network-offline',e) )
|
||||
//remoteStorage.on('network-online', (e) => this.el.sceneEl.emit('remoteStorage.network-online',e) )
|
||||
//remoteStorage.on('error', (e) => this.el.sceneEl.emit('remoteStorage.error',e) )
|
||||
//remoteStorage.on('ready', (e) => { } )
|
||||
|
||||
remoteStorage.access.claim( `webxr`, 'rw'); // our data dir
|
||||
remoteStorage.caching.enable( `/webxr/` ) // local-first, remotestorage-second
|
||||
|
||||
}
|
||||
|
||||
addStyles()
|
||||
loadScript(init)
|
||||
|
||||
// decorate fileLoaders
|
||||
window.frontend.fileLoaders = (function(fileLoaders){
|
||||
return function(){
|
||||
// show rs widgets
|
||||
if( !document.querySelector("#remotestorage-widget") ){
|
||||
let opts = {}
|
||||
opts.modalBackdrop = false
|
||||
widget = new window.Widget(window.remoteStorage, opts)
|
||||
widget.attach();
|
||||
addButtons()
|
||||
}
|
||||
|
||||
//fileLoaders()
|
||||
}
|
||||
})( window.frontend.fileLoaders )
|
||||
})
|
||||
105
src/3rd/js/plugin/remotestorage/remotestorage.js
Normal file
105
src/3rd/js/plugin/remotestorage/remotestorage.js
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
// this demonstrates the remotestorage aframe component
|
||||
|
||||
// reactive component for displaying the menu
|
||||
remoteStorageComponent = (el) => new Proxy({
|
||||
|
||||
html: `
|
||||
<style type="text/css">
|
||||
body div#remotestorage-widget .rs-button{
|
||||
background: #AAA;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="remoteFilesTab">
|
||||
<div id="rswidget"></div>
|
||||
<br><br>
|
||||
<button id="uploadFile" ><i class="gg-software-upload"></i> upload</button>
|
||||
<button id="downloadfile"><i class="gg-software-download"></i> download</button>
|
||||
</div>
|
||||
`,
|
||||
|
||||
show: false,
|
||||
|
||||
toggle(state){
|
||||
this.show = state !== undefined ? state : !this.show
|
||||
},
|
||||
|
||||
init(opts){
|
||||
// create HTML element
|
||||
$files.tabs = $files.tabs.concat({id:"remoteFiles", name: "remote files"})
|
||||
el.innerHTML = this.html
|
||||
el.className = "tab"
|
||||
this.toggle(this.show) // trigger visibility
|
||||
document.querySelector("#files .tab-frame").appendChild(el);
|
||||
|
||||
// setup input listeners
|
||||
(['click']).map( (e) => el.addEventListener(e, (ev) => typeof this[e] == 'function' && this[e](ev.target.id,ev) ) )
|
||||
|
||||
// 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"
|
||||
}
|
||||
window.remoteStorage = new RemoteStorage({logging: true })
|
||||
if( Object.keys(apis).length ) remoteStorage.setApiKeys(apis)
|
||||
|
||||
remoteStorage.on('connected', (e) => { console.log("connected") } )
|
||||
//remoteStorage.on('network-offline', (e) => this.el.sceneEl.emit('remoteStorage.network-offline',e) )
|
||||
//remoteStorage.on('network-online', (e) => this.el.sceneEl.emit('remoteStorage.network-online',e) )
|
||||
//remoteStorage.on('error', (e) => this.el.sceneEl.emit('remoteStorage.error',e) )
|
||||
//remoteStorage.on('ready', (e) => { } )
|
||||
|
||||
remoteStorage.access.claim( `webxr`, 'rw'); // our data dir
|
||||
remoteStorage.caching.enable( `/webxr/` ) // local-first, remotestorage-second
|
||||
|
||||
// create widget
|
||||
let opts = {}
|
||||
opts.modalBackdrop = false
|
||||
widget = new window.Widget(window.remoteStorage, opts)
|
||||
widget.attach( "rswidget" );
|
||||
|
||||
},
|
||||
|
||||
click(id,e){
|
||||
switch(id){
|
||||
case "icon":
|
||||
case "more": return this.toggle(); break;
|
||||
}
|
||||
this.toggle(false)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
get(me,k,v){ return me[k] },
|
||||
|
||||
set(me,k,v){
|
||||
me[k] = v
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
// reactify component!
|
||||
document.addEventListener('$files:ready', (e) => {
|
||||
window.$remotestorage = remoteStorageComponent( document.createElement('div') ).init(e.detail)
|
||||
})
|
||||
Loading…
Add table
Reference in a new issue