feat: add music widget

This commit is contained in:
verbiricha
2023-09-19 08:37:10 +02:00
parent a309737d8c
commit f5b67a2293
7 changed files with 82 additions and 1 deletions

22
src/hooks/status.ts Normal file
View File

@ -0,0 +1,22 @@
import { useMemo } from "react";
import { EventKind, ReplaceableNoteStore, RequestBuilder } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react";
type StatusTag = "general" | "music";
export function useStatus(tag: StatusTag, author?: string, leaveOpen = true) {
const sub = useMemo(() => {
if (!author) return null;
const b = new RequestBuilder(`status:${tag}:${author.slice(0, 8)}`);
b.withOptions({ leaveOpen });
b.withFilter()
.kinds([30315 as EventKind])
.tag("d", [tag])
.authors([author]);
return b;
}, [author]);
const { data } = useRequestBuilder(ReplaceableNoteStore, sub);
return data;
}

View File

@ -110,3 +110,21 @@
width: 24px;
height: 24px;
}
.music {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px;
gap: 4px;
}
.music .cover {
object-fit: cover;
width: 120px;
height: 120px;
}
.music .track {
margin: 0;
}

View File

@ -5,6 +5,7 @@ import { useParams } from "react-router-dom";
import { ZapAlerts } from "./widgets/zaps";
import { Views } from "./widgets/views";
import { TopZappersWidget } from "./widgets/top-zappers";
import { Music } from "./widgets/music";
export function AlertsPage() {
const params = useParams();
@ -24,6 +25,9 @@ export function AlertsPage() {
case "top-zappers": {
return <TopZappersWidget link={link} />;
}
case "music": {
return <Music link={link} />;
}
}
return null;
}

View File

@ -78,7 +78,11 @@ export function LayoutPage() {
</MenuItem>
<MenuItem onClick={() => navigate("/settings")}>
<Icon name="settings" size={24} />
Settings
<FormattedMessage defaultMessage="Settings" />
</MenuItem>
<MenuItem onClick={() => navigate("/widgets")}>
<Icon name="widget" size={24} />
<FormattedMessage defaultMessage="Widgets" />
</MenuItem>
<MenuItem onClick={() => Login.logout()}>
<Icon name="logout" size={24} />

View File

@ -12,6 +12,7 @@ import { eventToLink, hexToBech32 } from "utils";
import { ZapAlertItem } from "./widgets/zaps";
import { TopZappersWidget } from "./widgets/top-zappers";
import { Views } from "./widgets/views";
import { Music } from "./widgets/music";
import groupBy from "lodash/groupBy";
interface ZapAlertConfigurationProps {
@ -195,6 +196,13 @@ export function WidgetsPage() {
<Copy text={`${baseUrl}/alert/${npub}/views`} />
{currentLink && <Views link={currentLink} />}
</div>
<div className="flex f-col g8">
<h3>
<FormattedMessage defaultMessage="Music" />
</h3>
<Copy text={`${baseUrl}/alert/${npub}/music`} />
{currentLink && <Music link={currentLink} />}
</div>
</div>
);
}

View File

@ -0,0 +1,22 @@
import { NostrLink } from "@snort/system";
import { unixNow } from "@snort/shared";
import { useCurrentStreamFeed } from "hooks/current-stream-feed";
import { useStatus } from "hooks/status";
import { getHost, findTag } from "utils";
export function Music({ link }: { link: NostrLink }) {
const currentEvent = useCurrentStreamFeed(link, true);
const host = getHost(currentEvent);
const nowPlaying = useStatus("music", host, true);
const cover = nowPlaying && findTag(nowPlaying, "cover");
const expiry = nowPlaying && findTag(nowPlaying, "expiration");
const isExpired = expiry && Number(expiry) > unixNow();
return (
!isExpired && (
<div className="music">
{cover && <img className="cover" src={cover} alt={nowPlaying.content} />}
{nowPlaying && <p className="track">🎵 {nowPlaying.content}</p>}
</div>
)
);
}