work in progress [might break]

This commit is contained in:
Leon van Kammen 2023-12-15 17:19:04 +01:00
parent 3c8841f181
commit 061ea4b4cb
8 changed files with 22798 additions and 61 deletions

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Fri Dec 15 04:23:00 PM CET 2023 * v0.5.1 generated at Fri Dec 15 05:17:47 PM CET 2023
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: MPL-2.0 * SPDX-License-Identifier: MPL-2.0
*/ */
@ -662,16 +662,16 @@ window.XRFMENU = {
// enable meetings // enable meetings
let startMeeting = () => { let startMeeting = () => {
aScene.setAttribute('meeting', 'id: xrfragments') aScene.setAttribute('meeting', 'id: xrfragments')
$('a#meeting').innerText = '📍 new meeting location' $('a#meeting').innerText = '🧑‍🤝‍🧑 breakout meeting'
$('a#meeting').setAttribute('aria-description','breakout room')
} }
$('a#meeting').addEventListener('click', () => { $('a#meeting').addEventListener('click', () => {
if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room
let parentRoom = document.location.href let parentRoom = document.location.href
XRFMENU.updateHashPosition(true) XRFMENU.updateHashPosition(true)
let visitorname = aScene.getAttribute("meeting").visitorname let meeting = $('[meeting]').components['meeting']
aScene.removeAttribute('meeting') meeting.data.parentRoom = parentRoom
// breakoutroom meeting.update()
aScene.setAttribute('meeting', `id: xrfragments; visitorname: ${visitorname}; parentRoom: ${parentRoom}`)
}else startMeeting() }else startMeeting()
}) })
if( document.location.hash.match(/(#|&)meet/) ) startMeeting() if( document.location.hash.match(/(#|&)meet/) ) startMeeting()
@ -3161,6 +3161,12 @@ AFRAME.registerComponent('meeting', {
if( this.room ) this.room.leave() if( this.room ) this.room.leave()
this.meeting.remove() this.meeting.remove()
}, },
update: function(){
setTimeout( () => {
this.remove()
this.init()
},100)
},
init: function(){ init: function(){
// embed https://github.com/dmotz/trystero (trystero-torrent.min.js build) // embed https://github.com/dmotz/trystero (trystero-torrent.min.js build)
@ -3282,7 +3288,7 @@ AFRAME.registerComponent('meeting', {
this.initChatLine() this.initChatLine()
if( !this.data.visitorname ) this.chat.append("💁 Hi there! Please enter your name") if( !this.data.visitorname ) this.chat.append("Please enter your name below",["info"])
else{ else{
if( this.data.parentRoom ) this.chat.append(`leaving ${this.data.parentRoom}`,["info"]); if( this.data.parentRoom ) this.chat.append(`leaving ${this.data.parentRoom}`,["info"]);
this.trysteroInit() this.trysteroInit()
@ -3441,7 +3447,7 @@ AFRAME.registerComponent('meeting', {
if( e.key !== "Enter" ) return if( e.key !== "Enter" ) return
if( !this.data.visitorname ){ if( !this.data.visitorname ){
this.data.visitorname = chatline.value this.data.visitorname = chatline.value
this.chat.append("btw. camera/mic access is totally optional ♥️") this.chat.append("note: camera/mic access is totally optional ♥️",["info"])
this.trysteroInit() this.trysteroInit()
}else{ }else{
let str = `${this.idsToNames[ this.room.selfId ]}: ${chatline.value.substr(0,65515).trim()}` let str = `${this.idsToNames[ this.room.selfId ]}: ${chatline.value.substr(0,65515).trim()}`
@ -3487,15 +3493,19 @@ AFRAME.registerComponent('meeting', {
a.push(t1) a.push(t1)
t = t2.join(x) t = t2.join(x)
let y = (!(x.match(/:\/\//)) ? 'https://' : '') + x let y = (!(x.match(/:\/\//)) ? 'https://' : '') + x
let attr = 'target="_blank"'
if (isNaN(x) ){ if (isNaN(x) ){
let url_human = y.split('/')[2] let url_human = y.split('/')[2]
let isXRFragment = y.match("pos=") let isXRFragment = y.match(/\.(glb|gltf|obj|usdz|fbx|col)/)
if( isXRFragment ){ // detect xr fragments if( isXRFragment ){ // detect xr fragments
url_human = y.replace(/.*[?\?]/,'') // shorten xr fragment links isMeeting = y.match(/(#|&)meet/)
url_human = y.replace(/.*[?\?]/,'') // shorten xr fragment links
.replace(/[?\&]meet/,'') .replace(/[?\&]meet/,'')
y = y.replace(/.*[\?]/, '?') // start from search (to prevent page-refresh) y = y.replace(/.*[\?]/, '?') // start from search (to prevent page-refresh)
attr = ''
if( isMeeting ) attr = `onclick="$('[meeting]').components['meeting'].update()"`
} }
a.push(`<a href="${y}" ${isXRFragment ? '' : `target="_blank"`} style="pointer-events:all">${url_human}</a>`) a.push(`<a href="${y}" ${attr} style="pointer-events:all">${url_human}</a>`)
}else }else
a.push(x) a.push(x)
}) })

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Fri Dec 15 04:23:00 PM CET 2023 * v0.5.1 generated at Fri Dec 15 05:17:47 PM CET 2023
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: MPL-2.0 * SPDX-License-Identifier: MPL-2.0
*/ */
@ -656,16 +656,16 @@ window.XRFMENU = {
// enable meetings // enable meetings
let startMeeting = () => { let startMeeting = () => {
aScene.setAttribute('meeting', 'id: xrfragments') aScene.setAttribute('meeting', 'id: xrfragments')
$('a#meeting').innerText = '📍 new meeting location' $('a#meeting').innerText = '🧑‍🤝‍🧑 breakout meeting'
$('a#meeting').setAttribute('aria-description','breakout room')
} }
$('a#meeting').addEventListener('click', () => { $('a#meeting').addEventListener('click', () => {
if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room
let parentRoom = document.location.href let parentRoom = document.location.href
XRFMENU.updateHashPosition(true) XRFMENU.updateHashPosition(true)
let visitorname = aScene.getAttribute("meeting").visitorname let meeting = $('[meeting]').components['meeting']
aScene.removeAttribute('meeting') meeting.data.parentRoom = parentRoom
// breakoutroom meeting.update()
aScene.setAttribute('meeting', `id: xrfragments; visitorname: ${visitorname}; parentRoom: ${parentRoom}`)
}else startMeeting() }else startMeeting()
}) })
if( document.location.hash.match(/(#|&)meet/) ) startMeeting() if( document.location.hash.match(/(#|&)meet/) ) startMeeting()
@ -3155,6 +3155,12 @@ AFRAME.registerComponent('meeting', {
if( this.room ) this.room.leave() if( this.room ) this.room.leave()
this.meeting.remove() this.meeting.remove()
}, },
update: function(){
setTimeout( () => {
this.remove()
this.init()
},100)
},
init: function(){ init: function(){
// embed https://github.com/dmotz/trystero (trystero-torrent.min.js build) // embed https://github.com/dmotz/trystero (trystero-torrent.min.js build)
@ -3276,7 +3282,7 @@ AFRAME.registerComponent('meeting', {
this.initChatLine() this.initChatLine()
if( !this.data.visitorname ) this.chat.append("💁 Hi there! Please enter your name") if( !this.data.visitorname ) this.chat.append("Please enter your name below",["info"])
else{ else{
if( this.data.parentRoom ) this.chat.append(`leaving ${this.data.parentRoom}`,["info"]); if( this.data.parentRoom ) this.chat.append(`leaving ${this.data.parentRoom}`,["info"]);
this.trysteroInit() this.trysteroInit()
@ -3435,7 +3441,7 @@ AFRAME.registerComponent('meeting', {
if( e.key !== "Enter" ) return if( e.key !== "Enter" ) return
if( !this.data.visitorname ){ if( !this.data.visitorname ){
this.data.visitorname = chatline.value this.data.visitorname = chatline.value
this.chat.append("btw. camera/mic access is totally optional ♥️") this.chat.append("note: camera/mic access is totally optional ♥️",["info"])
this.trysteroInit() this.trysteroInit()
}else{ }else{
let str = `${this.idsToNames[ this.room.selfId ]}: ${chatline.value.substr(0,65515).trim()}` let str = `${this.idsToNames[ this.room.selfId ]}: ${chatline.value.substr(0,65515).trim()}`
@ -3481,15 +3487,19 @@ AFRAME.registerComponent('meeting', {
a.push(t1) a.push(t1)
t = t2.join(x) t = t2.join(x)
let y = (!(x.match(/:\/\//)) ? 'https://' : '') + x let y = (!(x.match(/:\/\//)) ? 'https://' : '') + x
let attr = 'target="_blank"'
if (isNaN(x) ){ if (isNaN(x) ){
let url_human = y.split('/')[2] let url_human = y.split('/')[2]
let isXRFragment = y.match("pos=") let isXRFragment = y.match(/\.(glb|gltf|obj|usdz|fbx|col)/)
if( isXRFragment ){ // detect xr fragments if( isXRFragment ){ // detect xr fragments
url_human = y.replace(/.*[?\?]/,'') // shorten xr fragment links isMeeting = y.match(/(#|&)meet/)
url_human = y.replace(/.*[?\?]/,'') // shorten xr fragment links
.replace(/[?\&]meet/,'') .replace(/[?\&]meet/,'')
y = y.replace(/.*[\?]/, '?') // start from search (to prevent page-refresh) y = y.replace(/.*[\?]/, '?') // start from search (to prevent page-refresh)
attr = ''
if( isMeeting ) attr = `onclick="$('[meeting]').components['meeting'].update()"`
} }
a.push(`<a href="${y}" ${isXRFragment ? '' : `target="_blank"`} style="pointer-events:all">${url_human}</a>`) a.push(`<a href="${y}" ${attr} style="pointer-events:all">${url_human}</a>`)
}else }else
a.push(x) a.push(x)
}) })

22714
dist/xrfragment.module.js vendored

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Fri Dec 15 04:23:00 PM CET 2023 * v0.5.1 generated at Fri Dec 15 05:17:47 PM CET 2023
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: MPL-2.0 * SPDX-License-Identifier: MPL-2.0
*/ */
@ -656,16 +656,16 @@ window.XRFMENU = {
// enable meetings // enable meetings
let startMeeting = () => { let startMeeting = () => {
aScene.setAttribute('meeting', 'id: xrfragments') aScene.setAttribute('meeting', 'id: xrfragments')
$('a#meeting').innerText = '📍 new meeting location' $('a#meeting').innerText = '🧑‍🤝‍🧑 breakout meeting'
$('a#meeting').setAttribute('aria-description','breakout room')
} }
$('a#meeting').addEventListener('click', () => { $('a#meeting').addEventListener('click', () => {
if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room
let parentRoom = document.location.href let parentRoom = document.location.href
XRFMENU.updateHashPosition(true) XRFMENU.updateHashPosition(true)
let visitorname = aScene.getAttribute("meeting").visitorname let meeting = $('[meeting]').components['meeting']
aScene.removeAttribute('meeting') meeting.data.parentRoom = parentRoom
// breakoutroom meeting.update()
aScene.setAttribute('meeting', `id: xrfragments; visitorname: ${visitorname}; parentRoom: ${parentRoom}`)
}else startMeeting() }else startMeeting()
}) })
if( document.location.hash.match(/(#|&)meet/) ) startMeeting() if( document.location.hash.match(/(#|&)meet/) ) startMeeting()

View file

@ -1,5 +1,5 @@
/* /*
* v0.5.1 generated at Fri Dec 15 04:23:00 PM CET 2023 * v0.5.1 generated at Fri Dec 15 05:17:47 PM CET 2023
* https://xrfragment.org * https://xrfragment.org
* SPDX-License-Identifier: MPL-2.0 * SPDX-License-Identifier: MPL-2.0
*/ */
@ -656,16 +656,16 @@ window.XRFMENU = {
// enable meetings // enable meetings
let startMeeting = () => { let startMeeting = () => {
aScene.setAttribute('meeting', 'id: xrfragments') aScene.setAttribute('meeting', 'id: xrfragments')
$('a#meeting').innerText = '📍 new meeting location' $('a#meeting').innerText = '🧑‍🤝‍🧑 breakout meeting'
$('a#meeting').setAttribute('aria-description','breakout room')
} }
$('a#meeting').addEventListener('click', () => { $('a#meeting').addEventListener('click', () => {
if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room
let parentRoom = document.location.href let parentRoom = document.location.href
XRFMENU.updateHashPosition(true) XRFMENU.updateHashPosition(true)
let visitorname = aScene.getAttribute("meeting").visitorname let meeting = $('[meeting]').components['meeting']
aScene.removeAttribute('meeting') meeting.data.parentRoom = parentRoom
// breakoutroom meeting.update()
aScene.setAttribute('meeting', `id: xrfragments; visitorname: ${visitorname}; parentRoom: ${parentRoom}`)
}else startMeeting() }else startMeeting()
}) })
if( document.location.hash.match(/(#|&)meet/) ) startMeeting() if( document.location.hash.match(/(#|&)meet/) ) startMeeting()

View file

@ -38,24 +38,17 @@
This XR experience works on almost any device.<br> This XR experience works on almost any device.<br>
Allowing rich audiovisual events without forcing<br> Allowing rich audiovisual events with(out)<br>
use of a VR/AR headset (it's awesome though ♥️)<br> VR/AR headsets (it's awesome though ♥️)<br>
<br> <br>
<table>
${
$$('.menu>.btn').map( (btn) => {
let info = btn.getAttribute("aria-description")
return info && info != "help menu" ? `<tr><td>${btn.outerHTML}</td><td>${info}</td></tr>` : ''
}).join('\n')
}
</table>
<b>This uses only open standards:</b><br> <b>This uses only open standards:</b><br>
📦 visit 3D models using URLs<br> 📦 surf 3D models using URLs<br>
🧑‍🤝‍🧑 meet inside hyperlinked 3D models<br> 🧑‍🤝‍🧑 meet inside hyperlinked 3D models<br>
🚫 no proprietary tech/game-engines<br> 🚫 no proprietary tech/game engines or platforms<br>
🙈 unhosted, privacy-friendly, avatar-agnostic scenes<br>
🔗 <a href="https://xrfragment.org" target="_blank">XR Fragments</a> for 3D hyper-linking & navigation<br> 🔗 <a href="https://xrfragment.org" target="_blank">XR Fragments</a> for 3D hyper-linking & navigation<br>
📷 Serverless <a href="https://webrtc.org" target="_blank">P2P WebRTC</a> using <a href="https://github.com/dmotz/trystero" target="_blank">trystero</a><br> 📷 Serverless & encrypted <a href="https://webrtc.org" target="_blank">P2P WebRTC</a> using <a href="https://github.com/dmotz/trystero" target="_blank">trystero</a><br>
🅰 <a href="https://aframe.io" target="_blank">AFRAME</a> + <a href="https://three.org" target="_blank">Three.js</a> for <a href="https://immersiveweb.dev" target="_blank">WebXR</a><br> 🦍 <a href="https://immersiveweb.dev" target="_blank">WebXR</a> using <a href="https://aframe.io" target="_blank">AFRAME</a> + <a href="https://three.org" target="_blank">Three.js</a><br>
🙉 go selfhost <a href="https://github.com/coderofsalvation/xrfragment-helloworld">worlds-in-a-webpage</a><br> 🙉 go selfhost <a href="https://github.com/coderofsalvation/xrfragment-helloworld">worlds-in-a-webpage</a><br>
♥️ Be sustainable: go 100% <a href="https://www.forbes.com/sites/adrianbridgwater/2023/02/06/the-future-for-open-source/" target="_blank">opensource</a> ♥️ Be sustainable: go 100% <a href="https://www.forbes.com/sites/adrianbridgwater/2023/02/06/the-future-for-open-source/" target="_blank">opensource</a>
<br><br> <br><br>

View file

@ -8,6 +8,12 @@ AFRAME.registerComponent('meeting', {
if( this.room ) this.room.leave() if( this.room ) this.room.leave()
this.meeting.remove() this.meeting.remove()
}, },
update: function(){
setTimeout( () => {
this.remove()
this.init()
},100)
},
init: function(){ init: function(){
// embed https://github.com/dmotz/trystero (trystero-torrent.min.js build) // embed https://github.com/dmotz/trystero (trystero-torrent.min.js build)
@ -129,7 +135,7 @@ AFRAME.registerComponent('meeting', {
this.initChatLine() this.initChatLine()
if( !this.data.visitorname ) this.chat.append("💁 Hi there! Please enter your name") if( !this.data.visitorname ) this.chat.append("Please enter your name below",["info"])
else{ else{
if( this.data.parentRoom ) this.chat.append(`leaving ${this.data.parentRoom}`,["info"]); if( this.data.parentRoom ) this.chat.append(`leaving ${this.data.parentRoom}`,["info"]);
this.trysteroInit() this.trysteroInit()
@ -288,7 +294,7 @@ AFRAME.registerComponent('meeting', {
if( e.key !== "Enter" ) return if( e.key !== "Enter" ) return
if( !this.data.visitorname ){ if( !this.data.visitorname ){
this.data.visitorname = chatline.value this.data.visitorname = chatline.value
this.chat.append("btw. camera/mic access is totally optional ♥️") this.chat.append("note: camera/mic access is totally optional ♥️",["info"])
this.trysteroInit() this.trysteroInit()
}else{ }else{
let str = `${this.idsToNames[ this.room.selfId ]}: ${chatline.value.substr(0,65515).trim()}` let str = `${this.idsToNames[ this.room.selfId ]}: ${chatline.value.substr(0,65515).trim()}`
@ -334,15 +340,19 @@ AFRAME.registerComponent('meeting', {
a.push(t1) a.push(t1)
t = t2.join(x) t = t2.join(x)
let y = (!(x.match(/:\/\//)) ? 'https://' : '') + x let y = (!(x.match(/:\/\//)) ? 'https://' : '') + x
let attr = 'target="_blank"'
if (isNaN(x) ){ if (isNaN(x) ){
let url_human = y.split('/')[2] let url_human = y.split('/')[2]
let isXRFragment = y.match("pos=") let isXRFragment = y.match(/\.(glb|gltf|obj|usdz|fbx|col)/)
if( isXRFragment ){ // detect xr fragments if( isXRFragment ){ // detect xr fragments
url_human = y.replace(/.*[?\?]/,'') // shorten xr fragment links isMeeting = y.match(/(#|&)meet/)
url_human = y.replace(/.*[?\?]/,'') // shorten xr fragment links
.replace(/[?\&]meet/,'') .replace(/[?\&]meet/,'')
y = y.replace(/.*[\?]/, '?') // start from search (to prevent page-refresh) y = y.replace(/.*[\?]/, '?') // start from search (to prevent page-refresh)
attr = ''
if( isMeeting ) attr = `onclick="$('[meeting]').components['meeting'].update()"`
} }
a.push(`<a href="${y}" ${isXRFragment ? '' : `target="_blank"`} style="pointer-events:all">${url_human}</a>`) a.push(`<a href="${y}" ${attr} style="pointer-events:all">${url_human}</a>`)
}else }else
a.push(x) a.push(x)
}) })

View file

@ -52,16 +52,16 @@ window.XRFMENU = {
// enable meetings // enable meetings
let startMeeting = () => { let startMeeting = () => {
aScene.setAttribute('meeting', 'id: xrfragments') aScene.setAttribute('meeting', 'id: xrfragments')
$('a#meeting').innerText = '📍 new meeting location' $('a#meeting').innerText = '🧑‍🤝‍🧑 breakout meeting'
$('a#meeting').setAttribute('aria-description','breakout room')
} }
$('a#meeting').addEventListener('click', () => { $('a#meeting').addEventListener('click', () => {
if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room if( aScene.getAttribute('meeting') ){ // meeting already, start breakout room
let parentRoom = document.location.href let parentRoom = document.location.href
XRFMENU.updateHashPosition(true) XRFMENU.updateHashPosition(true)
let visitorname = aScene.getAttribute("meeting").visitorname let meeting = $('[meeting]').components['meeting']
aScene.removeAttribute('meeting') meeting.data.parentRoom = parentRoom
// breakoutroom meeting.update()
aScene.setAttribute('meeting', `id: xrfragments; visitorname: ${visitorname}; parentRoom: ${parentRoom}`)
}else startMeeting() }else startMeeting()
}) })
if( document.location.hash.match(/(#|&)meet/) ) startMeeting() if( document.location.hash.match(/(#|&)meet/) ) startMeeting()