This commit is contained in:
Kieran 2023-07-06 18:48:55 +01:00
parent 76d0496ba1
commit ad7dc56214
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
8 changed files with 140 additions and 37 deletions

View File

@ -26,7 +26,9 @@
</symbol>
<symbol id="link" viewBox="0 0 32 32" fill="none">
<path d="M22 14L22 10M22 10H18M22 10L16 16M14.6667 10H13.2C12.0799 10 11.5198 10 11.092 10.218C10.7157 10.4097 10.4097 10.7157 10.218 11.092C10 11.5198 10 12.0799 10 13.2V18.8C10 19.9201 10 20.4802 10.218 20.908C10.4097 21.2843 10.7157 21.5903 11.092 21.782C11.5198 22 12.0799 22 13.2 22H18.8C19.9201 22 20.4802 22 20.908 21.782C21.2843 21.5903 21.5903 21.2843 21.782 20.908C22 20.4802 22 19.9201 22 18.8V17.3333" stroke="currentColor" stroke-width="1.33333" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</symbol>
<symbol id="zap-stream" viewBox="0 0 160 160" fill="none">
<path fill-rule="evenodd" clip-rule="evenodd" d="M82.4852 54.5094L87.7882 48.2773C87.8525 48.2098 87.9174 48.1429 87.9826 48.0768C94.4927 41.1346 103.63 36.8165 113.748 36.8165C133.516 36.8165 149.541 53.2997 149.541 73.6327C149.541 82.0501 146.795 89.8077 142.174 96.0093L142.197 96.029L141.843 96.4456C141.126 97.3799 140.364 98.2774 139.563 99.1352L87.9613 160L43.5147 158.617L58.9832 140.033L112.875 76.6987C114.038 75.3317 113.873 73.2807 112.506 72.1175C111.139 70.9544 109.088 71.1196 107.925 72.4865L71.2247 115.617C64.7813 121.963 55.8992 125.885 46.0917 125.885C26.4118 125.885 10.458 110.093 10.458 90.6136C10.458 81.6851 13.8096 73.5314 19.3355 67.318L76.4941 3.75969e-05L120.334 8.27526e-08L51.0699 81.3993C49.9068 82.7663 50.072 84.8173 51.4389 85.9805C52.8059 87.1437 54.857 86.9784 56.0201 85.6115L72.1945 66.6032C72.207 66.6164 72.2194 66.6297 72.2319 66.643L82.4852 54.5094Z" fill="white"/>
</symbol>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

