Files
archy/neode-ui/src/views/appSession/appSessionConfig.ts
T

117 lines
4.1 KiB
TypeScript
Raw Normal View History

2026-03-22 03:30:21 +00:00
/** Static configuration maps for app session routing and display */
import { GENERATED_APP_PORTS, GENERATED_APP_TITLES, GENERATED_NEW_TAB_APPS } from './generatedAppSessionConfig'
import { IS_DEMO, demoAppUrl } from '@/composables/useDemoIntro'
2026-03-22 03:30:21 +00:00
export type DisplayMode = 'panel' | 'overlay' | 'fullscreen'
export const DISPLAY_MODE_KEY = 'archipelago_app_display_mode'
/** Container apps: manifest-generated launch ports plus overrides for companions and aliases. */
2026-03-22 03:30:21 +00:00
export const APP_PORTS: Record<string, number> = {
...GENERATED_APP_PORTS,
2026-03-22 03:30:21 +00:00
'bitcoin-knots': 8334,
'bitcoin-core': 8334,
2026-03-22 03:30:21 +00:00
'bitcoin-ui': 8334,
'electrumx': 50002,
'electrs': 50002,
'archy-electrs-ui': 50002,
'mempool-electrs': 50002,
2026-05-05 11:29:18 -04:00
'lnd': 18083,
'archy-lnd-ui': 18083,
2026-03-22 03:30:21 +00:00
'mempool-web': 4080,
'ollama': 11434,
'immich': 2283,
'immich_server': 2283,
2026-05-17 17:30:04 -04:00
'nginx-proxy-manager': 8081,
'netbird': 8087,
2026-05-05 11:29:18 -04:00
'tailscale': 8240,
2026-03-22 03:30:21 +00:00
'fedimintd': 8175,
'fedimint-gateway': 8176,
'endurain': 8080,
}
/** Apps that need nginx proxy for iframe embedding.
2026-04-30 16:29:56 -04:00
* IndeeHub web UI is on 7778. Port 7777 is the Nostr relay. */
export const PROXY_APPS: Record<string, string> = {
'gitea': '/app/gitea/',
'nginx-proxy-manager': '/app/nginx-proxy-manager/',
'uptime-kuma': '/app/uptime-kuma/',
}
2026-03-22 03:30:21 +00:00
2026-05-05 11:29:18 -04:00
/** App launches use direct ports. Do not route through /app/... path proxies. */
2026-03-22 03:30:21 +00:00
export const HTTPS_PROXY_PATHS: Record<string, string> = {
}
/** External HTTPS apps -- always loaded directly */
export const EXTERNAL_URLS: Record<string, string> = {
'nostrudel': 'https://nostrudel.ninja',
}
export const APP_TITLES: Record<string, string> = {
...GENERATED_APP_TITLES,
'bitcoin-knots': 'Bitcoin Knots', 'bitcoin-core': 'Bitcoin Core',
'btcpay-server': 'BTCPay Server', 'indeedhub': 'Indeehub',
2026-07-14 06:56:03 -04:00
'botfights': 'BotFights', 'gitea': 'Gitea',
2026-03-22 03:30:21 +00:00
'homeassistant': 'Home Assistant', 'uptime-kuma': 'Uptime Kuma',
'nginx-proxy-manager': 'Nginx Proxy Manager',
2026-07-14 06:56:03 -04:00
'nostrudel': 'noStrudel',
2026-03-22 03:30:21 +00:00
}
/** Apps that set X-Frame-Options and MUST open in a new tab (can't iframe) */
export const NEW_TAB_APPS = new Set([
...GENERATED_NEW_TAB_APPS,
2026-03-22 03:30:21 +00:00
'nginx-proxy-manager',
'tailscale',
])
/** Sites known to block iframes -- skip the timeout and go straight to fallback */
export const IFRAME_BLOCKED_APPS = new Set<string>([])
/** Resolve app URL using direct port mapping (source of truth) */
export function resolveAppUrl(id: string, routeQueryPath?: string, runtimeUrl?: string): string {
// Demo: route to the app's mock UI or real external site (mempool.space,
// indee.tx1138.com). Carry through a deep-link path (e.g. /tx/<hash> for
// mempool). Non-demoable apps fall through to a generic notice page.
if (IS_DEMO) {
const base = demoAppUrl(id)
if (base) {
if (!routeQueryPath) return base
// Join without a double slash (/app/mempool/ + /tx/x → /app/mempool/tx/x)
return base.replace(/\/+$/, '') + (routeQueryPath.startsWith('/') ? routeQueryPath : '/' + routeQueryPath)
}
return `/app/${id}/`
}
2026-03-22 03:30:21 +00:00
// External HTTPS apps
const ext = EXTERNAL_URLS[id]
if (ext) return ext
// Bitcoin UI is a host-network companion on :8334. Do not launch it via
// /app/bitcoin-ui/: the static UI is built for root and renders a blank
// shell when proxied under a path prefix on some nodes.
2026-04-29 12:31:45 -04:00
if (id === 'bitcoin-knots' || id === 'bitcoin-core' || id === 'bitcoin-ui') {
if (import.meta.env.DEV) return '/app/bitcoin-ui/'
return 'http://' + window.location.hostname + ':8334'
2026-04-29 12:31:45 -04:00
}
if (runtimeUrl && id !== 'netbird') {
let base = runtimeUrl.replace(/localhost/i, window.location.hostname)
if (routeQueryPath) base += routeQueryPath
return base
}
2026-05-05 11:29:18 -04:00
// Local apps launch by host port.
2026-03-22 03:30:21 +00:00
const port = APP_PORTS[id]
if (!port) return ''
2026-05-05 11:29:18 -04:00
let base = 'http://' + window.location.hostname + ':' + String(port)
2026-03-22 03:30:21 +00:00
if (routeQueryPath) base += routeQueryPath
return base
}
/** Resolve a human-readable title for an app */
export function resolveAppTitle(id: string): string {
return APP_TITLES[id] || id.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase())
}