added about page + css tweaks

This commit is contained in:
Leon van Kammen 2026-07-23 10:01:34 +02:00
parent af2e1bfdb2
commit 9dd86155c6
24 changed files with 1228 additions and 197 deletions

View file

@ -13,6 +13,9 @@ NOTES:
configure in-zip or filesystem-cache
opendirectory.lua <--- mount other instances over http (via xrforge or rclone)
.xrforge/hook/scandir <-- event to hook
scan files
---------- middleware/xrexperience.lua
| events: ---------------------
@ -26,6 +29,12 @@ scan files
```
## Ideas
* landingpage = /about
* scan functions in xrforge.lua / .xrforge
* video-hover: https://codepen.io/coderofsalvation/pen/YPNOyqx
## Scan manyfold
-------------
@ -38,7 +47,8 @@ curl -L -X 'GET' 'http://xrforge.isvery.ninja/models?page=1&order=recent' -H
## Permacomputing Spirit
* developed on [Dillo](https://dillo-browser.github.io/) as lowest common denominator / compatibility
* does not use javascript unless really needed (WebXR being the exception)
* does not use javascript (WebXR viewer being the exception)
* gracefully degrades to admin/filebrowser for &gt;noscript&gt;/potato-browsers
* server is using lua-scripting via cosmopolitan libc's [redbean](https://redbean.dev)
> So yes in case you'd think the codebase is 90-ish: that's **exactly why it works** on potato-devices AND modern devices.
> So yes, the codebase/html/css is intentionally 90-ish: that's **exactly why it works** on potato-devices AND modern devices.

2
run.sh
View file

@ -1,3 +1,3 @@
#!/bin/sh
cd src
../result/bin/xrforge.com -D . -- server
../result/bin/xrforge.com -D . -c 0 server

View file

@ -1,2 +1,8 @@
-H
"Access-Control-Allow-Origin: *"
-H
"Access-Control-Allow-Method: GET, POST, OPTIONS"
-H
"Allow: GET, POST, OPTIONS"
-D
.

View file

@ -39,10 +39,13 @@ app.runcmd(app) -- run clicmds
-- init URL router
app.url['^/data'] = '/data.lua' -- setup custom file endpoint
app.url['^/$'] = '/page/index.lua' -- alias for app.tpl( LoadAsset('index.html'), app )
app.get('^/design[/]?$', util.pagerender('page/design.html'))
app.url['^/$'] = '/page/index.lua'
app.url['^/experiences[/]?$'] = '/page/experiences.lua'
app.url['^/admin[/]?$'] = '/page/admin/index.lua'
app.get('^/design[/]?$', util.pagerender('page/design.html'))
app.get('^/about[/]?$', util.pagerender('page/about.html'))
app.url['^/admin[/]?$'] = '/page/admin/index.lua'
app.post('^/save', function(req,res,next) -- setup inline POST endpoint
-- also .get(), .put(), .delete(), .options()

View file

@ -10,6 +10,7 @@ return function(app)
admin_title = "XRForge Admin",
admin_subtitle = "Manage your XR experiences here",
disk_dir = ".",
hide_keywords = "wip beta -v[0-9] customerX",
manyfold_instance_1 = "https://xrforge.isvery.ninja",
manyfold_instance_2 = "",
manyfold_instance_3 = "",

View file

@ -51,6 +51,8 @@ end
util.pagerender = function(file,data)
return function(req,res,next)
data = data or {opts = app.opts}
data.page = file:gsub(".*","")
res.status(200)
res.header('content-type','text/html; charset=utf-8')
res.body( util.template( LoadAsset(file),data or app) )
@ -59,11 +61,12 @@ util.pagerender = function(file,data)
end
util.template = function(content,data)
local finaldata = util.merge(data or app,{})
finaldata = util.merge(finaldata, util.flatten(app.opts,"opts") )
finaldata.header = app.tpl( LoadAsset('page/header.html'), finaldata )
finaldata.footer = app.tpl( LoadAsset('page/footer.html'), finaldata )
return app.tpl( content, finaldata )
local mdata = util.merge(data or app,{})
mdata = util.merge(mdata, util.flatten(app.opts,"opts") )
mdata.header_include = mdata.header_include or ''
mdata.header = app.tpl( LoadAsset('page/header.html'), mdata )
mdata.footer = app.tpl( LoadAsset('page/footer.html'), mdata )
return app.tpl( content, mdata )
end
util.memoize = function(fn, ttl_seconds)

View file

@ -9,8 +9,8 @@
.col3{ color:#878; }
.col4{ color:#7070ff; }
.col5{ color:#447; }
.col5{ color:#224; }
.col5{ color:#112; }
.col6{ color:#224; }
.col7{ color:#112; }
.page{ width:640px; }
@ -54,6 +54,10 @@ select{
border: 1px solid #557;
color: #AAD;
}
input,select,textarea{
background:#112;
}
input[type=checkbox]{
transform:scale(1.7) translate(3px,4px)
}
@ -63,7 +67,7 @@ input[type=checkbox]{
.btn,
input[type=submit]{
display: inline-block;
margin: 0px 10px 10px 0px;
margin: 0 15px 0px 0px;
}
.btn a,
@ -76,6 +80,7 @@ input[type=submit] {
padding:8px 16px;
color: #f3f;
text-decoration:none;
background:#112;
}
.btn a:hover,
@ -97,7 +102,7 @@ a, a:active, a:visited, a:link, input[type=submit] {
}
a:hover{
color:#FFF;
color:#FFF !important;
cursor:pointer;
border-bottom:1px dotted #f3f;
}
@ -122,10 +127,14 @@ form > table > tbody > tr > td:nth-child(3) {
}
/* primary secondary colors */
.border.primary{ border:1px dotted #87a; }
.border.secondary{ border:1px dotted #7070ff; }
.primary { color: #ff33Ff;}
.secondary { color: #7070ff;}
.btn a.primary{ background: #ff33Ff; color:#000}
.btn a.secondary{ background: #7070ff; color:#000}
.pad1{
padding:20px;
@ -153,7 +162,6 @@ h1,h2,h3,h4,h5{
.sym{ font-size:100px; color:#000; }
table.header td{ border-bottom: 1px solid #223; }
.header td a{
border:none;
font-weight:bold;
@ -164,7 +172,8 @@ table.header td{ border-bottom: 1px solid #223; }
hr{
margin:20px 0px;
border-bottom:1px dotted #224;
border:none;
border-bottom:1px solid #224;
}
ul{
@ -202,14 +211,14 @@ img.icon{ display:none; }
.tab .label{
display: block;
background: #000;
margin-bottom: -4px;
width: 158px;
margin-bottom: -2px;
width: 168px;
margin-left: -140px;
border-top: 1px dotted #557;
border-left: 1px dotted #556;
border-right: 1px dotted #556;
padding: 9px 0px 0px 20px;
font-weight: bold;
font-size: 14px;
}
.notification{
@ -221,7 +230,15 @@ img.icon{ display:none; }
margin-bottom: 25px;
}
.jumbotron h1{
font-size: 29px;
font-weight: normal;
}
/* progressive enhancement quirks */
.spectrum{ display:none }
@media (min-width:1px) {
.grid .tile{
height:unset;

View file

@ -66,6 +66,103 @@ img.icon{
width: 17px;
}
.btn .primary{ background: #ff33Ff; color:#000 !important;}
.btn .secondary{ background: #7070ff; color:#000 !important;}
iframe#viewer{
position: fixed;
width: 100%;
height: calc( 100vh - 59px);
margin-top: 0px;
background: #FFF;
left: 0;
top: 70px;
}
/* telescopic text */
u {
cursor: pointer;
display: inline;
text-decoration:none;
white-space:nowrap;
font-weight:bold;
padding:0;
}
u > u,
u > span{
display: none;
}
u:focus-within > u,
u:focus-within > span {
display: inline;
}
u span{
font-weight:normal;
white-space: normal;
background:none;
}
/* underline settings */
.telescopic u:nth-child(odd)::before,
.telescopic u:nth-child(even)::before{
border-bottom:4px solid #F0F;
content:' ';
display:inline-block;
margin-right:5px;
width:23px;
height:32px;
position: absolute;
animation:fade 1000ms infinite;
-webkit-animation:fade 1000ms infinite;
}
.telescopic u:nth-child(odd)::before{
border-bottom:4px solid #77F;
}
.telescopic * {
line-height:40px;
}
.vertical u:focus-within > u::after,
.vertical u:focus-within > span::after {
content:' ';
display:block;
}
.show > u,
.show > span{
display:inline;
}
.telescopic u.show::before,
.telescopic u.show::after{
display:none;
}
/* spectrum ruler */
.spectrum{
display:block !important;
box-shadow: 0px 0px 5px #F0F;
}
.spectrum > div,
.ruler{
margin:3px 0px;
clear:both;
background:linear-gradient(90deg, #F07, #77F, #F07);
height:2px;
}
#spectrumheader{
position: absolute;
top: 57px;
z-index: 1000;
left: 0px;
height: 5px;
width: 100%;
}

BIN
src/img/backdrop.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
src/img/badges.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

4
src/img/blinkhint.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.5 KiB

164
src/img/codeberg.svg Normal file
View file

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="16"
height="16"
viewBox="0 0 4.2333332 4.2333335"
version="1.1"
id="svg1468"
sodipodi:docname="codeberg-logo_icon_white.svg"
inkscape:version="1.2-alpha1 (b6a15bb, 2022-02-23)"
inkscape:export-filename="/home/robert/Documents/Codeberg/Logo-Kit/svg/Codeberg-favicon_64px.png"
inkscape:export-xdpi="384"
inkscape:export-ydpi="384"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<title
id="title16">Codeberg logo</title>
<defs
id="defs1462">
<linearGradient
xlink:href="#linearGradient6924"
id="linearGradient6918"
x1="42519.285"
y1="-7078.7891"
x2="42575.336"
y2="-6966.9307"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient6924">
<stop
style="stop-color:#2185d0;stop-opacity:0"
offset="0"
id="stop6920" />
<stop
id="stop6926"
offset="0.49517274"
style="stop-color:#2185d0;stop-opacity:0.48923996" />
<stop
style="stop-color:#2185d0;stop-opacity:0.63279623"
offset="1"
id="stop6922" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient6924-6"
id="linearGradient6918-3"
x1="42519.285"
y1="-7078.7891"
x2="42575.336"
y2="-6966.9307"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient6924-6">
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="0"
id="stop6920-7" />
<stop
id="stop6926-5"
offset="0.49517274"
style="stop-color:#ffffff;stop-opacity:0.30000001;" />
<stop
style="stop-color:#ffffff;stop-opacity:0.30000001;"
offset="1"
id="stop6922-3" />
</linearGradient>
</defs>
<sodipodi:namedview
showborder="false"
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="22.627417"
inkscape:cx="2.8505242"
inkscape:cy="18.274291"
inkscape:document-units="px"
inkscape:current-layer="svg1468"
inkscape:document-rotation="0"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
units="px"
inkscape:snap-global="false"
inkscape:snap-page="true"
showguides="false"
inkscape:window-width="1531"
inkscape:window-height="873"
inkscape:window-x="69"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid2067" />
</sodipodi:namedview>
<metadata
id="metadata1465">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Codeberg logo</dc:title>
<cc:license
rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
<dc:creator>
<cc:Agent>
<dc:title>Robert Martinez</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>Codeberg and the Codeberg Logo are trademarks of Codeberg e.V.</dc:title>
</cc:Agent>
</dc:rights>
<dc:date>2020-04-09</dc:date>
<dc:publisher>
<cc:Agent>
<dc:title>Codeberg e.V.</dc:title>
</cc:Agent>
</dc:publisher>
<dc:source>codeberg.org</dc:source>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="g370484"
inkscape:label="logo"
transform="matrix(0.06551432,0,0,0.06551432,-2.232417,-1.431776)">
<path
id="path6733-5"
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:url(#linearGradient6918-3);fill-opacity:1;stroke:none;stroke-width:3.67846;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:2;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke markers fill;stop-color:#000000;stop-opacity:1"
d="m 42519.285,-7078.7891 a 0.76086879,0.56791688 0 0 0 -0.738,0.6739 l 33.586,125.8886 a 87.182358,87.182358 0 0 0 39.381,-33.7636 l -71.565,-92.5196 a 0.76086879,0.56791688 0 0 0 -0.664,-0.2793 z"
transform="matrix(0.37058478,0,0,0.37058478,-15690.065,2662.0533)"
inkscape:label="berg" />
<path
id="path360787"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke-width:17.0055;paint-order:markers fill stroke;stop-color:#000000"
d="m 11249.461,-1883.6961 c -12.74,0 -23.067,10.3275 -23.067,23.0671 0,4.3335 1.22,8.5795 3.522,12.2514 l 19.232,-24.8636 c 0.138,-0.1796 0.486,-0.1796 0.624,0 l 19.233,24.8646 c 2.302,-3.6721 3.523,-7.9185 3.523,-12.2524 0,-12.7396 -10.327,-23.0671 -23.067,-23.0671 z"
sodipodi:nodetypes="sccccccs"
inkscape:label="sky"
transform="matrix(1.4006354,0,0,1.4006354,-15690.065,2662.0533)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
src/img/janusxr-xrf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

BIN
src/img/obsidian.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
src/img/xrecosystem.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

322
src/img/xrforge_term.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 117 KiB

333
src/page/about.html Normal file
View file

@ -0,0 +1,333 @@
${header}
<style type="text/css">
header h2{
font-size: 29px;
font-weight: normal;
}
header{
background: url(/img/backdrop.jpg);
background-position-x: 0%;
background-position-y: 0%;
background-repeat: repeat;
background-size: auto;
background-repeat: no-repeat;
background-size: cover;
background-position: center;
border-radius: 10px;
text-align: center;
}
div#hint{
float:right;
background: url(/img/blinkhint.svg);
height: 129px;
background-size: cover;
display:inline-block;
width: 200px;
}
div#badges{
background: url(/img/badges.png);
height: 90px;
background-repeat:no-repeat;
background-size: contain;
background-position:bottom;
width: 100%;
max-width:677px;
display:inline-block;
}
div#xrecosystem{
background: #000 url(/img/xrecosystem.png);
background-repeat: no-repeat;
height: 200px;
background-size: cover;
width: 100%;
border-radius:7px;
background-size: contain;
background-position: center;
margin:30px 0px;
}
</style>
<div class="about telescopic">
<header class="container">
<div style="padding:20px 10px;text-align:right">
<small>member of <a href="https://xrhf.isvery.ninja" target="_blank">XR Hypermedia Federation</a></small>
<div id="xrhf"></div>
</div>
<div id="logo"></div>
<h2>Turn files into AR/VR 🥽 experiences</h2>
<center>
A static website generator, XR hub, server &amp; client.
<br/>
<br/>
<div class="btn">
<a href="https://codeberg.org/coderofsalvation/xrforge" class="" style="text-align:left">
<img src="/img/codeberg.svg" style="width:20px">
Check the sourcecode<br>
<small>docker run codeforge.org/coderofsalvation/xrforge:latest</small>
</a>
</div>
&nbsp;&nbsp;&nbsp;
<div class="btn">
<a href="https://chat.isvery.ninja" class="secondary" style="text-align:left">
<img src="/img/obsidian.png" style="width:20px">
chat with community <br>
<small>irc.isvery.ninja port 443 via ObsidianIRC</small>
</a>
</div>
<br>
</center>
<div id="badges"></div>
<br>
<div id="hint"></div>
<div class="clear"></div>
</header>
<br>
<h3>Why people want XRForge</h3>
<div>
The metaverse has shown: people <b>like 3D</b> but certain <b>existing</b> 2D ecosystems are king.<br>
They're just more cost-efficient to use.<br>
Hence, XRForge promotes <b>projecting these ecosystems</b> as virtual <b>hyperlinked</b> worlds.<br>
XRForge can seed itself via local or remote
<u tabindex="0">datastores
<span>
<br>
<br>
<b>Support for datastores:</b>
<br>
<table class="table table-dark table-striped">
<tr><td>
Azure Blob <br>
Azure Files <br>
B2 <br>
Box <br>
Cloudinary <br>
Doi <br>
Drime <br>
Drive <br>
Dropbox <br>
Fichier <br>
Filefabric <br>
Filelu <br>
Filen <br>
Filescom <br>
FTP <br>
Gofile <br>
</td>
<td>
Google Cloud Storage <br>
Google Photos <br>
HDFS <br>
Hidrive <br>
HTTP <br>
Iclouddrive <br>
Imagekit <br>
Internet Archive <br>
Internxt <br>
Jottacloud <br>
Koofr <br>
Linkbox <br>
Local <br>
Mailru <br>
Mega <br>
</td>
<td>
Memory <br>
Netstorage <br>
Onedrive <br>
Opendrive <br>
Oracle Object Storage <br>
Pcloud <br>
Pikpak <br>
Pixeldrain <br>
Premiumizeme <br>
Proton Drive <br>
Putio <br>
Qingstor <br>
Quatrix <br>
S3 <br>
Seafile <br>
</td>
<td>
SFTP <br>
Shade <br>
Sharefile <br>
Sia <br>
SMB <br>
Storj <br>
Sugarsync <br>
Swift <br>
Ulozto <br>
WebDAV <br>
Yandex <br>
Zoho <br>
</td>
</tr>
</table>
</span>
</u>, making it perfect for large organisations.
<div id="xrecosystem"></div>
The
<u tabindex="0">Fediverse
<span>, a fleet of ad-free <a href="https://jointhefediverse.net/learn" target="_blank">federated platforms</a>,</span>
</u> makes an excellent backoffice for virtual <b>XR hypermedia</b> experiences.<br>
<b>Federated</b> experiences <b>allow anybody</b> to extend
<u tabindex="0">existing
<span>open-source foundations and shared data</span>
</u>
foundations to accelerate XR
<u tabindex="0">innovation
<span>, by allowing them to "remix" and expand the world </span>
</u>.<br>
<b>Byebye</b> constantly reinventing the wheel / walled gardens.<br>
<b>Hello</b> post-scarcity technology.
<br><br>
<center>
<img src="img/xrforge_term.svg" style="border-radius:7px; border-radius: 7px; width: 100%; max-width: 450px; margin-bottom: 40px;">
</center>
</div>
<div class="spectrum">
<div></div>
</div>
<center>
<h3>Comparison</h3>
<table class="table table-dark table-striped" id="comparison">
<thead>
<tr>
<td></td>
<td><b>XRForge</b></td>
<td><b>Other solutions</b><br>(Meta Horizon e.g.)</td>
</tr>
</thead>
<tbody>
<tr>
<td>No data-collection or login requirement</td>
<td></td>
<td></td>
</tr>
<tr>
<td>users can host content themselves</td>
<td><small>HTTP/DAT/IPFS Open Protocols</small></td>
<td><small>we own your data</small></td>
</tr>
<tr>
<td>User operated content and viewers</td>
<td></td>
<td><small>we control both</small></td>
</tr>
<tr>
<td>portals to remote content</td>
<td><small>JanusXR or <a href="https://xrfragment.org" target="_blank">XR Fragments</a> protocol</small></td>
<td></td>
</tr>
<tr>
<td>Platform does not control network</td>
<td><small>user-operated viewers and content</small></td>
<td><small>stakeholders can block anything</small></td>
</tr>
<tr>
<td>Platform to Platform portals</td>
<td><small>JanusXR or <a href="https://xrfragment.org" target="_blank">XR Fragments</a> protocol</small></td>
<td></td>
</tr>
<tr>
<td>2D web to 3D translators</td>
<td><small>JanusWeb translators</small></td>
<td></td>
</tr>
<tr>
<td>Embed 3D scene in regular file (pdf e.g.)</td>
<td><small>supported via JanusWeb</small></td>
<td></td>
</tr>
<tr>
<td>Portals from/to Internet/Intranet</td>
<td></td>
<td></td>
</tr>
<tr>
<td>User can make content private</td>
<td><small>XRForge permissions or HTTP password</small></td>
<td></td>
</tr>
<tr>
<td>Spatial anchors / URL addressibility</td>
<td><small>JanusWeb and <a href="https://xrfragment.org" target="_blank">XR Fragments</a> protocol</small></td>
<td></td>
</tr>
<tr>
<td>Direct portals to 3D file</td>
<td><small>Janusweb and <a href="https://xrfragment.org" target="_blank">XR Fragments</a> protocol</small></td>
<td></td>
</tr>
<tr>
<td>Detect 3D scene in webpage URL</td>
<td><small>Janusweb and <a href="https://xrfragment.org" target="_blank">XR Fragments</a> protocol</small></td>
<td></td>
</tr>
<tr>
<td>Export data + Credible exit</td>
<td><small>server-export runs on opensource <a href="https://github.com/jbaicoianu/janusweb" target="_blank">janusweb</a> viewer</small></td>
<td></td>
</tr>
<tr>
<td>Lightweight (runs on Raspberry PI e.g.)</td>
<td></td>
<td></td>
</tr>
<tr>
<td>XR worlds at rest</td>
<td></td>
<td><small>compute required for nonvisited spaces</small></td>
</tr>
<tr>
<td>Integrates with Fediverse</td>
<td><small>via ActivityPub and RSS/HTML translators</small></td>
<td></td>
</tr>
<tr>
<td>Integrate with (own) dataclouds</td>
<td style="width:33%"><small>scroll down below</small>
<div style="max-height: 200px; overflow-y: scroll; background: var(--bs-body-bg); padding: 10px; border-radius: 9px;">
<small>
Via rclone: Google Drive, Amazon S3, Microsoft OneDrive, Dropbox, Backblaze B2, SFTP, Google Cloud Storage (GCS), Microsoft Azure Blob Storage, MinIO, FTP, WebDAV, Wasabi, Cloudflare R2, Local Filesystem, MEGA, pCloud, Nextcloud, DigitalOcean Spaces, Hetzner Storage Box, Box, Google Photos, iCloud Drive, SMB/CIFS, Oracle Object Storage, Proton Drive, IDrive e2, Alibaba Cloud (Aliyun) OSS, Yandex Disk, Hetzner Object Storage, OVHcloud, ownCloud, Scaleway, Koofr, Put.io, Seafile, Mail.ru, 1Fichier, Akamai NetStorage, Internet Archive, Jottacloud, Storj, Tencent COS, Huawei OBS, Qiniu Kodo, OpenStack Swift, Arvan Cloud AOS, Bizfly Cloud, Ceph, China Mobile Ecloud, Citrix ShareFile, Cloudinary, Cubbit, Digi Storage, Dreamhost, Drime, Enterprise File Fabric, Exaba, Fastmail Files, FileLu Cloud, Filen, Files.com, Gofile, HDFS, HiDrive, HTTP, ImageKit, Internxt, IONOS Cloud, Leviia, Liara, Linkbox, Magalu, Memory, OpenDrive, Oracle Cloud Storage, Outscale, Petabox, PikPak, Pixeldrain, Premiumize.me, QingStor, Quatrix, Rabata, RackCorp, Rackspace Cloud Files, Rsync.net, Scaleway, Seafile, Seagate Lyve Cloud, SeaweedFS, Selectel, Servercore, Spectra Logic, Storj, SugarSync, Uloz.to, Zoho WorkDrive</small>
</small>
</td>
<td>
</td>
</body>
</table>
</center>
<br/>
<br/>
<div class="spectrum">
<div></div>
<div></div>
</div>
<center>
<h3>JanusXR: The deep spatial web (within the web)</h3>
<div style="max-width:945px;">
<a href="https://coderofsalvation.github.io/janus-guide/" target="_blank">
<img src="/img/janusxr-xrf.png" style="width:100%"/>
</a>
<br>
</div>
<br>
</center>
</div>
${footer}

View file

@ -8,13 +8,13 @@ ${header}
${notification}
<div class="tab">
<div class="label col2">
Local content
</div>
</div>
<form method="POST">
<div class="tab">
<div class="label col2">
Local content
</div>
</div>
<div class="margin1">
<table width="100%">
<tr>
@ -39,6 +39,35 @@ ${notification}
<br/>
<br/>
<div class="tab">
<div class="label col2">
Hide content
</div>
</div>
<div class="margin1">
<table width="100%">
<tr>
<th width="165"/>
<th />
<th />
</tr>
<tr>
<td>
Keywords
</td>
<td >
<input type="text" value="${opts.hide_keywords}"></input>
</td>
<td class="col3">
Space-separated, <a href="http://lua-users.org/wiki/PatternsTutorial" target="_blank">lua patterns</a> are allowed
</td>
</tr>
</table>
</div>
<br/>
<br/>
<div class="tab">
<div class="label col2">
Manyfold instances
@ -119,7 +148,7 @@ ${notification}
<div style="margin-left:165px">
<br/>
<div class="btn">
<input type="submit" class="btn secondary" value="save" />
<input type="submit" class="btn secondary" value="Save" style=""/>
</div>
</div>
</div>

View file

@ -1,127 +1,130 @@
${header}
<h1>HEADER 1</h1>
Lorem ipsum dolor sit amter.<br>
Amet puti solor fati corpus <a href="#foo" >a link</a> flap.<br><br>
<hr>
<div class="design">
<div class="btn">
<a href="#foo">button</a>
</div>
<h1>HEADER 1</h1>
Lorem ipsum dolor sit amter.<br>
Amet puti solor fati corpus <a href="#foo" >a link</a> flap.<br><br>
<hr>
<div class="btn">
<a href="#foo" class="btn primary">button primary ⮮</a>
</div>
<div class="btn">
<a href="#foo">button</a>
</div>
<div class="btn">
<a href="https://foo.com" target="_blank" class="btn secondary">button secondary ⮩</a>
</div>
<br>
<hr>
<div class="btn">
<a href="#foo" class="btn primary">button primary ⮮</a>
</div>
<div class="tab">
<div class="label col3">
Category B
<div class="btn">
<a href="https://foo.com" target="_blank" class="btn secondary">button secondary ⮩</a>
</div>
<br>
<hr>
<div class="tab">
<div class="label col3">
Category B
</div>
</div>
<div class="margin1">
<form>
<table width="100%">
<tr>
<td width="165">
Instance URL 1
</td>
<td >
<input type="text"/>
</td>
<td class="col3">
Infotext about input
</td>
</tr>
<tr>
<td>
Sync interval
</td>
<td>
<select>
<option value="30">every 30 mins</option>
<option value="15" selected>every 15 mins</option>
<option value="5">every 5 minutes</option>
</select>
</td>
<td class="col3">
Infotext about select (tip: use selectboxes not checkboxes)
</td>
</tr>
</table>
</form>
<ul>
<li>foo bar</li>
<li>flop flap</li>
</ul>
<pre>
</pre>
<pre>
┌─────────────────┐┌────────────────┐
│ Foo CLI ││ Foo Web │
└─────────────────┘└────────────────┘
┌───────────────────────────────────┐
│ Foo Repository │
│ ┌────────┐ ┌────────┐ ┌─────────┐ │
│ │ code │ │ issues │ │ patches │ │
│ └────────┘ └────────┘ └─────────┘ │
├───────────────────────────────────┤
│ Foo Storage (Git) │
└───────────────────────────────────┘
┌────────────────┐┌─────────────────┐
│ Foo Node ││ Foo HTTPD │
├────────────────┤├─────────────────┤
│ NoiseXK ││ HTTP + JSON │
└────────────────┘└─────────────────┘
</pre>
<pre class="primary">
┌─────────────────┐┌────────────────┐
│ Foo CLI ││ Foo Web │
└─────────────────┘└────────────────┘
┌───────────────────────────────────┐
│ Foo Repository │
│ ┌────────┐ ┌────────┐ ┌─────────┐ │
│ │ code │ │ issues │ │ patches │ │
│ └────────┘ └────────┘ └─────────┘ │
├───────────────────────────────────┤
│ Foo Storage (Git) │
└───────────────────────────────────┘
┌────────────────┐┌─────────────────┐
│ Foo Node ││ Foo HTTPD │
├────────────────┤├─────────────────┤
│ NoiseXK ││ HTTP + JSON │
└────────────────┘└─────────────────┘
</pre>
<pre class="secondary">
┌─────────────────┐┌────────────────┐
│ Foo CLI ││ Foo Web │
└─────────────────┘└────────────────┘
┌───────────────────────────────────┐
│ Foo Repository │
│ ┌────────┐ ┌────────┐ ┌─────────┐ │
│ │ code │ │ issues │ │ patches │ │
│ └────────┘ └────────┘ └─────────┘ │
├───────────────────────────────────┤
│ Foo Storage (Git) │
└───────────────────────────────────┘
┌────────────────┐┌─────────────────┐
│ Foo Node ││ Foo HTTPD │
├────────────────┤├─────────────────┤
│ NoiseXK ││ HTTP + JSON │
└────────────────┘└─────────────────┘
</pre>
</div>
</div>
<div class="margin1">
<form>
<table width="100%">
<tr>
<td width="165">
Instance URL 1
</td>
<td >
<input type="text"/>
</td>
<td class="col3">
Infotext about input
</td>
</tr>
<tr>
<td>
Sync interval
</td>
<td>
<select>
<option value="30">every 30 mins</option>
<option value="15" selected>every 15 mins</option>
<option value="5">every 5 minutes</option>
</select>
</td>
<td class="col3">
Infotext about select (tip: use selectboxes not checkboxes)
</td>
</tr>
</table>
</form>
<ul>
<li>foo bar</li>
<li>flop flap</li>
</ul>
<pre>
</pre>
<pre>
┌─────────────────┐┌────────────────┐
│ Foo CLI ││ Foo Web │
└─────────────────┘└────────────────┘
┌───────────────────────────────────┐
│ Foo Repository │
│ ┌────────┐ ┌────────┐ ┌─────────┐ │
│ │ code │ │ issues │ │ patches │ │
│ └────────┘ └────────┘ └─────────┘ │
├───────────────────────────────────┤
│ Foo Storage (Git) │
└───────────────────────────────────┘
┌────────────────┐┌─────────────────┐
│ Foo Node ││ Foo HTTPD │
├────────────────┤├─────────────────┤
│ NoiseXK ││ HTTP + JSON │
└────────────────┘└─────────────────┘
</pre>
<pre class="primary">
┌─────────────────┐┌────────────────┐
│ Foo CLI ││ Foo Web │
└─────────────────┘└────────────────┘
┌───────────────────────────────────┐
│ Foo Repository │
│ ┌────────┐ ┌────────┐ ┌─────────┐ │
│ │ code │ │ issues │ │ patches │ │
│ └────────┘ └────────┘ └─────────┘ │
├───────────────────────────────────┤
│ Foo Storage (Git) │
└───────────────────────────────────┘
┌────────────────┐┌─────────────────┐
│ Foo Node ││ Foo HTTPD │
├────────────────┤├─────────────────┤
│ NoiseXK ││ HTTP + JSON │
└────────────────┘└─────────────────┘
</pre>
<pre class="secondary">
┌─────────────────┐┌────────────────┐
│ Foo CLI ││ Foo Web │
└─────────────────┘└────────────────┘
┌───────────────────────────────────┐
│ Foo Repository │
│ ┌────────┐ ┌────────┐ ┌─────────┐ │
│ │ code │ │ issues │ │ patches │ │
│ └────────┘ └────────┘ └─────────┘ │
├───────────────────────────────────┤
│ Foo Storage (Git) │
└───────────────────────────────────┘
┌────────────────┐┌─────────────────┐
│ Foo Node ││ Foo HTTPD │
├────────────────┤├─────────────────┤
│ NoiseXK ││ HTTP + JSON │
└────────────────┘└─────────────────┘
</pre>
</div>
${footer}

45
src/page/experiences.html Normal file
View file

@ -0,0 +1,45 @@
${header}
<div style="height:120px;" class="jumbotron">
<h1>${opts.title}</h1>
${opts.subtitle}
</div>
<hr style="margin-top:0">
<div class="btn">
<a href="#foo">button</a>
</div>
<div class="btn">
<a href="#foo" class="primary">button primary <img src="img/arrow-down.svg" class="icon"/></a>
</div>
<div class="btn">
<a href="https://foo.com" target="_blank" class="secondary">button secondary <img src="img/arrow-right.svg" class="icon"/></a>
</div>
<br>
<hr>
<br>
<div class="grid">
<div class="tile">
<div class="img" style="background-image:url(https://xrforge.isvery.ninja/models/dpjnj8pt1cjc/model_files/bzjvdm7l523l.png?derivative=preview);"></div>
<div class="text">
<img src="img/folder.svg" class="icon"/>&nbsp;Item 1
</div>
</div>
<div class="tile">
<div class="img" style="background-image:url(https://xrforge.isvery.ninja/models/dpjnj8pt1cjc/model_files/bzjvdm7l523l.png?derivative=preview);"></div>
<div class="text">
<img src="img/folder.svg" class="icon"/>&nbsp;Item 2
</div>
</div>
<div class="tile">
<div class="img" style="background-image:url(https://xrforge.isvery.ninja/models/dpjnj8pt1cjc/model_files/bzjvdm7l523l.png?derivative=preview);"></div>
<div class="text">
<img src="img/folder.svg" class="icon"/>&nbsp;Item 3
</div>
</div>
</div>
${footer}

18
src/page/experiences.lua Normal file
View file

@ -0,0 +1,18 @@
local util = require("util")
if not app.cache['experiences.html'] then
app.cache['experiences.html'] = util.memoize(
function()
print("processing!")
local data = util.merge({foo='1'},{ opts = app.opts })
local html = util.template( LoadAsset("page/experiences.html"),app)
return html
end,
60*5 -- re-run every 5 mins (otherwise return cache)
)
end
SetStatus(200)
SetHeader('Content-Type', 'text/html; charset=utf-8')
Write( app.cache['experiences.html']() )

View file

@ -6,9 +6,19 @@
<table width="100%" class="footer">
<tr>
<td class="col3">footer col1</td>
<td class="col3">footer col1</td>
<td class="col3">footer col1</td>
<td class="col3">
<a href="https://xrhf.isvery.ninja">XR Hypermedia Federation</a><br/>
<a href="https://coderofsalvation.github.io/janus-guide/">JanusXR Guide</a><br/>
<a href="https://nlnet.nl">NLNET</a><br/>
</td>
<td class="col3">
<a href="/experiences">Experiences</a><br/>
<a href="/about">About</a><br/>
<a href="/howto">Howto</a>
</td>
<td class="col3">
<a href="https://codeberg.org/coderofsalvation/xrforge">Sourcecode</a>
</td>
</tr>
</table>
</td>

View file

@ -7,8 +7,12 @@
<base href="${opts.baseurl}" />
<title>XRForge - selfsovereign interoperable XR experiences</title>
<link rel="stylesheet" href="css/xrforge.css"></link>
${header_include}
<noscript>
<meta http-equiv="refresh" content="0;url=experiences">
</noscript>
</head>
<body background="#000000">
<body background="#000000" class="${page}">
<table width="100%" class="header">
<tr>
@ -21,15 +25,17 @@
</td>
<td class="menu">
<div class="margin1L">
<a href="#">Experiences</a><br/>
<a href="#">Collections</a><br/>
<a href="#">About</a><br/>
<a href="#">Howto</a><br/>
<a href="/experiences">Experiences</a><br/>
<a href="/about">About</a><br/>
<a href="/howto">Howto</a><br/>
</div>
</td>
</tr>
</table>
<hr style="margin:0"/>
<div class="spectrum" id="spectrumheader">
<div></div>
</div>
<table width="100%">
<tr>

View file

@ -1,45 +1,5 @@
${header}
<div style="height:120px;" class="jumbotron">
<h1>${opts.title}</h1>
${opts.subtitle}
</div>
<hr style="margin-top:0">
<div class="btn">
<a href="#foo">button</a>
</div>
<div class="btn">
<a href="#foo" class="primary">button primary <img src="img/arrow-down.svg" class="icon"/></a>
</div>
<div class="btn">
<a href="https://foo.com" target="_blank" class="secondary">button secondary <img src="img/arrow-right.svg" class="icon"/></a>
</div>
<br>
<hr>
<br>
<div class="grid">
<div class="tile">
<div class="img" style="background-image:url(https://xrforge.isvery.ninja/models/dpjnj8pt1cjc/model_files/bzjvdm7l523l.png?derivative=preview);"></div>
<div class="text">
<img src="img/folder.svg" class="icon"/>&nbsp;Item 1
</div>
</div>
<div class="tile">
<div class="img" style="background-image:url(https://xrforge.isvery.ninja/models/dpjnj8pt1cjc/model_files/bzjvdm7l523l.png?derivative=preview);"></div>
<div class="text">
<img src="img/folder.svg" class="icon"/>&nbsp;Item 2
</div>
</div>
<div class="tile">
<div class="img" style="background-image:url(https://xrforge.isvery.ninja/models/dpjnj8pt1cjc/model_files/bzjvdm7l523l.png?derivative=preview);"></div>
<div class="text">
<img src="img/folder.svg" class="icon"/>&nbsp;Item 3
</div>
</div>
</div>
<iframe border="0" frameborder="0" src="https://web.janusxr.org" id="viewer"/>
${footer}