Merge branch 'dev'
This commit is contained in:
commit
627277303e
|
|
@ -240,8 +240,12 @@ spaces.get("/", async (c) => {
|
|||
const isPermissioned = vis === "permissioned";
|
||||
const accessible = isPublicSpace || isOwner || isMember || (isPermissioned && !!claims);
|
||||
|
||||
// For unauthenticated: only show public spaces
|
||||
if (!claims && !isPublicSpace) continue;
|
||||
// For unauthenticated: only show demo
|
||||
if (!claims && slug !== "demo") continue;
|
||||
|
||||
// For authenticated: skip public spaces the user has no role in
|
||||
// (demo is shown separately, other public spaces are noise)
|
||||
if (claims && isPublicSpace && !isOwner && !isMember && slug !== "demo") continue;
|
||||
|
||||
// Determine relationship
|
||||
const relationship = isOwner
|
||||
|
|
|
|||
|
|
@ -223,6 +223,18 @@ function autoResolveSpace(token: string, username: string): void {
|
|||
.catch(() => {});
|
||||
}
|
||||
|
||||
// ── Silent provisioning (no redirect) — ensures user's space exists ──
|
||||
|
||||
function autoProvisionSpace(token: string): void {
|
||||
fetch("/api/spaces/auto-provision", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}).catch(() => {});
|
||||
}
|
||||
|
||||
// ── Inline URL helpers (avoid import cycle with url-helpers) ──
|
||||
const _RESERVED = ["www", "rspace", "create", "new", "start", "auth"];
|
||||
function _isSubdomain(): boolean {
|
||||
|
|
@ -264,12 +276,12 @@ export class RStackIdentity extends HTMLElement {
|
|||
this.#refreshIfNeeded();
|
||||
this.#render();
|
||||
|
||||
// Belt-and-suspenders: if a session already exists on page load,
|
||||
// ensure the user's personal space is provisioned (catches edge
|
||||
// cases like iframe embedding or direct navigation).
|
||||
// If a session already exists on page load, provision the
|
||||
// user's personal space in the background (but do NOT redirect —
|
||||
// the user intentionally navigated to this space).
|
||||
const session = getSession();
|
||||
if (session?.accessToken && session.claims.username) {
|
||||
autoResolveSpace(session.accessToken, session.claims.username);
|
||||
autoProvisionSpace(session.accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,9 +171,8 @@ export class RStackSpaceSwitcher extends HTMLElement {
|
|||
return;
|
||||
}
|
||||
|
||||
// 3-section split — exclude demo from public since we show it separately
|
||||
// Split: user's own spaces vs permissioned spaces they can discover
|
||||
const mySpaces = this.#spaces.filter((s) => s.role);
|
||||
const publicSpaces = this.#spaces.filter((s) => s.accessible !== false && !s.role && s.slug !== "demo");
|
||||
const discoverSpaces = this.#spaces.filter((s) => s.accessible === false);
|
||||
|
||||
const hasOwnedSpace = mySpaces.some((s) => s.relationship === "owner");
|
||||
|
|
@ -214,25 +213,7 @@ export class RStackSpaceSwitcher extends HTMLElement {
|
|||
.join("");
|
||||
}
|
||||
|
||||
// ── Public spaces ──
|
||||
if (publicSpaces.length > 0) {
|
||||
if (mySpaces.length > 0) html += `<div class="divider"></div>`;
|
||||
html += `<div class="section-label">Public spaces</div>`;
|
||||
html += publicSpaces
|
||||
.map((s) => {
|
||||
const vis = this.#visibilityInfo(s);
|
||||
return `
|
||||
<a class="item ${vis.cls} ${s.slug === current ? "active" : ""}"
|
||||
href="${rspaceNavUrl(s.slug, moduleId)}">
|
||||
<span class="item-icon">${s.icon || "🌐"}</span>
|
||||
<span class="item-name">${this.#displayName(s)}</span>
|
||||
<span class="item-vis ${vis.cls}">${vis.label}</span>
|
||||
</a>`;
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
// ── Discover (inaccessible spaces) ──
|
||||
// ── Discover (permissioned spaces the user can request access to) ──
|
||||
if (auth && discoverSpaces.length > 0) {
|
||||
html += `<div class="divider"></div>`;
|
||||
html += `<div class="section-label">Discover</div>`;
|
||||
|
|
|
|||
Loading…
Reference in New Issue