diff --git a/README.md b/README.md index 82d2c62..d65ff7b 100644 --- a/README.md +++ b/README.md @@ -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 >noscript>/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. diff --git a/run.sh b/run.sh index 73a5f05..1c8aeea 100755 --- a/run.sh +++ b/run.sh @@ -1,3 +1,3 @@ #!/bin/sh cd src -../result/bin/xrforge.com -D . -- server +../result/bin/xrforge.com -D . -c 0 server diff --git a/src/.args b/src/.args index bd02a5f..2d471fe 100644 --- a/src/.args +++ b/src/.args @@ -1,2 +1,8 @@ +-H +"Access-Control-Allow-Origin: *" +-H +"Access-Control-Allow-Method: GET, POST, OPTIONS" +-H +"Allow: GET, POST, OPTIONS" -D . diff --git a/src/.init.lua b/src/.init.lua index 8ded0fa..ee6fe90 100644 --- a/src/.init.lua +++ b/src/.init.lua @@ -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() diff --git a/src/.lua/config.lua b/src/.lua/config.lua index a181fa4..56fb305 100644 --- a/src/.lua/config.lua +++ b/src/.lua/config.lua @@ -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 = "", diff --git a/src/.lua/util.lua b/src/.lua/util.lua index c3b05d4..2838101 100644 --- a/src/.lua/util.lua +++ b/src/.lua/util.lua @@ -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) diff --git a/src/css/xrforge.css b/src/css/xrforge.css index f72695a..0d5e160 100644 --- a/src/css/xrforge.css +++ b/src/css/xrforge.css @@ -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; diff --git a/src/css/xrforge.max.css b/src/css/xrforge.max.css index 0fcc051..53893e0 100644 --- a/src/css/xrforge.max.css +++ b/src/css/xrforge.max.css @@ -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%; +} + diff --git a/src/img/backdrop.gif b/src/img/backdrop.gif new file mode 100644 index 0000000..e18afb6 Binary files /dev/null and b/src/img/backdrop.gif differ diff --git a/src/img/badges.png b/src/img/badges.png new file mode 100644 index 0000000..27a0a5d Binary files /dev/null and b/src/img/badges.png differ diff --git a/src/img/blinkhint.svg b/src/img/blinkhint.svg new file mode 100644 index 0000000..738561b --- /dev/null +++ b/src/img/blinkhint.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/src/img/codeberg.svg b/src/img/codeberg.svg new file mode 100644 index 0000000..74a0fa9 --- /dev/null +++ b/src/img/codeberg.svg @@ -0,0 +1,164 @@ + + diff --git a/src/img/janusxr-xrf.png b/src/img/janusxr-xrf.png new file mode 100644 index 0000000..1ddff91 Binary files /dev/null and b/src/img/janusxr-xrf.png differ diff --git a/src/img/obsidian.png b/src/img/obsidian.png new file mode 100644 index 0000000..e06a171 Binary files /dev/null and b/src/img/obsidian.png differ diff --git a/src/img/xrecosystem.png b/src/img/xrecosystem.png new file mode 100644 index 0000000..3efb205 Binary files /dev/null and b/src/img/xrecosystem.png differ diff --git a/src/img/xrforge_term.svg b/src/img/xrforge_term.svg new file mode 100644 index 0000000..91f5e4d --- /dev/null +++ b/src/img/xrforge_term.svg @@ -0,0 +1,322 @@ + diff --git a/src/page/about.html b/src/page/about.html new file mode 100644 index 0000000..757bbe6 --- /dev/null +++ b/src/page/about.html @@ -0,0 +1,333 @@ +${header} + + + +
|
+ Azure Blob + Azure Files + B2 + Box + Cloudinary + Doi + Drime + Drive + Dropbox + Fichier + Filefabric + Filelu + Filen + Filescom + FTP + Gofile + |
+
+ Google Cloud Storage + Google Photos + HDFS + Hidrive + HTTP + Iclouddrive + Imagekit + Internet Archive + Internxt + Jottacloud + Koofr + Linkbox + Local + Mailru + Mega + |
+
+ Memory + Netstorage + Onedrive + Opendrive + Oracle Object Storage + Pcloud + Pikpak + Pixeldrain + Premiumizeme + Proton Drive + Putio + Qingstor + Quatrix + S3 + Seafile + |
+
+ SFTP + Shade + Sharefile + Sia + SMB + Storj + Sugarsync + Swift + Ulozto + WebDAV + Yandex + Zoho + |
+
| + | XRForge | +Other solutions (Meta Horizon e.g.) |
+
| No data-collection or login requirement | +â | +â | +
| users can host content themselves | +â HTTP/DAT/IPFS Open Protocols | +â we own your data | +
| User operated content and viewers | +â | +â we control both | +
| portals to remote content | +â JanusXR or XR Fragments protocol | +â | +
| Platform does not control network | +â user-operated viewers and content | +â stakeholders can block anything | +
| Platform to Platform portals | +â JanusXR or XR Fragments protocol | +â | +
| 2D web to 3D translators | +â JanusWeb translators | +â | +
| Embed 3D scene in regular file (pdf e.g.) | +â supported via JanusWeb | +â | +
| Portals from/to Internet/Intranet | +â | +â | +
| User can make content private | +â XRForge permissions or HTTP password | +â | +
| Spatial anchors / URL addressibility | +â JanusWeb and XR Fragments protocol | +â | +
| Direct portals to 3D file | +â Janusweb and XR Fragments protocol | +â | +
| Detect 3D scene in webpage URL | +â Janusweb and XR Fragments protocol | +â | +
| Export data + Credible exit | +â server-export runs on opensource janusweb viewer | +â | +
| Lightweight (runs on Raspberry PI e.g.) | +â | +â | +
| XR worlds at rest | +â | +â compute required for nonvisited spaces | +
| Integrates with Fediverse | +â via ActivityPub and RSS/HTML translators | +â | +
| Integrate with (own) dataclouds | +â
scroll down below
+
+
+ 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
+
+ |
+ + â + | +