fix: responive layout improvements

This commit is contained in:
kieran 2024-05-22 15:07:42 +01:00
parent 2a6929b894
commit 19d732c272
No known key found for this signature in database
GPG Key ID: DE71CEB3925BE941
7 changed files with 66 additions and 48 deletions

View File

@ -1,54 +1,55 @@
import { DAY, HOUR, MINUTE, MONTH, WEEK } from "@/const";
import { FormattedMessage } from "react-intl";
export function RelativeTime({ from }: { from: number }) {
export function RelativeTime({ from, suffix }: { from: number; suffix?: boolean }) {
const diff = (new Date().getTime() - from) / 1000;
const s = <FormattedMessage defaultMessage="ago" description="Relative time, ie. 1s ago" />;
if (diff > MONTH) {
return (
<FormattedMessage
defaultMessage="{m}mo"
defaultMessage="{m}mo {ago}"
description="Number of month(s) relative to now"
values={{ m: Math.floor(diff / MONTH).toFixed(0) }}
values={{ m: Math.floor(diff / MONTH).toFixed(0), ago: suffix ? s : undefined }}
/>
);
} else if (diff > WEEK) {
return (
<FormattedMessage
defaultMessage="{m}w"
defaultMessage="{m}w {ago}"
description="Number of week(s) relative to now"
values={{ m: Math.floor(diff / WEEK).toFixed(0) }}
values={{ m: Math.floor(diff / WEEK).toFixed(0), ago: suffix ? s : undefined }}
/>
);
} else if (diff > DAY) {
return (
<FormattedMessage
defaultMessage="{m}d"
defaultMessage="{m}d {ago}"
description="Number of day(s) relative to now"
values={{ m: Math.floor(diff / DAY).toFixed(0) }}
values={{ m: Math.floor(diff / DAY).toFixed(0), ago: suffix ? s : undefined }}
/>
);
} else if (diff > HOUR) {
return (
<FormattedMessage
defaultMessage="{m}h"
defaultMessage="{m}h {ago}"
description="Number of hour(s) relative to now"
values={{ m: Math.floor(diff / HOUR).toFixed(0) }}
values={{ m: Math.floor(diff / HOUR).toFixed(0), ago: suffix ? s : undefined }}
/>
);
} else if (diff > MINUTE) {
return (
<FormattedMessage
defaultMessage="{m}h"
defaultMessage="{m}h {ago}"
description="Number of minute(s) relative to now"
values={{ m: Math.floor(diff / MINUTE).toFixed(0) }}
values={{ m: Math.floor(diff / MINUTE).toFixed(0), ago: suffix ? s : undefined }}
/>
);
} else {
return (
<FormattedMessage
defaultMessage="{m}s"
defaultMessage="{m}s {ago}"
description="Number of second(s) relative to now"
values={{ m: Math.floor(diff).toFixed(0) }}
values={{ m: Math.floor(diff).toFixed(0), ago: suffix ? s : undefined }}
/>
);
}

View File

@ -2,7 +2,7 @@ import { ReactNode } from "react";
export default function VideoGrid({ children }: { children: ReactNode }) {
return (
<div className="grid gap-5 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-7 3xl:grid-cols-8 items-start">
<div className="grid gap-5 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6 3xl:grid-cols-7 items-start">
{children}
</div>
);

View File

@ -16,6 +16,7 @@ import { useUserProfile } from "@snort/system-react";
import { VideoDuration } from "./video/duration";
import useImgProxy from "@/hooks/img-proxy";
import PillOpaque from "./pill-opaque";
import { RelativeTime } from "./relative-time";
export function VideoTile({
ev,
@ -32,7 +33,7 @@ export function VideoTile({
style: "list" | "grid";
className?: string;
}) {
const { title, image, status, participants, contentWarning, duration, recording } = extractStreamInfo(ev);
const { title, image, status, participants, contentWarning, duration, recording, ends } = extractStreamInfo(ev);
const host = getHost(ev);
const hostProfile = useUserProfile(host);
const isGrownUp = useContentWarning();
@ -94,7 +95,17 @@ export function VideoTile({
<span className="font-medium" title={title}>
{(title?.length ?? 0) > 50 ? `${title?.slice(0, 47)}...` : title}
</span>
{showAuthor && <span className="text-layer-4">{getName(host, hostProfile)}</span>}
{showAuthor && (
<span className="text-layer-4">
{getName(host, hostProfile)}
{ends && (
<>
{" · "}
<RelativeTime from={Number(ends) * 1000} suffix={true} />
</>
)}
</span>
)}
</div>
</div>
</div>

View File

@ -62,10 +62,6 @@
"1qsXCO": {
"defaultMessage": "eg. name@wallet.com"
},
"1y8vnu": {
"defaultMessage": "{m}s",
"description": "Number of second(s) relative to now"
},
"2/2yg+": {
"defaultMessage": "Add"
},
@ -177,10 +173,6 @@
"9a9+ww": {
"defaultMessage": "Title"
},
"9bAnRw": {
"defaultMessage": "{m}d",
"description": "Number of day(s) relative to now"
},
"9pMqYs": {
"defaultMessage": "Nostr Address"
},
@ -259,6 +251,10 @@
"FIDK5Y": {
"defaultMessage": "All Time Top Zappers"
},
"FXepR9": {
"defaultMessage": "{m}mo {ago}",
"description": "Number of month(s) relative to now"
},
"FjDlus": {
"defaultMessage": "You can always replace it with your own address later."
},
@ -400,9 +396,17 @@
"OkXMLE": {
"defaultMessage": "Max Audio Bitrate"
},
"OumUwz": {
"defaultMessage": "{m}s {ago}",
"description": "Number of second(s) relative to now"
},
"Oxqtyf": {
"defaultMessage": "We hooked you up with a lightning wallet so you can get paid by viewers right away!"
},
"PDA8V2": {
"defaultMessage": "{m}h {ago}",
"description": "Number of hour(s) relative to now"
},
"PHE60k": {
"defaultMessage": "Leave blank if you do not wish to set up any goals."
},
@ -469,16 +473,16 @@
"TDUfVk": {
"defaultMessage": "Started"
},
"TNFpMZ": {
"defaultMessage": "{m}h",
"description": "Number of hour(s) relative to now"
},
"TP/cMX": {
"defaultMessage": "Ended"
},
"TwyMau": {
"defaultMessage": "Account"
},
"UCDS65": {
"defaultMessage": "ago",
"description": "Relative time, ie. 1s ago"
},
"UGFYV8": {
"defaultMessage": "Welcome to zap.stream!"
},
@ -519,10 +523,6 @@
"X2PZ7D": {
"defaultMessage": "Create Goal"
},
"XD/ATb": {
"defaultMessage": "{m}mo",
"description": "Number of month(s) relative to now"
},
"XIvYvF": {
"defaultMessage": "Failed to get invoice"
},
@ -572,6 +572,10 @@
"Zse7yG": {
"defaultMessage": "Raid target"
},
"aB/rH0": {
"defaultMessage": "{m}h {ago}",
"description": "Number of minute(s) relative to now"
},
"acrOoz": {
"defaultMessage": "Continue"
},
@ -681,10 +685,6 @@
"jgOqxt": {
"defaultMessage": "Widgets"
},
"jhTFev": {
"defaultMessage": "{m}w",
"description": "Number of week(s) relative to now"
},
"jkAQj5": {
"defaultMessage": "Stream Ended"
},
@ -760,10 +760,6 @@
"q9ryv4": {
"defaultMessage": "Cover image URL (optional)"
},
"qRV9H5": {
"defaultMessage": "{m}h",
"description": "Number of minute(s) relative to now"
},
"qx6bv2": {
"defaultMessage": "Stream Goal (optional)"
},
@ -779,6 +775,10 @@
"rgsbu9": {
"defaultMessage": "Current Viewers"
},
"s+ORFl": {
"defaultMessage": "{m}d {ago}",
"description": "Number of day(s) relative to now"
},
"s5ksS7": {
"defaultMessage": "Image Link"
},
@ -870,6 +870,10 @@
"y867Vs": {
"defaultMessage": "Volume"
},
"y8ogtp": {
"defaultMessage": "{m}w {ago}",
"description": "Number of week(s) relative to now"
},
"yLxIgl": {
"defaultMessage": "Clips"
},

View File

@ -46,8 +46,8 @@ export function VideoPage({ link, evPreload }: { link: NostrLink; evPreload?: Ta
return (
<div
className={classNames("lg:p-4 grow lg:grid lg:gap-2 lg:grid-cols-[auto_450px]", {
"max-w-[60dvw] mx-auto": !widePlayer,
className={classNames("xl:p-4 grow xl:grid xl:gap-2 xl:grid-cols-[auto_450px]", {
"xl:w-[1600px] xl:max-w-[1600px] mx-auto": !widePlayer,
})}>
<div
className={classNames("min-w-0 w-full max-h-[80dvh] aspect-video mx-auto bg-black", {

View File

@ -20,7 +20,6 @@
"1LBny5": "Stopped",
"1q4BO/": "Not a valid URL",
"1qsXCO": "eg. name@wallet.com",
"1y8vnu": "{m}s",
"2/2yg+": "Add",
"2lVQYF": "...more",
"2ukA4d": "{n} hours",
@ -58,7 +57,6 @@
"8xVdjn": "Video Codec",
"9WRlF4": "Send",
"9a9+ww": "Title",
"9bAnRw": "{m}d",
"9pMqYs": "Nostr Address",
"9rmSgv": "OBS (Open Broadcaster Software) is a free and open source software for video recording and live streaming on Windows, Mac and Linux. It is a popular choice with streamers. You'll need to install this to capture your video, audio and anything else you'd like to add to your stream. Once installed and configured to preference, add your Stream URL and Stream Key from the Stream settings to OBS to form a connection with zap.stream.",
"A1zT+z": "Search results: {term}",
@ -85,6 +83,7 @@
"ESyhzp": "Your comment for {name}",
"FAUhZf": "What are sats?",
"FIDK5Y": "All Time Top Zappers",
"FXepR9": "{m}mo {ago}",
"FjDlus": "You can always replace it with your own address later.",
"Fodi9+": "Get paid by viewers",
"G/yZLu": "Remove",
@ -132,7 +131,9 @@
"OKhRC6": "Share",
"ObZZEz": "No clips yet",
"OkXMLE": "Max Audio Bitrate",
"OumUwz": "{m}s {ago}",
"Oxqtyf": "We hooked you up with a lightning wallet so you can get paid by viewers right away!",
"PDA8V2": "{m}h {ago}",
"PHE60k": "Leave blank if you do not wish to set up any goals.",
"PUymyQ": "Come check out {name} stream on zap.stream! {link}",
"PXAur5": "Withdraw",
@ -155,9 +156,9 @@
"S39ba6": "What is OBS?",
"SC2nJT": "Audio Codec",
"TDUfVk": "Started",
"TNFpMZ": "{m}h",
"TP/cMX": "Ended",
"TwyMau": "Account",
"UCDS65": "ago",
"UGFYV8": "Welcome to zap.stream!",
"UJBFYK": "Add Card",
"UfSot5": "Past Streams",
@ -171,7 +172,6 @@
"Wp4l7+": "More Videos",
"WsjXrZ": "Click on Log In",
"X2PZ7D": "Create Goal",
"XD/ATb": "{m}mo",
"XIvYvF": "Failed to get invoice",
"XMGfiA": "Recent Clips",
"XgWvGA": "Reactions",
@ -188,6 +188,7 @@
"ZmqxZs": "You can change this later",
"ZsYhvh": "Zaps are lightning payments, which are published on nostr as receipts.",
"Zse7yG": "Raid target",
"aB/rH0": "{m}h {ago}",
"acrOoz": "Continue",
"aqjZxs": "Raid!",
"bD/ZwY": "Edit Cards",
@ -224,7 +225,6 @@
"j/jueq": "Raiding {name}",
"jJLRgo": "Publish Clip",
"jgOqxt": "Widgets",
"jhTFev": "{m}w",
"jkAQj5": "Stream Ended",
"jr4+vD": "Markdown",
"jvo0vs": "Save",
@ -250,12 +250,12 @@
"pxF+t0": "Popular",
"q+zTWM": "<s>{person}</s> zapped <s>{amount}</s> sats",
"q9ryv4": "Cover image URL (optional)",
"qRV9H5": "{m}h",
"qx6bv2": "Stream Goal (optional)",
"r2Jjms": "Log In",
"rJqhFR": "Stream Setup",
"rWBFZA": "Sexually explicit material ahead!",
"rgsbu9": "Current Viewers",
"s+ORFl": "{m}d {ago}",
"s5ksS7": "Image Link",
"s7V+5p": "Confirm your age",
"sInm1h": "Zap message",
@ -286,6 +286,7 @@
"xi3sgh": "How do i get more sats?",
"xmcVZ0": "Search",
"y867Vs": "Volume",
"y8ogtp": "{m}w {ago}",
"yLxIgl": "Clips",
"yR0V+W": "To start streaming on zap.stream, follow these steps:",
"yj8NrY": "Clip",

View File

@ -145,6 +145,7 @@ export function extractStreamInfo(ev?: NostrEvent) {
matchTag(t, "ends", v => (ret.ends = v));
matchTag(t, "service", v => (ret.service = v));
matchTag(t, "duration", v => (ret.duration = Number(v)));
matchTag(t, "published_at", v => (ret.ends = v));
}
const { regularTags, prefixedTags } = sortStreamTags(ev?.tags ?? []);
ret.tags = regularTags;