Merge branch 'main' into feat/custom-emoji-reactions

This commit is contained in:
2023-07-15 05:28:57 +00:00
8 changed files with 106 additions and 46 deletions

View File

@ -7,6 +7,10 @@
height: calc(100vh - 56px - 64px - 36px - 230px); height: calc(100vh - 56px - 64px - 36px - 230px);
} }
.live-chat ::-webkit-scrollbar {
width: 8px;
}
@media (min-width: 768px) { @media (min-width: 768px) {
.profile-info { .profile-info {
width: calc(100vw - 600px - 16px); width: calc(100vw - 600px - 16px);
@ -36,7 +40,7 @@
} }
.live-chat { .live-chat {
width: 320px; width: auto;
} }
} }
@ -74,10 +78,11 @@
flex-direction: column-reverse; flex-direction: column-reverse;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
padding-right: 8px;
} }
@media (min-width: 1020px){ @media (min-width: 1020px) {
.live-chat > .messages { .live-chat>.messages {
flex-grow: 1; flex-grow: 1;
} }
} }
@ -173,13 +178,15 @@
.top-zappers-container { .top-zappers-container {
display: flex; display: flex;
overflow-y: scroll; overflow-y: hidden;
overflow-x: auto;
-ms-overflow-style: none; -ms-overflow-style: none;
scrollbar-width: none; scrollbar-width: none;
user-select: none;
} }
.top-zappers-container::-webkit-scrollbar { .top-zappers-container::-webkit-scrollbar {
display: none; height: 8px;
} }
@media (min-width: 1020px) { @media (min-width: 1020px) {
@ -223,7 +230,10 @@
.zap-container:before { .zap-container:before {
content: ''; content: '';
position: absolute; position: absolute;
top: 0; right: 0; bottom: 0; left: 0; top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1; z-index: -1;
margin: -1px; margin: -1px;
background: linear-gradient(to bottom right, #FF902B, #F83838); background: linear-gradient(to bottom right, #FF902B, #F83838);
@ -248,9 +258,11 @@
0% { 0% {
background-position: 0% 50%; background-position: 0% 50%;
} }
50% { 50% {
background-position: 100% 50%; background-position: 100% 50%;
} }
100% { 100% {
background-position: 0% 50%; background-position: 0% 50%;
} }
@ -382,6 +394,7 @@
color: #FFFFFF80; color: #FFFFFF80;
cursor: pointer; cursor: pointer;
} }
.write-emoji-button:hover { .write-emoji-button:hover {
color: white; color: white;
} }

View File

@ -68,7 +68,7 @@ export function LiveChat({
height?: number; height?: number;
}) { }) {
const host = getHost(ev); const host = getHost(ev);
const feed = useLiveChatFeed(link, host); const feed = useLiveChatFeed(link, goal ? [goal.id] : undefined);
const login = useLogin(); const login = useLogin();
useEffect(() => { useEffect(() => {
const pubkeys = [ const pubkeys = [
@ -90,7 +90,7 @@ export function LiveChat({
.filter((z) => z && z.valid); .filter((z) => z && z.valid);
const goalZaps = feed.zaps const goalZaps = feed.zaps
.filter((ev) => (goal ? ev.created_at > goal.created_at : false)) .filter((ev) => (goal ? ev.created_at > goal.created_at && ev.tags.some(t => t[0] === "e" && t[1] === goal.id) : false))
.map((ev) => parseZap(ev, System.ProfileLoader.Cache)) .map((ev) => parseZap(ev, System.ProfileLoader.Cache))
.filter((z) => z && z.valid); .filter((z) => z && z.valid);
@ -133,11 +133,8 @@ export function LiveChat({
<div className="top-zappers-container"> <div className="top-zappers-container">
<TopZappers zaps={zaps} /> <TopZappers zaps={zaps} />
</div> </div>
{goal ? ( {goal && <Goal link={link} ev={goal} zaps={goalZaps} />}
<Goal link={link} ev={goal} zaps={goalZaps} /> {login?.pubkey === streamer && <NewGoalDialog link={link} />}
) : (
login?.pubkey === streamer && <NewGoalDialog link={link} />
)}
</div> </div>
)} )}
<div className="messages"> <div className="messages">

View File

@ -41,6 +41,9 @@ export function LiveVideoPlayer(
hls.on(Hls.Events.MANIFEST_PARSED, () => { hls.on(Hls.Events.MANIFEST_PARSED, () => {
setStatus(VideoStatus.Online); setStatus(VideoStatus.Online);
}); });
hls.on(Hls.Events.LEVEL_SWITCHING, (e, l) => {
console.debug("HLS Level Switch", l);
});
return () => hls.destroy(); return () => hls.destroy();
} catch (e) { } catch (e) {
console.error(e); console.error(e);

View File

@ -5,24 +5,26 @@ import {
FlatNoteStore, FlatNoteStore,
} from "@snort/system"; } from "@snort/system";
import { useRequestBuilder } from "@snort/system-react"; import { useRequestBuilder } from "@snort/system-react";
import { unixNow } from "@snort/shared";
import { System } from "index"; import { System } from "index";
import { useMemo } from "react"; import { useMemo } from "react";
import { LIVE_STREAM_CHAT } from "const"; import { LIVE_STREAM_CHAT } from "const";
export function useLiveChatFeed(link: NostrLink, host?: string) { export function useLiveChatFeed(link: NostrLink, eZaps?: Array<string>) {
const sub = useMemo(() => { const sub = useMemo(() => {
const rb = new RequestBuilder(`live:${link.id}:${link.author}`); const rb = new RequestBuilder(`live:${link.id}:${link.author}`);
rb.withOptions({ rb.withOptions({
leaveOpen: true, leaveOpen: true,
}); });
const zapsSince = unixNow() - (60 * 60 * 24 * 7); // 7-days of zaps
const aTag = `${link.kind}:${link.author}:${link.id}`; const aTag = `${link.kind}:${link.author}:${link.id}`;
rb.withFilter().kinds([LIVE_STREAM_CHAT]).tag("a", [aTag]).limit(100); rb.withFilter().kinds([LIVE_STREAM_CHAT]).tag("a", [aTag]).limit(100);
rb.withFilter().kinds([EventKind.ZapReceipt]).tag("a", [aTag]); rb.withFilter().kinds([EventKind.ZapReceipt]).tag("a", [aTag]).since(zapsSince);
if (host) { if (eZaps) {
rb.withFilter().kinds([EventKind.ZapReceipt]).tag("p", [host]); rb.withFilter().kinds([EventKind.ZapReceipt]).tag("e", eZaps);
} }
return rb; return rb;
}, [link, host]); }, [link, eZaps]);
const feed = useRequestBuilder<FlatNoteStore>(System, FlatNoteStore, sub); const feed = useRequestBuilder<FlatNoteStore>(System, FlatNoteStore, sub);

View File

@ -73,11 +73,21 @@ a {
color: inherit; color: inherit;
background: linear-gradient(black, black) padding-box, background: linear-gradient(black, black) padding-box,
linear-gradient(94.73deg, #2BD9FF 0%, #F838D9 100%) border-box; linear-gradient(94.73deg, #2BD9FF 0%, #F838D9 100%) border-box;
transition: 0.3s;
}
.btn-border:hover {
background: linear-gradient(black, black) padding-box,
linear-gradient(94.73deg, #14b4d8 0%, #ba179f 100%) border-box;
} }
.btn-primary { .btn-primary {
background: linear-gradient(94.73deg, #2BD9FF 0%, #8C8DED 47.4%, #F838D9 100%); background: #FFF;
color: white; color: #0a0a0a;
}
.btn-primary:hover {
opacity: 0.9;
} }
.btn-warning { .btn-warning {
@ -92,7 +102,11 @@ a {
gap: 8px; gap: 8px;
} }
input[type="text"], textarea, input[type="datetime-local"], input[type="password"], input[type="number"] { input[type="text"],
textarea,
input[type="datetime-local"],
input[type="password"],
input[type="number"] {
font-family: inherit; font-family: inherit;
border: unset; border: unset;
background-color: unset; background-color: unset;

View File

@ -2,7 +2,7 @@
display: grid; display: grid;
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(4, 1fr);
gap: 32px; gap: 32px;
padding: 40px; padding: 40px 0;
} }
@media (max-width: 1020px) { @media (max-width: 1020px) {
@ -18,7 +18,7 @@
.video-grid { .video-grid {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
gap: 12px; gap: 32px;
padding: 16px; padding: 16px;
} }
} }
@ -40,7 +40,37 @@
grid-area: main-content; grid-area: main-content;
} }
.homepage h2 { .divider {
background: #171717; display: flex;
padding: 40px; }
.divider:after {
content: "";
flex: 1;
}
.line {
align-items: center;
margin: 1em 0;
}
.line:after {
height: 1px;
margin: 0 1em;
}
.one-line:before,
.one-line:after {
background-color: #171717;
}
::-webkit-scrollbar {
width: 10px;
background: #111;
}
::-webkit-scrollbar-thumb {
background: #333;
border-radius: 100px;
min-height: 24px;
} }

View File

@ -64,7 +64,7 @@ export function RootPage({ nsfw }: { nsfw?: boolean }) {
</div> </div>
{planned.length > 0 && ( {planned.length > 0 && (
<> <>
<h2>Planned</h2> <h2 className="divider line one-line">Planned</h2>
<div className="video-grid"> <div className="video-grid">
{planned.map((e) => ( {planned.map((e) => (
<VideoTile ev={e} key={e.id} /> <VideoTile ev={e} key={e.id} />
@ -74,7 +74,7 @@ export function RootPage({ nsfw }: { nsfw?: boolean }) {
)} )}
{ended.length > 0 && ( {ended.length > 0 && (
<> <>
<h2>Ended</h2> <h2 className="divider line one-line">Ended</h2>
<div className="video-grid"> <div className="video-grid">
{ended.map((e) => ( {ended.map((e) => (
<VideoTile ev={e} key={e.id} /> <VideoTile ev={e} key={e.id} />

View File

@ -7,6 +7,7 @@
max-height: 230px; max-height: 230px;
width: 100vw; width: 100vw;
max-width: 100vw; max-width: 100vw;
background: #000;
} }
.live-chat { .live-chat {