fixes: mobile

This commit is contained in:
Kieran 2024-03-05 13:04:24 +00:00
parent 4990e6dbca
commit bb207d7af1
7 changed files with 61 additions and 36 deletions

View File

@ -7,7 +7,7 @@ import { FormattedMessage } from "react-intl";
import VideoGrid from "./video-grid";
import { VideoTile } from "./video-tile";
export default function VideoGridSorted({ evs }: { evs: Array<TaggedNostrEvent> }) {
export default function VideoGridSorted({ evs, showAll }: { evs: Array<TaggedNostrEvent>, showAll?: boolean }) {
const login = useLogin();
const mutedHosts = new Set(getTagValues(login?.muted.tags ?? [], "p"));
const tags = login?.follows.tags ?? [];
@ -17,7 +17,7 @@ export default function VideoGridSorted({ evs }: { evs: Array<TaggedNostrEvent>
},
[tags]
);
const { live, planned, ended } = useLiveStreams(evs);
const { live, planned, ended } = useLiveStreams(evs, showAll ? 0 : undefined);
const hashtags = getTagValues(tags, "t");
const following = live.filter(followsHost);
const liveNow = live.filter(e => !following.includes(e));

View File

@ -4,7 +4,7 @@ import { unixNow } from "@snort/shared";
import { NostrEvent, TaggedNostrEvent } from "@snort/system";
import { useMemo } from "react";
export function useLiveStreams(feed: Array<TaggedNostrEvent>) {
export function useLiveStreams(feed: Array<TaggedNostrEvent>, oldest?: number) {
function sortCreatedAt(a: NostrEvent, b: NostrEvent) {
return b.created_at > a.created_at ? 1 : -1;
}
@ -18,7 +18,7 @@ export function useLiveStreams(feed: Array<TaggedNostrEvent>) {
const feedSorted = useMemo(() => {
if (feed) {
return feed
.filter(a => a.created_at > unixNow() - 7 * DAY)
.filter(a => a.created_at > (oldest ?? (unixNow() - 7 * DAY)))
.filter(a => !import.meta.env.VITE_SINGLE_PUBLISHER || import.meta.env.VITE_SINGLE_PUBLISHER === getHost(a));
}
return [];

View File

@ -132,7 +132,7 @@ const router = createBrowserRouter([
),
},
{
path: "/search/:term",
path: "/search/:term?",
element: <SearchPage />,
},
{

View File

@ -56,11 +56,7 @@ export default function Category() {
rb.withFilter().kinds([EventKind.LiveEvent]).tag("t", cat.tags);
return rb;
}, [cat]);
const results = useRequestBuilder(sub).filter(a => {
const { status } = extractStreamInfo(a);
return status === StreamState.Live;
});
const results = useRequestBuilder(sub);
return (
<div>
<div className="flex gap-4">
@ -69,7 +65,7 @@ export default function Category() {
))}
</div>
<h1 className="uppercase my-4">{id}</h1>
<VideoGridSorted evs={results} />
<VideoGridSorted evs={results} showAll={true} />
</div>
);
}

View File

@ -146,10 +146,10 @@ export function LayoutPage() {
<Logo width={40} height={40} />
</div>
<SearchBar />
<Link to="/category">
<Link to="/category" className="max-xl:hidden">
<FormattedMessage defaultMessage="Categories" id="VKb1MS" />
</Link>
<Link to="/faq">
<Link to="/faq" className="max-xl:hidden">
<FormattedMessage defaultMessage="FAQ" id="W8nHSd" />
</Link>
</div>
@ -178,9 +178,10 @@ function SearchBar() {
const [search, setSearch] = useState(term ?? "");
return (
<div className="bg-layer-2 rounded-xl pr-4 py-1 flex items-center">
<div className="max-xl:bg-white xl:bg-layer-2 rounded-xl pr-4 py-1 flex items-center">
<input
type="text"
className="max-xl:hidden"
placeholder={formatMessage({
defaultMessage: "Search",
id: "xmcVZ0",
@ -193,7 +194,13 @@ function SearchBar() {
}
}}
/>
<Icon name="search" className="text-layer-4" size={16} />
<Icon
name="search"
className="max-xl:text-black mx:text-layer-4 max-xl:ml-4 max-xl:my-1"
size={16}
onClick={() => {
navigate("/search")
}}/>
</div>
);
}

View File

@ -8,7 +8,7 @@ export function RootPage() {
return (
<div className="flex flex-col gap-6">
<div className="flex gap-4">
<div className="flex gap-4 overflow-x-scroll scrollbar-hidden">
{AllCategories.filter(a => a.priority === 0).map(a => (
<CategoryLink key={a.id} {...a} />
))}

View File

@ -1,10 +1,10 @@
import VideoGrid from "@/element/video-grid";
import { VideoTile } from "@/element/video-tile";
import { Icon } from "@/element/icon";
import VideoGridSorted from "@/element/video-grid-sorted";
import { EventKind, RequestBuilder } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react";
import { useMemo } from "react";
import { FormattedMessage } from "react-intl";
import { useParams } from "react-router-dom";
import { useMemo, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useNavigate, useParams } from "react-router-dom";
export const SearchRelays = [
"wss://relay.nostr.band",
@ -15,12 +15,13 @@ export const SearchRelays = [
export default function SearchPage() {
const { term } = useParams();
const { formatMessage } = useIntl();
const navigate = useNavigate();
const [search, setSearch] = useState(term ?? "");
const sub = useMemo(() => {
if (!term) return;
const rb = new RequestBuilder(`search:${term}`);
rb.withOptions({
skipDiff: true,
});
rb.withFilter().relay(SearchRelays).kinds([EventKind.LiveEvent]).search(term).limit(50);
return rb;
}, [term]);
@ -28,20 +29,41 @@ export default function SearchPage() {
const results = useRequestBuilder(sub);
return (
<div>
<h2 className="mb-4">
<FormattedMessage
defaultMessage="Search results: {term}"
id="A1zT+z"
values={{
term,
<div className="bg-layer-2 rounded-xl pr-4 py-1 flex items-center xl:hidden">
<input
type="text"
placeholder={formatMessage({
defaultMessage: "Search",
id: "xmcVZ0",
})}
value={search}
onChange={e => setSearch(e.target.value)}
onKeyDown={e => {
if (e.key === "Enter") {
navigate(`/search/${encodeURIComponent(search)}`);
}
}}
/>
</h2>
<VideoGrid>
{results.map(a => (
<VideoTile ev={a} key={a.id} />
))}
</VideoGrid>
<Icon
name="search"
className="text-layer-4 ml-4 my-1"
size={16}
onClick={() => {
navigate("/search")
}} />
</div>
{term && <>
<h2 className="mb-4">
<FormattedMessage
defaultMessage="Search results: {term}"
id="A1zT+z"
values={{
term,
}}
/>
</h2>
<VideoGridSorted evs={results} showAll={true} />
</>}
</div>
);
}