feat(cloud): show Tor/FIPS transport pill on peer browse (B21)

content.browse-peer now returns the transport that actually reached the
peer (fips/tor/mesh/lan). PeerFiles shows it as a small coloured pill next
to the peer name (FIPS/Mesh green, LAN blue, Tor amber) and the loading
text no longer hardcodes "Connecting via Tor" (it was misleading when FIPS
was used). Pairs with B14 (transport recording).

Verified: cargo build --release EXIT 0; vue-tsc --noEmit EXIT 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-06-15 13:25:39 -04:00
co-authored by Claude Opus 4.8
parent 1c6dc153ce
commit 0801dd6632
3 changed files with 40 additions and 5 deletions
+29 -3
View File
@@ -30,7 +30,15 @@
</svg>
</div>
<div class="hidden md:block">
<h1 class="text-2xl font-bold text-white">{{ peerDisplayName }}</h1>
<div class="flex items-center gap-2">
<h1 class="text-2xl font-bold text-white">{{ peerDisplayName }}</h1>
<span
v-if="transportPill"
:class="transportPill.cls"
:title="transportPill.title"
class="text-xs px-2 py-0.5 rounded-full font-medium"
>{{ transportPill.label }}</span>
</div>
<p v-if="currentPeer?.did" class="text-sm text-white/50 font-mono truncate max-w-md" :title="currentPeer.did">{{ currentPeer.did }}</p>
<p v-else class="text-sm text-white/50">Peer files</p>
</div>
@@ -43,7 +51,7 @@
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
<p class="text-white/50 text-sm">Connecting via Tor... This may take a few seconds.</p>
<p class="text-white/50 text-sm">Connecting to peer This may take a few seconds.</p>
</div>
<!-- Error -->
@@ -288,6 +296,23 @@ const catalogItems = ref<CatalogItem[]>([])
const downloading = ref<string | null>(null)
const playing = ref<string | null>(null)
const purchaseError = ref<string | null>(null)
// Transport actually used to reach this peer (returned by content.browse-peer)
// so we can show a FIPS/Tor pill instead of always assuming Tor (B21).
const transport = ref<string | null>(null)
const transportPill = computed(() => {
switch (transport.value) {
case 'fips':
return { label: 'FIPS', cls: 'bg-green-500/20 text-green-300', title: 'Connected over the fast encrypted mesh (FIPS)' }
case 'mesh':
return { label: 'Mesh', cls: 'bg-green-500/20 text-green-300', title: 'Connected over the mesh' }
case 'lan':
return { label: 'LAN', cls: 'bg-blue-500/20 text-blue-300', title: 'Connected over the local network' }
case 'tor':
return { label: 'Tor', cls: 'bg-amber-500/20 text-amber-300', title: 'Connected over Tor (slower)' }
default:
return null
}
})
const previewUrls = reactive<Record<string, string>>({})
const audioPlayer = useAudioPlayer()
@@ -329,12 +354,13 @@ async function loadCatalog() {
loading.value = true
catalogError.value = ''
try {
const result = await rpcClient.call<{ items?: CatalogItem[] }>({
const result = await rpcClient.call<{ items?: CatalogItem[]; transport?: string }>({
method: 'content.browse-peer',
params: { onion },
timeout: 30000,
})
catalogItems.value = result?.items ?? []
transport.value = result?.transport ?? null
} catch (e: unknown) {
catalogError.value = e instanceof Error ? e.message : 'Failed to connect to peer'
if (!hadItems) catalogItems.value = []