chore: release v1.7.86-alpha

This commit is contained in:
archipelago
2026-06-12 04:21:18 -04:00
parent e474a2b4c9
commit b11c6c17d1
21 changed files with 330 additions and 104 deletions
+68 -4
View File
@@ -324,14 +324,49 @@ const messageToast = useMessageToast()
const web5Badge = useWeb5BadgeStore()
const appStore = useAppStore()
const CONNECTED_NODES_CACHE_KEY = 'archipelago.web5.connected-nodes.v1'
type ConnectedNodesCache = {
peers: Peer[]
observers: Peer[]
peerReachable: Record<string, boolean>
connectionRequests: ConnectionRequest[]
}
function readConnectedNodesCache(): Partial<ConnectedNodesCache> {
if (typeof window === 'undefined') return {}
try {
const raw = window.sessionStorage.getItem(CONNECTED_NODES_CACHE_KEY)
if (!raw) return {}
const parsed = JSON.parse(raw) as Partial<ConnectedNodesCache>
return {
peers: Array.isArray(parsed.peers) ? parsed.peers : [],
observers: Array.isArray(parsed.observers) ? parsed.observers : [],
peerReachable: parsed.peerReachable && typeof parsed.peerReachable === 'object' ? parsed.peerReachable : {},
connectionRequests: Array.isArray(parsed.connectionRequests) ? parsed.connectionRequests : [],
}
} catch {
return {}
}
}
function writeConnectedNodesCache(state: ConnectedNodesCache) {
if (typeof window === 'undefined') return
try {
window.sessionStorage.setItem(CONNECTED_NODES_CACHE_KEY, JSON.stringify(state))
} catch {
// Cache is best-effort.
}
}
const nodesContainerRef = ref<HTMLElement | null>(null)
const nodesContainerTab = ref<'trusted' | 'observers' | 'messages' | 'requests'>('trusted')
const { receivedMessages, loadingMessages, unreadCount, loadReceivedMessages, markAsRead } = messageToast
const peers = ref<Peer[]>([])
const observers = ref<Peer[]>([])
const cached = readConnectedNodesCache()
const peers = ref<Peer[]>(cached.peers ?? [])
const observers = ref<Peer[]>(cached.observers ?? [])
const loadingPeers = ref(false)
const peerReachableLocal = ref<Record<string, boolean>>({})
const peerReachableLocal = ref<Record<string, boolean>>(cached.peerReachable ?? {})
const peerReachable = computed(() => ({ ...appStore.peerHealth, ...peerReachableLocal.value }))
const discovering = ref(false)
@@ -351,7 +386,7 @@ const sendMessageError = ref('')
const sendMessageSuccess = ref('')
// Connection requests
const connectionRequests = ref<ConnectionRequest[]>([])
const connectionRequests = ref<ConnectionRequest[]>(cached.connectionRequests ?? [])
const loadingRequests = ref(false)
const processingRequestId = ref<string | null>(null)
@@ -388,6 +423,7 @@ function switchToRequestsTab() {
}
async function loadPeers() {
const hadPeers = peers.value.length > 0 || observers.value.length > 0
loadingPeers.value = true
try {
const res = await rpcClient.listPeers()
@@ -427,8 +463,18 @@ async function loadPeers() {
peerReachableLocal.value[p.onion] = false
}
}
writeConnectedNodesCache({
peers: peers.value,
observers: observers.value,
peerReachable: peerReachableLocal.value,
connectionRequests: connectionRequests.value,
})
} catch (e) {
if (import.meta.env.DEV) console.error('Failed to load peers:', e)
if (!hadPeers) {
peers.value = []
observers.value = []
}
} finally {
loadingPeers.value = false
}
@@ -483,6 +529,12 @@ async function loadConnectionRequests() {
const res = await rpcClient.call<{ requests: ConnectionRequest[] }>({ method: 'network.list-requests' })
connectionRequests.value = res.requests || []
web5Badge.pendingRequestCount = connectionRequests.value.length
writeConnectedNodesCache({
peers: peers.value,
observers: observers.value,
peerReachable: peerReachableLocal.value,
connectionRequests: connectionRequests.value,
})
} catch {
if (!hadRequests) connectionRequests.value = []
} finally {
@@ -496,6 +548,12 @@ async function acceptRequest(requestId: string) {
await rpcClient.call({ method: 'network.accept-request', params: { request_id: requestId } })
connectionRequests.value = connectionRequests.value.filter(r => r.id !== requestId)
web5Badge.pendingRequestCount = connectionRequests.value.length
writeConnectedNodesCache({
peers: peers.value,
observers: observers.value,
peerReachable: peerReachableLocal.value,
connectionRequests: connectionRequests.value,
})
await loadPeers()
emit('toast', t('web5.connectionAccepted'))
} catch {
@@ -511,6 +569,12 @@ async function rejectRequest(requestId: string) {
await rpcClient.call({ method: 'network.reject-request', params: { request_id: requestId } })
connectionRequests.value = connectionRequests.value.filter(r => r.id !== requestId)
web5Badge.pendingRequestCount = connectionRequests.value.length
writeConnectedNodesCache({
peers: peers.value,
observers: observers.value,
peerReachable: peerReachableLocal.value,
connectionRequests: connectionRequests.value,
})
emit('toast', t('web5.requestRejected'))
} catch {
emit('toast', t('web5.failedToRejectRequest'))
+25 -1
View File
@@ -389,6 +389,29 @@ import type { ManagedIdentity, IdentityProfile } from './types'
const { t } = useI18n()
const IDENTITIES_CACHE_KEY = 'archipelago.web5.identities.v1'
function readIdentitiesCache(): ManagedIdentity[] {
if (typeof window === 'undefined') return []
try {
const raw = window.sessionStorage.getItem(IDENTITIES_CACHE_KEY)
if (!raw) return []
const parsed = JSON.parse(raw) as ManagedIdentity[]
return Array.isArray(parsed) ? parsed : []
} catch {
return []
}
}
function writeIdentitiesCache(identities: ManagedIdentity[]) {
if (typeof window === 'undefined') return
try {
window.sessionStorage.setItem(IDENTITIES_CACHE_KEY, JSON.stringify(identities))
} catch {
// Cache is opportunistic only.
}
}
defineProps<{
showStagger: boolean
}>()
@@ -397,7 +420,7 @@ const emit = defineEmits<{
toast: [text: string]
}>()
const managedIdentities = ref<ManagedIdentity[]>([])
const managedIdentities = ref<ManagedIdentity[]>(readIdentitiesCache())
const identitiesLoading = ref(false)
const showCreateIdentityModal = ref(false)
const newIdentityName = ref('Personal')
@@ -508,6 +531,7 @@ async function loadIdentities() {
try {
const res = await rpcClient.call<{ identities: ManagedIdentity[] }>({ method: 'identity.list' })
managedIdentities.value = res.identities || []
writeIdentitiesCache(managedIdentities.value)
} catch {
if (!hadIdentities) managedIdentities.value = []
} finally {
+19 -19
View File
@@ -33,12 +33,12 @@
</div>
</div>
<div v-if="userDid" class="flex gap-2 mt-auto">
<button
@click="$emit('copyDid')"
class="flex-1 px-3 py-1.5 glass-button glass-button-sm rounded text-xs font-medium text-white/90 hover:text-white transition-colors"
>
{{ didCopied ? t('common.copiedBang') : t('web5.copyDid') }}
</button>
<button
@click="$emit('copyDid')"
class="flex-1 px-3 py-1.5 glass-button glass-button-sm rounded text-xs font-medium text-white/90 hover:text-white transition-colors"
>
{{ didCopied ? t('common.copiedBang') : t('web5.copyDid') }}
</button>
<button
@click="$emit('showDidDocument')"
class="flex-1 px-3 py-1.5 glass-button glass-button-sm rounded text-xs font-medium text-white/90 hover:text-white transition-colors"
@@ -69,19 +69,19 @@
</div>
</div>
<div v-if="dhtDid" class="flex gap-2 mt-auto">
<button
@click="$emit('copyDhtDid')"
class="flex-1 px-3 py-1.5 glass-button glass-button-sm rounded text-xs font-medium text-white/90 hover:text-white transition-colors"
>
{{ dhtDidCopied ? 'Copied!' : 'Copy' }}
</button>
<button
@click="$emit('refreshDhtDid')"
:disabled="publishingDht"
class="flex-1 px-3 py-1.5 glass-button glass-button-sm rounded text-xs font-medium text-white/90 hover:text-white transition-colors disabled:opacity-50"
>
{{ publishingDht ? 'Refreshing...' : 'Refresh DHT' }}
</button>
<button
@click="$emit('copyDhtDid')"
class="flex-1 px-3 py-1.5 glass-button glass-button-sm rounded text-xs font-medium text-white/90 hover:text-white transition-colors"
>
{{ dhtDidCopied ? 'Copied!' : 'Copy' }}
</button>
<button
@click="$emit('refreshDhtDid')"
:disabled="publishingDht"
class="flex-1 px-3 py-1.5 glass-button glass-button-sm rounded text-xs font-medium text-white/90 hover:text-white transition-colors disabled:opacity-50"
>
{{ publishingDht ? 'Refreshing...' : 'Refresh DHT' }}
</button>
</div>
<button
v-else-if="userDid"