Expand ecash explorer capabilities
Add Fedimint discovery, dual SQLite/Postgres storage, richer review handling, and generated social imagery.
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
---
|
||||
import { getMintWarnings, mintChip, type MintCapabilities, type MintListItem } from '@cashumints/shared';
|
||||
import {
|
||||
federationIdFromSlug, getMintWarnings, mintChip,
|
||||
type MintCapabilities, type MintListItem,
|
||||
} from '@cashumints/shared';
|
||||
import { iconUrl } from '../lib/api';
|
||||
import { displayDomain, iconGradient, initials, transitionName } from '../lib/format';
|
||||
import { localePath, useI18n } from '../i18n';
|
||||
@@ -33,10 +36,28 @@ const { locale } = pageLocale(Astro);
|
||||
const t = useI18n(locale);
|
||||
const f = formatters(t);
|
||||
|
||||
const domain = displayDomain(mint.url);
|
||||
const name = mint.name ?? domain.split('/')[0] ?? domain;
|
||||
/*
|
||||
* One card, both ecosystems.
|
||||
*
|
||||
* A federation has no URL, so the second line cannot be a domain: `fedimint:aeca6c…`
|
||||
* is a database key and means nothing to a reader. It shows the federation id instead,
|
||||
* shortened, which is the thing that actually identifies it — and which is what the
|
||||
* search box below matches on, so pasting an id finds its federation.
|
||||
*
|
||||
* Everything else on the card is identical, and deliberately: rating, review count,
|
||||
* sentiment bar and status all mean the same thing for both, and a reader moving
|
||||
* between /mints and /fedimints should not have to re-learn a card.
|
||||
*/
|
||||
const fedimint = mint.type === 'fedimint';
|
||||
const domain = fedimint ? federationIdFromSlug(mint.host) : displayDomain(mint.url);
|
||||
const name = fedimint
|
||||
? mint.name ?? t('card.unnamedFederation')
|
||||
: mint.name ?? domain.split('/')[0] ?? domain;
|
||||
const icon = iconUrl(mint.icon);
|
||||
const offline = mint.status === 'offline';
|
||||
/** Announced on Nostr and never confirmed by any check. Federations only. */
|
||||
const announced = mint.status === 'announced';
|
||||
const href = localePath(`${fedimint ? '/fedimint' : '/mint'}/${mint.host}`, locale);
|
||||
|
||||
/*
|
||||
Two words at most. Offline already has its own card styling, so only the states a
|
||||
@@ -87,7 +108,7 @@ const bar =
|
||||
*/}
|
||||
<a
|
||||
class:list={['mint-card', { 'is-offline': offline }]}
|
||||
href={localePath(`/mint/${mint.host}`, locale)}
|
||||
href={href}
|
||||
data-reveal
|
||||
data-reveal-delay={revealDelay}
|
||||
data-mint-card
|
||||
@@ -126,7 +147,7 @@ const bar =
|
||||
}
|
||||
<span class="mc-id">
|
||||
<span class="mc-name" data-vt-name={transitionName('name', mint.host)}>{name}</span>
|
||||
<span class="mc-domain">{domain}</span>
|
||||
<span class:list={['mc-domain', { mono: fedimint }]}>{domain}</span>
|
||||
</span>
|
||||
{rank !== undefined && <span class:list={['mc-rank', { gold: rank === 1 }]}>#{rank}</span>}
|
||||
</div>
|
||||
@@ -164,13 +185,20 @@ const bar =
|
||||
{chip && <span class:list={['mc-chip', chip.severity]}>{chip.label}</span>}
|
||||
<span class="last">
|
||||
{
|
||||
offline
|
||||
? mint.last_online
|
||||
? t('card.lastSeen', { when: f.relative(mint.last_online) })
|
||||
: t('card.neverSeen')
|
||||
: mint.last_review_at
|
||||
? t('card.reviewed', { when: f.relative(mint.last_review_at) })
|
||||
: t('card.noReviews')
|
||||
/*
|
||||
"Announced" has no "last seen" to print, and printing one anyway is exactly
|
||||
the fake status this site refuses to show. What it has instead is the fact
|
||||
that nothing has checked it, said in as many words.
|
||||
*/
|
||||
announced
|
||||
? t('card.notChecked')
|
||||
: offline
|
||||
? mint.last_online
|
||||
? t('card.lastSeen', { when: f.relative(mint.last_online) })
|
||||
: t('card.neverSeen')
|
||||
: mint.last_review_at
|
||||
? t('card.reviewed', { when: f.relative(mint.last_review_at) })
|
||||
: t('card.noReviews')
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user