chore: refactor tabs
This commit is contained in:
parent
0aff59b274
commit
032294456e
@ -12,6 +12,7 @@ export interface Tab {
|
|||||||
interface TabsProps {
|
interface TabsProps {
|
||||||
tabs: Tab[];
|
tabs: Tab[];
|
||||||
tab: Tab;
|
tab: Tab;
|
||||||
|
className?: string;
|
||||||
setTab: (t: Tab) => void;
|
setTab: (t: Tab) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ export const TabSelector = ({ t, tab, setTab }: TabElementProps) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"px-4 py-2 my-1 border border-border-color rounded-full cursor-pointer font-semibold bg-gray-dark",
|
"flex gap-2 items-center px-4 py-2 my-1 border border-border-color rounded-full cursor-pointer font-semibold bg-gray-dark",
|
||||||
"hover:drop-shadow-sm hover:bg-gray",
|
"hover:drop-shadow-sm hover:bg-gray",
|
||||||
{
|
{
|
||||||
"": tab.value === t.value,
|
"": tab.value === t.value,
|
||||||
@ -36,10 +37,10 @@ export const TabSelector = ({ t, tab, setTab }: TabElementProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const TabSelectors = ({ tabs, tab, setTab }: TabsProps) => {
|
const TabSelectors = ({ tabs, tab, className, setTab }: TabsProps) => {
|
||||||
const horizontalScroll = useHorizontalScroll();
|
const horizontalScroll = useHorizontalScroll();
|
||||||
return (
|
return (
|
||||||
<div className="flex gap-2 overflow-y-auto hide-scrollbar" ref={horizontalScroll}>
|
<div className={classNames(className, "flex gap-2 overflow-y-auto hide-scrollbar")} ref={horizontalScroll}>
|
||||||
{tabs.map((t, index) => (
|
{tabs.map((t, index) => (
|
||||||
<TabSelector key={index} tab={tab} setTab={setTab} t={t} />
|
<TabSelector key={index} tab={tab} setTab={setTab} t={t} />
|
||||||
))}
|
))}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { Tab, TabSelector } from "@/Components/TabSelectors/TabSelectors";
|
import TabSelectors, { Tab } from "@/Components/TabSelectors/TabSelectors";
|
||||||
import TrendingNotes from "@/Components/Trending/TrendingPosts";
|
import TrendingNotes from "@/Components/Trending/TrendingPosts";
|
||||||
import TrendingUsers from "@/Components/Trending/TrendingUsers";
|
import TrendingUsers from "@/Components/Trending/TrendingUsers";
|
||||||
|
|
||||||
@ -9,8 +9,8 @@ export default function Discover() {
|
|||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
// tabs
|
// tabs
|
||||||
const Tabs = {
|
const Tabs = {
|
||||||
Posts: { text: formatMessage({ defaultMessage: "Trending Notes", id: "Ix8l+B" }), value: 1 },
|
Posts: { text: formatMessage({ defaultMessage: "Trending Notes" }), value: 1 },
|
||||||
Profiles: { text: formatMessage({ defaultMessage: "Trending People", id: "CVWeJ6" }), value: 0 },
|
Profiles: { text: formatMessage({ defaultMessage: "Trending People" }), value: 0 },
|
||||||
};
|
};
|
||||||
const [tab, setTab] = useState<Tab>(Tabs.Profiles);
|
const [tab, setTab] = useState<Tab>(Tabs.Profiles);
|
||||||
|
|
||||||
@ -30,11 +30,7 @@ export default function Discover() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="tabs p">
|
<TabSelectors tabs={[Tabs.Profiles, Tabs.Posts]} tab={tab} setTab={setTab} />
|
||||||
{[Tabs.Profiles, Tabs.Posts].map(a => (
|
|
||||||
<TabSelector key={a.value} tab={tab} setTab={setTab} t={a} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
{renderTab()}
|
{renderTab()}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -8,11 +8,10 @@ import { useLocation, useNavigate, useParams } from "react-router-dom";
|
|||||||
|
|
||||||
import { ProxyImg } from "@/Components/ProxyImg";
|
import { ProxyImg } from "@/Components/ProxyImg";
|
||||||
import { SpotlightMediaModal } from "@/Components/Spotlight/SpotlightMedia";
|
import { SpotlightMediaModal } from "@/Components/Spotlight/SpotlightMedia";
|
||||||
import { Tab, TabSelector } from "@/Components/TabSelectors/TabSelectors";
|
import TabSelectors, { Tab } from "@/Components/TabSelectors/TabSelectors";
|
||||||
import FollowsList from "@/Components/User/FollowListBase";
|
import FollowsList from "@/Components/User/FollowListBase";
|
||||||
import MutedList from "@/Components/User/MutedList";
|
import MutedList from "@/Components/User/MutedList";
|
||||||
import useFollowsFeed from "@/Feed/FollowsFeed";
|
import useFollowsFeed from "@/Feed/FollowsFeed";
|
||||||
import useHorizontalScroll from "@/Hooks/useHorizontalScroll";
|
|
||||||
import useLogin from "@/Hooks/useLogin";
|
import useLogin from "@/Hooks/useLogin";
|
||||||
import AvatarSection from "@/Pages/Profile/AvatarSection";
|
import AvatarSection from "@/Pages/Profile/AvatarSection";
|
||||||
import ProfileDetails from "@/Pages/Profile/ProfileDetails";
|
import ProfileDetails from "@/Pages/Profile/ProfileDetails";
|
||||||
@ -67,7 +66,6 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
|||||||
const optionalTabs = [ProfileTabSelectors.Zaps, ProfileTabSelectors.Relays, ProfileTabSelectors.Bookmarks].filter(a =>
|
const optionalTabs = [ProfileTabSelectors.Zaps, ProfileTabSelectors.Relays, ProfileTabSelectors.Bookmarks].filter(a =>
|
||||||
unwrap(a),
|
unwrap(a),
|
||||||
) as Tab[];
|
) as Tab[];
|
||||||
const horizontalScroll = useHorizontalScroll();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@ -112,7 +110,7 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
|||||||
}
|
}
|
||||||
case ProfileTabType.FOLLOWS: {
|
case ProfileTabType.FOLLOWS: {
|
||||||
if (isMe) {
|
if (isMe) {
|
||||||
return <FollowsList pubkeys={follows ?? []} showFollowAll={!isMe} showAbout={false} className="p" />;
|
return <FollowsList pubkeys={follows ?? []} showFollowAll={!isMe} className="p" />;
|
||||||
} else {
|
} else {
|
||||||
return <FollowsTab id={id} />;
|
return <FollowsTab id={id} />;
|
||||||
}
|
}
|
||||||
@ -135,10 +133,6 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderTabSelector(v: Tab) {
|
|
||||||
return <TabSelector key={v.value} t={v} tab={tab} setTab={setTab} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bannerWidth = Math.min(window.innerWidth, 940);
|
const bannerWidth = Math.min(window.innerWidth, 940);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -167,16 +161,17 @@ export default function ProfilePage({ id: propId, state }: ProfilePageProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="main-content">
|
<div className="main-content">
|
||||||
<div className="tabs p" ref={horizontalScroll}>
|
<TabSelectors
|
||||||
{[
|
tabs={[
|
||||||
ProfileTabSelectors.Notes,
|
ProfileTabSelectors.Notes,
|
||||||
ProfileTabSelectors.Reactions,
|
ProfileTabSelectors.Reactions,
|
||||||
ProfileTabSelectors.Followers,
|
ProfileTabSelectors.Followers,
|
||||||
ProfileTabSelectors.Follows,
|
ProfileTabSelectors.Follows,
|
||||||
].map(renderTabSelector)}
|
].concat(isMe ? [...optionalTabs, ProfileTabSelectors.Muted] : optionalTabs)}
|
||||||
{optionalTabs.map(renderTabSelector)}
|
className="p"
|
||||||
{isMe && renderTabSelector(ProfileTabSelectors.Muted)}
|
tab={tab}
|
||||||
</div>
|
setTab={setTab}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="main-content">{tabContent()}</div>
|
<div className="main-content">{tabContent()}</div>
|
||||||
{modalImage && <SpotlightMediaModal onClose={() => setModalImage("")} media={[modalImage]} idx={0} />}
|
{modalImage && <SpotlightMediaModal onClose={() => setModalImage("")} media={[modalImage]} idx={0} />}
|
||||||
|
@ -18,7 +18,13 @@ export function Topics() {
|
|||||||
const active = topics.includes(name);
|
const active = topics.includes(name);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames("tab", { "!bg-white !text-black": active })}
|
className={classNames(
|
||||||
|
"flex gap-2 items-center px-4 py-2 my-1 border border-border-color rounded-full cursor-pointer font-semibold bg-gray-dark",
|
||||||
|
"hover:drop-shadow-sm hover:bg-gray",
|
||||||
|
{
|
||||||
|
"!bg-white !text-black": active,
|
||||||
|
},
|
||||||
|
)}
|
||||||
onClick={() => setTopics(s => (active ? s.filter(a => a !== name) : appendDedupe(s, [name])))}>
|
onClick={() => setTopics(s => (active ? s.filter(a => a !== name) : appendDedupe(s, [name])))}>
|
||||||
{text}
|
{text}
|
||||||
</div>
|
</div>
|
||||||
@ -30,7 +36,9 @@ export function Topics() {
|
|||||||
<h1>
|
<h1>
|
||||||
<FormattedMessage defaultMessage="Pick a few topics of interest" />
|
<FormattedMessage defaultMessage="Pick a few topics of interest" />
|
||||||
</h1>
|
</h1>
|
||||||
<div className="tabs flex-wrap justify-center">{Object.entries(FixedTopics).map(([k, v]) => tab(k, v.text))}</div>
|
<div className="flex gap-2 flex-wrap justify-center">
|
||||||
|
{Object.entries(FixedTopics).map(([k, v]) => tab(k, v.text))}
|
||||||
|
</div>
|
||||||
<AsyncButton
|
<AsyncButton
|
||||||
className="primary"
|
className="primary"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user