Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions __tests__/components/header/AppSidebar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jest.mock("@/components/app-wallets/AppWalletsContext");
expect(menuProps.menu).toEqual(
expect.arrayContaining([
expect.objectContaining({ label: "Profile", path: "/profile" }),
expect.objectContaining({ label: "Discovery", path: "/discover" }),
])
);
expect(networkChildren).toEqual(
Expand Down
2 changes: 1 addition & 1 deletion __tests__/components/navigation/BottomNavigation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ describe("BottomNavigation", () => {

const passedItems = navItemCalls.map((call) => call[0].item);
expect(passedItems.map((item: { name: string }) => item.name)).toEqual([
"Profile",
"Discovery",
"Waves",
"Messages",
"Home",
Expand Down
25 changes: 25 additions & 0 deletions app/discover/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ExploreWavesSection } from "@/components/home/explore-waves/ExploreWavesSection";
import { getAppMetadata } from "@/components/providers/metadata";
import type { Metadata } from "next";

export default function DiscoverPage() {
return (
<main className="tailwind-scope tw-min-h-screen tw-bg-black">
<ExploreWavesSection
title="Active discussions you are not yet following"
subtitle={null}
limit={20}
endpoint="waves-overview/hot"
viewAllHref={null}
excludeFollowed={true}
/>
</main>
);
}

export function generateMetadata(): Metadata {
return getAppMetadata({
title: "Discovery",
description: "Active discussions you are not yet following",
});
}
18 changes: 18 additions & 0 deletions components/common/icons/DiscoverIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const DiscoverIcon = ({
className,
}: {
readonly className?: string | undefined;
}) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 640 640"
className={className}
>
<path
fill="currentColor"
d="M528 320C528 205.1 434.9 112 320 112C205.1 112 112 205.1 112 320C112 434.9 205.1 528 320 528C434.9 528 528 434.9 528 320zM64 320C64 178.6 178.6 64 320 64C461.4 64 576 178.6 576 320C576 461.4 461.4 576 320 576C178.6 576 64 461.4 64 320zM370.7 389.1L226.4 444.6C207 452.1 187.9 433 195.4 413.6L250.9 269.3C254.2 260.8 260.8 254.2 269.3 250.9L413.6 195.4C433 187.9 452.1 207 444.6 226.4L389.1 370.7C385.8 379.2 379.2 385.8 370.7 389.1zM352 320C352 302.3 337.7 288 320 288C302.3 288 288 302.3 288 320C288 337.7 302.3 352 320 352C337.7 352 352 337.7 352 320z"
/>
</svg>
);

export default DiscoverIcon;
22 changes: 0 additions & 22 deletions components/common/icons/ProfileIcon.tsx

This file was deleted.

9 changes: 8 additions & 1 deletion components/header/AppSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@ import {
Transition,
TransitionChild,
} from "@headlessui/react";
import { DocumentTextIcon, WrenchIcon } from "@heroicons/react/24/outline";
import {
DocumentTextIcon,
UserIcon,
WrenchIcon,
} from "@heroicons/react/24/outline";
import { Fragment, useCallback, useEffect, useMemo } from "react";
import { useAppWallets } from "../app-wallets/AppWalletsContext";
import DiscoverIcon from "../common/icons/DiscoverIcon";
import UsersIcon from "../common/icons/UsersIcon";
import AppSidebarHeader from "./AppSidebarHeader";
import AppSidebarMenuItems from "./AppSidebarMenuItems";
import AppUserConnect from "./AppUserConnect";

const MENU = [
{ label: "Profile", path: "/profile", icon: UserIcon },
{ label: "Discovery", path: "/discover", icon: DiscoverIcon },
{
label: "Network",
icon: UsersIcon,
Expand Down
7 changes: 7 additions & 0 deletions components/header/header-search/HeaderSearchModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { useAppWallets } from "@/components/app-wallets/AppWalletsContext";
import BellIcon from "@/components/common/icons/BellIcon";
import ChatBubbleIcon from "@/components/common/icons/ChatBubbleIcon";
import DiscoverIcon from "@/components/common/icons/DiscoverIcon";
import HomeIcon from "@/components/common/icons/HomeIcon";
import WavesIcon from "@/components/common/icons/WavesIcon";
import { useCookieConsent } from "@/components/cookies/CookieConsentContext";
Expand Down Expand Up @@ -98,6 +99,12 @@ const PRIMARY_NAVIGATION_PAGES: SidebarPageEntry[] = [
section: "Main",
icon: ChatBubbleIcon,
},
{
name: "Discovery",
href: "/discover",
section: "Main",
icon: DiscoverIcon,
},
{
name: "Notifications",
href: "/notifications",
Expand Down
85 changes: 60 additions & 25 deletions components/home/explore-waves/ExploreWavesSection.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import { useAuth } from "@/components/auth/Auth";
import type { ApiWave } from "@/generated/models/ApiWave";
import { commonApiFetch } from "@/services/api/common-api";
import { ArrowRightIcon } from "@heroicons/react/24/outline";
Expand All @@ -8,25 +9,55 @@ import Link from "next/link";
import { ExploreWaveCard } from "./ExploreWaveCard";
import { ExploreWaveCardSkeleton } from "./ExploreWaveCardSkeleton";

const WAVES_LIMIT = 6;
const DEFAULT_WAVES_LIMIT = 6;

interface ExploreWavesSectionProps {
readonly title?: string | undefined;
readonly subtitle?: string | null | undefined;
readonly limit?: number | undefined;
readonly endpoint?: string | undefined;
readonly viewAllHref?: string | null | undefined;
readonly excludeFollowed?: boolean | undefined;
}

export function ExploreWavesSection({
title = "Tired of bot replies? Join the most interesting chats in crypto",
subtitle = "Most active waves",
limit = DEFAULT_WAVES_LIMIT,
endpoint = "waves-overview/hot",
viewAllHref = "/waves",
excludeFollowed = false,
}: ExploreWavesSectionProps) {
const { connectedProfile } = useAuth();
const userScope =
connectedProfile?.id ??
connectedProfile?.normalised_handle ??
connectedProfile?.handle ??
null;

export function ExploreWavesSection() {
const {
data: waves,
isLoading,
isError,
} = useQuery({
queryKey: ["explore-waves-homepage", WAVES_LIMIT],
} = useQuery<ApiWave[]>({
queryKey: [
"explore-waves",
endpoint,
limit,
excludeFollowed,
excludeFollowed ? userScope : null,
],
queryFn: async () => {
const data = await commonApiFetch<ApiWave[]>({
endpoint: "waves-overview/hot",
endpoint,
params: excludeFollowed ? { exclude_followed: "true" } : undefined,
});
return data.slice(0, WAVES_LIMIT);
return data.slice(0, limit);
},
staleTime: 5 * 60 * 1000, // 5 minutes
staleTime: excludeFollowed ? 0 : 5 * 60 * 1000,
...(excludeFollowed ? { gcTime: 0 } : {}),
});

// Hide section on error or if no waves
if (isError) {
return null;
}
Expand All @@ -41,17 +72,19 @@ export function ExploreWavesSection() {
<div className="tw-mb-8 tw-flex tw-flex-col tw-items-start tw-gap-4 md:tw-items-end">
<div className="tw-max-w-sm md:tw-mx-auto md:tw-max-w-xl md:tw-text-center lg:tw-max-w-full">
<span className="tw-m-0 tw-text-xl tw-font-semibold tw-tracking-tight tw-text-iron-200 md:tw-text-2xl">
Tired of bot replies? Join the most interesting chats in crypto
{title}
</span>
<p className="tw-mb-0 tw-mt-2 tw-text-base tw-text-iron-500">
Most active waves
</p>
{subtitle && (
<p className="tw-mb-0 tw-mt-2 tw-text-base tw-text-iron-500">
{subtitle}
</p>
)}
</div>
</div>

<div className="tw-grid tw-grid-cols-1 tw-gap-x-3 tw-gap-y-4 sm:tw-grid-cols-2 sm:tw-gap-5 lg:tw-grid-cols-3">
{isLoading
? Array.from({ length: WAVES_LIMIT }).map((_, index) => (
? Array.from({ length: limit }).map((_, index) => (
<div key={`skeleton-${index}`} className="tw-w-full">
<ExploreWaveCardSkeleton />
</div>
Expand All @@ -63,18 +96,20 @@ export function ExploreWavesSection() {
))}
</div>

<div className="tw-mt-8 tw-flex tw-justify-center md:tw-mt-10">
<Link
href="/waves"
className="tw-inline-flex tw-items-center tw-gap-1.5 tw-text-sm tw-font-medium tw-text-iron-400 tw-no-underline tw-transition-colors hover:tw-text-white"
>
<span>View all</span>
<ArrowRightIcon
className="tw-size-4 tw-flex-shrink-0"
aria-hidden
/>
</Link>
</div>
{viewAllHref && (
<div className="tw-mt-8 tw-flex tw-justify-center md:tw-mt-10">
<Link
href={viewAllHref}
className="tw-inline-flex tw-items-center tw-gap-1.5 tw-text-sm tw-font-medium tw-text-iron-400 tw-no-underline tw-transition-colors hover:tw-text-white"
>
<span>View all</span>
<ArrowRightIcon
className="tw-size-4 tw-flex-shrink-0"
aria-hidden
/>
</Link>
</div>
)}
</div>
</section>
);
Expand Down
11 changes: 11 additions & 0 deletions components/layout/sidebar/WebSidebarNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { useAppWallets } from "@/components/app-wallets/AppWalletsContext";
import { useAuth } from "@/components/auth/Auth";
import ChatBubbleIcon from "@/components/common/icons/ChatBubbleIcon";
import DiscoverIcon from "@/components/common/icons/DiscoverIcon";
import HomeIcon from "@/components/common/icons/HomeIcon";
import WavesIcon from "@/components/common/icons/WavesIcon";
import { useCookieConsent } from "@/components/cookies/CookieConsentContext";
Expand Down Expand Up @@ -240,6 +241,16 @@ const WebSidebarNav = React.forwardRef<
/>
</li>

<li>
<WebSidebarNavItem
href="/discover"
icon={DiscoverIcon}
active={pathname.startsWith("/discover")}
collapsed={isCollapsed}
label="Discovery"
/>
</li>
Comment thread
GelatoGenesis marked this conversation as resolved.

{networkSection && (
<li className={isCollapsed ? "tw-relative" : undefined}>
<WebSidebarExpandable
Expand Down
10 changes: 5 additions & 5 deletions components/navigation/BottomNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import React, { useCallback, useMemo, useRef } from "react";
import { useLayout } from "../brain/my-stream/layout/LayoutContext";
import BellIcon from "../common/icons/BellIcon";
import ChatBubbleIcon from "../common/icons/ChatBubbleIcon";
import DiscoverIcon from "../common/icons/DiscoverIcon";
import LogoIcon from "../common/icons/LogoIcon";
import CollectionsMenuIcon from "../common/icons/CollectionsMenuIcon";
import ProfileIcon from "../common/icons/ProfileIcon";
import UsersIcon from "../common/icons/UsersIcon";
import WavesIcon from "../common/icons/WavesIcon";
import NavItem from "./NavItem";
Expand All @@ -17,10 +17,10 @@ import type { NavItem as NavItemData } from "./navTypes";
const items: NavItemData[] = [
{
kind: "route",
name: "Profile",
href: "/profile",
icon: "profile",
iconComponent: ProfileIcon,
name: "Discovery",
href: "/discover",
icon: "discover",
iconComponent: DiscoverIcon,
},
{
kind: "view",
Expand Down
Loading