Compare commits

...
2 Commits
27 changed files with 57 additions and 56 deletions
+24 -14
View File
@@ -394,14 +394,28 @@ function escapeText(value: string): string {
let pendingPaint = 0;
/** Set for one paint after publishing, to mark the new card as it goes in. */
let markNewest = false;
/**
* Reviews published in this session, shown at the top until relays echo them back.
*
* Keyed by event id, holding how many relays took it: a review that only two of
* four relays accepted says so on its card, because that is a thing the author
* may want to act on.
*/
/** Reviews published in this session, shown at the top until relays echo them back. */
const optimistic = new Map<string, { accepted: number; total: number }>();
/** Optimistic cards whose brief publishing note is still visible. */
const publishingNotes = new Set<string>();
const PUBLISHING_NOTE_MS = 4_000;
const PUBLISHING_NOTE_FADE_MS = 220;
function dismissPublishingNote(id: string): void {
publishingNotes.delete(id);
const note = document.querySelector<HTMLElement>(
`[id="review-${id.toLowerCase()}"] .propagating`,
);
if (!note) return;
note.classList.add('is-out');
window.setTimeout(() => note.remove(), PUBLISHING_NOTE_FADE_MS);
}
function markOptimistic(id: string, accepted: number, total: number): void {
optimistic.set(id, { accepted, total });
publishingNotes.add(id);
window.setTimeout(() => dismissPublishingNote(id), PUBLISHING_NOTE_MS);
}
/* ---------- rendering ---------- */
@@ -476,8 +490,7 @@ function escapeText(value: string): string {
target.innerHTML = slice
.map((review) =>
reviewHtml(review, f, {
propagating: optimistic.has(review.id),
publishedTo: optimistic.get(review.id) ?? null,
propagating: publishingNotes.has(review.id),
permalink,
}),
)
@@ -667,10 +680,7 @@ function escapeText(value: string): string {
* that they would have seen had they written it on this page.
*/
if (handedForward && !all.some((review) => review.id === handedForward.id)) {
optimistic.set(handedForward.id, {
accepted: handedForward.accepted,
total: handedForward.total,
});
markOptimistic(handedForward.id, handedForward.accepted, handedForward.total);
all.unshift({
id: handedForward.id,
pubkey: handedForward.pubkey,
@@ -810,7 +820,7 @@ function escapeText(value: string): string {
},
onPublished: (published) => {
// Optimistic insert at the top. The relays will echo it back on next load.
optimistic.set(published.id, { accepted: published.accepted, total: published.total });
markOptimistic(published.id, published.accepted, published.total);
all.unshift({
id: published.id,
pubkey: published.pubkey,
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "دي أول مراجعة من الـnpub ده، ومفيش نشاط تاني ليه",
"reviews.published": "نُشرت",
"reviews.publishedPartial": "نُشرت إلى {accepted} من {total} إعادة شحن.",
"reviews.propagating": "البروغات، قد يستغرق الأمر لحظة للظهور في مكان آخر.",
"reviews.propagating": "بننشر على موزّعات Nostr",
"reviews.summary.line.one": "{count} تصنيف دون تعليق: {breakdown}",
"reviews.summary.line.other": "{count} تصنيف دون تعليق: {breakdown}",
"reviews.summary.lineDay.one": "{count} تصنيف دون تعليق على {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "أول تقييم من هذا npub، لم يتم العثور على أي نشاط آخر",
"reviews.published": "تم النشر.",
"reviews.publishedPartial": "تم النشر إلى {accepted} من أصل {total} مرحل.",
"reviews.propagating": "أثناء النشر، قد يستغرق الأمر لحظة حتى يظهر في مكان آخر.",
"reviews.propagating": "جارٍ النشر إلى مرحلات Nostr",
"reviews.summary.line.one": "{count} تقييم بدون تعليق: {breakdown}",
"reviews.summary.line.other": "{count} تقييمًا بدون تعليق: {breakdown}",
"reviews.summary.lineDay.one": "تقييم {count} بدون تعليق على {when}: {breakdown}",
+1 -1
View File
@@ -298,7 +298,7 @@
"reviews.anonNote": "První přezkum z tohoto npub, žádná jiná činnost nenalezena",
"reviews.published": "Publikováno.",
"reviews.publishedPartial": "Zveřejněno{accepted}z{total}relé.",
"reviews.propagating": "Propagatování může chvíli trvat, než se objeví jinde.",
"reviews.propagating": "Publikování na Nostr relayích",
"reviews.summary.line.one": "{count}hodnocení bez komentáře:{breakdown}",
"reviews.summary.line.other": "{count}ratingy bez komentáře:{breakdown}",
"reviews.summary.line.few": "{count}ratingy bez komentáře:{breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Første anmeldelse af denne npub; der er ikke fundet andre aktiviteter",
"reviews.published": "Udgivet.",
"reviews.publishedPartial": "Udgivet til {accepted} blandt {total}-relæerne.",
"reviews.propagating": "Når indholdet opdateres, kan det tage et øjeblik, før det vises andre steder.",
"reviews.propagating": "Udgiver til Nostr-relays",
"reviews.summary.line.one": "{count}-vurdering uden kommentar: {breakdown}",
"reviews.summary.line.other": "{count}-vurderinger uden kommentar: {breakdown}",
"reviews.summary.lineDay.one": "{count}-vurdering uden kommentar til {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Erste Rezension von diesem Verlag, keine weiteren Aktivitäten gefunden",
"reviews.published": "Veröffentlicht.",
"reviews.publishedPartial": "Veröffentlicht auf {accepted} der {total}-Relais.",
"reviews.propagating": "Die Übertragung kann einen Moment dauern, bis sie an anderer Stelle angezeigt wird.",
"reviews.propagating": "Veröffentlichen auf Nostr-Relays",
"reviews.summary.line.one": "{count}-Bewertung ohne Kommentar: {breakdown}",
"reviews.summary.line.other": "{count}-Bewertungen ohne Kommentar: {breakdown}",
"reviews.summary.lineDay.one": "{count}-Bewertung ohne Kommentar auf {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Πρώτη κριτική από αυτό το npub, δεν βρέθηκε άλλη δραστηριότητα",
"reviews.published": "Δημοσίευση.",
"reviews.publishedPartial": "Δημοσίευση στο{accepted} του{total} ⁇ λεμάν.",
"reviews.propagating": "Διαδοχικά, μπορεί να πάρει μια στιγμή για να εμφανιστεί αλλού.",
"reviews.propagating": "Δημοσίευση στα relays του Nostr",
"reviews.summary.line.one": "{count} αξιολόγηση χωρίς σχόλιο:{breakdown}",
"reviews.summary.line.other": "{count} αξιολογήσεις χωρίς σχόλιο:{breakdown}",
"reviews.summary.lineDay.one": "{count} αξιολόγηση χωρίς σχόλιο σχετικά με{when}:{breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "First review from this npub, no other activity found",
"reviews.published": "Published.",
"reviews.publishedPartial": "Published to {accepted} of {total} relays.",
"reviews.propagating": "Propagating, it may take a moment to appear elsewhere.",
"reviews.propagating": "Publishing to Nostr relays",
"reviews.summary.line.one": "{count} rating without a comment: {breakdown}",
"reviews.summary.line.other": "{count} ratings without a comment: {breakdown}",
"reviews.summary.lineDay.one": "{count} rating without a comment on {when}: {breakdown}",
+1 -1
View File
@@ -286,7 +286,7 @@
"reviews.anonNote": "Primera reseña de este npub, no se ha encontrado ninguna otra actividad",
"reviews.published": "Publicada.",
"reviews.publishedPartial": "Publicada en {accepted} de {total} relays.",
"reviews.propagating": "Propagándose, puede tardar un momento en aparecer en otros sitios.",
"reviews.propagating": "Publicando en relés Nostr",
"reviews.summary.line.one": "{count} valoración sin comentario: {breakdown}",
"reviews.summary.line.other": "{count} valoraciones sin comentario: {breakdown}",
"reviews.summary.lineDay.one": "{count} valoración sin comentario del {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Premier avis sur ce npub, aucune autre activité trouvée",
"reviews.published": "Publié.",
"reviews.publishedPartial": "Publié sur {accepted} des relais {total}.",
"reviews.propagating": "En se propageant, cela peut prendre un moment pour apparaître ailleurs.",
"reviews.propagating": "Publication sur les relais Nostr",
"reviews.summary.line.one": "Note {count} sans commentaire : {breakdown}",
"reviews.summary.line.other": "Notes {count} sans commentaire : {breakdown}",
"reviews.summary.lineDay.one": "Note {count} sans commentaire sur {when} : {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "इस npub से पहली समीक्षा, कोई अन्य गतिविधि नहीं मिली।",
"reviews.published": "प्रकाशित",
"reviews.publishedPartial": "{total} रिलेज़ में से {accepted} पर प्रकाशित।",
"reviews.propagating": "प्रसारित करते समय, कहीं और प्रकट होने में थोड़ा समय लग सकता है।",
"reviews.propagating": "Nostr रिले पर प्रकाशित किया जा रहा है",
"reviews.summary.line.one": "बिना टिप्पणी के {count} रेटिंग: {breakdown}",
"reviews.summary.line.other": "टिप्पणी के बिना रेटिंग: {count}; रेटिंग: {breakdown}",
"reviews.summary.lineDay.one": "{count} रेटिंग, {when} पर बिना टिप्पणी के: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Ulasan pertama dari npub ini, tidak ada aktivitas lain ditemukan",
"reviews.published": "Diterbitkan.",
"reviews.publishedPartial": "Diterbitkan ke {accepted} dari {total} relay.",
"reviews.propagating": "Sedang disebarkan; mungkin perlu waktu untuk muncul di tempat lain.",
"reviews.propagating": "Mempublikasikan ke relay Nostr",
"reviews.summary.line.one": "Rating {count} tanpa komentar: {breakdown}",
"reviews.summary.line.other": "Rating {count} tanpa komentar: {breakdown}",
"reviews.summary.lineDay.one": "{count} rating tanpa komentar di {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Prima recensione da questo npub, nessun'altra attività trovata",
"reviews.published": "Pubblicato.",
"reviews.publishedPartial": "Pubblicato in {accepted} di {total} relè.",
"reviews.propagating": "Propagando, può richiedere un momento per apparire altrove.",
"reviews.propagating": "Pubblicazione sui relay Nostr",
"reviews.summary.line.one": "{count} valutazione senza un commento: {breakdown}",
"reviews.summary.line.other": "{count} valutazioni senza un commento: {breakdown}",
"reviews.summary.lineDay.one": "{count} valutazione senza un commento su {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "このnpubからの最初のレビュー、他の活動が見つかりません",
"reviews.published": "掲載情報",
"reviews.publishedPartial": "に公開 {accepted} の {total} リレー.",
"reviews.propagating": "伝播は、他の場所で出現する瞬間を取るかもしれません。",
"reviews.propagating": "Nostrリレーに公開中",
"reviews.summary.line.one": "{count} コメントのない評価: {breakdown}",
"reviews.summary.line.other": "{count} コメントのない評価: {breakdown}",
"reviews.summary.lineDay.one": "{count} 評価なし にコメント {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Eerste review van deze npub, verder geen activiteit gevonden",
"reviews.published": "Gepubliceerd.",
"reviews.publishedPartial": "Gepubliceerd op {accepted} van de {total} relays.",
"reviews.propagating": "Wordt verspreid, het kan even duren voordat hij elders verschijnt.",
"reviews.propagating": "Publiceren naar Nostr-relays",
"reviews.summary.line.one": "{count} beoordeling zonder tekst: {breakdown}",
"reviews.summary.line.other": "{count} beoordelingen zonder tekst: {breakdown}",
"reviews.summary.lineDay.one": "{count} beoordeling zonder tekst op {when}: {breakdown}",
+1 -1
View File
@@ -298,7 +298,7 @@
"reviews.anonNote": "Pierwsza recenzja z tego npubu, nie znaleziono żadnej innej aktywności",
"reviews.published": "Opublikowano.",
"reviews.publishedPartial": "Opublikowano dla {accepted} sztafetyi {total}.",
"reviews.propagating": "Rozmnażając, może potrzebować chwili, by pojawić się gdzie indziej.",
"reviews.propagating": "Publikowanie na relayach Nostr",
"reviews.summary.line.one": "{count} ocena bez komentarza: {breakdown}",
"reviews.summary.line.few": "{count} oceny bez komentarza: {breakdown}",
"reviews.summary.line.many": "{count} ocen bez komentarza: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Primeira revisão deste npub, nenhuma outra atividade encontrada",
"reviews.published": "Publicado.",
"reviews.publishedPartial": "Publicado em {accepted} dos relés {total}.",
"reviews.propagating": "Propagando, pode demorar um pouco para aparecer em outro lugar.",
"reviews.propagating": "Publicando nos relays Nostr",
"reviews.summary.line.one": "Classificação {count} sem comentários: {breakdown}",
"reviews.summary.line.other": "Avaliações {count} sem comentários: {breakdown}",
"reviews.summary.lineDay.one": "Classificação {count} sem comentários em {when}: {breakdown}",
+1 -1
View File
@@ -290,7 +290,7 @@
"reviews.anonNote": "Prima revizuire a acestei npub-uri, nicio altă activitate nu a fost găsită",
"reviews.published": "Publicat.",
"reviews.publishedPartial": "Publicată în{accepted} din{total} relee.",
"reviews.propagating": "Propaganda, poate dura un moment să apară în altă parte.",
"reviews.propagating": "Se publică pe relayurile Nostr",
"reviews.summary.line.one": "{count}rating fără comentarii:{breakdown}",
"reviews.summary.line.other": "{count} ratinguri fără comentarii:{breakdown}",
"reviews.summary.line.few": "{count} ratinguri fără comentarii:{breakdown}",
+1 -1
View File
@@ -298,7 +298,7 @@
"reviews.anonNote": "Первый отзыв с этого npub, другой активности не найдено",
"reviews.published": "Опубликовано.",
"reviews.publishedPartial": "Опубликовано на {accepted} из {total} relays.",
"reviews.propagating": "Распространяется по сети, в других местах отзыв может появиться не сразу.",
"reviews.propagating": "Публикация на relays Nostr",
"reviews.summary.line.one": "Рейтинг «{count}» без комментариев: {breakdown}",
"reviews.summary.line.other": "Рейтинги «{count}» без комментариев: {breakdown}",
"reviews.summary.line.few": "Рейтинги «{count}» без комментариев: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Första recensionen av denna npub, inga andra aktiviteter har hittats",
"reviews.published": "Publicerad.",
"reviews.publishedPartial": "Publicerad till reläet {accepted} i serien {total}.",
"reviews.propagating": "När innehållet sprids kan det ta en stund innan det visas på andra ställen.",
"reviews.propagating": "Publicerar till Nostr-relayer",
"reviews.summary.line.one": "{count}-betyg utan kommentar: {breakdown}",
"reviews.summary.line.other": "{count}-betyg utan kommentar: {breakdown}",
"reviews.summary.lineDay.one": "Betyg för {count} utan kommentar om {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Bu npub'dan ilk inceleme, başka bir faaliyet bulunmadı",
"reviews.published": "Yayınlandı.",
"reviews.publishedPartial": "{accepted} {total} rölesine yayımlandı.",
"reviews.propagating": "Yayılırken başka bir yerde ortaya çıkması biraz zaman alabilir.",
"reviews.propagating": "Nostr relay'lerine yayınlanıyor",
"reviews.summary.line.one": "{count} yorumsuz puan: {breakdown}",
"reviews.summary.line.other": "{count} yorumsuz puanlar: {breakdown}",
"reviews.summary.lineDay.one": "{when} yorumsuz {count} puanı: {breakdown}",
+1 -1
View File
@@ -298,7 +298,7 @@
"reviews.anonNote": "Перший відгук від цього npub, іншої активності не знайдено",
"reviews.published": "Опубліковано.",
"reviews.publishedPartial": "Опубліковано на {accepted} із {total} relays.",
"reviews.propagating": "Поширюється мережею, поява в інших місцях може тривати деякий час.",
"reviews.propagating": "Публікація на relays Nostr",
"reviews.summary.line.one": "{count} рейтинг без коментаря: {breakdown}",
"reviews.summary.line.few": "{count} оцінки без коментарів: {breakdown}",
"reviews.summary.line.many": "{count} оцінок без коментарів: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "اس ناول سے پہلا جائزہ، کوئی اور سرگرمی نہیں پائی گئی",
"reviews.published": "شائع ہوا۔",
"reviews.publishedPartial": "شائع شدہ{accepted}کا مطلب{total}ریلویز.",
"reviews.propagating": "اِس لئے شاید آپ کسی اَور ملک میں جا کر اُس کے بارے میں بات کریں ۔",
"reviews.propagating": "Nostr ریلے پر شائع ہو رہا ہے",
"reviews.summary.line.one": "{count}بغیر تبصرے کے شرحیں:{breakdown}",
"reviews.summary.line.other": "{count}بغیر تبصرے کے شرحیں:{breakdown}",
"reviews.summary.lineDay.one": "{count}بغیر تبصرے کے خواندگی{when}:{breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "Xem lại lần đầu từ npb này, không tìm thấy hoạt động nào khác",
"reviews.published": "Xuất bản.",
"reviews.publishedPartial": "Do {accepted} của {total} rơle.",
"reviews.propagating": "Tuyên truyền, có thể phải mất một lúc mới xuất hiện.",
"reviews.propagating": "Đang đăng lên các relay Nostr",
"reviews.summary.line.one": "{count} đánh giá mà không bình luận: {breakdown}",
"reviews.summary.line.other": "{breakdown} {count} đánh giá mà không bình luận: 918274242",
"reviews.summary.lineDay.one": "{count} đánh giá mà không bình luận gì về {when}: {breakdown}",
+1 -1
View File
@@ -282,7 +282,7 @@
"reviews.anonNote": "这是关于这款npub的首条评论,未发现其他相关活动",
"reviews.published": "已发布。",
"reviews.publishedPartial": "已发布至 {total} 继电器中的 {accepted}。",
"reviews.propagating": "正在同步,内容可能需要片刻时间才会显示在其他地方。",
"reviews.propagating": "正在发布到 Nostr 中继",
"reviews.summary.line.one": "{count} 的评分(无评论):{breakdown}",
"reviews.summary.line.other": "{count} 的评分(无评论):{breakdown}",
"reviews.summary.lineDay.one": "{count}的评分,未对{when}发表评论:{breakdown}",
+3 -17
View File
@@ -37,16 +37,8 @@ export interface MintRef {
}
export interface CardOptions {
/** Adds the "propagating to relays" note, for a review published in this session. */
/** Adds the transient publishing note for a review published in this session. */
propagating?: boolean;
/**
* How many relays took it, when the review was published in this session.
*
* Only said out loud when some relay refused: "published to 2 of 4" is a fact the
* author can act on (try again later, and it is already on the network), where a
* clean 4 of 4 is just noise on the card.
*/
publishedTo?: { accepted: number; total: number } | null;
/** Adds a link to the mint being reviewed. */
mint?: MintRef | null;
/**
@@ -303,15 +295,9 @@ function actionsHtml(review: LoadedReview, f: Formatters, options: CardOptions):
/* ---------- the card ---------- */
export function reviewHtml(review: LoadedReview, f: Formatters, options: CardOptions = {}): string {
// The note pulses gently while the review is still in flight. It stops the moment
// the relays echo the review back, because then the card is redrawn without it.
const relays = options.publishedTo;
const partial =
relays && relays.accepted < relays.total
? f.t('reviews.publishedPartial', { accepted: relays.accepted, total: relays.total })
: f.t('reviews.published');
// The note pulses gently for a few seconds after a review is published.
const propagating = options.propagating
? `<p class="rev-note propagating">${escapeHtml(partial)} ${escapeHtml(f.t('reviews.propagating'))}</p>`
? `<p class="rev-note propagating">${escapeHtml(f.t('reviews.propagating'))}</p>`
: '';
// The anchor id only for real event ids, so `#review-{id}` deep links resolve and
+6 -1
View File
@@ -1268,8 +1268,13 @@ main { flex: 1; }
0%, 25% { opacity: .85; }
100% { opacity: 0; }
}
/* Still travelling. Stops when the relays echo the review back on the next load. */
/* Visible for a few seconds after a review is published from this tab. */
.rev-note.propagating { animation: soft-pulse 2s var(--ease-in-out) infinite; }
.rev-note.propagating.is-out {
animation: none;
opacity: 0;
transition: opacity var(--dur-quick) var(--ease-out);
}
/* ---------- status dot ---------- */
.status-dot { position: relative; }