Merge branch 'dev'
CI/CD / deploy (push) Successful in 2m55s
Details
CI/CD / deploy (push) Successful in 2m55s
Details
This commit is contained in:
commit
a89a6fbebb
|
|
@ -13,6 +13,7 @@ import type { CrowdSurfDoc, CrowdSurfPrompt, Contribution } from '../schemas';
|
|||
import { getDecayProgress, getTimeRemaining, getRightSwipeCount, isReadyToTrigger, getUrgency, parseContributions, crowdsurfSchema, crowdsurfDocId } from '../schemas';
|
||||
import { getModuleApiBase } from "../../../shared/url-helpers";
|
||||
import type { DocumentId } from "../../../shared/local-first/document";
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
// ── Auth helpers ──
|
||||
function getSession(): { accessToken: string; claims: { sub: string; did?: string; username?: string } } | null {
|
||||
|
|
@ -45,6 +46,7 @@ class FolkCrowdSurfDashboard extends HTMLElement {
|
|||
|
||||
// State
|
||||
private activeTab: ViewTab = 'discover';
|
||||
private _history = new ViewHistory<ViewTab>('discover', 'crowdsurf');
|
||||
private loading = true;
|
||||
private prompts: CrowdSurfPrompt[] = [];
|
||||
private currentPromptIndex = 0;
|
||||
|
|
@ -95,9 +97,12 @@ class FolkCrowdSurfDashboard extends HTMLElement {
|
|||
this.initMultiplayer();
|
||||
}
|
||||
this._stopPresence = startPresenceHeartbeat(() => ({ module: 'crowdsurf', context: this.prompts[this.currentPromptIndex]?.text || 'CrowdSurf' }));
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
this._stopPresence?.();
|
||||
this._lfcUnsub?.();
|
||||
this._lfcUnsub = null;
|
||||
|
|
@ -105,6 +110,13 @@ class FolkCrowdSurfDashboard extends HTMLElement {
|
|||
if (this._expiryTimer !== null) clearInterval(this._expiryTimer);
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'crowdsurf') return;
|
||||
this.activeTab = e.detail.view;
|
||||
this.render();
|
||||
this.bindEvents();
|
||||
};
|
||||
|
||||
// ── Multiplayer init ──
|
||||
|
||||
private async initMultiplayer() {
|
||||
|
|
@ -337,6 +349,7 @@ class FolkCrowdSurfDashboard extends HTMLElement {
|
|||
this.lfClient.createPrompt(prompt);
|
||||
}
|
||||
|
||||
this._history.push('discover');
|
||||
this.activeTab = 'discover';
|
||||
this.render();
|
||||
this.bindEvents();
|
||||
|
|
@ -738,6 +751,7 @@ class FolkCrowdSurfDashboard extends HTMLElement {
|
|||
btn.addEventListener('click', () => {
|
||||
const tab = btn.dataset.tab as ViewTab;
|
||||
if (tab && tab !== this.activeTab) {
|
||||
this._history.push(tab);
|
||||
this.activeTab = tab;
|
||||
this.render();
|
||||
this.bindEvents();
|
||||
|
|
@ -761,6 +775,7 @@ class FolkCrowdSurfDashboard extends HTMLElement {
|
|||
|
||||
// Go to create tab
|
||||
this.shadow.querySelector('[data-action="go-create"]')?.addEventListener('click', () => {
|
||||
this._history.push('create');
|
||||
this.activeTab = 'create';
|
||||
this.render();
|
||||
this.bindEvents();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { startPresenceHeartbeat } from '../../../shared/collab-presence';
|
|||
import { getModuleApiBase } from "../../../shared/url-helpers";
|
||||
import type { DocumentId } from "../../../shared/local-first/document";
|
||||
import { bnbSchema, bnbDocId } from "../schemas";
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
const BNB_TOUR_STEPS: TourStep[] = [
|
||||
{ target: '.bnb-search', title: 'Search', message: 'Filter listings by location, type, or economy model.' },
|
||||
|
|
@ -63,6 +64,7 @@ class FolkBnbView extends HTMLElement {
|
|||
#stats: any = null;
|
||||
#selectedStay: any = null;
|
||||
#view: 'grid' | 'map' = 'grid';
|
||||
private _history = new ViewHistory<'grid' | 'map'>('grid', 'rbnb');
|
||||
#search = '';
|
||||
#typeFilter = '';
|
||||
#economyFilter = '';
|
||||
|
|
@ -78,13 +80,23 @@ class FolkBnbView extends HTMLElement {
|
|||
this.#loadData();
|
||||
this._stopPresence = startPresenceHeartbeat(() => ({ module: 'rbnb', context: 'Listings' }));
|
||||
if (this.#space !== 'demo') this.subscribeOffline();
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
this._stopPresence?.();
|
||||
this._offlineUnsub?.(); this._offlineUnsub = null;
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'rbnb') return;
|
||||
this.#view = e.detail.view;
|
||||
this.#render();
|
||||
this.#renderContent();
|
||||
};
|
||||
|
||||
private async subscribeOffline() {
|
||||
const runtime = (window as any).__rspaceOfflineRuntime;
|
||||
if (!runtime?.isInitialized) return;
|
||||
|
|
@ -230,7 +242,9 @@ class FolkBnbView extends HTMLElement {
|
|||
// View toggles
|
||||
for (const btn of this.querySelectorAll('.bnb-view__toggle')) {
|
||||
btn.addEventListener('click', () => {
|
||||
this.#view = (btn as HTMLElement).dataset.view as 'grid' | 'map';
|
||||
const v = (btn as HTMLElement).dataset.view as 'grid' | 'map';
|
||||
this._history.push(v);
|
||||
this.#view = v;
|
||||
this.#render();
|
||||
this.#renderContent();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import {
|
|||
calculateAffordability,
|
||||
} from '../lib/mortgage-engine';
|
||||
import type { MortgageSummary } from '../lib/mortgage-engine';
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
type ViewMode = 'mycelial' | 'flow' | 'grid' | 'lender' | 'borrower';
|
||||
|
||||
|
|
@ -90,6 +91,7 @@ class FolkMortgageSimulator extends HTMLElement {
|
|||
private summary!: MortgageSummary;
|
||||
private currentMonth = DEFAULT_CONFIG.startMonth;
|
||||
private viewMode: ViewMode = 'mycelial';
|
||||
private _history = new ViewHistory<ViewMode>('mycelial', 'rflows');
|
||||
private selectedTrancheId: string | null = null;
|
||||
private controlsOpen = true;
|
||||
private playing = false;
|
||||
|
|
@ -121,12 +123,26 @@ class FolkMortgageSimulator extends HTMLElement {
|
|||
this._recompute();
|
||||
this._attachListeners();
|
||||
this.render();
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
this._stopPlayback();
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'rflows') return;
|
||||
this.viewMode = e.detail.view;
|
||||
const tabs = this.shadow.querySelectorAll('.view-tab');
|
||||
tabs.forEach((tab: Element) => {
|
||||
const t = tab as HTMLElement;
|
||||
t.className = `view-tab ${t.dataset.view === this.viewMode ? 'active' : ''}`;
|
||||
});
|
||||
this._updateView();
|
||||
};
|
||||
|
||||
// ─── Core simulation ──────────────────────────────────
|
||||
|
||||
private _recompute() {
|
||||
|
|
@ -1548,6 +1564,7 @@ class FolkMortgageSimulator extends HTMLElement {
|
|||
|
||||
switch (action) {
|
||||
case 'view': {
|
||||
this._history.push(target.dataset.view as ViewMode);
|
||||
this.viewMode = target.dataset.view as ViewMode;
|
||||
// Update tab highlights in-place
|
||||
const tabs = this.shadow.querySelectorAll('.view-tab');
|
||||
|
|
|
|||
|
|
@ -70,11 +70,13 @@ import { TourEngine } from "../../../shared/tour-engine";
|
|||
import { startPresenceHeartbeat } from '../../../shared/collab-presence';
|
||||
import type { DocumentId } from "../../../shared/local-first/document";
|
||||
import { networkSchema, networkDocId } from "../schemas";
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
class FolkCrmView extends HTMLElement {
|
||||
private shadow: ShadowRoot;
|
||||
private space = "";
|
||||
private activeTab: Tab = "pipeline";
|
||||
private _history = new ViewHistory<Tab>("pipeline", "rnetwork");
|
||||
private searchQuery = "";
|
||||
private sortColumn = "";
|
||||
private sortAsc = true;
|
||||
|
|
@ -129,6 +131,7 @@ class FolkCrmView extends HTMLElement {
|
|||
private _onTabChange = (e: Event) => {
|
||||
const tab = (e as CustomEvent).detail?.tab;
|
||||
if (tab && tab !== this.activeTab) {
|
||||
this._history.push(tab as Tab);
|
||||
this.activeTab = tab as Tab;
|
||||
this.searchQuery = "";
|
||||
this.sortColumn = "";
|
||||
|
|
@ -164,13 +167,23 @@ class FolkCrmView extends HTMLElement {
|
|||
setTimeout(() => this._tour.start(), 1200);
|
||||
}
|
||||
this._stopPresence = startPresenceHeartbeat(() => ({ module: 'rnetwork', context: this.graphSelectedId ? 'CRM' : `CRM - ${this.activeTab}` }));
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
document.removeEventListener("rapp-tab-change", this._onTabChange);
|
||||
this._stopPresence?.();
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'rnetwork') return;
|
||||
this.activeTab = e.detail.view;
|
||||
this.searchQuery = "";
|
||||
this.render();
|
||||
};
|
||||
|
||||
private async subscribeCollabOverlay() {
|
||||
const runtime = (window as any).__rspaceOfflineRuntime;
|
||||
if (!runtime?.isInitialized) return;
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ import type { SwagDoc, SwagDesign } from "../schemas";
|
|||
import { swagSchema, swagDocId } from "../schemas";
|
||||
import { startPresenceHeartbeat } from '../../../shared/collab-presence';
|
||||
import type { DocumentId } from "../../../shared/local-first/document";
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
// Auth helpers
|
||||
function getSession(): { accessToken: string; claims: { sub: string; did?: string; username?: string } } | null {
|
||||
|
|
@ -195,6 +196,7 @@ class FolkSwagDesigner extends HTMLElement {
|
|||
|
||||
// Tab state
|
||||
private activeTab: TabId = "browse";
|
||||
private _history = new ViewHistory<TabId>("browse", "rswag");
|
||||
|
||||
// Demo state
|
||||
private selectedProduct = "tee";
|
||||
|
|
@ -284,15 +286,24 @@ class FolkSwagDesigner extends HTMLElement {
|
|||
setTimeout(() => this._tour.start(), 1200);
|
||||
}
|
||||
this._stopPresence = startPresenceHeartbeat(() => ({ module: 'rswag', context: 'Swag Designer' }));
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
this._stopPresence?.();
|
||||
this._lfcUnsub?.();
|
||||
this._lfcUnsub = null;
|
||||
this.lfClient?.disconnect();
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'rswag') return;
|
||||
this.activeTab = e.detail.view;
|
||||
this.render();
|
||||
};
|
||||
|
||||
private async initMultiplayer() {
|
||||
try {
|
||||
this.lfClient = new SwagLocalFirstClient(this.space);
|
||||
|
|
@ -929,7 +940,9 @@ class FolkSwagDesigner extends HTMLElement {
|
|||
// Tab switching
|
||||
this.shadow.querySelectorAll<HTMLElement>(".tab-btn").forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
this.activeTab = btn.dataset.tab as TabId;
|
||||
const tab = btn.dataset.tab as TabId;
|
||||
this._history.push(tab);
|
||||
this.activeTab = tab;
|
||||
this.render();
|
||||
});
|
||||
});
|
||||
|
|
@ -938,7 +951,9 @@ class FolkSwagDesigner extends HTMLElement {
|
|||
this.shadow.querySelectorAll<HTMLElement>("[data-tab]").forEach(btn => {
|
||||
if (!btn.classList.contains("tab-btn")) {
|
||||
btn.addEventListener("click", () => {
|
||||
this.activeTab = btn.dataset.tab as TabId;
|
||||
const tab = btn.dataset.tab as TabId;
|
||||
this._history.push(tab);
|
||||
this.activeTab = tab;
|
||||
this.render();
|
||||
});
|
||||
}
|
||||
|
|
@ -1014,6 +1029,7 @@ class FolkSwagDesigner extends HTMLElement {
|
|||
this.shadow.querySelectorAll<HTMLElement>(".dither-btn").forEach(btn => {
|
||||
btn.addEventListener("click", () => {
|
||||
this.ditherDesignSlug = btn.dataset.slug || "";
|
||||
this._history.push("dither");
|
||||
this.activeTab = "dither";
|
||||
this.render();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
import type { DocumentId } from "../../../shared/local-first/document";
|
||||
import { startPresenceHeartbeat } from '../../../shared/collab-presence';
|
||||
import { commitmentsSchema, commitmentsDocId } from "../schemas";
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
// ── Constants ──
|
||||
|
||||
|
|
@ -254,6 +255,7 @@ class FolkTimebankApp extends HTMLElement {
|
|||
private shadow: ShadowRoot;
|
||||
private space = 'demo';
|
||||
private currentView: 'canvas' | 'collaborate' | 'dashboard' = 'canvas';
|
||||
private _history = new ViewHistory<'canvas' | 'collaborate' | 'dashboard'>('canvas', 'rtime');
|
||||
|
||||
// Pool panel state
|
||||
private canvas!: HTMLCanvasElement;
|
||||
|
|
@ -357,6 +359,7 @@ class FolkTimebankApp extends HTMLElement {
|
|||
this.fetchData();
|
||||
this._stopPresence = startPresenceHeartbeat(() => ({ module: 'rtime', context: 'Timebank' }));
|
||||
if (this.space !== 'demo') this.subscribeOffline();
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
private async subscribeOffline() {
|
||||
|
|
@ -392,10 +395,28 @@ class FolkTimebankApp extends HTMLElement {
|
|||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
if (this.animFrame) cancelAnimationFrame(this.animFrame);
|
||||
this._stopPresence?.(); this._offlineUnsub?.(); this._offlineUnsub = null;
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'rtime') return;
|
||||
this.currentView = e.detail.view;
|
||||
// Toggle visibility of view panels
|
||||
const canvasView = this.shadow.getElementById('canvas-view');
|
||||
const collabView = this.shadow.getElementById('collaborate-view');
|
||||
const dashView = this.shadow.getElementById('dashboard-view');
|
||||
if (canvasView) canvasView.style.display = this.currentView === 'canvas' ? 'flex' : 'none';
|
||||
if (collabView) collabView.style.display = this.currentView === 'collaborate' ? 'flex' : 'none';
|
||||
if (dashView) dashView.style.display = this.currentView === 'dashboard' ? 'flex' : 'none';
|
||||
this.shadow.querySelectorAll('.tab').forEach(t => t.classList.toggle('active', (t as HTMLElement).dataset.view === this.currentView));
|
||||
if (this.currentView === 'canvas') { this.resizePoolCanvas(); this.rebuildSidebar(); }
|
||||
if (this.currentView === 'collaborate') this.refreshCollaborate();
|
||||
if (this.currentView === 'dashboard') this.refreshDashboard();
|
||||
};
|
||||
|
||||
private async fetchData() {
|
||||
const base = this.getApiBase();
|
||||
try {
|
||||
|
|
@ -707,6 +728,7 @@ class FolkTimebankApp extends HTMLElement {
|
|||
tab.addEventListener('click', () => {
|
||||
const view = (tab as HTMLElement).dataset.view as 'canvas' | 'collaborate' | 'dashboard';
|
||||
if (view === this.currentView) return;
|
||||
this._history.push(view);
|
||||
this.currentView = view;
|
||||
this.shadow.querySelectorAll('.tab').forEach(t => t.classList.toggle('active', (t as HTMLElement).dataset.view === view));
|
||||
const canvasView = this.shadow.getElementById('canvas-view')!;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import { authFetch, requireAuth } from "../../../shared/auth-fetch";
|
|||
import { startPresenceHeartbeat } from '../../../shared/collab-presence';
|
||||
import type { DocumentId } from "../../../shared/local-first/document";
|
||||
import { tubeSchema, tubeDocId } from "../schemas";
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
class FolkVideoPlayer extends HTMLElement {
|
||||
private shadow: ShadowRoot;
|
||||
|
|
@ -17,6 +18,7 @@ class FolkVideoPlayer extends HTMLElement {
|
|||
private videos: Array<{ name: string; size: number; duration?: string; date?: string }> = [];
|
||||
private currentVideo: string | null = null;
|
||||
private mode: "library" | "live" | "360live" = "library";
|
||||
private _history = new ViewHistory<"library" | "live" | "360live">("library", "rtube");
|
||||
private streamKey = "";
|
||||
private searchTerm = "";
|
||||
private isDemo = false;
|
||||
|
|
@ -63,13 +65,25 @@ class FolkVideoPlayer extends HTMLElement {
|
|||
setTimeout(() => this._tour.start(), 1200);
|
||||
}
|
||||
this._stopPresence = startPresenceHeartbeat(() => ({ module: 'rtube', context: this.currentVideo || 'Video' }));
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
this._stopPresence?.();
|
||||
this._offlineUnsub?.(); this._offlineUnsub = null;
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'rtube') return;
|
||||
if (this.mode === "360live" && e.detail.view !== "360live") {
|
||||
this.destroyHlsPlayers();
|
||||
}
|
||||
this.mode = e.detail.view;
|
||||
this.render();
|
||||
};
|
||||
|
||||
private async subscribeOffline() {
|
||||
const runtime = (window as any).__rspaceOfflineRuntime;
|
||||
if (!runtime?.isInitialized) return;
|
||||
|
|
@ -587,6 +601,7 @@ class FolkVideoPlayer extends HTMLElement {
|
|||
if (this.mode === "360live" && newMode !== "360live") {
|
||||
this.destroyHlsPlayers();
|
||||
}
|
||||
this._history.push(newMode);
|
||||
this.mode = newMode;
|
||||
this.render();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { startPresenceHeartbeat } from '../../../shared/collab-presence';
|
|||
import { getModuleApiBase } from "../../../shared/url-helpers";
|
||||
import type { DocumentId } from "../../../shared/local-first/document";
|
||||
import { vnbSchema, vnbDocId } from "../schemas";
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
const VNB_TOUR_STEPS: TourStep[] = [
|
||||
{ target: '.vnb-search', title: 'Search', message: 'Filter by vehicle type, dates, or economy model.' },
|
||||
|
|
@ -68,6 +69,7 @@ class FolkVnbView extends HTMLElement {
|
|||
#stats: any = null;
|
||||
#selectedRental: any = null;
|
||||
#view: 'grid' | 'map' = 'grid';
|
||||
private _history = new ViewHistory<'grid' | 'map'>('grid', 'rvnb');
|
||||
#search = '';
|
||||
#typeFilter = '';
|
||||
#economyFilter = '';
|
||||
|
|
@ -83,13 +85,23 @@ class FolkVnbView extends HTMLElement {
|
|||
this.#loadData();
|
||||
this._stopPresence = startPresenceHeartbeat(() => ({ module: 'rvnb', context: 'Venues' }));
|
||||
if (this.#space !== 'demo') this.subscribeOffline();
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
this._stopPresence?.();
|
||||
this._offlineUnsub?.(); this._offlineUnsub = null;
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'rvnb') return;
|
||||
this.#view = e.detail.view;
|
||||
this.#render();
|
||||
this.#renderContent();
|
||||
};
|
||||
|
||||
private async subscribeOffline() {
|
||||
const runtime = (window as any).__rspaceOfflineRuntime;
|
||||
if (!runtime?.isInitialized) return;
|
||||
|
|
@ -234,7 +246,9 @@ class FolkVnbView extends HTMLElement {
|
|||
// View toggles
|
||||
for (const btn of this.querySelectorAll('.vnb-view__toggle')) {
|
||||
btn.addEventListener('click', () => {
|
||||
this.#view = (btn as HTMLElement).dataset.view as 'grid' | 'map';
|
||||
const v = (btn as HTMLElement).dataset.view as 'grid' | 'map';
|
||||
this._history.push(v);
|
||||
this.#view = v;
|
||||
this.#render();
|
||||
this.#renderContent();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import type { WalletDoc, WatchedAddress } from "../schemas";
|
|||
import { walletSchema, walletDocId } from "../schemas";
|
||||
import { startPresenceHeartbeat } from '../../../shared/collab-presence';
|
||||
import type { DocumentId } from "../../../shared/local-first/document";
|
||||
import { ViewHistory } from "../../../shared/view-history.js";
|
||||
|
||||
interface ChainInfo {
|
||||
chainId: string;
|
||||
|
|
@ -197,6 +198,7 @@ class FolkWalletViewer extends HTMLElement {
|
|||
|
||||
// Visualization state
|
||||
private activeView: ViewTab = "budget";
|
||||
private _history = new ViewHistory<ViewTab>("budget", "rwallet");
|
||||
private transfers: Map<string, any> | null = null;
|
||||
private transfersLoading = false;
|
||||
private d3Ready = false;
|
||||
|
|
@ -265,9 +267,12 @@ class FolkWalletViewer extends HTMLElement {
|
|||
setTimeout(() => this._tour.start(), 1200);
|
||||
}
|
||||
this._stopPresence = startPresenceHeartbeat(() => ({ module: 'rwallet', context: 'Wallet' }));
|
||||
window.addEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this._history.destroy();
|
||||
window.removeEventListener('rspace-view-restored', this._onViewRestored as EventListener);
|
||||
this._stopPresence?.();
|
||||
if (this.flowsPlayInterval) {
|
||||
clearInterval(this.flowsPlayInterval);
|
||||
|
|
@ -275,6 +280,15 @@ class FolkWalletViewer extends HTMLElement {
|
|||
}
|
||||
}
|
||||
|
||||
private _onViewRestored = (e: CustomEvent) => {
|
||||
if (e.detail?.moduleId !== 'rwallet') return;
|
||||
this.activeView = e.detail.view;
|
||||
this.render();
|
||||
if (this.activeView !== "balances") {
|
||||
requestAnimationFrame(() => this.drawActiveVisualization());
|
||||
}
|
||||
};
|
||||
|
||||
private checkAuthState() {
|
||||
try {
|
||||
const session = localStorage.getItem("encryptid_session");
|
||||
|
|
@ -1265,6 +1279,7 @@ class FolkWalletViewer extends HTMLElement {
|
|||
|
||||
private handleViewTabClick(view: ViewTab) {
|
||||
if (this.activeView === view) return;
|
||||
this._history.push(view);
|
||||
this.activeView = view;
|
||||
|
||||
if (view !== "balances" && !this.transfers && !this.isDemo) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue