Merge branch 'dev'
This commit is contained in:
commit
6f80f7abeb
|
|
@ -5,6 +5,14 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||
<title>rSpace Canvas</title>
|
||||
<style>
|
||||
/* When loaded inside an iframe, hide shell chrome */
|
||||
html.rspace-embedded .rstack-header { display: none !important; }
|
||||
html.rspace-embedded .rstack-tab-row { display: none !important; }
|
||||
html.rspace-embedded #toolbar { top: 16px !important; }
|
||||
html.rspace-embedded #community-info { display: none !important; }
|
||||
</style>
|
||||
<script>if (window.self !== window.parent) document.documentElement.classList.add('rspace-embedded');</script>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
|
|
@ -672,6 +680,76 @@
|
|||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/shell.css">
|
||||
<style>
|
||||
.rspace-welcome {
|
||||
position: fixed; bottom: 20px; right: 20px; z-index: 10000;
|
||||
display: none; align-items: flex-end; justify-content: flex-end;
|
||||
}
|
||||
.rspace-welcome__popup {
|
||||
position: relative;
|
||||
width: min(380px, 44vw); max-height: 50vh;
|
||||
background: #1e293b; border: 1px solid rgba(255,255,255,0.12);
|
||||
border-radius: 16px; padding: 24px 24px 18px;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.5); color: #e2e8f0;
|
||||
overflow-y: auto; animation: rspace-welcome-in 0.3s ease-out;
|
||||
}
|
||||
@keyframes rspace-welcome-in {
|
||||
from { opacity: 0; transform: translateY(20px) scale(0.95); }
|
||||
to { opacity: 1; transform: translateY(0) scale(1); }
|
||||
}
|
||||
.rspace-welcome__close {
|
||||
position: absolute; top: 10px; right: 12px;
|
||||
background: none; border: none; color: #64748b;
|
||||
font-size: 1.4rem; cursor: pointer; line-height: 1;
|
||||
padding: 4px; border-radius: 4px;
|
||||
}
|
||||
.rspace-welcome__close:hover { color: #e2e8f0; background: rgba(255,255,255,0.08); }
|
||||
.rspace-welcome__title {
|
||||
font-size: 1.35rem; margin: 0 0 8px;
|
||||
background: linear-gradient(135deg, #14b8a6, #22d3ee);
|
||||
-webkit-background-clip: text; -webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
.rspace-welcome__text {
|
||||
font-size: 0.85rem; color: #94a3b8; margin: 0 0 14px; line-height: 1.55;
|
||||
}
|
||||
.rspace-welcome__text strong { color: #e2e8f0; }
|
||||
.rspace-welcome__grid {
|
||||
display: grid; grid-template-columns: 1fr 1fr;
|
||||
gap: 5px; margin-bottom: 14px; font-size: 0.8rem; color: #cbd5e1;
|
||||
}
|
||||
.rspace-welcome__grid span { padding: 3px 0; }
|
||||
.rspace-welcome__actions {
|
||||
display: flex; gap: 8px; margin-bottom: 12px;
|
||||
}
|
||||
.rspace-welcome__btn {
|
||||
padding: 8px 16px; border-radius: 8px; font-size: 0.82rem;
|
||||
font-weight: 600; text-decoration: none; cursor: pointer; border: none;
|
||||
transition: transform 0.15s, box-shadow 0.15s;
|
||||
}
|
||||
.rspace-welcome__btn:hover { transform: translateY(-1px); }
|
||||
.rspace-welcome__btn--primary {
|
||||
background: linear-gradient(135deg, #14b8a6, #0d9488); color: white;
|
||||
box-shadow: 0 2px 8px rgba(20,184,166,0.3);
|
||||
}
|
||||
.rspace-welcome__btn--secondary {
|
||||
background: rgba(255,255,255,0.08); color: #94a3b8;
|
||||
}
|
||||
.rspace-welcome__btn--secondary:hover { color: #e2e8f0; }
|
||||
.rspace-welcome__footer {
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
}
|
||||
.rspace-welcome__link {
|
||||
font-size: 0.72rem; color: #64748b; text-decoration: none;
|
||||
transition: color 0.15s;
|
||||
}
|
||||
.rspace-welcome__link:hover { color: #c4b5fd; }
|
||||
.rspace-welcome__dot { color: #475569; font-size: 0.6rem; }
|
||||
@media (max-width: 600px) {
|
||||
.rspace-welcome { bottom: 12px; right: 12px; left: 12px; }
|
||||
.rspace-welcome__popup { width: 100%; max-width: none; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body data-theme="light">
|
||||
<header class="rstack-header" data-theme="light">
|
||||
|
|
@ -683,6 +761,7 @@
|
|||
<rstack-mi></rstack-mi>
|
||||
</div>
|
||||
<div class="rstack-header__right">
|
||||
<a class="rstack-header__demo-btn" href="https://demo.rspace.online/rspace">Try Demo</a>
|
||||
<rstack-identity></rstack-identity>
|
||||
</div>
|
||||
</header>
|
||||
|
|
@ -694,6 +773,33 @@
|
|||
<p id="community-slug"></p>
|
||||
</div>
|
||||
|
||||
<!-- Welcome overlay (first-time demo visitors) -->
|
||||
<div id="rspace-welcome" class="rspace-welcome" style="display:none">
|
||||
<div class="rspace-welcome__popup">
|
||||
<button class="rspace-welcome__close" onclick="window.__rspaceDismissWelcome()">×</button>
|
||||
<h2 class="rspace-welcome__title">Welcome to rSpace</h2>
|
||||
<p class="rspace-welcome__text">
|
||||
A collaborative, local-first community platform with 22+ interoperable tools.
|
||||
You're viewing the <strong>demo space</strong> — sign in to access your own.
|
||||
</p>
|
||||
<div class="rspace-welcome__grid">
|
||||
<span>🎨 Canvas</span><span>📝 Notes</span>
|
||||
<span>🗳 Voting</span><span>💸 Funds</span>
|
||||
<span>🗺 Maps</span><span>📁 Files</span>
|
||||
<span>🔐 Passkeys</span><span>📡 Offline-First</span>
|
||||
</div>
|
||||
<div class="rspace-welcome__actions">
|
||||
<a href="/create-space" class="rspace-welcome__btn rspace-welcome__btn--primary">Create a Space</a>
|
||||
<button onclick="window.__rspaceDismissWelcome()" class="rspace-welcome__btn rspace-welcome__btn--secondary">Explore Demo</button>
|
||||
</div>
|
||||
<div class="rspace-welcome__footer">
|
||||
<a href="/about" class="rspace-welcome__link">Learn more about rSpace</a>
|
||||
<span class="rspace-welcome__dot">·</span>
|
||||
<a href="https://ridentity.online" class="rspace-welcome__link">EncryptID</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button id="mobile-menu" title="Tools">✚</button>
|
||||
<div id="mobile-zoom">
|
||||
<button id="mz-out" title="Zoom Out">−</button>
|
||||
|
|
@ -894,13 +1000,24 @@
|
|||
import { RStackAppSwitcher } from "@shared/components/rstack-app-switcher";
|
||||
import { RStackSpaceSwitcher } from "@shared/components/rstack-space-switcher";
|
||||
import { RStackTabBar } from "@shared/components/rstack-tab-bar";
|
||||
import { RStackMi } from "@shared/components/rstack-mi";
|
||||
import { rspaceNavUrl } from "@shared/url-helpers";
|
||||
|
||||
// Expose URL helper globally (matches shell.js)
|
||||
window.__rspaceNavUrl = rspaceNavUrl;
|
||||
|
||||
// Register shell header components
|
||||
RStackIdentity.define();
|
||||
RStackAppSwitcher.define();
|
||||
RStackSpaceSwitcher.define();
|
||||
RStackTabBar.define();
|
||||
RStackMi.define();
|
||||
|
||||
// Reload space list when user signs in/out
|
||||
document.addEventListener("auth-change", () => {
|
||||
const sw = document.querySelector("rstack-space-switcher");
|
||||
sw?.reload?.();
|
||||
});
|
||||
|
||||
// Load module list for app switcher
|
||||
fetch("/api/modules").then(r => r.json()).then(data => {
|
||||
|
|
@ -1038,6 +1155,54 @@
|
|||
tabBar.setAttribute("space", communitySlug);
|
||||
}
|
||||
|
||||
// ── "Try Demo" button visibility ──
|
||||
// Hide on demo space, show on bare domain
|
||||
(function() {
|
||||
var btn = document.querySelector('.rstack-header__demo-btn');
|
||||
if (!btn) return;
|
||||
if (communitySlug === 'demo') btn.setAttribute('data-hide', '');
|
||||
var host = window.location.host.split(':')[0];
|
||||
if (host === 'rspace.online' || host === 'www.rspace.online') {
|
||||
btn.removeAttribute('data-hide');
|
||||
}
|
||||
})();
|
||||
|
||||
// ── Auto-space resolution (logged-in users on demo → personal space) ──
|
||||
(function() {
|
||||
try {
|
||||
var raw = localStorage.getItem('encryptid_session');
|
||||
if (!raw) return;
|
||||
var session = JSON.parse(raw);
|
||||
if (!session || !session.claims || !session.claims.username) return;
|
||||
if (communitySlug !== 'demo') return;
|
||||
fetch('/api/spaces/auto-provision', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + session.accessToken,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
if (data.slug) {
|
||||
window.location.replace(rspaceNavUrl(data.slug, 'rspace'));
|
||||
}
|
||||
}).catch(function() {});
|
||||
} catch(e) {}
|
||||
})();
|
||||
|
||||
// ── Welcome overlay (first visit to demo) ──
|
||||
(function() {
|
||||
if (communitySlug !== 'demo') return;
|
||||
if (localStorage.getItem('rspace_welcomed')) return;
|
||||
var el = document.getElementById('rspace-welcome');
|
||||
if (el) el.style.display = 'flex';
|
||||
})();
|
||||
window.__rspaceDismissWelcome = function() {
|
||||
localStorage.setItem('rspace_welcomed', '1');
|
||||
var el = document.getElementById('rspace-welcome');
|
||||
if (el) el.style.display = 'none';
|
||||
};
|
||||
|
||||
const canvas = document.getElementById("canvas");
|
||||
const canvasContent = document.getElementById("canvas-content");
|
||||
const status = document.getElementById("status");
|
||||
|
|
|
|||
Loading…
Reference in New Issue