4
public/zap-stream.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="160" height="160" viewBox="0 0 160 160" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M82.4852 54.5094L87.7882 48.2773C87.8525 48.2098 87.9174 48.1429 87.9826 48.0768C94.4927 41.1346 103.63 36.8165 113.748 36.8165C133.516 36.8165 149.541 53.2997 149.541 73.6327C149.541 82.0501 146.795 89.8077 142.174 96.0093L142.197 96.029L141.843 96.4456C141.126 97.3799 140.364 98.2774 139.563 99.1352L87.9613 160L43.5147 158.617L58.9832 140.033L112.875 76.6987C114.038 75.3317 113.873 73.2807 112.506 72.1175C111.139 70.9544 109.088 71.1196 107.925 72.4865L71.2247 115.617C64.7813 121.963 55.8992 125.885 46.0917 125.885C26.4118 125.885 10.458 110.093 10.458 90.6136C10.458 81.6851 13.8096 73.5314 19.3355 67.318L76.4941 3.75969e-05L120.334 8.27526e-08L51.0699 81.3993C49.9068 82.7663 50.072 84.8173 51.4389 85.9805C52.8059 87.1437 54.857 86.9784 56.0201 85.6115L72.1945 66.6032C72.207 66.6164 72.2194 66.6297 72.2319 66.643L82.4852 54.5094Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -80,8 +80,8 @@ a {
color: white;
}
.btn-red {
background: rgb(143, 0, 0);
.btn-warning {
background: #FF563F;
color: white;
}
@ -150,4 +150,4 @@ div.paper {
.border-warning {
border: 1px solid #FF563F;
}
}

View File

@ -47,6 +47,10 @@ const router = createBrowserRouter([
path: "/p/:npub",
element: <ProfilePage />,
},
{
path: "/nsfw",
element: <RootPage nsfw={true} />
},
{
path: "/:id",
element: <StreamPage />,

View File

@ -32,7 +32,7 @@
grid-template-rows: 64px min-content;
grid-template-columns: 600px 1fr;
gap: 0;
}
}
.video-content video {
height: 100%;
@ -61,21 +61,24 @@
padding: 0 40px;
grid-template-columns: auto 450px;
}
.video-content {
max-height: calc(100vh - 320px);
}
.video-content video {
height: 100%;
}
}
header {
grid-area: header;
align-items: center;
display: grid;
grid-template-columns: min-content min-content auto;
padding: 8px 16px;
gap: 8px;
grid-area: header;
align-items: center;
display: grid;
grid-template-columns: min-content min-content min-content auto;
padding: 8px 16px;
gap: 8px;
white-space: nowrap;
}
@media (min-width: 1020px) {
@ -90,39 +93,60 @@ header {
}
header .logo {
background: url("public/logo.png") no-repeat #171717;
background-size: cover;
border-radius: 16px;
width: 48px;
height: 48px;
cursor: pointer;
background: url("public/logo.png") no-repeat #171717;
background-size: cover;
border-radius: 16px;
width: 48px;
height: 48px;
cursor: pointer;
}
header .btn-header {
height: 32px;
border-bottom: 2px solid transparent;
user-select: none;
cursor: pointer;
font-weight: 700;
font-size: 16px;
line-height: 20px;
padding: 8px 16px;
display: flex;
align-items: center;
}
header .btn-header.active {
border-bottom: 2px solid;
}
header .btn-header:hover {
border-bottom: 2px solid;
}
header .paper {
min-width: 300px;
height: 32px;
min-width: 300px;
height: 32px;
}
header .header-right {
justify-self: end;
display: flex;
gap: 24px;
justify-self: end;
display: flex;
gap: 24px;
}
header input[type="text"]:active {
border: unset;
border: unset;
}
header button {
height: 48px;
display: flex;
align-items: center;
gap: 8px;
height: 48px;
display: flex;
align-items: center;
gap: 8px;
}
header .profile img {
width: 48px;
height: 48px;
width: 48px;
height: 48px;
}
@media (max-width: 1020px) {
@ -183,3 +207,39 @@ button span.hide-on-mobile {
display: flex;
gap: 8px;
}
.fullscreen-exclusive {
width: 100vw;
height: 100vh;
position: absolute;
top: 0;
left: 0;
z-index: 999;
background: #0A0A0A;
}
.age-check {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
}
.age-check::after {
content: " ";
background: url("public/zap-stream.svg") no-repeat;
background-position: center;
background-size: contain;
position: absolute;
top: 20px;
left: 20px;
width: calc(100vw - 40px);
height: calc(100vh - 40px);
z-index: -1;
opacity: 0.02;
}
.age-check .btn {
padding: 12px 16px;
}

View File

@ -3,12 +3,13 @@ import "./layout.css";
import {
EventPublisher,
} from "@snort/system";
import { Outlet, useNavigate, useLocation } from "react-router-dom";
import { Outlet, useNavigate, useLocation, Link } from "react-router-dom";
import AsyncButton from "element/async-button";
import { Login } from "index";
import { useLogin } from "hooks/login";
import { Profile } from "element/profile";
import { NewStreamDialog } from "element/new-stream";
import { useState } from "react";
export function LayoutPage() {
const navigate = useNavigate();
@ -51,15 +52,16 @@ export function LayoutPage() {
</>
);
}
const isNsfw = window.location.pathname === "/nsfw";
return (
<div
className={
location.pathname === "/" || location.pathname.startsWith("/p/") || location.pathname.startsWith("/providers")
location.pathname === "/" || location.pathname.startsWith("/p/") || location.pathname.startsWith("/providers") || location.pathname === "/nsfw"
? "page only-content"
: location.pathname.startsWith("/chat/")
? "page chat"
: "page"
? "page chat"
: "page"
}
>
<header>
@ -68,12 +70,43 @@ export function LayoutPage() {
<input className="search-input" type="text" placeholder="Search" />
<Icon name="search" size={15} />
</div>
<Link to={"/nsfw"}>
<div className={`btn-header${isNsfw ? " active" : ""}`}>
Adult (18+)
</div>
</Link>
<div className="header-right">
{loggedIn()}
{loggedOut()}
</div>
</header>
<Outlet />
{isNsfw && <ContentWarningOverlay />}
</div>
);
}
function ContentWarningOverlay() {
const navigate = useNavigate();
const [is18Plus, setIs18Plus] = useState(Boolean(window.localStorage.getItem("accepted-content-warning")));
if (is18Plus) return null;
function grownUp() {
window.localStorage.setItem("accepted-content-warning", "true");
setIs18Plus(true);
}
return <div className="fullscreen-exclusive age-check">
<h1>Sexually explicit material ahead!</h1>
<h2>Confirm your age</h2>
<div className="flex g24">
<button className="btn btn-warning" onClick={grownUp}>
Yes, I am over 18
</button>
<button className="btn" onClick={() => navigate("/")}>
No, I am under 18
</button>
</div>
</div>
}

View File

@ -12,7 +12,7 @@ import { VideoTile } from "../element/video-tile";
import { findTag } from "../utils";
import { LIVE_STREAM } from "../const";
export function RootPage() {
export function RootPage({ nsfw }: { nsfw?: boolean }) {
const rb = useMemo(() => {
const rb = new RequestBuilder("root");
rb.withOptions({
@ -31,7 +31,7 @@ export function RootPage() {
);
const feedSorted = useMemo(() => {
if (feed.data) {
return [...feed.data].sort((a, b) => {
return [...feed.data].filter(a => nsfw ? findTag(a, "content-warning") !== undefined : findTag(a, "content-warning") === undefined).sort((a, b) => {
const aStatus = findTag(a, "status")!;
const bStatus = findTag(b, "status")!;
if (aStatus === bStatus) {
@ -44,7 +44,7 @@ export function RootPage() {
});
}
return [];
}, [feed.data]);
}, [feed.data, nsfw]);
const live = feedSorted.filter(
(a) => findTag(a, "status") === StreamState.Live

View File

@ -60,7 +60,7 @@ function ProfileInfo({ ev }: { ev?: NostrEvent }) {
)}
<AsyncButton
type="button"
className="btn btn-red"
className="btn btn-warning"
onClick={deleteStream}
>
Delete