diff --git a/src/html.ts b/src/html.ts index 14e7e72..306d85d 100644 --- a/src/html.ts +++ b/src/html.ts @@ -7,7 +7,7 @@ import { readFileSync } from 'node:fs' import { BANGS } from './bangs.js' import { LINKS, MOSHPIT_ROOT_SHA256, type NetworkStats, type Resolution } from './moshpit.js' import type { Promo } from './promoted.js' -import { ringBar, ringSites, RSS_RING, siteHref, type RingSite } from './ring.js' +import { proxyUrl, ringBar, ringSites, RSS_RING, siteHref, type RingSite } from './ring.js' import { LABELS, type Provider, type SearchResult } from './search.js' import { thumbSrc, VERTICALS, type Media, type MediaResult, type Vertical } from './verticals.js' @@ -178,11 +178,16 @@ export function homePage(stats: NetworkStats | null, options: { newsletter?: boo function moshpitCard(resolution: Resolution): string { const live = resolution.nameRegistered + // A name with a server opens for everyone through our relay (.pit.world): that is the link we lead with, + // because most people searching have no Moshpit DNS. The bare name is for those who do. + const served = live && Boolean(resolution.target) + const web = proxyUrl(resolution.name) return `` } diff --git a/src/listings-html.ts b/src/listings-html.ts index 86fb7b1..8290981 100644 --- a/src/listings-html.ts +++ b/src/listings-html.ts @@ -2,7 +2,7 @@ import { docPage, esc } from './html.js' import type { ClaimStart, ContactStatus, Listing } from './listings.js' import { CATEGORIES, PRICES, categoryOf, operatorHref, priceLabel } from './pros.js' -import { ringSnippet, RSS_RING } from './ring.js' +import { proxyUrl, ringSnippet, RSS_RING } from './ring.js' const p = (s: string) => encodeURIComponent(s) const ext = (href: string, text: string) => `${esc(text)}` @@ -19,8 +19,12 @@ function licenseRow(l: Listing): string { return `
  • License ${esc(l.license)}${esc(checked)}${verify}
  • ` } -/** The listing's website: a link on its own domain (some sites only answer on www or http), else https:///. */ +/** + * The listing's website: a link on its own domain (some sites only answer on www or http), else https:///. + * A site that lives only on Moshpit opens through our relay, so the link works in any browser. + */ export function siteUrl(l: Listing): string { + if (l.moshpitOnly) return proxyUrl(l.domain) const own = l.links.find((u) => { try { return new URL(u).hostname.replace(/^www\./, '') === l.domain @@ -49,7 +53,7 @@ function details(l: Listing): string { l.address && `
  • Address ${esc(l.address)}
  • `, licenseRow(l), l.phone && `
  • Phone ${esc(l.phone)}
  • `, - l.moshpit && `
  • On Moshpit ${ext(`https://${l.moshpit}/`, l.moshpit)}
  • `, + l.moshpit && `
  • On Moshpit ${ext(`https://${l.moshpit}/`, l.moshpit)} · ${ext(proxyUrl(l.moshpit), `${l.moshpit}.pit.world`)} (any browser)
  • `, l.feed && `
  • Feed ${ext(l.feed, bare(l.feed))}
  • `, ...l.links.filter((u) => u !== siteUrl(l)).map((u) => `
  • ${ext(u, bare(u))}
  • `), ].filter(Boolean) diff --git a/test/pit.test.ts b/test/pit.test.ts index 9c36587..3670400 100644 --- a/test/pit.test.ts +++ b/test/pit.test.ts @@ -522,3 +522,16 @@ describe('the Moshpit ring', () => { expect((await request('/ring/sideways')).status).toBe(404) }) }) + +describe('the Moshpit name card leads with a link that opens anywhere', () => { + it('a served name links through .pit.world, with the bare name for Moshpit DNS', async () => { + const { resultsPage } = await import('../src/html.ts') + const page = resultsPage({ query: 'family.tree', result: null, error: null, resolution: { name: 'family.tree', registered: true, nameRegistered: true, target: 'dev2.profullstack.com', mode: 'clearnet', page: 'https://pit.moshcode.sh/n/family.tree' } }) + expect(page).toContain('

    Open family.tree') + expect(page).toContain('href="https://family.tree/" rel="noreferrer noopener">On Moshpit DNS') + const unclaimed = resultsPage({ query: 'nobody.tree', result: null, error: null, resolution: { name: 'nobody.tree', registered: true, nameRegistered: false, target: null, mode: null, page: 'https://pit.moshcode.sh/n/nobody.tree' } }) + expect(unclaimed).not.toContain('nobody.tree.pit.world') + expect(unclaimed).toContain('>Claim it') + }) +})