added share button + parent world link
This commit is contained in:
parent
1f4b3d52ec
commit
c81f37d2c3
23 changed files with 257 additions and 50 deletions
4
.env
4
.env
|
|
@ -1,6 +1,6 @@
|
||||||
# aliases
|
# aliases
|
||||||
build(){ $(pwd)/src/util/xrforge.sh build; }
|
build(){ $(pwd)/src/util/build.sh build; }
|
||||||
rebuild(){ $(pwd)/src/util/xrforge.sh rebuild; }
|
rebuild(){ $(pwd)/src/util/build.sh rebuild; }
|
||||||
|
|
||||||
# forgejo server hook
|
# forgejo server hook
|
||||||
#test "$GITEA_ROOT_URL" = "https://xrforge.isvery.ninja/" && {
|
#test "$GITEA_ROOT_URL" = "https://xrforge.isvery.ninja/" && {
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@ app.opts = require('config')(app)
|
||||||
|
|
||||||
-- load system plugins (in specific order for admin panel)
|
-- load system plugins (in specific order for admin panel)
|
||||||
app.plugin.global = app.addPlugin('plugin/global')
|
app.plugin.global = app.addPlugin('plugin/global')
|
||||||
|
app.plugin.pubnix = app.addPlugin('plugin/pubnix')
|
||||||
app.plugin.diskscan = app.addPlugin('plugin/diskscan')
|
app.plugin.diskscan = app.addPlugin('plugin/diskscan')
|
||||||
app.plugin.convert = app.addPlugin('plugin/convert')
|
app.plugin.convert = app.addPlugin('plugin/convert')
|
||||||
app.plugin.moderation = app.addPlugin('plugin/moderation')
|
app.plugin.moderation = app.addPlugin('plugin/moderation')
|
||||||
|
|
@ -76,7 +77,7 @@ print = function(...) Log(kLogInfo, ... or "''") end -- nice redbean logging fro
|
||||||
-- init URL router
|
-- init URL router
|
||||||
app.url['^/data'] = '/data.lua' -- setup custom file endpoint
|
app.url['^/data'] = '/data.lua' -- setup custom file endpoint
|
||||||
|
|
||||||
app.get('^/$', app.plugin.global.middleware.homepage_2D_or_3D )
|
app.use( app.plugin.global.middleware.homepage_2D_or_3D )
|
||||||
app.url['^/admin[/]?$'] = '/page/admin/index.lua'
|
app.url['^/admin[/]?$'] = '/page/admin/index.lua'
|
||||||
|
|
||||||
app.get('^/design[/]?$', util.pagerender('page/design.html'))
|
app.get('^/design[/]?$', util.pagerender('page/design.html'))
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function util.stripPath(str)
|
function util.stripPath(str)
|
||||||
return str:gsub("^./",""):gsub("^/",""):gsub("/$","")
|
return str:gsub("^/zip/",""):gsub("^./",""):gsub("^/",""):gsub("/$","")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- WARNING: this is a destructive function which renders the redbean server inactive
|
-- WARNING: this is a destructive function which renders the redbean server inactive
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ form > table > tbody > tr > td:nth-child(3) {
|
||||||
.primary { color: #ff33Ff;}
|
.primary { color: #ff33Ff;}
|
||||||
.secondary { color: #7070ff;}
|
.secondary { color: #7070ff;}
|
||||||
.btn a.primary{ background: #ff33Ff; color:#000}
|
.btn a.primary{ background: #ff33Ff; color:#000}
|
||||||
.btn a.secondary{ background: #224; color: #83f; }
|
.btn a.secondary{ background: #000; color: #83f; }
|
||||||
|
|
||||||
.pad1{
|
.pad1{
|
||||||
padding:20px;
|
padding:20px;
|
||||||
|
|
|
||||||
12
src/img/share.svg
Normal file
12
src/img/share.svg
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M18 9C19.6569 9 21 7.65685 21 6C21 4.34315 19.6569 3 18 3C16.3431 3 15 4.34315 15 6C15 6.12549 15.0077 6.24919 15.0227 6.37063L8.08261 9.84066C7.54305 9.32015 6.80891 9 6 9C4.34315 9 3 10.3431 3 12C3 13.6569 4.34315 15 6 15C6.80891 15 7.54305 14.6798 8.08261 14.1593L15.0227 17.6294C15.0077 17.7508 15 17.8745 15 18C15 19.6569 16.3431 21 18 21C19.6569 21 21 19.6569 21 18C21 16.3431 19.6569 15 18 15C17.1911 15 16.457 15.3202 15.9174 15.8407L8.97733 12.3706C8.99229 12.2492 9 12.1255 9 12C9 11.8745 8.99229 11.7508 8.97733 11.6294L15.9174 8.15934C16.457 8.67985 17.1911 9 18 9Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 736 B |
Binary file not shown.
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 91 KiB |
|
|
@ -1,3 +1,4 @@
|
||||||
|
<!-- https://aframe.io/aframe/examples/boilerplate/hello-world/ -->
|
||||||
<a-scene>
|
<a-scene>
|
||||||
<a-assets>
|
<a-assets>
|
||||||
<a-asset-item id="tree" src="tree2.glb"></a-asset-item>
|
<a-asset-item id="tree" src="tree2.glb"></a-asset-item>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ ${header}
|
||||||
<div style="height:90px;" class="jumbotron">
|
<div style="height:90px;" class="jumbotron">
|
||||||
<h1 style="display:none">${opts.title}</h1>
|
<h1 style="display:none">${opts.title}</h1>
|
||||||
<br>
|
<br>
|
||||||
<center class="col3">${opts.plugin_global_subtitle}</center>
|
<center class="col3">${opts.plugin_global_subtitle} </center>
|
||||||
</div>
|
</div>
|
||||||
<hr style="margin-top:0"/>
|
<hr style="margin-top:0"/>
|
||||||
]])
|
]])
|
||||||
|
|
@ -21,20 +21,23 @@ end}
|
||||||
{if items then
|
{if items then
|
||||||
for i=1,#items do
|
for i=1,#items do
|
||||||
local item = items[i]
|
local item = items[i]
|
||||||
local icon = 'list-tree'
|
local visible = item.view2D == nil or (item.view2D ~= nil and item.view2D ~= false)
|
||||||
local thumbnail = ''
|
if visible then
|
||||||
if #item.thumbnail > 0 then thumbnail = 'style="background-image: url(' .. EscapeFragment( util.stripPath(item.thumbnail) ) .. ');"' end
|
local icon = 'list-tree'
|
||||||
if item.view3D or item.portal3D == false then icon = 'play' end
|
local thumbnail = ''
|
||||||
print([[
|
if #item.thumbnail > 0 then thumbnail = 'style="background-image: url(' .. EscapeFragment( util.stripPath(item.thumbnail) ) .. ');"' end
|
||||||
<div class="tile">
|
if item.view3D or item.portal3D == false then icon = 'play' end
|
||||||
<a href="]] .. util.stripPath(item.url) .. [[">
|
print([[
|
||||||
<div class="img" ]] .. util.stripPath(thumbnail) .. [[></div>
|
<div class="tile">
|
||||||
<div class="text">
|
<a href="]] .. util.stripPath(item.url) .. [[">
|
||||||
<img src="img/]] .. icon .. [[.svg" class="icon ]] .. icon .. [["/> <a href="]] .. util.stripPath(item.url) .. [[">]] .. item.title .. [[</a>
|
<div class="img" ]] .. util.stripPath(thumbnail) .. [[></div>
|
||||||
</div>
|
<div class="text">
|
||||||
</a>
|
<img src="img/]] .. icon .. [[.svg" class="icon ]] .. icon .. [["/> <a href="]] .. util.stripPath(item.url) .. [[">]] .. item.title .. [[</a>
|
||||||
</div>
|
</div>
|
||||||
]])
|
</a>
|
||||||
|
</div>
|
||||||
|
]])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end}
|
end}
|
||||||
{if itemsremote then
|
{if itemsremote then
|
||||||
|
|
@ -46,7 +49,7 @@ end}
|
||||||
if item.view3D or item.portal3D == false then icon = 'play' end
|
if item.view3D or item.portal3D == false then icon = 'play' end
|
||||||
print([[
|
print([[
|
||||||
<div class="tile">
|
<div class="tile">
|
||||||
<a href="]] .. util.stripPath(item.url) .. [[">
|
<a href="]] .. util.stripPath(item.url) .. [[">
|
||||||
<div class="img" ]] .. util.stripPath(thumbnail) .. [[></div>
|
<div class="img" ]] .. util.stripPath(thumbnail) .. [[></div>
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<img src="img/]] .. icon .. [[.svg" class="icon ]] .. icon .. [["/> <a href="]] .. util.stripPath(item.url) .. [[">]] .. item.title .. [[</a>
|
<img src="img/]] .. icon .. [[.svg" class="icon ]] .. icon .. [["/> <a href="]] .. util.stripPath(item.url) .. [[">]] .. item.title .. [[</a>
|
||||||
|
|
|
||||||
|
|
@ -30,17 +30,13 @@ return {
|
||||||
-- "parent = " .. util.stripPath(v.parent.path) .. " " ..
|
-- "parent = " .. util.stripPath(v.parent.path) .. " " ..
|
||||||
-- "matchpath = " .. util.stripPath(matchpath)
|
-- "matchpath = " .. util.stripPath(matchpath)
|
||||||
-- )
|
-- )
|
||||||
if match(v.path, matchpath) then -- show parent folder if any
|
--if match(v.path, matchpath) then -- add parent folder if any
|
||||||
local parent = app.cache.items[ v.parent.id ]
|
--res.items[ v.parent.id ] = v.parent
|
||||||
if v.portal then
|
-- if match(v.parent.path, app.opts.plugin_diskscan_dir) then -- add rootfolder if needed
|
||||||
trace("-- portal redirect")
|
-- local root = app.cache.items[ app.opts.plugin_diskscan_dir ]
|
||||||
redirect = v.portal.url
|
-- res.items[ root.id ] = root
|
||||||
end
|
-- end
|
||||||
if match(parent.path, app.opts.plugin_diskscan_dir) then -- add rootfolder if needed
|
--end
|
||||||
local root = app.cache.items[ app.opts.plugin_diskscan_dir ]
|
|
||||||
--res.items[ root.id ] = root
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add items from dir
|
-- add items from dir
|
||||||
if match(v.parent.path, matchpath) then
|
if match(v.parent.path, matchpath) then
|
||||||
|
|
@ -49,6 +45,15 @@ return {
|
||||||
res.items[ v.id ] = v
|
res.items[ v.id ] = v
|
||||||
res.parent = parent
|
res.parent = parent
|
||||||
end
|
end
|
||||||
|
if not isroot then
|
||||||
|
res.items[ v.parent.id ] = {
|
||||||
|
view2D = false,
|
||||||
|
url = v.parent.url,
|
||||||
|
title = "parent world",
|
||||||
|
name = "parent world",
|
||||||
|
thumbnail = '',
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -57,7 +62,9 @@ return {
|
||||||
local data = util.merge({
|
local data = util.merge({
|
||||||
url = req.param.url, -- query hint to render janus.url in iframe (index.html)
|
url = req.param.url, -- query hint to render janus.url in iframe (index.html)
|
||||||
items = {},
|
items = {},
|
||||||
parent=res.parent
|
referrer = isroot and app.opts.plugin_federation_parent_url or util.getURL(),
|
||||||
|
parent=res.parent,
|
||||||
|
template=res.template
|
||||||
},{ opts = app.opts })
|
},{ opts = app.opts })
|
||||||
local i = 0
|
local i = 0
|
||||||
foreach( res.items, function(k,v)
|
foreach( res.items, function(k,v)
|
||||||
|
|
@ -70,10 +77,13 @@ return {
|
||||||
end
|
end
|
||||||
-- prioritize markup experience above binary 3D files as experience containers
|
-- prioritize markup experience above binary 3D files as experience containers
|
||||||
if not data.item or (isMarkupExperience(v) and not isMarkupExperience(data.item)) then
|
if not data.item or (isMarkupExperience(v) and not isMarkupExperience(data.item)) then
|
||||||
|
-- update referrer url
|
||||||
|
data.referrer = util.getURL( v.view3D and v.parent.parent.url or v.parent.url )
|
||||||
data.item = v
|
data.item = v
|
||||||
data.title = data.item.title
|
data.title = data.item.title
|
||||||
data.parent = v.parent
|
data.parent = v.parent
|
||||||
data.url = app.opts.baseurl .. util.stripPath(v.url) -- because we are running in iframe
|
data.url = app.opts.baseurl .. util.stripPath(v.url) -- because we are running in iframe
|
||||||
|
-- .. EscapeFragment( (v.url:match("#") and "&" or "#" ) .. 'janus.referrer=' .. EscapeFragment(v.referrer) )
|
||||||
if v.janusxr and (v.janusxr.jml or v.janusxr.aframe) then
|
if v.janusxr and (v.janusxr.jml or v.janusxr.aframe) then
|
||||||
-- what to do here? no generated portals?
|
-- what to do here? no generated portals?
|
||||||
data.janusxr = app.tpl( util.readfile(v.path), data )
|
data.janusxr = app.tpl( util.readfile(v.path), data )
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
<a href="https://nlnet.nl">NLNET</a><br/>
|
<a href="https://nlnet.nl">NLNET</a><br/>
|
||||||
</td>
|
</td>
|
||||||
<td class="col3">
|
<td class="col3">
|
||||||
<a href="?view=3D">View from XR Device</a><br/>
|
<a href="${urlpath}?view=3D">View from XR Device</a><br/>
|
||||||
<a href="${opts.plugin_diskscan_dirname}">Content overview</a><br/>
|
<a href="${opts.plugin_diskscan_dirname}">Content overview</a><br/>
|
||||||
<a href="about">About</a><br/>
|
<a href="about">About</a><br/>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,32 @@
|
||||||
{if true then
|
{if true then
|
||||||
print( app.opts.plugin_global_topmenu_html:gsub("\n"," ") )
|
print( app.opts.plugin_global_topmenu_html:gsub("\n"," ") )
|
||||||
end}
|
end}
|
||||||
|
{if template == "page/dir.html" then
|
||||||
|
print([[<div class="btn"><a class="border secondary" href="${urlpath}?view=3D">3D</a></div> ]])
|
||||||
|
end}
|
||||||
|
{if template == "page/index.html" then
|
||||||
|
local sharedata = {
|
||||||
|
title = (item and item.title or opts.plugin_global_title)
|
||||||
|
}
|
||||||
|
print([[
|
||||||
|
<a id="share" href="mailto:friend@your.org?subject=${util.getURL()}&body=check%20this%20on%20your%20XR%20headset">
|
||||||
|
<img src="img/share.svg" class="icon share"/>
|
||||||
|
</a>
|
||||||
|
<script>
|
||||||
|
if( navigator.share ){
|
||||||
|
const sharebtn = document.querySelector('#share')
|
||||||
|
const title = "]] .. (item and item.title or opts.plugin_global_title) .. [["
|
||||||
|
sharebtn.setAttribute('href', '') // override mailto:
|
||||||
|
sharebtn.addEventListener('click', (e) => {
|
||||||
|
navigator.share({title, url: document.location.href})
|
||||||
|
e.stopPropagation()
|
||||||
|
e.preventDefault()
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
]])
|
||||||
|
end}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ ${header}
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<iframe border="0" frameborder="0" src="janusweb/index.html#janus.url=${url}" id="viewer"></iframe>
|
<iframe border="0" frameborder="0" src="janusweb/index.html#janus.url=${url}&janus.referrer=${referrer}" id="viewer"></iframe>
|
||||||
|
|
||||||
{if item and item.parent and item.parent.info then
|
{if item and item.parent and item.parent.info then
|
||||||
print([[
|
print([[
|
||||||
|
|
@ -35,8 +35,9 @@ end}
|
||||||
url = document.location.origin + document.location.pathname + '?url=' + url
|
url = document.location.origin + document.location.pathname + '?url=' + url
|
||||||
}
|
}
|
||||||
}catch(e){}
|
}catch(e){}
|
||||||
const isFileWithExtension = url.replace( new RegExp('./','g'),"").match("\\.")
|
const isFileWithExtension = url.replace( new RegExp('.*/','g'),"").match("\\.") ? true : false
|
||||||
if( !isFileWithExtension ){
|
//url = url.replace(/#.*/,'') + '#janus.referrer=' + encodeURIComponent(document.location.href)
|
||||||
|
if( !isFileWithExtension ){
|
||||||
window.history.replaceState( url, iframe.contentDocument.title, url );
|
window.history.replaceState( url, iframe.contentDocument.title, url );
|
||||||
}
|
}
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ end}
|
||||||
</assets>
|
</assets>
|
||||||
{if item then
|
{if item then
|
||||||
print([[
|
print([[
|
||||||
<room pos="0 0 0" skybox="true" showavatar="false">
|
<room pos="0 0 0" skybox="true" showavatar="false">
|
||||||
<object id="${url}"/>
|
<object id="${url}"/>
|
||||||
]])
|
]])
|
||||||
else
|
else
|
||||||
local room = app.opts.plugin_janusxr_portalroom
|
local room = app.opts.plugin_janusxr_portalroom
|
||||||
|
|
@ -47,10 +47,14 @@ end}
|
||||||
end}
|
end}
|
||||||
<light js_id="dan9-janus:light/light_cone_angle=0-6" pos="0 3 2" collision_trigger="false" />
|
<light js_id="dan9-janus:light/light_cone_angle=0-6" pos="0 3 2" collision_trigger="false" />
|
||||||
{if true then
|
{if true then
|
||||||
function addPortal(id,x,v,url,i,z,thumb,rotation,scale)
|
function addPortal(id,x,v,url,i,z,thumb,rotation,scale,item)
|
||||||
print('\t<object js_id="' .. id .. '_' .. i .. '" pos="' .. x .. ' 0 ' .. z .. '" rotation="' .. rotation .. '">')
|
print('\t<object js_id="' .. id .. '_' .. i .. '" pos="' .. x .. ' 0 ' .. z .. '" rotation="' .. rotation .. '">')
|
||||||
print('\t <link url="' .. url .. '" ' .. thumb .. ' title_col="0.4 0.37 0.4" pos="0 0 0.001" draw_glow="' .. (thumb:match("shader") and 'false' or 'true') .. '" scale="3 3 0.1" />')
|
print('\t <link url="' .. url .. '" ' .. thumb .. ' title_col="0.4 0.37 0.4" pos="0 0 0.001" draw_glow="' .. (thumb:match("shader") and 'false' or 'true') .. '" scale="3 3 0.1" />')
|
||||||
print('\t <text text="' .. v.title .. '" pos="0 3.4 0" col="1 1 1" font_scale="false" scale="' .. scale .. '" />')
|
print('\t <text text="' .. v.title .. '" pos="0 3.4 0" col="1 1 1" font_scale="false" scale="' .. scale .. '" />')
|
||||||
|
--TODO: fix janusweb paragraph for markdown urls
|
||||||
|
--if item.README ~= nil then
|
||||||
|
-- print('\t <paragraph js_id="README" url="' .. item.README .. '" width="600" height="900" pos="0 1 2" transparent="true"/>')
|
||||||
|
--end
|
||||||
print('\t</object>')
|
print('\t</object>')
|
||||||
end
|
end
|
||||||
end}
|
end}
|
||||||
|
|
@ -66,7 +70,7 @@ end}
|
||||||
end
|
end
|
||||||
if v.dir then url = url .. "/" end
|
if v.dir then url = url .. "/" end
|
||||||
if v.redirect then url = v.redirect end -- dont wrap standalone glb's in janusxr
|
if v.redirect then url = v.redirect end -- dont wrap standalone glb's in janusxr
|
||||||
addPortal('dir',center, v, url,i, -4, thumb, '0 0 0', '0.2 0.2 0.2')
|
addPortal('dir',center, v, url,i, -4, thumb, '0 0 0', '0.2 0.2 0.2', v)
|
||||||
end
|
end
|
||||||
end}
|
end}
|
||||||
{if not item and itemsremote and #itemsremote > 0 then
|
{if not item and itemsremote and #itemsremote > 0 then
|
||||||
|
|
@ -80,7 +84,7 @@ end}
|
||||||
end
|
end
|
||||||
if v.dir then url = url .. "/" end
|
if v.dir then url = url .. "/" end
|
||||||
if v.redirect then url = v.redirect end -- dont wrap standalone glb's in janusxr
|
if v.redirect then url = v.redirect end -- dont wrap standalone glb's in janusxr
|
||||||
addPortal('remote',center, v, url,i, 4, thumb, '0 180 0', '0.2 0.2 0.2')
|
addPortal('remote',center, v, url,i, 4, thumb, '0 180 0', '0.2 0.2 0.2',v)
|
||||||
end
|
end
|
||||||
print([[
|
print([[
|
||||||
<text js_id="locationremote" pos="0 6 5" billboard="y" col="#BBFFFF" scale="10 10 1" text="${opts.plugin_global_remote_title}" emissive="0 0 0" roughness="0.3" metalness="0" />
|
<text js_id="locationremote" pos="0 6 5" billboard="y" col="#BBFFFF" scale="10 10 1" text="${opts.plugin_global_remote_title}" emissive="0 0 0" roughness="0.3" metalness="0" />
|
||||||
|
|
@ -88,6 +92,7 @@ end}
|
||||||
end}
|
end}
|
||||||
|
|
||||||
<object id="cube" rotation="0 0 0" position="0 0 0" scale="2 0.1 2"/> <!-- something to stand on -->
|
<object id="cube" rotation="0 0 0" position="0 0 0" scale="2 0.1 2"/> <!-- something to stand on -->
|
||||||
|
${janusxr_jml_deco}
|
||||||
${opts.plugin_janusxr_jml}
|
${opts.plugin_janusxr_jml}
|
||||||
</room>
|
</room>
|
||||||
</fireboxroom>
|
</fireboxroom>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,20 @@ local dir = require "opendirectory"
|
||||||
app.on('init', function()
|
app.on('init', function()
|
||||||
print("scanning experiences (this make take a while..)")
|
print("scanning experiences (this make take a while..)")
|
||||||
app.opts.plugin_diskscan_dirname = app.opts.plugin_diskscan_dir:gsub("^[.]?[/]?","")
|
app.opts.plugin_diskscan_dirname = app.opts.plugin_diskscan_dir:gsub("^[.]?[/]?","")
|
||||||
|
-- swap between internal / external version of diskscan_dir
|
||||||
|
if app.opts.plugin_diskscan_dir:match("^/zip/") then
|
||||||
|
if util.fileExist(app.opts.plugin_diskscan_dir) then
|
||||||
|
print("ℹ️ serving " .. app.opts.plugin_diskscan_dir .. " from local disk")
|
||||||
|
app.opts.plugin_diskscan_dir = app.opts.plugin_diskscan_dir:gsub("^/zip/","")
|
||||||
|
app.set('app.opts', app.opts)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not util.fileExist(app.opts.plugin_diskscan_dir) then
|
||||||
|
print("ℹ️ serving " .. app.opts.plugin_diskscan_dir .. " from internal (executable)")
|
||||||
|
app.opts.plugin_diskscan_dir = '/zip/' .. util.stripPath(app.opts.plugin_diskscan_dir)
|
||||||
|
app.set('app.opts', app.opts)
|
||||||
|
end
|
||||||
|
end
|
||||||
app.plugin.diskscan.scan(app.opts.plugin_diskscan_dir)
|
app.plugin.diskscan.scan(app.opts.plugin_diskscan_dir)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
@ -36,6 +50,7 @@ return {
|
||||||
path = scandir,
|
path = scandir,
|
||||||
url = "/" .. util.stripPath(scandir),
|
url = "/" .. util.stripPath(scandir),
|
||||||
name = scandir:gsub(".*/",""),
|
name = scandir:gsub(".*/",""),
|
||||||
|
thumbnail = "",
|
||||||
title = scandir:gsub(".*/",""):gsub("-"," "),
|
title = scandir:gsub(".*/",""):gsub("-"," "),
|
||||||
file = { ino = scandir },
|
file = { ino = scandir },
|
||||||
id = scandir
|
id = scandir
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ app.on('dir', function(opts)
|
||||||
title = url:gsub(".*//",""),
|
title = url:gsub(".*//",""),
|
||||||
thumbnail = thumburl,
|
thumbnail = thumburl,
|
||||||
url = '/janusweb/index.html#janus.url=' .. EscapeFragment(url)
|
url = '/janusweb/index.html#janus.url=' .. EscapeFragment(url)
|
||||||
|
.. '&janus.referrer=' .. EscapeFragment( util.getURL(opts.urlpath ) )
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -34,7 +35,7 @@ end)
|
||||||
local plugin = {
|
local plugin = {
|
||||||
name = 'Federation',
|
name = 'Federation',
|
||||||
tab = "<img src='img/link.svg' class='icon invert'/> Federation",
|
tab = "<img src='img/link.svg' class='icon invert'/> Federation",
|
||||||
info = 'Add links to other (janus)XR(forges), and have them show up as extra portals in portalrooms',
|
info = 'Add links to other (janus)XR(forges), and have them show up as extra portals in portalrooms.<br><b>NOTE:</b> please leave at the <b>Parent World URL</b> non-empty, as it promotes interconnected ecosystems of experiences ♥',
|
||||||
opts = { -- TODO populate this based on xrforge-federation.json
|
opts = { -- TODO populate this based on xrforge-federation.json
|
||||||
{
|
{
|
||||||
key='app.opts.plugin_federation_strategy',
|
key='app.opts.plugin_federation_strategy',
|
||||||
|
|
@ -43,6 +44,14 @@ local plugin = {
|
||||||
default="homepage",
|
default="homepage",
|
||||||
values={always='always',homepage='only homepage'}
|
values={always='always',homepage='only homepage'}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_federation_parent_url',
|
||||||
|
title='Parent World URL',
|
||||||
|
info="3D portal (entrypoint) in homepage",
|
||||||
|
default="https://www.janusxr.org",
|
||||||
|
placeholder="https://www.janusxr.org",
|
||||||
|
values=''
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key='app.opts.plugin_federation_url_1',
|
key='app.opts.plugin_federation_url_1',
|
||||||
title='Federated URL 1',
|
title='Federated URL 1',
|
||||||
|
|
@ -54,7 +63,7 @@ local plugin = {
|
||||||
key='app.opts.plugin_federation_url_2',
|
key='app.opts.plugin_federation_url_2',
|
||||||
title='Federated URL 2',
|
title='Federated URL 2',
|
||||||
info="URL and/or Thumbnail URL (space separated)",
|
info="URL and/or Thumbnail URL (space separated)",
|
||||||
default="https://www.janusxr.org https://www.janusvr.com/images/logos/logotextoverlight.png",
|
default="https://aframe.io/aframe/examples/boilerplate/hello-world/ /myverse/janusxr_tutorial/AFRAME.jpg",
|
||||||
values=''
|
values=''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,7 @@ local plugin = {
|
||||||
},
|
},
|
||||||
middleware = {
|
middleware = {
|
||||||
homepage_2D_or_3D = function(req,res,next)
|
homepage_2D_or_3D = function(req,res,next)
|
||||||
if (app.opts.plugin_global_homepage == '3D') or (req.param.view == '3D') or (req.param.url) then
|
if (req.url == '/' or req.url == '/index.html' and app.opts.plugin_global_homepage == '3D') or (req.param.view == '3D') or (req.param.url) then
|
||||||
res.template = 'page/index.html'
|
res.template = 'page/index.html'
|
||||||
else
|
else
|
||||||
res.template = 'page/dir.html'
|
res.template = 'page/dir.html'
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,15 @@ app.on('scan_experience', function(exp)
|
||||||
--print_r(exp)
|
--print_r(exp)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
app.on('dir', function(opts)
|
||||||
|
local hash = GetPath()
|
||||||
|
if #app.opts.plugin_janusxr_random_objects > 0 and
|
||||||
|
#app.opts.plugin_janusxr_random_colors > 0 then
|
||||||
|
opts.data.janusxr_jml_deco = app.plugin.janusxr.getRandomDeco(7,50,hash,0,30) ..
|
||||||
|
app.plugin.janusxr.getRandomDeco(7,50,hash .. hash,30,30)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
app.on('scan_experience_file', function(exp)
|
app.on('scan_experience_file', function(exp)
|
||||||
local me = app.plugin.janusxr
|
local me = app.plugin.janusxr
|
||||||
local size = exp.file.attr:size()
|
local size = exp.file.attr:size()
|
||||||
|
|
@ -56,8 +65,7 @@ app.on('scan_experience_file', function(exp)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
app.on('set', function(k,v)
|
app.on('set', function(k,v) end)
|
||||||
end)
|
|
||||||
|
|
||||||
-- this registers the plugin UI
|
-- this registers the plugin UI
|
||||||
local rooms = {random="random room",room_plane="wirefloor",room1="room1",room2="room2",room3="room3",room4="room4",room5="room5",room6="room6",room7="room7"}
|
local rooms = {random="random room",room_plane="wirefloor",room1="room1",room2="room2",room3="room3",room4="room4",room5="room5",room6="room6",room7="room7"}
|
||||||
|
|
@ -118,6 +126,22 @@ local plugin = {
|
||||||
default="room_plane",
|
default="room_plane",
|
||||||
values={random="random room",room_plane="wirefloor",room1="room1",room2="room2",room3="room3",room4="room4",room5="room5",room6="room6",room7="room7"}
|
values={random="random room",room_plane="wirefloor",room1="room1",room2="room2",room3="room3",room4="room4",room5="room5",room6="room6",room7="room7"}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_janusxr_random_objects',
|
||||||
|
title='Random objects',
|
||||||
|
info="Random object id's in portal rooms",
|
||||||
|
default="capsule cone cube cylinder pyramid sphere torus",
|
||||||
|
placeholder="capsule cone cube cylinder pipe pyramid sphere torus",
|
||||||
|
values="",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_janusxr_random_colors',
|
||||||
|
title='Random colors',
|
||||||
|
info="Random object colors in portal rooms",
|
||||||
|
default="#ffffff #111122 #FF33FF #8833FF #7070FF #404070 #222244",
|
||||||
|
placeholder="#ffffff #111122 #FF33FF #8833FF #7070FF #404070 #222244",
|
||||||
|
values="",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key='app.opts.plugin_janusxr_scraper',
|
key='app.opts.plugin_janusxr_scraper',
|
||||||
title='Scraper',
|
title='Scraper',
|
||||||
|
|
@ -141,6 +165,7 @@ local plugin = {
|
||||||
values=''
|
values=''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getRandomRoom = function()
|
getRandomRoom = function()
|
||||||
local me = app.plugin.janusxr
|
local me = app.plugin.janusxr
|
||||||
local room= ''
|
local room= ''
|
||||||
|
|
@ -153,6 +178,52 @@ local plugin = {
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
return room
|
return room
|
||||||
|
end,
|
||||||
|
|
||||||
|
getRandomDeco = function(num_objects, radius, seed_string, y, scale)
|
||||||
|
num_objects = num_objects or 6
|
||||||
|
y = y or 0
|
||||||
|
radius = radius or 2 -- Configurable distance from (0, 0, 0)
|
||||||
|
seed_string = seed_string or 'xf2dxf2dxf3f23' -- Given hashstring
|
||||||
|
local JML = ''
|
||||||
|
local colors = util.split( app.opts.plugin_janusxr_random_colors, ' ')
|
||||||
|
local ids = util.split( app.opts.plugin_janusxr_random_objects, ' ')
|
||||||
|
|
||||||
|
local function hash_string_to_number(str)
|
||||||
|
local hash = 5381
|
||||||
|
for i = 1, #str do
|
||||||
|
local char = string.byte(str, i)
|
||||||
|
hash = (hash * 33 + char) % 2147483647
|
||||||
|
end
|
||||||
|
return hash
|
||||||
|
end
|
||||||
|
local index = {
|
||||||
|
color= hash_string_to_number(seed_string) % #colors,
|
||||||
|
id = hash_string_to_number(seed_string) % #ids
|
||||||
|
}
|
||||||
|
|
||||||
|
for i = 1, num_objects do
|
||||||
|
-- Calculate angle in radians to space objects evenly around a circle
|
||||||
|
local angle = (i - 1) * (2 * math.pi / num_objects)
|
||||||
|
-- Calculate X and Z positions along the circle radius
|
||||||
|
local x = radius * math.cos(angle)
|
||||||
|
local z = radius * math.sin(angle)
|
||||||
|
local y = y -- Height level
|
||||||
|
|
||||||
|
local selected_id = ids[ index.id+1]
|
||||||
|
local selected_color = colors[ index.color+1 ]
|
||||||
|
|
||||||
|
local pos_str = string.format("%.2f %g %.2f", x, y, z)
|
||||||
|
local xml_tag = string.format('<object id="%s" pos="%s" col="%s" rotation="0 45 0" scale="%s %s %s" roughness="0.1" metalness="0.5"/>',
|
||||||
|
selected_id, pos_str, selected_color, scale, scale, scale)
|
||||||
|
|
||||||
|
JML = JML .. xml_tag .. "\n"
|
||||||
|
|
||||||
|
-- increase indexes
|
||||||
|
index.id = (index.id + 1 ) % #ids
|
||||||
|
index.color = (index.color + 1 ) % #colors
|
||||||
|
end
|
||||||
|
return JML
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ app.on('scan_experience_file', function(exp)
|
||||||
if exp.path:match(v) then
|
if exp.path:match(v) then
|
||||||
print("✅ └─ plugin/markdown: detected " .. v)
|
print("✅ └─ plugin/markdown: detected " .. v)
|
||||||
exp.parent.info = '<div id="info">' .. markdown( util.readfile(exp.path) ) .. '</div>'
|
exp.parent.info = '<div id="info">' .. markdown( util.readfile(exp.path) ) .. '</div>'
|
||||||
|
exp.parent.README = util.stripPath( exp.path )
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ app.on('dir', function(opts)
|
||||||
title = url:gsub(".*//",""),
|
title = url:gsub(".*//",""),
|
||||||
thumbnail = thumburl,
|
thumbnail = thumburl,
|
||||||
url = '/janusweb/index.html#janus.url=' .. EscapeFragment(url)
|
url = '/janusweb/index.html#janus.url=' .. EscapeFragment(url)
|
||||||
|
.. '&janus.referrer=' .. EscapeFragment( util.getURL(opts.urlpath ) )
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
50
src/plugin/pubnix.lua
Normal file
50
src/plugin/pubnix.lua
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
local util = require('util')
|
||||||
|
|
||||||
|
app.on('scan_experience', function(exp)
|
||||||
|
--print_r(exp)
|
||||||
|
end)
|
||||||
|
|
||||||
|
app.on('scan_experience_file', function(exp)
|
||||||
|
end)
|
||||||
|
|
||||||
|
app.on('set', function(k,v)
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- this registers the plugin UI
|
||||||
|
local plugin = {
|
||||||
|
name = "PubNIX",
|
||||||
|
info = '<b class="tag">disabled</b> Turn server into a <a href="https://tildeverse.org/" target="_blank">pubnix</a>: automatically scan userdirectories in /home/* for XR experiences, and add them as 3D portals.',
|
||||||
|
opts = {
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_pubnix_enabled',
|
||||||
|
title='Add homedirs',
|
||||||
|
info='Scan for experiences in /home/*',
|
||||||
|
default = "enabled",
|
||||||
|
values={enabled="enabled",disabled="disabled"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_pubnix_folder',
|
||||||
|
title='Require folder',
|
||||||
|
info='Require specific folder (/home/john/xrforge e.g.)',
|
||||||
|
default = "./xrforge",
|
||||||
|
values=''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_pubnix_thumbnail',
|
||||||
|
title='User thumbnail',
|
||||||
|
info='look for /home/john/xrforge/~john.jpg sidecarfile',
|
||||||
|
default = "enabled",
|
||||||
|
values={enabled="enabled",disabled="disabled"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key='app.opts.plugin_pubnix_exclude',
|
||||||
|
title='Exclude pattern',
|
||||||
|
info='Space-separated, <a href="http://lua-users.org/wiki/PatternsTutorial" target="_blank">lua patterns</a> for directories',
|
||||||
|
default = "",
|
||||||
|
placeholder = "admin root",
|
||||||
|
values=''
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugin
|
||||||
|
|
@ -25,6 +25,7 @@ app.on('dir', function(opts)
|
||||||
title = url:gsub(".*//",""),
|
title = url:gsub(".*//",""),
|
||||||
thumbnail = thumburl,
|
thumbnail = thumburl,
|
||||||
url = '/janusweb/index.html#janus.url=' .. EscapeFragment(url)
|
url = '/janusweb/index.html#janus.url=' .. EscapeFragment(url)
|
||||||
|
.. '&janus.referrer=' .. EscapeFragment( util.getURL(opts.urlpath ) )
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ app.on('scan_experience_file', function(exp)
|
||||||
local hasHref = false
|
local hasHref = false
|
||||||
if ext == 'glb' then
|
if ext == 'glb' then
|
||||||
-- detect XR Fragment exp https://xrfragment.org/#%F0%9F%93%9C%20level0%3A%20File
|
-- detect XR Fragment exp https://xrfragment.org/#%F0%9F%93%9C%20level0%3A%20File
|
||||||
local tree = me.extract_glb_json( util.stripPath(exp.path) )
|
local tree = me.extract_glb_json( exp.path ) --util.stripPath(exp.path) )
|
||||||
hasHref = me.detectHrefInStruct(tree)
|
hasHref = me.detectHrefInStruct(tree)
|
||||||
end
|
end
|
||||||
-- check sidecarfiles: https://xrfragment.org/#sidecar%20files
|
-- check sidecarfiles: https://xrfragment.org/#sidecar%20files
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ download(){
|
||||||
wget "https://github.com/coderofsalvation/janusweb/releases/download/v${version}-rc/janusweb-${version}.tar.gz"
|
wget "https://github.com/coderofsalvation/janusweb/releases/download/v${version}-rc/janusweb-${version}.tar.gz"
|
||||||
}
|
}
|
||||||
test -d janusweb-${version} || tar -xvf janusweb-${version}.tar.gz
|
test -d janusweb-${version} || tar -xvf janusweb-${version}.tar.gz
|
||||||
test -d src/janusweb || cp -r janusweb-${version} src/janusweb
|
test -d src/janusweb || cp -Lr janusweb-${version} src/janusweb
|
||||||
}
|
}
|
||||||
|
|
||||||
"$@"
|
"$@"
|
||||||
Loading…
Add table
Reference in a new issue