18+ page
This commit is contained in:
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,10 @@ const router = createBrowserRouter([
|
||||
path: "/p/:npub",
|
||||
element: <ProfilePage />,
|
||||
},
|
||||
{
|
||||
path: "/nsfw",
|
||||
element: <RootPage nsfw={true} />
|
||||
},
|
||||
{
|
||||
path: "/:id",
|
||||
element: <StreamPage />,
|
||||
|
@ -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;
|
||||
}
|
@ -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>
|
||||
}
|
@ -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
|
||||
|
@ -60,7 +60,7 @@ function ProfileInfo({ ev }: { ev?: NostrEvent }) {
|
||||
)}
|
||||
<AsyncButton
|
||||
type="button"
|
||||
className="btn btn-red"
|
||||
className="btn btn-warning"
|
||||
onClick={deleteStream}
|
||||
>
|
||||
Delete
|
||||
|
Reference in New Issue
Block a user