note and profile titles in header
This commit is contained in:
parent
b11482ede1
commit
c493b959e7
80
packages/app/src/Pages/Layout/Header.tsx
Normal file
80
packages/app/src/Pages/Layout/Header.tsx
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { useLocation } from "react-router-dom";
|
||||||
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import { LogoHeader } from "@/Pages/Layout/LogoHeader";
|
||||||
|
import { RootTabs } from "@/Element/Feed/RootTabs";
|
||||||
|
import NotificationsHeader from "@/Pages/Layout/NotificationsHeader";
|
||||||
|
import { NostrLink, NostrPrefix, parseNostrLink } from "@snort/system";
|
||||||
|
import { bech32ToHex } from "@/SnortUtils";
|
||||||
|
import { useEventFeed } from "@snort/system-react";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
import DisplayName from "@/Element/User/DisplayName";
|
||||||
|
|
||||||
|
export function Header() {
|
||||||
|
const location = useLocation();
|
||||||
|
const showRootTabs = location.pathname === "/";
|
||||||
|
const pageName = location.pathname.split("/")[1];
|
||||||
|
const [nostrLink, setNostrLink] = useState<NostrLink | undefined>();
|
||||||
|
|
||||||
|
const scrollUp = useCallback(() => {
|
||||||
|
window.scrollTo({ top: 0, behavior: "instant" });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
try {
|
||||||
|
setNostrLink(parseNostrLink(pageName));
|
||||||
|
} catch (e) {
|
||||||
|
setNostrLink(undefined);
|
||||||
|
}
|
||||||
|
}, [pageName]);
|
||||||
|
|
||||||
|
let title: React.ReactNode = <span className="capitalize">{pageName}</span>;
|
||||||
|
if (nostrLink) {
|
||||||
|
if (nostrLink.type === NostrPrefix.Event || nostrLink.type === NostrPrefix.Note) {
|
||||||
|
title = <NoteTitle link={nostrLink} />;
|
||||||
|
} else if (nostrLink.type === NostrPrefix.PublicKey || nostrLink.type === NostrPrefix.Profile) {
|
||||||
|
title = <DisplayName pubkey={bech32ToHex(pageName)} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header
|
||||||
|
className={classNames(
|
||||||
|
{ "md:hidden": pageName === "messages" },
|
||||||
|
"flex justify-between items-center self-stretch px-4 gap-6 sticky top-0 z-10 bg-bg-color py-1 md:bg-header md:bg-opacity-50 md:shadow-lg md:backdrop-blur-lg",
|
||||||
|
)}>
|
||||||
|
<div className="md:hidden">
|
||||||
|
<LogoHeader showText={false} />
|
||||||
|
</div>
|
||||||
|
{showRootTabs && <RootTabs base="" />}
|
||||||
|
{!showRootTabs && (
|
||||||
|
<div
|
||||||
|
onClick={scrollUp}
|
||||||
|
className="cursor-pointer flex-1 text-center p-2 overflow-hidden whitespace-nowrap truncate">
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="md:hidden">
|
||||||
|
<NotificationsHeader />
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function NoteTitle({ link }: { link: NostrLink }) {
|
||||||
|
const ev = useEventFeed(link);
|
||||||
|
|
||||||
|
if (!ev.data?.pubkey) {
|
||||||
|
return <FormattedMessage defaultMessage="Note" id="qMePPG" />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Note by {name}"
|
||||||
|
id="ALdW69"
|
||||||
|
values={{ name: <DisplayName pubkey={ev.data.pubkey} /> }}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
@ -12,14 +12,11 @@ import { LoginUnlock } from "@/Element/PinPrompt";
|
|||||||
import useKeyboardShortcut from "@/Hooks/useKeyboardShortcut";
|
import useKeyboardShortcut from "@/Hooks/useKeyboardShortcut";
|
||||||
import { LoginStore } from "@/Login";
|
import { LoginStore } from "@/Login";
|
||||||
import NavSidebar from "./NavSidebar";
|
import NavSidebar from "./NavSidebar";
|
||||||
import NotificationsHeader from "./NotificationsHeader";
|
|
||||||
import RightColumn from "./RightColumn";
|
import RightColumn from "./RightColumn";
|
||||||
import { LogoHeader } from "./LogoHeader";
|
|
||||||
import useLoginFeed from "@/Feed/LoginFeed";
|
import useLoginFeed from "@/Feed/LoginFeed";
|
||||||
import ErrorBoundary from "@/Element/ErrorBoundary";
|
import ErrorBoundary from "@/Element/ErrorBoundary";
|
||||||
import Footer from "@/Pages/Layout/Footer";
|
import Footer from "@/Pages/Layout/Footer";
|
||||||
import { RootTabs } from "@/Element/Feed/RootTabs";
|
import { Header } from "@/Pages/Layout/Header";
|
||||||
import classNames from "classnames";
|
|
||||||
|
|
||||||
export default function Index() {
|
export default function Index() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@ -66,37 +63,6 @@ export default function Index() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Header() {
|
|
||||||
const location = useLocation();
|
|
||||||
const showRootTabs = location.pathname === "/";
|
|
||||||
const pageName = location.pathname.split("/")[1];
|
|
||||||
const scrollUp = useCallback(() => {
|
|
||||||
window.scrollTo({ top: 0, behavior: "instant" });
|
|
||||||
}, []);
|
|
||||||
return (
|
|
||||||
<header
|
|
||||||
className={classNames(
|
|
||||||
{ "md:hidden": pageName === "messages" },
|
|
||||||
"flex justify-between items-center self-stretch px-4 gap-6 sticky top-0 z-10 bg-bg-color py-1 md:bg-header md:bg-opacity-50 md:shadow-lg md:backdrop-blur-lg",
|
|
||||||
)}>
|
|
||||||
<div className="md:hidden">
|
|
||||||
<LogoHeader showText={false} />
|
|
||||||
</div>
|
|
||||||
{showRootTabs && <RootTabs base="" />}
|
|
||||||
{!showRootTabs && (
|
|
||||||
<div
|
|
||||||
onClick={scrollUp}
|
|
||||||
className="capitalize cursor-pointer flex-1 text-center p-2 overflow-hidden whitespace-nowrap truncate">
|
|
||||||
{pageName}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="md:hidden">
|
|
||||||
<NotificationsHeader />
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function StalkerModal({ id }) {
|
function StalkerModal({ id }) {
|
||||||
return (
|
return (
|
||||||
<div className="stalker" onClick={() => LoginStore.removeSession(id)}>
|
<div className="stalker" onClick={() => LoginStore.removeSession(id)}>
|
||||||
|
@ -319,6 +319,9 @@
|
|||||||
"AIgmDy": {
|
"AIgmDy": {
|
||||||
"defaultMessage": "Add up to 4 hashtags"
|
"defaultMessage": "Add up to 4 hashtags"
|
||||||
},
|
},
|
||||||
|
"ALdW69": {
|
||||||
|
"defaultMessage": "Note by {name}"
|
||||||
|
},
|
||||||
"AN0Z7Q": {
|
"AN0Z7Q": {
|
||||||
"defaultMessage": "Muted Words"
|
"defaultMessage": "Muted Words"
|
||||||
},
|
},
|
||||||
@ -1361,6 +1364,9 @@
|
|||||||
"qDwvZ4": {
|
"qDwvZ4": {
|
||||||
"defaultMessage": "Unknown error"
|
"defaultMessage": "Unknown error"
|
||||||
},
|
},
|
||||||
|
"qMePPG": {
|
||||||
|
"defaultMessage": "Note"
|
||||||
|
},
|
||||||
"qMx1sA": {
|
"qMx1sA": {
|
||||||
"defaultMessage": "Default Zap amount"
|
"defaultMessage": "Default Zap amount"
|
||||||
},
|
},
|
||||||
|
@ -105,6 +105,7 @@
|
|||||||
"ABAQyo": "Chats",
|
"ABAQyo": "Chats",
|
||||||
"ADmfQT": "Parent",
|
"ADmfQT": "Parent",
|
||||||
"AIgmDy": "Add up to 4 hashtags",
|
"AIgmDy": "Add up to 4 hashtags",
|
||||||
|
"ALdW69": "Note by {name}",
|
||||||
"AN0Z7Q": "Muted Words",
|
"AN0Z7Q": "Muted Words",
|
||||||
"ASRK0S": "This author has been muted",
|
"ASRK0S": "This author has been muted",
|
||||||
"Ai8VHU": "Unlimited note retention on Snort relay",
|
"Ai8VHU": "Unlimited note retention on Snort relay",
|
||||||
@ -448,6 +449,7 @@
|
|||||||
"pzTOmv": "Followers",
|
"pzTOmv": "Followers",
|
||||||
"qD9EUF": "Email <> DM bridge for your Snort nostr address",
|
"qD9EUF": "Email <> DM bridge for your Snort nostr address",
|
||||||
"qDwvZ4": "Unknown error",
|
"qDwvZ4": "Unknown error",
|
||||||
|
"qMePPG": "Note",
|
||||||
"qMx1sA": "Default Zap amount",
|
"qMx1sA": "Default Zap amount",
|
||||||
"qUJTsT": "Blocked",
|
"qUJTsT": "Blocked",
|
||||||
"qZsKBR": "Renew {tier}",
|
"qZsKBR": "Renew {tier}",
|
||||||
|
Loading…
Reference in New Issue
Block a user