tab selector vs content naming, refactoring
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
ffa4a192f6
commit
ef673c2a05
@ -583,7 +583,7 @@ https://git.v0l.io/Kieran/snort/compare/v0.1.9...v0.1.10
|
||||
- Fix event mention bug by @SamSamskies in https://github.com/v0l/snort/pull/421
|
||||
- fix NaN when parsing empty string by @SamSamskies in https://github.com/v0l/snort/pull/422
|
||||
- NIP06 support by @w3irdrobot in https://github.com/v0l/snort/pull/425
|
||||
- Added key attr to Tabs to remove React warning by @w3irdrobot in https://github.com/v0l/snort/pull/424
|
||||
- Added key attr to TabSelectors to remove React warning by @w3irdrobot in https://github.com/v0l/snort/pull/424
|
||||
- New Crowdin updates by @v0l in https://github.com/v0l/snort/pull/426
|
||||
- New Crowdin updates by @v0l in https://github.com/v0l/snort/pull/436
|
||||
- Update Wavlake embed URL, add support for album & artist links by @blastshielddown in https://github.com/v0l/snort/pull/439
|
||||
|
@ -8,7 +8,7 @@ import { FormattedMessage, useIntl } from "react-intl";
|
||||
import CloseButton from "@/Components/Button/CloseButton";
|
||||
import Icon from "@/Components/Icons/Icon";
|
||||
import Modal from "@/Components/Modal/Modal";
|
||||
import Tabs from "@/Components/Tabs/Tabs";
|
||||
import TabSelectors from "@/Components/TabSelectors/TabSelectors";
|
||||
import ProfileImage from "@/Components/User/ProfileImage";
|
||||
import { formatShort } from "@/Utils/Number";
|
||||
|
||||
@ -75,7 +75,7 @@ const ReactionsModal = ({ onClose, event, initialTab = 0 }: ReactionsModalProps)
|
||||
<FormattedMessage {...messages.ReactionsCount} values={{ n: total }} />
|
||||
</h2>
|
||||
</div>
|
||||
<Tabs tabs={tabs} tab={tab} setTab={setTab} />
|
||||
<TabSelectors tabs={tabs} tab={tab} setTab={setTab} />
|
||||
<div className="reactions-body" key={tab.value}>
|
||||
{tab.value === 0 && likes.map(ev => renderReactionItem(ev, "heart"))}
|
||||
{tab.value === 1 &&
|
||||
|
@ -1,4 +1,4 @@
|
||||
import "./Tabs.css";
|
||||
import "./TabSelectors.css";
|
||||
|
||||
import { ReactNode } from "react";
|
||||
|
||||
@ -20,7 +20,7 @@ interface TabElementProps extends Omit<TabsProps, "tabs"> {
|
||||
t: Tab;
|
||||
}
|
||||
|
||||
export const TabElement = ({ t, tab, setTab }: TabElementProps) => {
|
||||
export const TabSelector = ({ t, tab, setTab }: TabElementProps) => {
|
||||
return (
|
||||
<div
|
||||
className={`tab${tab.value === t.value ? " active" : ""}${t.disabled ? " disabled" : ""}`}
|
||||
@ -30,15 +30,15 @@ export const TabElement = ({ t, tab, setTab }: TabElementProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Tabs = ({ tabs, tab, setTab }: TabsProps) => {
|
||||
const TabSelectors = ({ tabs, tab, setTab }: TabsProps) => {
|
||||
const horizontalScroll = useHorizontalScroll();
|
||||
return (
|
||||
<div className="tabs" ref={horizontalScroll}>
|
||||
{tabs.map((t, index) => (
|
||||
<TabElement key={index} tab={tab} setTab={setTab} t={t} />
|
||||
<TabSelector key={index} tab={tab} setTab={setTab} t={t} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tabs;
|
||||
export default TabSelectors;
|
@ -2,7 +2,7 @@ import { useState } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import SuggestedProfiles from "@/Components/SuggestedProfiles";
|
||||
import { Tab, TabElement } from "@/Components/Tabs/Tabs";
|
||||
import { Tab, TabSelector } from "@/Components/TabSelectors/TabSelectors";
|
||||
import TrendingNotes from "@/Components/Trending/TrendingPosts";
|
||||
import TrendingUsers from "@/Components/Trending/TrendingUsers";
|
||||
|
||||
@ -32,7 +32,7 @@ export default function Discover() {
|
||||
<>
|
||||
<div className="tabs p">
|
||||
{[Tabs.Follows, Tabs.Posts, Tabs.Profiles].map(a => (
|
||||
<TabElement key={a.value} tab={tab} setTab={setTab} t={a} />
|
||||
<TabSelector key={a.value} tab={tab} setTab={setTab} t={a} />
|
||||
))}
|
||||
</div>
|
||||
{renderTab()}
|
||||
|
@ -7,7 +7,7 @@ import { Bar, BarChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recha
|
||||
|
||||
import { AsyncIcon } from "@/Components/Button/AsyncIcon";
|
||||
import Icon from "@/Components/Icons/Icon";
|
||||
import Tabs, { Tab } from "@/Components/Tabs/Tabs";
|
||||
import TabSelectors, { Tab } from "@/Components/TabSelectors/TabSelectors";
|
||||
import { orderAscending } from "@/Utils";
|
||||
import { Day } from "@/Utils/Const";
|
||||
import { formatShort } from "@/Utils/Number";
|
||||
@ -123,7 +123,11 @@ export default function NotificationSummary({ evs }: { evs: Array<TaggedNostrEve
|
||||
{filterIcon(NotificationSummaryFilter.Mentions, "at-sign", "text-mention")}
|
||||
</div>
|
||||
</div>
|
||||
<Tabs tabs={periodTabs} tab={unwrap(periodTabs.find(a => a.value === period))} setTab={t => setPeriod(t.value)} />
|
||||
<TabSelectors
|
||||
tabs={periodTabs}
|
||||
tab={unwrap(periodTabs.find(a => a.value === period))}
|
||||
setTab={t => setPeriod(t.value)}
|
||||
/>
|
||||
<div>
|
||||
<ResponsiveContainer height={200}>
|
||||
<BarChart data={Object.values(stats)} margin={{ left: 0, right: 0 }} style={{ userSelect: "none" }}>
|
||||
|
@ -1,29 +1,34 @@
|
||||
import "./ProfilePage.css";
|
||||
|
||||
import { fetchNip05Pubkey, LNURL } from "@snort/shared";
|
||||
import { CachedMetadata, EventKind, NostrPrefix, tryParseNostrLink } from "@snort/system";
|
||||
import { CachedMetadata, NostrPrefix, tryParseNostrLink } from "@snort/system";
|
||||
import { useUserProfile } from "@snort/system-react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useLocation, useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import Note from "@/Components/Event/EventComponent";
|
||||
import Timeline from "@/Components/Feed/Timeline";
|
||||
import { ProxyImg } from "@/Components/ProxyImg";
|
||||
import { SpotlightMediaModal } from "@/Components/Spotlight/SpotlightMedia";
|
||||
import { Tab, TabElement } from "@/Components/Tabs/Tabs";
|
||||
import { Tab, TabSelector } from "@/Components/TabSelectors/TabSelectors";
|
||||
import BlockList from "@/Components/User/BlockList";
|
||||
import FollowsList from "@/Components/User/FollowListBase";
|
||||
import MutedList from "@/Components/User/MutedList";
|
||||
import useFollowsFeed from "@/Feed/FollowsFeed";
|
||||
import useHorizontalScroll from "@/Hooks/useHorizontalScroll";
|
||||
import { useMuteList, usePinList } from "@/Hooks/useLists";
|
||||
import { useMuteList } from "@/Hooks/useLists";
|
||||
import useLogin from "@/Hooks/useLogin";
|
||||
import useModeration from "@/Hooks/useModeration";
|
||||
import AvatarSection from "@/Pages/Profile/AvatarSection";
|
||||
import ProfileDetails from "@/Pages/Profile/ProfileDetails";
|
||||
import ProfileTab from "@/Pages/Profile/ProfileTab";
|
||||
import { BookMarksTab, FollowersTab, FollowsTab, RelaysTab, ZapsProfileTab } from "@/Pages/Profile/ProfileTabs";
|
||||
import {
|
||||
BookMarksTab,
|
||||
FollowersTab,
|
||||
FollowsTab,
|
||||
RelaysTab,
|
||||
ZapsProfileTab,
|
||||
} from "@/Pages/Profile/ProfileTabComponents";
|
||||
import ProfileTabSelectors from "@/Pages/Profile/ProfileTabSelectors";
|
||||
import { ProfileTabType } from "@/Pages/Profile/ProfileTabType";
|
||||
import { NotesTab } from "@/Pages/Root/NotesTab";
|
||||
import { parseId, unwrap } from "@/Utils";
|
||||
import { EmailRegex } from "@/Utils/Const";
|
||||
|
||||
@ -58,15 +63,17 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
||||
|
||||
// feeds
|
||||
const { blocked } = useModeration();
|
||||
const pinned = usePinList(id);
|
||||
const muted = useMuteList(id);
|
||||
const follows = useFollowsFeed(id);
|
||||
|
||||
// tabs
|
||||
const [tab, setTab] = useState<Tab>(ProfileTab.Notes);
|
||||
const optionalTabs = [ProfileTab.Zaps, ProfileTab.Relays, ProfileTab.Bookmarks, ProfileTab.Muted].filter(a =>
|
||||
unwrap(a),
|
||||
) as Tab[];
|
||||
const [tab, setTab] = useState<Tab>(ProfileTabSelectors.Notes);
|
||||
const optionalTabs = [
|
||||
ProfileTabSelectors.Zaps,
|
||||
ProfileTabSelectors.Relays,
|
||||
ProfileTabSelectors.Bookmarks,
|
||||
ProfileTabSelectors.Muted,
|
||||
].filter(a => unwrap(a)) as Tab[];
|
||||
const horizontalScroll = useHorizontalScroll();
|
||||
|
||||
useEffect(() => {
|
||||
@ -98,7 +105,7 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
||||
}
|
||||
}
|
||||
}
|
||||
setTab(ProfileTab.Notes);
|
||||
setTab(ProfileTabSelectors.Notes);
|
||||
}, [id, propId, params]);
|
||||
|
||||
function tabContent() {
|
||||
@ -106,35 +113,7 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
||||
|
||||
switch (tab.value) {
|
||||
case ProfileTabType.NOTES:
|
||||
return (
|
||||
<>
|
||||
{pinned
|
||||
.filter(a => a.kind === EventKind.TextNote)
|
||||
.map(n => {
|
||||
return (
|
||||
<Note
|
||||
key={`pinned-${n.id}`}
|
||||
data={n}
|
||||
options={{ showTime: false, showPinned: true, canUnpin: isMe }}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Timeline
|
||||
key={id}
|
||||
subject={{
|
||||
type: "pubkey",
|
||||
items: [id],
|
||||
discriminator: id.slice(0, 12),
|
||||
relay: relays,
|
||||
}}
|
||||
postsOnly={false}
|
||||
method={"LIMIT_UNTIL"}
|
||||
loadMore={false}
|
||||
ignoreModeration={true}
|
||||
window={60 * 60 * 6}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
return <NotesTab id={id} relays={relays} isMe={isMe} />;
|
||||
case ProfileTabType.ZAPS: {
|
||||
return <ZapsProfileTab id={id} />;
|
||||
}
|
||||
@ -163,8 +142,8 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
||||
}
|
||||
}
|
||||
|
||||
function renderTab(v: Tab) {
|
||||
return <TabElement key={v.value} t={v} tab={tab} setTab={setTab} />;
|
||||
function renderTabSelector(v: Tab) {
|
||||
return <TabSelector key={v.value} t={v} tab={tab} setTab={setTab} />;
|
||||
}
|
||||
|
||||
const bannerWidth = Math.min(window.innerWidth, 940);
|
||||
@ -189,9 +168,11 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
||||
</div>
|
||||
<div className="main-content">
|
||||
<div className="tabs p" ref={horizontalScroll}>
|
||||
{[ProfileTab.Notes, ProfileTab.Followers, ProfileTab.Follows].map(renderTab)}
|
||||
{optionalTabs.map(renderTab)}
|
||||
{isMe && blocked.length > 0 && renderTab(ProfileTab.Blocked)}
|
||||
{[ProfileTabSelectors.Notes, ProfileTabSelectors.Followers, ProfileTabSelectors.Follows].map(
|
||||
renderTabSelector,
|
||||
)}
|
||||
{optionalTabs.map(renderTabSelector)}
|
||||
{isMe && blocked.length > 0 && renderTabSelector(ProfileTabSelectors.Blocked)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="main-content">{tabContent()}</div>
|
||||
|
@ -1,7 +1,10 @@
|
||||
import { HexKey, NostrLink, NostrPrefix } from "@snort/system";
|
||||
import { EventKind, HexKey, NostrLink, NostrPrefix } from "@snort/system";
|
||||
import { useMemo } from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import { Note } from "@/Components/Event/Note/Note";
|
||||
import Zap from "@/Components/Event/Zap";
|
||||
import Timeline from "@/Components/Feed/Timeline";
|
||||
import RelaysMetadata from "@/Components/Relay/RelaysMetadata";
|
||||
import Bookmarks from "@/Components/User/Bookmarks";
|
||||
import FollowsList from "@/Components/User/FollowListBase";
|
||||
@ -9,7 +12,7 @@ import useFollowersFeed from "@/Feed/FollowersFeed";
|
||||
import useFollowsFeed from "@/Feed/FollowsFeed";
|
||||
import useRelaysFeed from "@/Feed/RelaysFeed";
|
||||
import useZapsFeed from "@/Feed/ZapsFeed";
|
||||
import { useBookmarkList } from "@/Hooks/useLists";
|
||||
import { useBookmarkList, usePinList } from "@/Hooks/useLists";
|
||||
import messages from "@/Pages/messages";
|
||||
import { formatShort } from "@/Utils/Number";
|
||||
|
||||
@ -47,3 +50,31 @@ export function BookMarksTab({ id }: { id: HexKey }) {
|
||||
const bookmarks = useBookmarkList(id);
|
||||
return <Bookmarks pubkey={id} bookmarks={bookmarks} />;
|
||||
}
|
||||
|
||||
export function NotesTab({ id, relays, isMe }: { id: HexKey; relays?: Array<string>; isMe: boolean }) {
|
||||
const pinned = usePinList(id);
|
||||
const options = useMemo(() => ({ showTime: false, showPinned: true, canUnpin: isMe }), [isMe]);
|
||||
return (
|
||||
<>
|
||||
{pinned
|
||||
.filter(a => a.kind === EventKind.TextNote)
|
||||
.map(n => {
|
||||
return <Note key={`pinned-${n.id}`} data={n} options={options} />;
|
||||
})}
|
||||
<Timeline
|
||||
key={id}
|
||||
subject={{
|
||||
type: "pubkey",
|
||||
items: [id],
|
||||
discriminator: id.slice(0, 12),
|
||||
relay: relays,
|
||||
}}
|
||||
postsOnly={false}
|
||||
method={"LIMIT_UNTIL"}
|
||||
loadMore={false}
|
||||
ignoreModeration={true}
|
||||
window={60 * 60 * 6}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import Icon from "@/Components/Icons/Icon";
|
||||
import { Tab } from "@/Components/Tabs/Tabs";
|
||||
import { Tab } from "@/Components/TabSelectors/TabSelectors";
|
||||
import { ProfileTabType } from "@/Pages/Profile/ProfileTabType";
|
||||
|
||||
const ProfileTab = {
|
||||
const ProfileTabSelectors = {
|
||||
Notes: {
|
||||
text: (
|
||||
<>
|
||||
@ -88,4 +88,4 @@ const ProfileTab = {
|
||||
},
|
||||
} as { [key: string]: Tab };
|
||||
|
||||
export default ProfileTab;
|
||||
export default ProfileTabSelectors;
|
@ -3,7 +3,7 @@ import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
import Timeline from "@/Components/Feed/Timeline";
|
||||
import Tabs, { Tab } from "@/Components/Tabs/Tabs";
|
||||
import TabSelectors, { Tab } from "@/Components/TabSelectors/TabSelectors";
|
||||
import TrendingNotes from "@/Components/Trending/TrendingPosts";
|
||||
import TrendingUsers from "@/Components/Trending/TrendingUsers";
|
||||
import FollowListBase from "@/Components/User/FollowListBase";
|
||||
@ -107,7 +107,7 @@ const SearchPage = () => {
|
||||
value={search}
|
||||
onChange={e => setSearch(e.target.value)}
|
||||
/>
|
||||
<Tabs tabs={SearchTab} tab={tab} setTab={setTab} />
|
||||
<TabSelectors tabs={SearchTab} tab={tab} setTab={setTab} />
|
||||
</div>
|
||||
{tabContent()}
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user