chore: release v1.7.57-alpha
This commit is contained in:
@@ -79,7 +79,7 @@ import { useServerStore } from '@/stores/server'
|
||||
import { useAppLauncherStore } from '@/stores/appLauncher'
|
||||
import type { PackageDataEntry } from '@/types/api'
|
||||
import { resolveAppUrl } from '@/views/appSession/appSessionConfig'
|
||||
import { canLaunch, handleImageError, opensInTab, resolveAppIcon } from './appsConfig'
|
||||
import { canLaunch, handleImageError, isWebsitePackage, opensInTab, resolveAppIcon, resolveRuntimeLaunchUrl } from './appsConfig'
|
||||
import { getCuratedAppList } from '../discover/curatedApps'
|
||||
|
||||
const ITEMS_PER_PAGE = 16 // 4 columns x 4 rows
|
||||
@@ -120,8 +120,15 @@ function getIcon(id: string, pkg: PackageDataEntry): string {
|
||||
|
||||
function handleTap(id: string, pkg: PackageDataEntry) {
|
||||
if (canLaunch(pkg)) {
|
||||
if (isWebsitePackage(id, pkg)) {
|
||||
const url = resolveRuntimeLaunchUrl(pkg)
|
||||
if (url) {
|
||||
window.open(url, '_blank', 'noopener,noreferrer')
|
||||
return
|
||||
}
|
||||
}
|
||||
if (opensInTab(id)) {
|
||||
const appUrl = resolveAppUrl(id)
|
||||
const appUrl = resolveRuntimeLaunchUrl(pkg) || resolveAppUrl(id)
|
||||
if (appUrl) {
|
||||
window.open(appUrl, '_blank', 'noopener,noreferrer')
|
||||
return
|
||||
|
||||
@@ -5,6 +5,8 @@ import { computed } from 'vue'
|
||||
import { PackageState, type PackageDataEntry } from '@/types/api'
|
||||
import { resolveAppUrl } from '../appSession/appSessionConfig'
|
||||
|
||||
export type AppsTab = 'apps' | 'websites' | 'services'
|
||||
|
||||
// Service container name patterns (backend/infra, not user-facing)
|
||||
export const SERVICE_NAMES = new Set([
|
||||
'dwn', 'archy-mempool-db', 'archy-btcpay-db', 'archy-nbxplorer', 'archy-tor',
|
||||
@@ -22,6 +24,15 @@ export const SERVICE_NAMES = new Set([
|
||||
'syntropy-institute', 't-zero', 'arch-presentation',
|
||||
])
|
||||
|
||||
const INTERNAL_TOOLING_NAMES = new Set([
|
||||
'buildx_buildkit_default',
|
||||
])
|
||||
|
||||
export function isInternalToolingPackage(id: string, pkg?: PackageDataEntry): boolean {
|
||||
const manifestId = pkg?.manifest?.id || ''
|
||||
return INTERNAL_TOOLING_NAMES.has(id) || INTERNAL_TOOLING_NAMES.has(manifestId) || id.startsWith('buildx_buildkit') || manifestId.startsWith('buildx_buildkit')
|
||||
}
|
||||
|
||||
export function isServiceContainer(id: string): boolean {
|
||||
if (SERVICE_NAMES.has(id)) return true
|
||||
if (id.startsWith('indeedhub-build_')) return true
|
||||
@@ -58,14 +69,32 @@ export function getAppCategory(id: string, pkg: PackageDataEntry): string {
|
||||
return cat || 'other'
|
||||
}
|
||||
|
||||
export function runtimeLanAddress(pkg: PackageDataEntry): string {
|
||||
return pkg.installed?.['interface-addresses']?.main?.['lan-address'] || ''
|
||||
}
|
||||
|
||||
export function isKnownApp(id: string, pkg?: PackageDataEntry): boolean {
|
||||
const manifestId = pkg?.manifest?.id
|
||||
return !!(APP_CATEGORY_MAP[id] || (manifestId && APP_CATEGORY_MAP[manifestId]) || isWebOnlyApp(id))
|
||||
}
|
||||
|
||||
export function isWebsitePackage(id: string, pkg?: PackageDataEntry): boolean {
|
||||
if (isInternalToolingPackage(id, pkg)) return false
|
||||
if (isServicePackage(id, pkg)) return true
|
||||
if (isKnownApp(id, pkg)) return false
|
||||
return !!pkg && !!runtimeLanAddress(pkg)
|
||||
}
|
||||
|
||||
export function filterEntriesForTab(
|
||||
entries: Array<[string, PackageDataEntry]>,
|
||||
activeTab: 'apps' | 'services',
|
||||
activeTab: AppsTab,
|
||||
selectedCategory: string,
|
||||
): Array<[string, PackageDataEntry]> {
|
||||
return entries.filter(([id, pkg]) => {
|
||||
const isSvc = isServicePackage(id, pkg)
|
||||
if (activeTab === 'services' ? !isSvc : isSvc) return false
|
||||
if (isInternalToolingPackage(id, pkg)) return false
|
||||
const wantsWebsites = activeTab === 'websites' || activeTab === 'services'
|
||||
const isWebsite = isWebsitePackage(id, pkg)
|
||||
if (wantsWebsites ? !isWebsite : isWebsite) return false
|
||||
if (activeTab === 'apps' && selectedCategory !== 'all') {
|
||||
return getAppCategory(id, pkg) === selectedCategory
|
||||
}
|
||||
@@ -151,6 +180,12 @@ export function canLaunch(pkg: PackageDataEntry): boolean {
|
||||
return !!hasUI && pkg.state === 'running' && pkg.health !== 'starting' && pkg.health !== 'unhealthy'
|
||||
}
|
||||
|
||||
export function resolveRuntimeLaunchUrl(pkg: PackageDataEntry): string {
|
||||
const addr = runtimeLanAddress(pkg)
|
||||
if (!addr || typeof window === 'undefined') return addr
|
||||
return addr.replace(/^http:\/\/(localhost|127\.0\.0\.1)(?=[:/]|$)/, `http://${window.location.hostname}`)
|
||||
}
|
||||
|
||||
export function getStatusClass(state: PackageState, health?: string | null, exitCode?: number | null): string {
|
||||
if (state === PackageState.Running && health === 'starting') return 'bg-yellow-500/20 text-yellow-200'
|
||||
if (state === PackageState.Running && health === 'unhealthy') return 'bg-orange-500/20 text-orange-200'
|
||||
@@ -212,7 +247,7 @@ export function useCategoriesWithApps(
|
||||
allCategories: Ref<Array<{ id: string; name: string }>>,
|
||||
) {
|
||||
return computed(() => {
|
||||
const entries = Object.entries(packages.value).filter(([id, pkg]) => !isServicePackage(id, pkg))
|
||||
const entries = Object.entries(packages.value).filter(([id, pkg]) => !isWebsitePackage(id, pkg) && !isInternalToolingPackage(id, pkg))
|
||||
return allCategories.value.filter(cat => {
|
||||
if (cat.id === 'all') return true
|
||||
return entries.some(([id, pkg]) => getAppCategory(id, pkg) === cat.id)
|
||||
|
||||
Reference in New Issue
Block a user