Bump to v0.8.1 — banner height fix, search timeout

Fix profile banner cropping square images (h-36 → h-44 with top-biased
focal point). Fix search hanging forever when no relay supports NIP-50
(8s timeout on fetchEvents in advancedSearch).
This commit is contained in:
Jure
2026-03-20 08:46:17 +01:00
parent 7411cbf981
commit 7ed478eb0e
6 changed files with 17 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
# Maintainer: hoornet <hoornet@users.noreply.github.com> # Maintainer: hoornet <hoornet@users.noreply.github.com>
pkgname=wrystr pkgname=wrystr
pkgver=0.8.0 pkgver=0.8.1
pkgrel=1 pkgrel=1
pkgdesc="Cross-platform Nostr desktop client with Lightning integration" pkgdesc="Cross-platform Nostr desktop client with Lightning integration"
arch=('x86_64') arch=('x86_64')

View File

@@ -1,7 +1,7 @@
{ {
"name": "wrystr", "name": "wrystr",
"private": true, "private": true,
"version": "0.8.0", "version": "0.8.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "wrystr" name = "wrystr"
version = "0.8.0" version = "0.8.1"
description = "Cross-platform Nostr desktop client with Lightning integration" description = "Cross-platform Nostr desktop client with Lightning integration"
authors = ["hoornet"] authors = ["hoornet"]
edition = "2021" edition = "2021"

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Wrystr", "productName": "Wrystr",
"version": "0.8.0", "version": "0.8.1",
"identifier": "com.hoornet.wrystr", "identifier": "com.hoornet.wrystr",
"build": { "build": {
"beforeDevCommand": "npm run dev", "beforeDevCommand": "npm run dev",

View File

@@ -352,14 +352,14 @@ export function ProfileView() {
<div className="border-b border-border"> <div className="border-b border-border">
{/* Banner */} {/* Banner */}
{profile?.banner ? ( {profile?.banner ? (
<div className="relative h-36 bg-bg-raised overflow-hidden"> <div className="relative h-44 bg-bg-raised overflow-hidden">
{!bannerLoaded && ( {!bannerLoaded && (
<div className="absolute inset-0 bg-bg-raised animate-pulse" /> <div className="absolute inset-0 bg-bg-raised animate-pulse" />
)} )}
<img <img
src={profile.banner} src={profile.banner}
alt="" alt=""
className="w-full h-full object-cover cursor-pointer hover:opacity-90 transition-opacity" className="w-full h-full object-cover object-[center_30%] cursor-pointer hover:opacity-90 transition-opacity"
onClick={() => setBannerLightbox(true)} onClick={() => setBannerLightbox(true)}
onLoad={() => setBannerLoaded(true)} onLoad={() => setBannerLoaded(true)}
onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }} onError={(e) => { (e.target as HTMLImageElement).style.display = "none"; }}

View File

@@ -950,14 +950,22 @@ export async function advancedSearch(parsed: ParsedSearch, limit = 50): Promise<
const opts = { cacheUsage: NDKSubscriptionCacheUsage.ONLY_RELAY }; const opts = { cacheUsage: NDKSubscriptionCacheUsage.ONLY_RELAY };
// Wrap fetchEvents with a timeout — NDK can hang forever if no relay supports the filter
const fetchWithTimeout = (filter: NDKFilter & { search?: string }, timeoutMs = 8000): Promise<Set<NDKEvent>> => {
return Promise.race([
instance.fetchEvents(filter, opts),
new Promise<Set<NDKEvent>>((resolve) => setTimeout(() => resolve(new Set()), timeoutMs)),
]);
};
const noteFilter = noteKinds.length > 0 ? buildFilter(noteKinds) : null; const noteFilter = noteKinds.length > 0 ? buildFilter(noteKinds) : null;
const articleFilter = articleKinds.length > 0 ? buildFilter(articleKinds) : null; const articleFilter = articleKinds.length > 0 ? buildFilter(articleKinds) : null;
const shouldSearchUsers = (!hasKindFilter || parsed.kinds.includes(0)) && hasSearch && !hasHashtags; const shouldSearchUsers = (!hasKindFilter || parsed.kinds.includes(0)) && hasSearch && !hasHashtags;
const [noteEvents, articleEvents, userEvents] = await Promise.all([ const [noteEvents, articleEvents, userEvents] = await Promise.all([
noteFilter ? instance.fetchEvents(noteFilter, opts) : Promise.resolve(new Set<NDKEvent>()), noteFilter ? fetchWithTimeout(noteFilter) : Promise.resolve(new Set<NDKEvent>()),
articleFilter ? instance.fetchEvents(articleFilter, opts) : Promise.resolve(new Set<NDKEvent>()), articleFilter ? fetchWithTimeout(articleFilter) : Promise.resolve(new Set<NDKEvent>()),
shouldSearchUsers ? instance.fetchEvents({ kinds: [NDKKind.Metadata], search: searchText, limit: 20 } as NDKFilter & { search: string }, opts) : Promise.resolve(new Set<NDKEvent>()), shouldSearchUsers ? fetchWithTimeout({ kinds: [NDKKind.Metadata], search: searchText, limit: 20 } as NDKFilter & { search: string }) : Promise.resolve(new Set<NDKEvent>()),
]); ]);
let notes = Array.from(noteEvents); let notes = Array.from(noteEvents);