From 2d580510d28e82da3fd41643c03ab0d88114b7ec Mon Sep 17 00:00:00 2001 From: Q Date: Sun, 27 Aug 2023 02:23:30 +0330 Subject: [PATCH 01/13] feat: lens integration --- .../lens-protocol/explore/page.tsx | 13 + .../integration/lens-protocol/layout.tsx | 77 +++ .../lens-protocol/opengraph-image.tsx | 9 + .../integration/lens-protocol/page.tsx | 5 + .../lens-protocol/profiles/[handle]/page.tsx | 7 + .../profiles/address/[address]/page.tsx | 7 + .../lens-protocol/profiles/page.tsx | 6 + .../lens-protocol/publications/[id]/page.tsx | 9 + .../integration/lens-protocol/search/page.tsx | 17 + .../lens-protocol/twitter-image.tsx | 9 + components/shared/example-demos.tsx | 16 + data/turbo-integrations.ts | 8 + .../components/auth/is-user-authenticated.tsx | 12 + .../components/auth/login-button.tsx | 39 ++ .../components/auth/logout-button.tsx | 11 + .../components/auth/not-authenticated-yet.tsx | 9 + .../lens-protocol/components/feed.tsx | 39 ++ .../lens-protocol/components/navbar.tsx | 96 +++ .../components/profile/address-profiles.tsx | 44 ++ .../components/profile/explore-profiles.tsx | 45 ++ .../profile/follow-unfollow-button.tsx | 79 +++ .../components/profile/owned-profiles.tsx | 91 +++ .../components/profile/profile-card.tsx | 41 ++ .../components/profile/profile-list-modal.tsx | 72 +++ .../components/profile/profile-revenue.tsx | 25 + .../components/profile/profile-stats.tsx | 57 ++ .../components/profile/profile.tsx | 74 +++ .../components/profile/search-profiles.tsx | 31 + .../publications/actions/button.tsx | 39 ++ .../publications/actions/comment.tsx | 30 + .../components/publications/actions/index.tsx | 6 + .../components/publications/actions/like.tsx | 85 +++ .../publications/actions/mirror.tsx | 65 +++ .../components/publications/commnets.tsx | 40 ++ .../publications/explore-publications.tsx | 28 + .../publication-actions-and-stats.tsx | 19 + .../publications/publication-card.tsx | 133 +++++ .../publications/publication-revenue.tsx | 21 + .../components/publications/publication.tsx | 68 +++ .../publications/search-publications.tsx | 26 + .../components/publications/stats/index.tsx | 54 ++ .../components/publications/stats/stat.tsx | 33 ++ .../lens-protocol/components/spinner.tsx | 20 + integrations/lens-protocol/lens-provider.ts | 7 + integrations/lens-protocol/utils/index.ts | 12 + package.json | 2 + pnpm-lock.yaml | 551 +++++++++++++++++- public/integrations/lensprotocol-dark.svg | 3 + public/integrations/lensprotocol-light.svg | 3 + 49 files changed, 2183 insertions(+), 10 deletions(-) create mode 100644 app/(general)/integration/lens-protocol/explore/page.tsx create mode 100644 app/(general)/integration/lens-protocol/layout.tsx create mode 100644 app/(general)/integration/lens-protocol/opengraph-image.tsx create mode 100644 app/(general)/integration/lens-protocol/page.tsx create mode 100644 app/(general)/integration/lens-protocol/profiles/[handle]/page.tsx create mode 100644 app/(general)/integration/lens-protocol/profiles/address/[address]/page.tsx create mode 100644 app/(general)/integration/lens-protocol/profiles/page.tsx create mode 100644 app/(general)/integration/lens-protocol/publications/[id]/page.tsx create mode 100644 app/(general)/integration/lens-protocol/search/page.tsx create mode 100644 app/(general)/integration/lens-protocol/twitter-image.tsx create mode 100644 integrations/lens-protocol/components/auth/is-user-authenticated.tsx create mode 100644 integrations/lens-protocol/components/auth/login-button.tsx create mode 100644 integrations/lens-protocol/components/auth/logout-button.tsx create mode 100644 integrations/lens-protocol/components/auth/not-authenticated-yet.tsx create mode 100644 integrations/lens-protocol/components/feed.tsx create mode 100644 integrations/lens-protocol/components/navbar.tsx create mode 100644 integrations/lens-protocol/components/profile/address-profiles.tsx create mode 100644 integrations/lens-protocol/components/profile/explore-profiles.tsx create mode 100644 integrations/lens-protocol/components/profile/follow-unfollow-button.tsx create mode 100644 integrations/lens-protocol/components/profile/owned-profiles.tsx create mode 100644 integrations/lens-protocol/components/profile/profile-card.tsx create mode 100644 integrations/lens-protocol/components/profile/profile-list-modal.tsx create mode 100644 integrations/lens-protocol/components/profile/profile-revenue.tsx create mode 100644 integrations/lens-protocol/components/profile/profile-stats.tsx create mode 100644 integrations/lens-protocol/components/profile/profile.tsx create mode 100644 integrations/lens-protocol/components/profile/search-profiles.tsx create mode 100644 integrations/lens-protocol/components/publications/actions/button.tsx create mode 100644 integrations/lens-protocol/components/publications/actions/comment.tsx create mode 100644 integrations/lens-protocol/components/publications/actions/index.tsx create mode 100644 integrations/lens-protocol/components/publications/actions/like.tsx create mode 100644 integrations/lens-protocol/components/publications/actions/mirror.tsx create mode 100644 integrations/lens-protocol/components/publications/commnets.tsx create mode 100644 integrations/lens-protocol/components/publications/explore-publications.tsx create mode 100644 integrations/lens-protocol/components/publications/publication-actions-and-stats.tsx create mode 100644 integrations/lens-protocol/components/publications/publication-card.tsx create mode 100644 integrations/lens-protocol/components/publications/publication-revenue.tsx create mode 100644 integrations/lens-protocol/components/publications/publication.tsx create mode 100644 integrations/lens-protocol/components/publications/search-publications.tsx create mode 100644 integrations/lens-protocol/components/publications/stats/index.tsx create mode 100644 integrations/lens-protocol/components/publications/stats/stat.tsx create mode 100644 integrations/lens-protocol/components/spinner.tsx create mode 100644 integrations/lens-protocol/lens-provider.ts create mode 100644 integrations/lens-protocol/utils/index.ts create mode 100644 public/integrations/lensprotocol-dark.svg create mode 100644 public/integrations/lensprotocol-light.svg diff --git a/app/(general)/integration/lens-protocol/explore/page.tsx b/app/(general)/integration/lens-protocol/explore/page.tsx new file mode 100644 index 00000000..f4371ea0 --- /dev/null +++ b/app/(general)/integration/lens-protocol/explore/page.tsx @@ -0,0 +1,13 @@ +'use client' + +import { ExploreProfiles } from '@/integrations/lens-protocol/components/profile/explore-profiles' +import { ExplorePublications } from '@/integrations/lens-protocol/components/publications/explore-publications' + +export default function PageIntegration() { + return ( + <> + + + + ) +} diff --git a/app/(general)/integration/lens-protocol/layout.tsx b/app/(general)/integration/lens-protocol/layout.tsx new file mode 100644 index 00000000..5db57620 --- /dev/null +++ b/app/(general)/integration/lens-protocol/layout.tsx @@ -0,0 +1,77 @@ +'use client' +import { ReactNode } from 'react' + +import { LensProvider } from '@lens-protocol/react-web' +import { motion } from 'framer-motion' +import Image from 'next/image' +import Balancer from 'react-wrap-balancer' + +import { WalletConnect } from '@/components/blockchain/wallet-connect' +import { IsDarkTheme } from '@/components/shared/is-dark-theme' +import { IsLightTheme } from '@/components/shared/is-light-theme' +import { IsWalletConnected } from '@/components/shared/is-wallet-connected' +import { IsWalletDisconnected } from '@/components/shared/is-wallet-disconnected' +import { LinkComponent } from '@/components/shared/link-component' +import { FADE_DOWN_ANIMATION_VARIANTS } from '@/config/design' +import { turboIntegrations } from '@/data/turbo-integrations' +import { Navbar } from '@/integrations/lens-protocol/components/navbar' +import { lensProviderConfig } from '@/integrations/lens-protocol/lens-provider' + +export default function LayoutIntegration({ children }: { children: ReactNode }) { + return ( + <> +
+ + + Lens Protocol logo + + + Lens Protocol logo + + + Lens Protocol + + + {turboIntegrations.lensProtocol.description} + + + + + + + + +
+ + + +
+
+
+ + +
+ +
{children}
+
+
+
+
+ + ) +} diff --git a/app/(general)/integration/lens-protocol/opengraph-image.tsx b/app/(general)/integration/lens-protocol/opengraph-image.tsx new file mode 100644 index 00000000..f4050388 --- /dev/null +++ b/app/(general)/integration/lens-protocol/opengraph-image.tsx @@ -0,0 +1,9 @@ +import { IntegrationOgImage } from '@/components/ui/social/og-image-integrations' + +export const runtime = 'edge' +export const size = { + width: 1200, + height: 630, +} + +export default IntegrationOgImage('lensProtocol') diff --git a/app/(general)/integration/lens-protocol/page.tsx b/app/(general)/integration/lens-protocol/page.tsx new file mode 100644 index 00000000..c2e9c4ff --- /dev/null +++ b/app/(general)/integration/lens-protocol/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from 'next/navigation' + +export default function PageIntegration() { + redirect('/integration/lens-protocol/profiles') +} diff --git a/app/(general)/integration/lens-protocol/profiles/[handle]/page.tsx b/app/(general)/integration/lens-protocol/profiles/[handle]/page.tsx new file mode 100644 index 00000000..bce4bd6d --- /dev/null +++ b/app/(general)/integration/lens-protocol/profiles/[handle]/page.tsx @@ -0,0 +1,7 @@ +'use client' + +import { Profile } from '@/integrations/lens-protocol/components/profile/profile' + +export default function PageIntegration({ params }: { params: { handle: string } }) { + return +} diff --git a/app/(general)/integration/lens-protocol/profiles/address/[address]/page.tsx b/app/(general)/integration/lens-protocol/profiles/address/[address]/page.tsx new file mode 100644 index 00000000..032f5562 --- /dev/null +++ b/app/(general)/integration/lens-protocol/profiles/address/[address]/page.tsx @@ -0,0 +1,7 @@ +'use client' + +import { AddressProfiles } from '@/integrations/lens-protocol/components/profile/address-profiles' + +export default function PageIntegration({ params }: { params: { address: string } }) { + return +} diff --git a/app/(general)/integration/lens-protocol/profiles/page.tsx b/app/(general)/integration/lens-protocol/profiles/page.tsx new file mode 100644 index 00000000..c09ef001 --- /dev/null +++ b/app/(general)/integration/lens-protocol/profiles/page.tsx @@ -0,0 +1,6 @@ +'use client' +import { OwnedProfiles } from '@/integrations/lens-protocol/components/profile/owned-profiles' + +export default function PageIntegration() { + return +} diff --git a/app/(general)/integration/lens-protocol/publications/[id]/page.tsx b/app/(general)/integration/lens-protocol/publications/[id]/page.tsx new file mode 100644 index 00000000..570ca96f --- /dev/null +++ b/app/(general)/integration/lens-protocol/publications/[id]/page.tsx @@ -0,0 +1,9 @@ +'use client' + +import { PublicationId } from '@lens-protocol/react-web' + +import { Publication } from '@/integrations/lens-protocol/components/publications/publication' + +export default function PageIntegration({ params }: { params: { id: string } }) { + return +} diff --git a/app/(general)/integration/lens-protocol/search/page.tsx b/app/(general)/integration/lens-protocol/search/page.tsx new file mode 100644 index 00000000..8947d6c7 --- /dev/null +++ b/app/(general)/integration/lens-protocol/search/page.tsx @@ -0,0 +1,17 @@ +'use client' + +import { useSearchParams } from 'next/navigation' + +import { SearchProfiles } from '@/integrations/lens-protocol/components/profile/search-profiles' +import { SearchPublications } from '@/integrations/lens-protocol/components/publications/search-publications' + +export default function PageIntegration() { + const searchParams = useSearchParams() + const query = searchParams.get('q') ?? '' + return ( + <> + + + + ) +} diff --git a/app/(general)/integration/lens-protocol/twitter-image.tsx b/app/(general)/integration/lens-protocol/twitter-image.tsx new file mode 100644 index 00000000..dbca541e --- /dev/null +++ b/app/(general)/integration/lens-protocol/twitter-image.tsx @@ -0,0 +1,9 @@ +import Image from './opengraph-image' + +export const runtime = 'edge' +export const size = { + width: 1200, + height: 630, +} + +export default Image diff --git a/components/shared/example-demos.tsx b/components/shared/example-demos.tsx index 7991bf2f..8e4d2326 100644 --- a/components/shared/example-demos.tsx +++ b/components/shared/example-demos.tsx @@ -472,6 +472,22 @@ const demos = [ ), }, + { + title: turboIntegrations.lensProtocol.name, + description: turboIntegrations.lensProtocol.description, + href: turboIntegrations.lensProtocol.href, + demo: ( +
+ +
+ ), + }, { title: turboIntegrations.starter.name, description: turboIntegrations.starter.description, diff --git a/data/turbo-integrations.ts b/data/turbo-integrations.ts index 999b11c3..bb9ae54d 100644 --- a/data/turbo-integrations.ts +++ b/data/turbo-integrations.ts @@ -148,6 +148,14 @@ export const turboIntegrations = { imgLight: "/integrations/arweave-light.png", imgDark: "/integrations/arweave-dark.png", }, + lensProtocol: { + name: 'Lens Protocol', + href: '/integration/lens-protocol', + url: 'https://www.lens.xyz/', + description: 'Lens Protocol is the social layer for Web3', + imgLight: '/integrations/lensprotocol-light.svg', + imgDark: '/integrations/lensprotocol-dark.svg', + }, starter: { name: "Starter Template", href: "/integration/starter", diff --git a/integrations/lens-protocol/components/auth/is-user-authenticated.tsx b/integrations/lens-protocol/components/auth/is-user-authenticated.tsx new file mode 100644 index 00000000..84308916 --- /dev/null +++ b/integrations/lens-protocol/components/auth/is-user-authenticated.tsx @@ -0,0 +1,12 @@ +import { ReactNode } from 'react' + +import { useActiveWallet } from '@lens-protocol/react-web' + +import { Spinner } from '../spinner' + +export const IsUserAuthenticated = ({ children, showLoading }: { children: ReactNode; showLoading?: boolean }) => { + const { data: wallet, loading } = useActiveWallet() + if (loading && showLoading) return + if (wallet && children) return <>{children} + return null +} diff --git a/integrations/lens-protocol/components/auth/login-button.tsx b/integrations/lens-protocol/components/auth/login-button.tsx new file mode 100644 index 00000000..a8cb628f --- /dev/null +++ b/integrations/lens-protocol/components/auth/login-button.tsx @@ -0,0 +1,39 @@ +import { useEffect } from 'react' + +import { useWalletLogin } from '@lens-protocol/react-web' +import { useAccount } from 'wagmi' + +import { useToast } from '@/lib/hooks/use-toast' + +export const LoginButton = () => { + const { execute: login, error: loginError, isPending } = useWalletLogin() + const { address } = useAccount() + const { toast, dismiss } = useToast() + + useEffect(() => { + if (loginError) showErrorToast(String(loginError)) + }, [loginError]) + + const showErrorToast = (loginError: string) => { + toast({ + title: 'Login failed', + description: loginError, + }) + + setTimeout(() => { + dismiss() + }, 10000) + } + + const onLoginClick = async () => { + if (!address) return null + await login({ + address, + }) + } + return ( + + ) +} diff --git a/integrations/lens-protocol/components/auth/logout-button.tsx b/integrations/lens-protocol/components/auth/logout-button.tsx new file mode 100644 index 00000000..d777b042 --- /dev/null +++ b/integrations/lens-protocol/components/auth/logout-button.tsx @@ -0,0 +1,11 @@ +import { useWalletLogout } from '@lens-protocol/react-web' + +export const LogoutButton = () => { + const { execute: logout, isPending } = useWalletLogout() + + return ( + + ) +} diff --git a/integrations/lens-protocol/components/auth/not-authenticated-yet.tsx b/integrations/lens-protocol/components/auth/not-authenticated-yet.tsx new file mode 100644 index 00000000..0eeb2d8a --- /dev/null +++ b/integrations/lens-protocol/components/auth/not-authenticated-yet.tsx @@ -0,0 +1,9 @@ +import { ReactNode } from 'react' + +import { useActiveWallet } from '@lens-protocol/react-web' + +export const NotAuthenticatedYet = ({ children }: { children: ReactNode }) => { + const { data: wallet } = useActiveWallet() + if (!wallet) return <>{children} + return null +} diff --git a/integrations/lens-protocol/components/feed.tsx b/integrations/lens-protocol/components/feed.tsx new file mode 100644 index 00000000..1755b39a --- /dev/null +++ b/integrations/lens-protocol/components/feed.tsx @@ -0,0 +1,39 @@ +import { ProfileId, useActiveProfile, useFeed } from '@lens-protocol/react-web' + +import { PublicationCard, PublicationCardMode } from './publications/publication-card' +import { Spinner } from './spinner' + +export const Feed = ({ profileId }: { profileId: ProfileId }) => { + const activeProfile = useActiveProfile() + const { data, loading, hasMore, next } = useFeed({ + observerId: activeProfile?.data?.id ?? undefined, + profileId, + limit: 10, + }) + console.error(data) + if (loading) return + return ( +
+

Feed

+ {data?.map((feedItem) => ( + + ))} + {hasMore && ( + + )} + {loading && ( +
+ +
+ )} + {!data?.length && User feed is empty.} +
+ ) +} diff --git a/integrations/lens-protocol/components/navbar.tsx b/integrations/lens-protocol/components/navbar.tsx new file mode 100644 index 00000000..a55610c1 --- /dev/null +++ b/integrations/lens-protocol/components/navbar.tsx @@ -0,0 +1,96 @@ +import { useCallback, useState } from 'react' + +import { useActiveProfile } from '@lens-protocol/react-web' +import { useRouter } from 'next/navigation' + +import { LinkComponent } from '@/components/shared/link-component' +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' + +import { getProfilePictureSrc } from '../utils' +import { IsUserAuthenticated } from './auth/is-user-authenticated' +import { LoginButton } from './auth/login-button' +import { LogoutButton } from './auth/logout-button' +import { NotAuthenticatedYet } from './auth/not-authenticated-yet' + +export const Navbar = () => { + const [searchQuery, setSearchQuery] = useState('') + const router = useRouter() + const search = useCallback(() => { + router.push(`/integration/lens-protocol/search?q=${searchQuery}`) + }, [searchQuery]) + const { data: activeProfile } = useActiveProfile() + return ( + + ) +} diff --git a/integrations/lens-protocol/components/profile/address-profiles.tsx b/integrations/lens-protocol/components/profile/address-profiles.tsx new file mode 100644 index 00000000..725fe731 --- /dev/null +++ b/integrations/lens-protocol/components/profile/address-profiles.tsx @@ -0,0 +1,44 @@ +import { useActiveProfile, useProfilesOwnedBy } from '@lens-protocol/react-web' + +import { Spinner } from '../spinner' +import { ProfileCard } from './profile-card' + +export const AddressProfiles = ({ address }: { address: string }) => { + const { data: activeProfile } = useActiveProfile() + const { + data: profiles, + loading, + hasMore, + next, + } = useProfilesOwnedBy({ + limit: 10, + address, + observerId: activeProfile?.id, + }) + return ( +
+

+ {address}Profiles +

+
+ {profiles?.map((profile) => { + return ( +
+ +
+ ) + })} +
+ {hasMore && ( + + )} + {loading && ( +
+ +
+ )} +
+ ) +} diff --git a/integrations/lens-protocol/components/profile/explore-profiles.tsx b/integrations/lens-protocol/components/profile/explore-profiles.tsx new file mode 100644 index 00000000..705f3af5 --- /dev/null +++ b/integrations/lens-protocol/components/profile/explore-profiles.tsx @@ -0,0 +1,45 @@ +import { useActiveProfile, useExploreProfiles } from '@lens-protocol/react-web' +import { useRouter } from 'next/navigation' + +import { Spinner } from '../spinner' +import { ProfileCard } from './profile-card' + +export const ExploreProfiles = () => { + const profile = useActiveProfile() + const { + data: profiles, + loading, + hasMore, + next, + } = useExploreProfiles({ + limit: 10, + observerId: profile?.data?.id ?? undefined, + }) + const router = useRouter() + return ( + <> +
+

Profiles

+
+ {profiles?.map((profile) => ( + router.push(`/integration/lens-protocol/profiles/${profile.handle}`)} + /> + ))} +
+ {hasMore && ( + + )} + {loading && ( +
+ +
+ )} +
+ + ) +} diff --git a/integrations/lens-protocol/components/profile/follow-unfollow-button.tsx b/integrations/lens-protocol/components/profile/follow-unfollow-button.tsx new file mode 100644 index 00000000..d9420d1c --- /dev/null +++ b/integrations/lens-protocol/components/profile/follow-unfollow-button.tsx @@ -0,0 +1,79 @@ +import { useEffect } from 'react' + +import { FollowPolicyType, Profile, ProfileOwnedByMe, useActiveProfile, useFollow, useUnfollow } from '@lens-protocol/react-web' + +import { useToast } from '@/lib/hooks/use-toast' + +const UnauthorizedFollowButton = () => { + const { toast, dismiss } = useToast() + const showErrorToast = () => { + toast({ + title: 'You need to login first.', + }) + + setTimeout(() => { + dismiss() + }, 10000) + } + return ( + + ) +} + +const AuthorizedFollowUnfollowButton = ({ profile, activeProfile }: { profile: Profile; activeProfile: ProfileOwnedByMe }) => { + const { execute: follow, error, isPending: followLoading } = useFollow({ follower: activeProfile, followee: profile }) + const { execute: unfollow, isPending: unfollowLoading } = useUnfollow({ follower: activeProfile, followee: profile }) + const { toast, dismiss } = useToast() + + useEffect(() => { + if (error) showErrorToast(String(error)) + }, [error]) + + const showErrorToast = (error: string) => { + toast({ + title: 'Operation failed', + description: error, + }) + + setTimeout(() => { + dismiss() + }, 10000) + } + if (profile.isFollowedByMe) + return ( + + ) + return ( + + ) +} + +export const FollowUnfollowButton = ({ profile }: { profile: Profile }) => { + const { data: activeProfile } = useActiveProfile() + if (!activeProfile) return + if (profile.ownedByMe) return null + return +} diff --git a/integrations/lens-protocol/components/profile/owned-profiles.tsx b/integrations/lens-protocol/components/profile/owned-profiles.tsx new file mode 100644 index 00000000..8863a7f0 --- /dev/null +++ b/integrations/lens-protocol/components/profile/owned-profiles.tsx @@ -0,0 +1,91 @@ +import { useActiveProfile, useActiveProfileSwitch, useProfilesOwnedByMe } from '@lens-protocol/react-web' +import Image from 'next/image' + +import { IsDarkTheme } from '@/components/shared/is-dark-theme' +import { IsLightTheme } from '@/components/shared/is-light-theme' +import { LinkComponent } from '@/components/shared/link-component' +import { Avatar, AvatarFallback } from '@/components/ui/avatar' +import { turboIntegrations } from '@/data/turbo-integrations' + +import { IsUserAuthenticated } from '../auth/is-user-authenticated' +import { LoginButton } from '../auth/login-button' +import { NotAuthenticatedYet } from '../auth/not-authenticated-yet' +import { Spinner } from '../spinner' +import { ProfileCard } from './profile-card' + +export const OwnedProfiles = () => { + const { + data: profiles, + loading, + hasMore, + next, + } = useProfilesOwnedByMe({ + limit: 10, + }) + const { data: activeProfile } = useActiveProfile() + const { execute: switchActiveProfile, isPending } = useActiveProfileSwitch() + return ( +
+

Owned Profiles

+ +
+ {profiles?.map((profile) => { + const isProfileSelected = profile.id === activeProfile?.id + return ( +
+ + + + View + +
+ } + /> +
+ ) + })} + + + + + + Create a new profile on testnet + + + + Lens Protocol logo + + + Lens Protocol logo + + Claim a new handle on Lens + Comming soon... + +
+ {hasMore && ( + + )} + {loading && ( +
+ +
+ )} + + +
+
You need to login first to be able to see your profiles.
+ +
+
+ + ) +} diff --git a/integrations/lens-protocol/components/profile/profile-card.tsx b/integrations/lens-protocol/components/profile/profile-card.tsx new file mode 100644 index 00000000..0937bcbf --- /dev/null +++ b/integrations/lens-protocol/components/profile/profile-card.tsx @@ -0,0 +1,41 @@ +import { ReactNode } from 'react' + +import { Profile } from '@lens-protocol/react-web' +import { useRouter } from 'next/navigation' + +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' + +import { getProfilePictureSrc } from '../../utils' +import { FollowUnfollowButton } from './follow-unfollow-button' + +export const ProfileCard = ({ profile, onClick, cta }: { profile: Profile; onClick?: () => void; cta?: ReactNode }) => { + const router = useRouter() + return ( +
{ + e.stopPropagation() + if (onClick) onClick() + else router.push(`/integration/lens-protocol/profiles/${profile.handle}`) + }}> + + + {profile.handle.substring(0, 1)} + + @{profile.handle} + {profile.name ?? profile.handle} +
+ + {profile.stats.totalFollowers} + Followers + + + {profile.stats.totalFollowing} + Followings + +
+ + {cta && cta} +
+ ) +} diff --git a/integrations/lens-protocol/components/profile/profile-list-modal.tsx b/integrations/lens-protocol/components/profile/profile-list-modal.tsx new file mode 100644 index 00000000..d5f2cce9 --- /dev/null +++ b/integrations/lens-protocol/components/profile/profile-list-modal.tsx @@ -0,0 +1,72 @@ +import { ReactNode } from 'react' + +import { Profile } from '@lens-protocol/react-web' +import { useRouter } from 'next/navigation' + +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' +import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '@/components/ui/dialog' + +import { getProfilePictureSrc } from '../../utils' +import { Spinner } from '../spinner' +import { FollowUnfollowButton } from './follow-unfollow-button' + +export const ProfileListModal = ({ + profiles, + trigger, + hasMore, + loading, + title, + next, +}: { + profiles: Profile[] + trigger: ReactNode + hasMore: boolean + loading: boolean + title: string + next: () => void +}) => { + const router = useRouter() + return ( + + {trigger} + + +

{title}

+
+
+ {profiles?.map((profile) => ( +
+
{ + e.stopPropagation() + router.push(`/integration/lens-protocol/profiles/${profile.handle}`) + }}> + + + {profile.handle.substring(0, 1)} + +
+ {profile.name ?? profile.handle} + @{profile.handle} +
+
+ +
+ ))} + {hasMore && ( + + )} + {loading && ( +
+ +
+ )} + {profiles.length === 0 && This list is empty.} +
+
+
+ ) +} diff --git a/integrations/lens-protocol/components/profile/profile-revenue.tsx b/integrations/lens-protocol/components/profile/profile-revenue.tsx new file mode 100644 index 00000000..6f3ea7df --- /dev/null +++ b/integrations/lens-protocol/components/profile/profile-revenue.tsx @@ -0,0 +1,25 @@ +import { ProfileId, useProfileFollowRevenue } from '@lens-protocol/react-web' + +import { Spinner } from '../spinner' + +export const ProfileRevenue = ({ profileId }: { profileId: ProfileId }) => { + const { data, loading: revenueLoading } = useProfileFollowRevenue({ + profileId, + }) + if (revenueLoading) return + return ( +
+

Profile Revenue

+ {data?.map((revenue) => { + const { asset } = revenue.totalAmount + return ( +
+ {revenue.totalAmount.toNumber()} + {asset.symbol} +
+ ) + })} + {!data?.length && None yet} +
+ ) +} diff --git a/integrations/lens-protocol/components/profile/profile-stats.tsx b/integrations/lens-protocol/components/profile/profile-stats.tsx new file mode 100644 index 00000000..642cf4bc --- /dev/null +++ b/integrations/lens-protocol/components/profile/profile-stats.tsx @@ -0,0 +1,57 @@ +import { Profile, useActiveProfile, useProfileFollowers, useProfileFollowing } from '@lens-protocol/react-web' + +import { ProfileListModal } from './profile-list-modal' + +export const ProfileStats = ({ profile }: { profile: Profile }) => { + const { data: activeProfile } = useActiveProfile() + const { + data: followers, + loading: followersLoading, + hasMore: followersHasMore, + next: followersNext, + } = useProfileFollowers({ + profileId: profile.id, + observerId: activeProfile?.id, + limit: 10, + }) + const { + data: followings, + loading: followingsLoading, + hasMore: followingsHasMore, + next: followingsNext, + } = useProfileFollowing({ + walletAddress: profile.ownedBy, + observerId: activeProfile?.id, + limit: 10, + }) + return ( +
+ (follower.wallet.defaultProfile ? [follower.wallet.defaultProfile] : [])) ?? []} + title="Followers" + trigger={ + + {profile.stats.totalFollowers} + Followers + + } + /> + following.profile) ?? []} + title="Followings" + trigger={ + + {profile.stats.totalFollowing} + Followings + + } + /> +
+ ) +} diff --git a/integrations/lens-protocol/components/profile/profile.tsx b/integrations/lens-protocol/components/profile/profile.tsx new file mode 100644 index 00000000..40e709d5 --- /dev/null +++ b/integrations/lens-protocol/components/profile/profile.tsx @@ -0,0 +1,74 @@ +import { useActiveProfile, useProfile } from '@lens-protocol/react-web' + +import { LinkComponent } from '@/components/shared/link-component' +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' + +import { getProfilePictureSrc } from '../../utils' +import { IsUserAuthenticated } from '../auth/is-user-authenticated' +import { LoginButton } from '../auth/login-button' +import { NotAuthenticatedYet } from '../auth/not-authenticated-yet' +import { Feed } from '../feed' +import { Spinner } from '../spinner' +import { FollowUnfollowButton } from './follow-unfollow-button' +import { ProfileRevenue } from './profile-revenue' +import { ProfileStats } from './profile-stats' + +export const Profile = ({ handle }: { handle: string }) => { + const activeProfile = useActiveProfile() + const { data: profile, loading } = useProfile({ handle, observerId: activeProfile?.data?.id ?? undefined }) + + if (loading) + return ( +
+ +
+ ) + if (!profile) return
Profile not found!
+ return ( +
+
+ + + {profile.handle.substring(0, 1)} + + {profile.name && {profile.name}} + @{profile.handle} + + {!profile.ownedByMe && } + {profile.bio && ( + <> +
Bio
+
{profile.bio}
+ + )} +
+
Owned by
+ {profile.ownedBy} + + See all profiles + +
+ {Object.keys(profile.attributes).length > 0 && ( +
+ {Object.entries(profile.attributes).map(([key, attribute]) => ( +
+ {key}: + {attribute.toString()} +
+ ))} +
+ )} + +
+
+ + + + +
You need to login to see the profile feed.
+ +
+
+
+ ) +} diff --git a/integrations/lens-protocol/components/profile/search-profiles.tsx b/integrations/lens-protocol/components/profile/search-profiles.tsx new file mode 100644 index 00000000..1e5f9485 --- /dev/null +++ b/integrations/lens-protocol/components/profile/search-profiles.tsx @@ -0,0 +1,31 @@ +import { useActiveProfile, useSearchProfiles } from '@lens-protocol/react-web' +import { useRouter } from 'next/navigation' + +import { Spinner } from '../spinner' +import { ProfileCard } from './profile-card' + +export const SearchProfiles = ({ query }: { query: string }) => { + const profile = useActiveProfile() + const { data: profiles, loading, hasMore, next } = useSearchProfiles({ query, limit: 10, observerId: profile?.data?.id ?? undefined }) + const router = useRouter() + return ( +
+

Profiles

+
+ {profiles?.map((profile) => ( + router.push(`/integration/lens-protocol/profiles/${profile.handle}`)} /> + ))} +
+ {hasMore && ( + + )} + {loading && ( +
+ +
+ )} +
+ ) +} diff --git a/integrations/lens-protocol/components/publications/actions/button.tsx b/integrations/lens-protocol/components/publications/actions/button.tsx new file mode 100644 index 00000000..194c73ae --- /dev/null +++ b/integrations/lens-protocol/components/publications/actions/button.tsx @@ -0,0 +1,39 @@ +import { ReactNode } from 'react' + +import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' + +export const ActionButton = ({ + color, + execute, + name, + hideCount, + count, + disabled, + icon, +}: { + color: string + execute: () => void + name: string + hideCount: boolean + count: number + disabled: boolean + icon: ReactNode +}) => { + return ( + + ) +} diff --git a/integrations/lens-protocol/components/publications/actions/comment.tsx b/integrations/lens-protocol/components/publications/actions/comment.tsx new file mode 100644 index 00000000..66f9a8d7 --- /dev/null +++ b/integrations/lens-protocol/components/publications/actions/comment.tsx @@ -0,0 +1,30 @@ +import { FaRegCommentAlt } from 'react-icons/fa' + +import { useToast } from '@/lib/hooks/use-toast' + +import { IActionButton } from '.' +import { ActionButton } from './button' + +export const CommentButton = ({ publication, hideCount }: IActionButton) => { + const { toast, dismiss } = useToast() + const showErrorToast = () => { + toast({ + title: 'Commenting on a publication is not supported currently.', + }) + + setTimeout(() => { + dismiss() + }, 10000) + } + return ( + showErrorToast()} + hideCount={hideCount} + icon={} + name="comment" + /> + ) +} diff --git a/integrations/lens-protocol/components/publications/actions/index.tsx b/integrations/lens-protocol/components/publications/actions/index.tsx new file mode 100644 index 00000000..c1549102 --- /dev/null +++ b/integrations/lens-protocol/components/publications/actions/index.tsx @@ -0,0 +1,6 @@ +import { Comment, Post } from '@lens-protocol/react-web' + +export interface IActionButton { + publication: Post | Comment + hideCount: boolean +} diff --git a/integrations/lens-protocol/components/publications/actions/like.tsx b/integrations/lens-protocol/components/publications/actions/like.tsx new file mode 100644 index 00000000..12fab61c --- /dev/null +++ b/integrations/lens-protocol/components/publications/actions/like.tsx @@ -0,0 +1,85 @@ +import { Profile, ReactionTypes, useActiveProfile, useReaction } from '@lens-protocol/react-web' +import { FaHeart, FaRegHeart } from 'react-icons/fa' + +import { useToast } from '@/lib/hooks/use-toast' + +import { IActionButton } from '.' +import { IsUserAuthenticated } from '../../auth/is-user-authenticated' +import { NotAuthenticatedYet } from '../../auth/not-authenticated-yet' +import { ActionButton } from './button' + +const UnAuthorizedLikeButton = ({ publication, hideCount }: IActionButton) => { + const { toast, dismiss } = useToast() + const showErrorToast = () => { + toast({ + title: 'You need to login first.', + }) + + setTimeout(() => { + dismiss() + }, 10000) + } + return ( + showErrorToast()} + hideCount={hideCount} + icon={} + name="like" + /> + ) +} + +const AuthorizedLikeButton = ({ publication, hideCount, profile }: IActionButton & { profile: Profile }) => { + const { addReaction, removeReaction, hasReaction, isPending } = useReaction({ + profileId: profile?.id, + }) + + const reactionType = ReactionTypes.Upvote + + const hasReactionType = hasReaction({ + reactionType, + publication, + }) + + const execute = async () => { + if (isPending) return + if (!hasReactionType) { + await addReaction({ + reactionType, + publication, + }) + } else if (hasReactionType) { + await removeReaction({ + reactionType, + publication, + }) + } + } + + return ( + : } + name="like" + /> + ) +} + +export const LikeButton = (props: IActionButton) => { + const { data: profile } = useActiveProfile() + return ( + <> + + + + {profile && } + + ) +} diff --git a/integrations/lens-protocol/components/publications/actions/mirror.tsx b/integrations/lens-protocol/components/publications/actions/mirror.tsx new file mode 100644 index 00000000..f19c2093 --- /dev/null +++ b/integrations/lens-protocol/components/publications/actions/mirror.tsx @@ -0,0 +1,65 @@ +import { ProfileOwnedByMe, useActiveProfile, useCreateMirror } from '@lens-protocol/react-web' +import { FaRetweet } from 'react-icons/fa' + +import { useToast } from '@/lib/hooks/use-toast' + +import { IActionButton } from '.' +import { IsUserAuthenticated } from '../../auth/is-user-authenticated' +import { NotAuthenticatedYet } from '../../auth/not-authenticated-yet' +import { ActionButton } from './button' + +const UnAuthorizedMirrorButton = ({ publication, hideCount }: IActionButton) => { + const { toast, dismiss } = useToast() + const showErrorToast = () => { + toast({ + title: 'You need to login first.', + }) + + setTimeout(() => { + dismiss() + }, 10000) + } + return ( + showErrorToast()} + hideCount={hideCount} + icon={} + name="mirror" + /> + ) +} + +const AuthorizedMirrorButton = ({ publication, hideCount, profile }: IActionButton & { profile: ProfileOwnedByMe }) => { + const { execute: create, isPending, error } = useCreateMirror({ publisher: profile }) + if (error) alert(error) + return ( + } + name="mirror" + execute={() => + create({ + publication, + }) + } + /> + ) +} + +export const MirrorButton = (props: IActionButton) => { + const { data: profile } = useActiveProfile() + return ( + <> + + + + {profile && } + + ) +} diff --git a/integrations/lens-protocol/components/publications/commnets.tsx b/integrations/lens-protocol/components/publications/commnets.tsx new file mode 100644 index 00000000..4e885e32 --- /dev/null +++ b/integrations/lens-protocol/components/publications/commnets.tsx @@ -0,0 +1,40 @@ +import { PublicationId, useComments } from '@lens-protocol/react-web' + +import { Spinner } from '../spinner' +import { PublicationCard } from './publication-card' + +export const Comments = ({ publicationId }: { publicationId: PublicationId }) => { + const { + data: comments, + loading, + hasMore, + next, + } = useComments({ + commentsOf: publicationId, + limit: 10, + }) + if (loading) return + return ( +
+ {comments?.map((comment, index) => ( + + ))} + {hasMore && ( + + )} + {loading && ( +
+ +
+ )} +
+ ) +} diff --git a/integrations/lens-protocol/components/publications/explore-publications.tsx b/integrations/lens-protocol/components/publications/explore-publications.tsx new file mode 100644 index 00000000..dc1a5736 --- /dev/null +++ b/integrations/lens-protocol/components/publications/explore-publications.tsx @@ -0,0 +1,28 @@ +import { Post, PublicationTypes, useExplorePublications } from '@lens-protocol/react-web' + +import { Spinner } from '../spinner' +import { PublicationCard } from './publication-card' + +export const ExplorePublications = () => { + const { data: publications, loading, hasMore, next } = useExplorePublications({ limit: 10, publicationTypes: [PublicationTypes.Post] }) + return ( + <> +
+

Publications

+ {publications?.map((publication) => ( + + ))} + {hasMore && ( + + )} + {loading && ( +
+ +
+ )} +
+ + ) +} diff --git a/integrations/lens-protocol/components/publications/publication-actions-and-stats.tsx b/integrations/lens-protocol/components/publications/publication-actions-and-stats.tsx new file mode 100644 index 00000000..9a670b09 --- /dev/null +++ b/integrations/lens-protocol/components/publications/publication-actions-and-stats.tsx @@ -0,0 +1,19 @@ +import { Comment, Post } from '@lens-protocol/react-web' + +import { CommentButton } from './actions/comment' +import { LikeButton } from './actions/like' +import { MirrorButton } from './actions/mirror' +import { PublicationStats } from './stats' + +export const PublicationActionsAndStats = ({ publication, showCounts = false }: { publication: Post | Comment; showCounts: boolean }) => { + return ( +
+ {showCounts && } +
+ + + +
+
+ ) +} diff --git a/integrations/lens-protocol/components/publications/publication-card.tsx b/integrations/lens-protocol/components/publications/publication-card.tsx new file mode 100644 index 00000000..c1d77b57 --- /dev/null +++ b/integrations/lens-protocol/components/publications/publication-card.tsx @@ -0,0 +1,133 @@ +import { ReactNode } from 'react' + +import { Comment, FeedItem, Post } from '@lens-protocol/react-web' +import moment from 'moment' +import { useRouter } from 'next/navigation' +import { FaRetweet } from 'react-icons/fa' + +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' +import { cn } from '@/lib/utils' + +import { getProfilePictureSrc } from '../../utils' +import { Comments } from './commnets' +import { PublicationActionsAndStats } from './publication-actions-and-stats' +import { PublicationRevenue } from './publication-revenue' + +export enum PublicationCardMode { + Normal = 'normal', + Compact = 'compact', + FeedComment = 'FeedComment', + Full = 'full', +} + +const Wrapper = ({ + shouldLinkToFullMode, + children, + id, + classNames, + chainedStyle, + last, +}: { + shouldLinkToFullMode: boolean + children: ReactNode + id: string + classNames: string + chainedStyle: boolean + last: boolean +}) => { + const router = useRouter() + const defaultClassName = 'card w-full block px-3 dark:bg-neutral-800' + const bottomLine = + 'before:absolute before:left-[32px] before:top-[40px] before:h-full before:bg-slate-200 before:dark:bg-neutral-600 before:self-start before:w-[1px]' + const topLine = + 'after:absolute after:left-[32px] after:top-[0px] after:h-[24px] after:bg-slate-200 after:dark:bg-neutral-600 after:self-start after:w-[1px]' + const chainedClassName = 'relative ml-[-12px]' + const baseClassName = cn(defaultClassName, chainedStyle && chainedClassName, chainedStyle && !last && bottomLine, chainedStyle && topLine) + if (shouldLinkToFullMode) + return ( +
{ + e.stopPropagation() + router.push(`/integration/lens-protocol/publications/${id}`) + }}> + {children} +
+ ) + return
{children}
+} + +export const PublicationCard = ({ + publication, + feedItem, + mode = PublicationCardMode.Normal, + wrapperClassNames = '', + last = false, + chainedStyle = false, +}: { + publication: Post | Comment + feedItem?: FeedItem + mode?: PublicationCardMode + wrapperClassNames?: string + last?: boolean + chainedStyle?: boolean +}) => { + const router = useRouter() + const compactMode = mode === PublicationCardMode.Compact + const fullMode = mode === PublicationCardMode.Full + const feedCommentMode = mode === PublicationCardMode.FeedComment + const { profile } = publication + const mirrored = feedItem?.electedMirror ?? false + const bottomLine = + 'relative before:absolute before:left-[-20px] before:top-[-16px] before:h-[calc(100%_+_32px)] before:bg-slate-200 before:dark:bg-neutral-600 before:self-start before:w-[1px]' + return ( + + {mirrored && ( +
+ + {feedItem?.electedMirror?.profile.name ?? feedItem?.electedMirror?.profile.handle} + Mirrored +
+ )} +
+
+
{ + e.stopPropagation() + router.push(`/integration/lens-protocol/profiles/${profile.handle}`) + }}> + + + {profile.handle.substring(0, 1)} + +
+ {profile.name ?? profile.handle} + {!compactMode && @{profile.handle}} +
+
+
+
+
+
{publication.metadata.content}
+
+ {moment(publication.createdAt).format('HH:mm YY MMM DD')} +
+ {!compactMode && } + {fullMode && } +
+
+ {fullMode && } + {feedCommentMode && feedItem?.comments?.[0] && ( + + )} +
+
+ ) +} diff --git a/integrations/lens-protocol/components/publications/publication-revenue.tsx b/integrations/lens-protocol/components/publications/publication-revenue.tsx new file mode 100644 index 00000000..fd3df92d --- /dev/null +++ b/integrations/lens-protocol/components/publications/publication-revenue.tsx @@ -0,0 +1,21 @@ +import { PublicationId, usePublicationRevenue } from '@lens-protocol/react-web' + +export const PublicationRevenue = ({ publicationId }: { publicationId: PublicationId }) => { + const { data, loading: revenueLoading } = usePublicationRevenue({ + publicationId, + }) + if (revenueLoading) return null + return ( +
+

Publication Revenue

+ {data ? ( +
+ {data.revenue.totalAmount.toNumber()} + {data.revenue.totalAmount.asset.symbol} +
+ ) : ( + None yet + )} +
+ ) +} diff --git a/integrations/lens-protocol/components/publications/publication.tsx b/integrations/lens-protocol/components/publications/publication.tsx new file mode 100644 index 00000000..45f5fa39 --- /dev/null +++ b/integrations/lens-protocol/components/publications/publication.tsx @@ -0,0 +1,68 @@ +import { Comment, Mirror, Post, PublicationId, usePublication } from '@lens-protocol/react-web' +import { FaRegCommentAlt, FaRetweet } from 'react-icons/fa' + +import { LinkComponent } from '@/components/shared/link-component' + +import { Spinner } from '../spinner' +import { PublicationCard, PublicationCardMode } from './publication-card' + +export const Publication = ({ publicationId }: { publicationId: PublicationId }) => { + return ( +
+ +
+ ) +} + +export const PublicationDetails = ({ publicationId }: { publicationId: PublicationId }) => { + const { data: publication, loading } = usePublication({ + publicationId, + }) + if (loading) return + if (!publication) return
Publication not found!
+ if (publication.__typename === 'Mirror') return + if (publication.__typename === 'Comment') return + if (publication.__typename === 'Post') return + return
Unknown type of publication!
+} + +const RenderPost = ({ publication }: { publication: Post }) => { + return +} + +const RenderMirror = ({ publication }: { publication: Mirror }) => { + const { profile } = publication + return ( +
+
+ + + {profile.name ?? profile.handle} + + Mirrored +
+ {publication.mirrorOf.__typename === 'Post' && } + {publication.mirrorOf.__typename === 'Comment' && } +
+ ) +} + +const RenderComment = ({ publication }: { publication: Comment }) => { + const { profile } = publication + return ( +
+
+ Original publication +
+ {publication.commentOn?.__typename === 'Post' && } +
+ + + {profile.name ?? profile.handle} + + Commented +
+ +
+ ) +} diff --git a/integrations/lens-protocol/components/publications/search-publications.tsx b/integrations/lens-protocol/components/publications/search-publications.tsx new file mode 100644 index 00000000..e8ae70da --- /dev/null +++ b/integrations/lens-protocol/components/publications/search-publications.tsx @@ -0,0 +1,26 @@ +import { Post, useSearchPublications } from '@lens-protocol/react-web' + +import { Spinner } from '../spinner' +import { PublicationCard } from './publication-card' + +export const SearchPublications = ({ query }: { query: string }) => { + const { data: publications, loading, hasMore, next } = useSearchPublications({ query, limit: 10 }) + return ( +
+

Publications

+ {publications?.map((publication) => ( + + ))} + {hasMore && ( + + )} + {loading && ( +
+ +
+ )} +
+ ) +} diff --git a/integrations/lens-protocol/components/publications/stats/index.tsx b/integrations/lens-protocol/components/publications/stats/index.tsx new file mode 100644 index 00000000..b2fdc14a --- /dev/null +++ b/integrations/lens-protocol/components/publications/stats/index.tsx @@ -0,0 +1,54 @@ +import { Comment, Post, useActiveProfile, useWhoCollectedPublication, useWhoMirroredPublication, useWhoReacted } from '@lens-protocol/react-web' + +import { Stat } from './stat' + +export const PublicationStats = ({ publication }: { publication: Post | Comment }) => { + const { data: profile } = useActiveProfile() + const likes = useWhoReacted({ + publicationId: publication.id, + observerId: profile?.id, + limit: 10, + }) + const mirrors = useWhoMirroredPublication({ + publicationId: publication.id, + observerId: profile?.id, + limit: 10, + }) + const collects = useWhoCollectedPublication({ + publicationId: publication.id, + observerId: profile?.id, + limit: 10, + }) + return ( +
+ + {publication.stats.commentsCount} + comments + + reaction.profile)} + hasMore={likes.hasMore} + loading={likes.loading} + name="likes" + next={likes.next} + value={publication.stats.totalUpvotes} + /> + + (wallet.defaultProfile ? [wallet.defaultProfile] : []))} + hasMore={collects.hasMore} + loading={collects.loading} + name="collects" + next={collects.next} + value={publication.stats.totalAmountOfCollects} + /> +
+ ) +} diff --git a/integrations/lens-protocol/components/publications/stats/stat.tsx b/integrations/lens-protocol/components/publications/stats/stat.tsx new file mode 100644 index 00000000..f46c3073 --- /dev/null +++ b/integrations/lens-protocol/components/publications/stats/stat.tsx @@ -0,0 +1,33 @@ +import { Profile } from '@lens-protocol/react-web' + +import { ProfileListModal } from '../../profile/profile-list-modal' + +export const Stat = ({ + name, + value, + data, + hasMore, + loading, + next, +}: { + name: string + value: number + data?: Profile[] + hasMore: boolean + loading: boolean + next: () => void +}) => ( + + {value} + {name} + + } + /> +) diff --git a/integrations/lens-protocol/components/spinner.tsx b/integrations/lens-protocol/components/spinner.tsx new file mode 100644 index 00000000..fc87d54c --- /dev/null +++ b/integrations/lens-protocol/components/spinner.tsx @@ -0,0 +1,20 @@ +export const Spinner = ({ isSmall }: { isSmall?: boolean }) => { + const cn = isSmall + ? 'mr-2 h-4 w-4 animate-spin fill-blue-600 text-gray-200 dark:text-gray-600' + : 'mr-2 h-8 w-8 animate-spin fill-blue-600 text-gray-200 dark:text-gray-600' + return ( +
+ + Loading... +
+ ) +} diff --git a/integrations/lens-protocol/lens-provider.ts b/integrations/lens-protocol/lens-provider.ts new file mode 100644 index 00000000..9a6ce888 --- /dev/null +++ b/integrations/lens-protocol/lens-provider.ts @@ -0,0 +1,7 @@ +import { LensConfig, development } from '@lens-protocol/react-web' +import { bindings as wagmiBindings } from '@lens-protocol/wagmi' + +export const lensProviderConfig: LensConfig = { + bindings: wagmiBindings(), + environment: development, +} diff --git a/integrations/lens-protocol/utils/index.ts b/integrations/lens-protocol/utils/index.ts new file mode 100644 index 00000000..4f510a48 --- /dev/null +++ b/integrations/lens-protocol/utils/index.ts @@ -0,0 +1,12 @@ +import { Profile } from '@lens-protocol/react-web' + +export const getProfilePictureSrc = (profile: Profile): string | undefined => { + if (!profile || !profile.picture) return undefined + if (profile.picture.__typename === 'MediaSet') { + const splittedUrl = profile.picture.original.url.split('ipfs://') + if (splittedUrl.length === 2) return `https://ipfs.io/ipfs/${splittedUrl[1]}` + return profile.picture.original.url + } + if (profile.picture.__typename === 'NftImage') return `https://cdn.stamp.fyi/avatar/eth:${profile.picture.uri}` + return undefined +} diff --git a/package.json b/package.json index 5c3a0b86..ede8ea69 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,8 @@ "@gelatonetwork/automate-sdk": "^2.14.0", "@graphql-typed-document-node/core": "^3.2.0", "@hookform/resolvers": "^3.1.1", + "@lens-protocol/react-web": "^1.3.0", + "@lens-protocol/wagmi": "^2.1.0", "@lit-protocol/lit-node-client": "2.1.161", "@livepeer/react": "^2.6.0", "@moralisweb3/common-evm-utils": "^2.22.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 34002e8a..8bc27826 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,9 @@ lockfileVersion: '6.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + dependencies: '@bgd-labs/aave-address-book': specifier: ^1.30.0 @@ -19,6 +23,12 @@ dependencies: '@hookform/resolvers': specifier: ^3.1.1 version: 3.1.1(react-hook-form@7.43.9) + '@lens-protocol/react-web': + specifier: ^1.3.0 + version: 1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4) + '@lens-protocol/wagmi': + specifier: ^2.1.0 + version: 2.1.0(@lens-protocol/react-web@1.3.0)(ethers@5.7.2)(viem@1.0.0)(wagmi@1.3.10) '@lit-protocol/lit-node-client': specifier: 2.1.161 version: 2.1.161(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(react@18.2.0) @@ -384,6 +394,11 @@ devDependencies: packages: + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + /@adraffy/ens-normalize@1.9.0: resolution: {integrity: sha512-iowxq3U30sghZotgl4s/oJRci6WPBfNO5YYgk2cIOMCHr3LeGPcsZjCEr+33Q4N+oV3OABDAtA+pyvWjbvBifQ==} @@ -410,6 +425,42 @@ packages: leven: 3.1.0 dev: false + /@apollo/client@3.8.1(graphql@16.8.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-JGGj/9bdoLEqzatRikDeN8etseY5qeFAY0vSAx/Pd0ePNsaflKzHx6V2NZ0NsGkInq+9IXXX3RLVDf0EotizMA==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + graphql-ws: ^5.5.5 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + subscriptions-transport-ws: ^0.9.0 || ^0.11.0 + peerDependenciesMeta: + graphql-ws: + optional: true + react: + optional: true + react-dom: + optional: true + subscriptions-transport-ws: + optional: true + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.8.0) + '@wry/context': 0.7.3 + '@wry/equality': 0.5.6 + '@wry/trie': 0.4.3 + graphql: 16.8.0 + graphql-tag: 2.12.6(graphql@16.8.0) + hoist-non-react-statics: 3.3.2 + optimism: 0.17.5 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + response-iterator: 0.2.6 + symbol-observable: 4.0.0 + ts-invariant: 0.10.3 + tslib: 2.5.0 + zen-observable-ts: 1.2.5 + dev: false + /@ardatan/fast-json-stringify@0.0.6(ajv-formats@2.1.1)(ajv@8.12.0): resolution: {integrity: sha512-//BefMIP6U1ptNeBf44Le4vqThejTwZndtYLtAuFBwA/DmbVbbYTCLNIMhZ96WZnhI92EvTXneT5tKJrgINE9A==} peerDependencies: @@ -6441,6 +6492,251 @@ packages: /@ledgerhq/connect-kit-loader@1.1.2: resolution: {integrity: sha512-mscwGroSJQrCTjtNGBu+18FQbZYA4+q6Tyx6K7CXHl6AwgZKbWfZYdgP2F+fyZcRUdGRsMX8QtvU61VcGGtO1A==} + /@lens-protocol/api-bindings@0.10.0(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-CoILWFbVQWg7rfJUv1EINimrOG1MJpn413PlWFOILsXEQT4RiSp0JRPs752piog6DKQ4QJCaDld1fi/Haix/qg==} + peerDependencies: + '@faker-js/faker': ^7.6.0 + react: ^18.2.0 + peerDependenciesMeta: + '@faker-js/faker': + optional: true + dependencies: + '@apollo/client': 3.8.1(graphql@16.8.0)(react-dom@18.2.0)(react@18.2.0) + '@lens-protocol/domain': 0.10.0(ethers@5.7.2) + '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2) + graphql: 16.8.0 + graphql-tag: 2.12.6(graphql@16.8.0) + react: 18.2.0 + tslib: 2.5.0 + transitivePeerDependencies: + - '@jest/globals' + - ethers + - graphql-ws + - jest-mock-extended + - jest-when + - react-dom + - subscriptions-transport-ws + - wait-for-expect + dev: false + + /@lens-protocol/blockchain-bindings@0.9.1(ethers@5.7.2): + resolution: {integrity: sha512-dc06vo4nlbmL4lwwoSLGi6upo3sdON0wz3KUi6oknPhgoMKt6qIiAbyBfyyDgLIaLPOKEcxkoCg4rKtc7j+3Eg==} + peerDependencies: + ethers: ^5.7.2 + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/providers': 5.7.2 + '@lens-protocol/domain': 0.10.0(ethers@5.7.2) + '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2) + ethers: 5.7.2 + tslib: 2.5.0 + transitivePeerDependencies: + - '@faker-js/faker' + - '@jest/globals' + - bufferutil + - jest-mock-extended + - jest-when + - utf-8-validate + - wait-for-expect + dev: false + + /@lens-protocol/domain@0.10.0(ethers@5.7.2): + resolution: {integrity: sha512-Au5a5BfOZDisRBxZ0w4pGqFp9ATf1iLo+haEcNwH11L8ssGVzZ3FLKK7jF1az4pliCt+gfwcAo83BQk8Hso2aQ==} + peerDependencies: + '@faker-js/faker': ^7.6.0 + '@jest/globals': ^29.3.1 + jest-mock-extended: ^3.0.1 + jest-when: ^3.5.2 + wait-for-expect: ^3.0.2 + peerDependenciesMeta: + '@faker-js/faker': + optional: true + '@jest/globals': + optional: true + jest-mock-extended: + optional: true + jest-when: + optional: true + wait-for-expect: + optional: true + dependencies: + '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2) + tslib: 2.5.0 + transitivePeerDependencies: + - ethers + dev: false + + /@lens-protocol/gated-content@0.3.2(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4): + resolution: {integrity: sha512-e6JnKMQZ+TfEMT0J9hhIhMFqPd2b3gHZbchQOsdempgt0sSCXYLXLp0FGoRlwtaAtDK+FqYVQXyYJEQZgCJv5w==} + peerDependencies: + '@ethersproject/contracts': ^5.7.0 + '@ethersproject/hash': ^5.7.0 + '@ethersproject/providers': ^5.7.2 + '@ethersproject/wallet': ^5.7.0 + ethers: ^5.7.2 + zod: ^3.20.6 + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/contracts': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/providers': 5.7.2 + '@ethersproject/wallet': 5.7.0 + '@lens-protocol/api-bindings': 0.10.0(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0) + '@lens-protocol/domain': 0.10.0(ethers@5.7.2) + '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2) + '@lens-protocol/storage': 0.7.4(ethers@5.7.2) + '@lit-protocol/constants': 2.1.62 + '@lit-protocol/crypto': 2.1.62 + '@lit-protocol/encryption': 2.1.62 + '@lit-protocol/node-client': 2.1.62(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0) + '@lit-protocol/types': 2.1.62 + ethers: 5.7.2 + siwe: 1.1.6(ethers@5.7.2) + tslib: 2.5.0 + zod: 3.21.4 + transitivePeerDependencies: + - '@faker-js/faker' + - '@jest/globals' + - '@react-native-async-storage/async-storage' + - '@walletconnect/modal' + - bufferutil + - encoding + - graphql-ws + - jest-mock-extended + - jest-when + - lokijs + - react + - react-dom + - subscriptions-transport-ws + - utf-8-validate + - wait-for-expect + dev: false + + /@lens-protocol/react-web@1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4): + resolution: {integrity: sha512-0ztmgGi6URjyX2hYujaJ+HH30gRsI4/Rgk3VviLTtNi1xmduECywEqFljUqZx8zIEndZs+bDpXPojCHhHmjdAQ==} + peerDependencies: + '@xmtp/react-sdk': 1.0.0-preview.40 + ethers: ^5.7.2 + react: ^18.2.0 + peerDependenciesMeta: + '@xmtp/react-sdk': + optional: true + dependencies: + '@lens-protocol/api-bindings': 0.10.0(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0) + '@lens-protocol/domain': 0.10.0(ethers@5.7.2) + '@lens-protocol/gated-content': 0.3.2(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4) + '@lens-protocol/react': 1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0) + '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2) + '@lens-protocol/storage': 0.7.4(ethers@5.7.2) + ethers: 5.7.2 + react: 18.2.0 + tslib: 2.5.0 + transitivePeerDependencies: + - '@ethersproject/contracts' + - '@ethersproject/hash' + - '@ethersproject/providers' + - '@ethersproject/wallet' + - '@faker-js/faker' + - '@jest/globals' + - '@react-native-async-storage/async-storage' + - '@walletconnect/modal' + - bufferutil + - encoding + - graphql-ws + - jest-mock-extended + - jest-when + - lokijs + - react-dom + - subscriptions-transport-ws + - utf-8-validate + - wait-for-expect + - zod + dev: false + + /@lens-protocol/react@1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yrF79WMqmCe5yKpBXBmhhxuDrMszQljZT2gjWy3+zOg0EbktMCg69Z7wmEczOrk6CjSEL2GxW510fZ+8yaJNIQ==} + peerDependencies: + ethers: ^5.7.2 + react: ^18.2.0 + dependencies: + '@apollo/client': 3.8.1(graphql@16.8.0)(react-dom@18.2.0)(react@18.2.0) + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/providers': 5.7.2 + '@lens-protocol/api-bindings': 0.10.0(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0) + '@lens-protocol/blockchain-bindings': 0.9.1(ethers@5.7.2) + '@lens-protocol/domain': 0.10.0(ethers@5.7.2) + '@lens-protocol/gated-content': 0.3.2(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4) + '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2) + '@lens-protocol/storage': 0.7.4(ethers@5.7.2) + ethers: 5.7.2 + graphql: 16.8.0 + jwt-decode: 3.1.2 + lodash: 4.17.21 + react: 18.2.0 + tslib: 2.5.0 + uuid: 9.0.0 + zod: 3.21.4 + transitivePeerDependencies: + - '@ethersproject/contracts' + - '@ethersproject/hash' + - '@ethersproject/wallet' + - '@faker-js/faker' + - '@jest/globals' + - '@react-native-async-storage/async-storage' + - '@walletconnect/modal' + - bufferutil + - encoding + - graphql-ws + - jest-mock-extended + - jest-when + - lokijs + - react-dom + - subscriptions-transport-ws + - utf-8-validate + - wait-for-expect + dev: false + + /@lens-protocol/shared-kernel@0.10.0(ethers@5.7.2): + resolution: {integrity: sha512-I8WSYI39ALB9dMZOYKb6pmnaKPkEaoXI73G8dZ0ghQRoV7AkWu8a2RrPYuoCq1VIFwQElCL9AmCjuLHTQkOeuQ==} + peerDependencies: + ethers: ^5.7.2 + peerDependenciesMeta: + ethers: + optional: true + dependencies: + decimal.js: 10.4.3 + ethers: 5.7.2 + lodash: 4.17.21 + tslib: 2.5.0 + uuid: 9.0.0 + dev: false + + /@lens-protocol/storage@0.7.4(ethers@5.7.2): + resolution: {integrity: sha512-ezr44IhhcF3OEgJrqCmeOUX1p+UMYhU1sv6ua8AqbpTJZT33nPhXbyiXOYjtPTXi2VZJZPBpKU8rpkixrEgXTA==} + dependencies: + '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2) + tslib: 2.5.0 + zod: 3.21.4 + transitivePeerDependencies: + - ethers + dev: false + + /@lens-protocol/wagmi@2.1.0(@lens-protocol/react-web@1.3.0)(ethers@5.7.2)(viem@1.0.0)(wagmi@1.3.10): + resolution: {integrity: sha512-TpwZjaY8xegyA/Waj8ABxRCmkhz7rcyctSK8NO5+akQ67AVfzn8yhBqNep5Wx4HJokiCRKA8XmSi9md7dNDkLA==} + peerDependencies: + '@lens-protocol/react-web': 1.3.0 + ethers: ^5.7.2 + viem: ^1.0.0 + wagmi: ^1.1.0 + dependencies: + '@lens-protocol/react-web': 1.3.0(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(ethers@5.7.2)(react-dom@18.2.0)(react@18.2.0)(zod@3.21.4) + '@lens-protocol/shared-kernel': 0.10.0(ethers@5.7.2) + ethers: 5.7.2 + viem: 1.0.0(typescript@5.0.4)(zod@3.21.4) + wagmi: 1.3.10(react-dom@18.2.0)(react-native@0.72.4)(react@18.2.0)(typescript@5.0.4)(viem@1.0.0)(zod@3.21.4) + dev: false + /@lit-labs/ssr-dom-shim@1.1.1: resolution: {integrity: sha512-kXOeFbfCm4fFf2A3WwVEeQj55tMZa8c8/f9AKHMobQMkzNUfUj+antR3fRPaZJawsa1aZiP/Da3ndpZrwEe4rQ==} @@ -6458,6 +6754,20 @@ packages: - utf-8-validate dev: false + /@lit-protocol/access-control-conditions@2.1.62: + resolution: {integrity: sha512-nP+iqiLUzQa6bfZL9hM9a+s+YVW21HoHkHP7s2E11VFQmucdnJmUUr7Aw46SK/4yClTjLb6RuHyfIPvCdmIKhQ==} + dependencies: + '@lit-protocol/constants': 2.1.62 + '@lit-protocol/misc': 2.1.62 + '@lit-protocol/types': 2.1.62 + '@lit-protocol/uint8arrays': 2.1.62 + ethers: 5.7.2 + tslib: 2.5.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /@lit-protocol/auth-browser@2.1.161(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0)(react@18.2.0): resolution: {integrity: sha512-QdUzRLjziMJtjLtBQkaRhmhn8T1EiqKTyPWyoyzx9/5WFpaRYc0TmMbK/EidcG68YGObTDEuy2r/XZ3lGr/fcg==} dependencies: @@ -6490,10 +6800,44 @@ packages: - utf-8-validate dev: false + /@lit-protocol/auth-browser@2.1.62(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0): + resolution: {integrity: sha512-/4BTl0omR+JUCyJJc93FCiygSn/4ldrbeBuzWYQzuOFh2f6fcY1GJe3ttEoSJUfwu7OblW86YpWAT65b56rACA==} + dependencies: + '@lit-protocol/constants': 2.1.62 + '@lit-protocol/misc': 2.1.62 + '@lit-protocol/misc-browser': 2.1.62 + '@lit-protocol/types': 2.1.62 + '@lit-protocol/uint8arrays': 2.1.62 + '@walletconnect/ethereum-provider': 2.9.2(@walletconnect/modal@2.6.1) + ethers: 5.7.2 + lit-connect-modal: 0.1.11 + lit-siwe: 1.1.8(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0) + tslib: 2.5.0 + tweetnacl: 1.0.3 + tweetnacl-util: 0.13.5 + util: 0.12.5 + web-vitals: 3.3.1 + transitivePeerDependencies: + - '@ethersproject/contracts' + - '@ethersproject/hash' + - '@ethersproject/providers' + - '@ethersproject/wallet' + - '@react-native-async-storage/async-storage' + - '@walletconnect/modal' + - bufferutil + - encoding + - lokijs + - utf-8-validate + dev: false + /@lit-protocol/bls-sdk@2.1.161: resolution: {integrity: sha512-+ubypaILDWjZejtsyHCeuEGbiMIX6PXKEw9uTMM7wV4PCOTtwUixsaGZr8/+xM6ivGnowO3e80hKKCR3gpXhaA==} dev: false + /@lit-protocol/bls-sdk@2.1.62: + resolution: {integrity: sha512-UjNjycoNXOEoLH/foIJx1L9PLL5OxmHcCD/mFXr4KSeQV/v4srvGNpY/4ng7+k9sJEbvwRwv+FB07ng3/Ihacg==} + dev: false + /@lit-protocol/constants@2.1.161: resolution: {integrity: sha512-91Rs01/BmRdi7YYmwqkaqI7TYOxhldpLIf5nLBaAQNZloijdF073KbXa9dFZtVbTo3c8fG5O6ts6DOQLK7mSKA==} dependencies: @@ -6501,6 +6845,13 @@ packages: tslib: 2.5.0 dev: false + /@lit-protocol/constants@2.1.62: + resolution: {integrity: sha512-4CigP3GS7Cxpa9RXT1twCCvYI5wvfo1UAMbdrjoDgM9VMDtpvSrmlG8AwC9yMoqPM6409BYcgGI9LDGzUjNUjg==} + dependencies: + '@lit-protocol/types': 2.1.62 + tslib: 2.5.0 + dev: false + /@lit-protocol/crypto@2.1.161: resolution: {integrity: sha512-0ntmjz1jdFqGgng7jomHMHt/aW2Ov9tOrKCQ/8phy1x3hkTL2o336vkMU7H+3UbpOt2wryHrobcFyP82ZLm/qQ==} dependencies: @@ -6518,10 +6869,31 @@ packages: - utf-8-validate dev: false + /@lit-protocol/crypto@2.1.62: + resolution: {integrity: sha512-pWte+VQOPmSFvfoMxvobmj5JjkGSD44XMkkTXGubpGTBr27hK9CuDxpVHTsI9NsGFSJRdPBpRou+YD5I22yDiA==} + dependencies: + '@lit-protocol/bls-sdk': 2.1.62 + '@lit-protocol/constants': 2.1.62 + '@lit-protocol/ecdsa-sdk': 2.1.62 + '@lit-protocol/misc': 2.1.62 + '@lit-protocol/nacl': 2.1.62 + '@lit-protocol/types': 2.1.62 + '@lit-protocol/uint8arrays': 2.1.62 + ethers: 5.7.2 + tslib: 2.5.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /@lit-protocol/ecdsa-sdk@2.1.161: resolution: {integrity: sha512-UuZvzCEYnoXflJItwmDATDc60H1dH+z8J8iW3rAkPbxYcwCBSbVSo4aUel2Y9Vf9/uaBtm1xSjeWnBv6PBVFWw==} dev: false + /@lit-protocol/ecdsa-sdk@2.1.62: + resolution: {integrity: sha512-VWYAQh31e5Vu6YXvw7iDQja/f2Je6Obj8VoXLweWWfSpUnKqe1JJKGDLxOAuQUT3ZSaX7bYrq7hLIJdwdWmJQw==} + dev: false + /@lit-protocol/encryption@2.1.161(node-fetch@2.6.9): resolution: {integrity: sha512-O8ZiZtjzrXvBY8OuRyOviAQ1VK3Lsmh1G5qAovGwB1Za8fshGB2mTR4PBlQ7Zf2rb+qlxC7220sZ8Y20UtCd5A==} dependencies: @@ -6545,6 +6917,25 @@ packages: - utf-8-validate dev: false + /@lit-protocol/encryption@2.1.62: + resolution: {integrity: sha512-Nmte/UINgc+YVlA3RewhW+1SFnKcSikd94HlBxS+TX9yb2KBUO6oKNjTQSGX4P/KD3zBxaFlbY8+jrWeYR1aQQ==} + dependencies: + '@lit-protocol/bls-sdk': 2.1.62 + '@lit-protocol/constants': 2.1.62 + '@lit-protocol/crypto': 2.1.62 + '@lit-protocol/ecdsa-sdk': 2.1.62 + '@lit-protocol/misc': 2.1.62 + '@lit-protocol/nacl': 2.1.62 + '@lit-protocol/types': 2.1.62 + '@lit-protocol/uint8arrays': 2.1.62 + ethers: 5.7.2 + jszip: 3.10.1 + tslib: 2.5.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /@lit-protocol/lit-node-client-nodejs@2.1.161(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0): resolution: {integrity: sha512-mQR56sh0rZF7XxmuQphPrx4hBB+rHY7sneDhdp6ZCxbUcM7NWRbz5h+idn8Ln49E6qXHplFCyp2dWqrwF0vr9w==} dependencies: @@ -6633,6 +7024,10 @@ packages: resolution: {integrity: sha512-TwO+nKCL2CC8L4O7ypJ06RvBmSXntL+Yrfr+Bqj/d1xhVOB+RwohMoF8lyP6zvQokcKZqar+uPgu/hiaQhIlJw==} dev: false + /@lit-protocol/lit-third-party-libs@2.1.62: + resolution: {integrity: sha512-js8Z3uG4v30Dw9HNqnjxkzMcB3cp3UcF6tfsWGo99+g5OqqKnkCDbb4IXeqnGbslVPn6ll6XouRQPmCcuzeGaw==} + dev: false + /@lit-protocol/misc-browser@2.1.161: resolution: {integrity: sha512-FpN5N+jSff9r3WoH/H7Es/MX0nwnYqmOL1Zfg1HWHlTXbUV8ROg7QX3UPQWLFFF1nGLw649+OgN+bkXdDTG7fg==} dependencies: @@ -6647,6 +7042,20 @@ packages: - utf-8-validate dev: false + /@lit-protocol/misc-browser@2.1.62: + resolution: {integrity: sha512-2NX//tUe5ChrWCN4Msi4RE8DlYjTMGqyPYJHS86r7nKHG7sHSPCucn84LiTmVGA3DVKzspeGJdMbEF/W8Ogn6w==} + dependencies: + '@lit-protocol/constants': 2.1.62 + '@lit-protocol/misc': 2.1.62 + '@lit-protocol/types': 2.1.62 + '@lit-protocol/uint8arrays': 2.1.62 + ethers: 5.7.2 + tslib: 2.5.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + /@lit-protocol/misc@2.1.161: resolution: {integrity: sha512-wA927QjBfTEtpXglsduB1QTadIdzl/ELytRO+UzilQwQOGwSr7I/jp9giJU8WKoeFHQZuZYREQvBRxyocu1quw==} dependencies: @@ -6655,20 +7064,78 @@ packages: tslib: 2.5.0 dev: false + /@lit-protocol/misc@2.1.62: + resolution: {integrity: sha512-i6A/kxiJQgy8BZJGH7H8V2kxqOA2xboAjH2BzAbE/pMezfHG7wybkXT9cnXnXOZsAnuGnOKd93u+j7bskuDd2w==} + dependencies: + '@lit-protocol/constants': 2.1.62 + '@lit-protocol/types': 2.1.62 + tslib: 2.5.0 + dev: false + /@lit-protocol/nacl@2.1.161: resolution: {integrity: sha512-FrbhM1J/SkMGZqOenW+Fm3lSHLiOUFvorU+rwG6PzOokgRWk+PSp2ZVsFT2xfM6dg527eq6L5IL5asRVZX9zZg==} dev: false + /@lit-protocol/nacl@2.1.62: + resolution: {integrity: sha512-0v9fa6Sd4xphjlYMZ9L8TTyR7G4YLvp323E8OJ76giuaPla4HXuwSiGMzUOaC6NKraArSrd54CKkHJ/bxEqVDA==} + dev: false + + /@lit-protocol/node-client@2.1.62(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0): + resolution: {integrity: sha512-rLEUleDoJ+AATZfWNWXvy7UdSrUXMyCjpyB5bevVfk9YjIa5rd9BBXdFENCIA+9kLgVOgtND/R1PpEI/vZkMmw==} + dependencies: + '@lit-protocol/access-control-conditions': 2.1.62 + '@lit-protocol/auth-browser': 2.1.62(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0) + '@lit-protocol/bls-sdk': 2.1.62 + '@lit-protocol/constants': 2.1.62 + '@lit-protocol/crypto': 2.1.62 + '@lit-protocol/ecdsa-sdk': 2.1.62 + '@lit-protocol/encryption': 2.1.62 + '@lit-protocol/lit-third-party-libs': 2.1.62 + '@lit-protocol/misc': 2.1.62 + '@lit-protocol/misc-browser': 2.1.62 + '@lit-protocol/nacl': 2.1.62 + '@lit-protocol/types': 2.1.62 + '@lit-protocol/uint8arrays': 2.1.62 + '@walletconnect/ethereum-provider': 2.9.2(@walletconnect/modal@2.6.1) + ethers: 5.7.2 + jszip: 3.10.1 + lit-connect-modal: 0.1.11 + lit-siwe: 1.1.8(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2)(@ethersproject/wallet@5.7.0) + node-fetch: 2.6.12 + tslib: 2.5.0 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + transitivePeerDependencies: + - '@ethersproject/contracts' + - '@ethersproject/hash' + - '@ethersproject/providers' + - '@ethersproject/wallet' + - '@react-native-async-storage/async-storage' + - '@walletconnect/modal' + - bufferutil + - encoding + - lokijs + - utf-8-validate + dev: false + /@lit-protocol/types@2.1.161: resolution: {integrity: sha512-d/PGjmuREERHghcxGOnq4SA0ivX8e3tta7eXEKKV7FfsUXW6fNsSfwaDRKUK3FtlhaRvKtdlatrrZP4emG1WSA==} dev: false + /@lit-protocol/types@2.1.62: + resolution: {integrity: sha512-DoIOmbI+Bg3zLWzqx4fLv1vW3k1sbDof/fxslHsLt5aX/MXHSZVKTJb+jWgNVcQ4ba+YLqgoKaPb1i58DMvCPw==} + dev: false + /@lit-protocol/uint8arrays@2.1.161: resolution: {integrity: sha512-EjW6mn9+DzI27lUV/1vyUoZV59hOJwKQ7UkjUdPDouW7EOcMhvpScYhgsYEx67Zv0hiiP8XWLBiDGZD4U2qVvg==} dev: false - /@lit/reactive-element@1.6.1: - resolution: {integrity: sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==} + /@lit-protocol/uint8arrays@2.1.62: + resolution: {integrity: sha512-Q9Leppzyb9Y2jwe+i8btAUkTXqgnu21PFql83v6N70dkELSC+fKBzRSRqUpFqruW7dcrG8mNWsOCQbQ0kL/w/w==} + dev: false + + /@lit/reactive-element@1.6.2: + resolution: {integrity: sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==} dependencies: '@lit-labs/ssr-dom-shim': 1.1.1 @@ -11617,6 +12084,27 @@ packages: tslib: 2.5.0 dev: true + /@wry/context@0.7.3: + resolution: {integrity: sha512-Nl8WTesHp89RF803Se9X3IiHjdmLBrIvPMaJkl+rKVJAYyPsz1TEUbu89943HpvujtSJgDUx9W4vZw3K1Mr3sA==} + engines: {node: '>=8'} + dependencies: + tslib: 2.5.0 + dev: false + + /@wry/equality@0.5.6: + resolution: {integrity: sha512-D46sfMTngaYlrH+OspKf8mIJETntFnf6Hsjb0V41jAXJ7Bx2kB8Rv8RCUujuVWYttFtHkUNp7g+FwxNQAr6mXA==} + engines: {node: '>=8'} + dependencies: + tslib: 2.5.0 + dev: false + + /@wry/trie@0.4.3: + resolution: {integrity: sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==} + engines: {node: '>=8'} + dependencies: + tslib: 2.5.0 + dev: false + /@xtuc/ieee754@1.2.0: resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} dev: false @@ -13856,6 +14344,10 @@ packages: engines: {node: '>=10'} dev: false + /decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + dev: false + /decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} dependencies: @@ -15125,7 +15617,7 @@ packages: lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 - optionator: 0.9.1 + optionator: 0.9.3 regexpp: 3.2.0 strip-ansi: 6.0.1 strip-json-comments: 3.1.1 @@ -16308,7 +16800,6 @@ packages: dependencies: graphql: 16.8.0 tslib: 2.5.0 - dev: true /graphql-ws@5.12.1(graphql@16.8.0): resolution: {integrity: sha512-umt4f5NnMK46ChM2coO36PTFhHouBrK9stWWBczERguwYrGnPNxJ9dimU6IyOBfOkC6Izhkg4H8+F51W/8CYDg==} @@ -17986,6 +18477,10 @@ packages: resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} dev: false + /jwt-decode@3.1.2: + resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} + dev: false + /keccak@3.0.3: resolution: {integrity: sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ==} engines: {node: '>=10.0.0'} @@ -18237,7 +18732,7 @@ packages: resolution: {integrity: sha512-xXAeVWKGr4/njq0rGC9dethMnYCq5hpKYrgQZYTzawt9YQhMiXfD+T1RgrdY3NamOxwq2aXlb0vOI6e29CKgVQ==} dependencies: '@lit-labs/ssr-dom-shim': 1.1.1 - '@lit/reactive-element': 1.6.1 + '@lit/reactive-element': 1.6.2 lit-html: 2.7.3 /lit-html@2.7.3: @@ -18265,7 +18760,7 @@ packages: /lit@2.6.1: resolution: {integrity: sha512-DT87LD64f8acR7uVp7kZfhLRrHkfC/N4BVzAtnw9Yg8087mbBJ//qedwdwX0kzDbxgPccWRW6mFwGbRQIxy0pw==} dependencies: - '@lit/reactive-element': 1.6.1 + '@lit/reactive-element': 1.6.2 lit-element: 3.3.2 lit-html: 2.7.3 dev: false @@ -18273,7 +18768,7 @@ packages: /lit@2.7.3: resolution: {integrity: sha512-0a+u+vVbmgSfPu+fyvqjMPBX0Kwbyj9QOv9MbQFZhWGlV2cyk3lEwgfUQgYN+i/lx++1Z3wZknSIp3QCKxHLyg==} dependencies: - '@lit/reactive-element': 1.6.1 + '@lit/reactive-element': 1.6.2 lit-element: 3.3.2 lit-html: 2.7.3 dev: false @@ -18281,7 +18776,7 @@ packages: /lit@2.7.6: resolution: {integrity: sha512-1amFHA7t4VaaDe+vdQejSVBklwtH9svGoG6/dZi9JhxtJBBlqY5D1RV7iLUYY0trCqQc4NfhYYZilZiVHt7Hxg==} dependencies: - '@lit/reactive-element': 1.6.1 + '@lit/reactive-element': 1.6.2 lit-element: 3.3.2 lit-html: 2.7.3 @@ -20228,10 +20723,19 @@ packages: asn1.js: 5.4.1 dev: false - /optionator@0.9.1: - resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + /optimism@0.17.5: + resolution: {integrity: sha512-TEcp8ZwK1RczmvMnvktxHSF2tKgMWjJ71xEFGX5ApLh67VsMSTy1ZUlipJw8W+KaqgOmQ+4pqwkeivY89j+4Vw==} + dependencies: + '@wry/context': 0.7.3 + '@wry/trie': 0.4.3 + tslib: 2.5.0 + dev: false + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 deep-is: 0.1.4 fast-levenshtein: 2.0.6 levn: 0.4.1 @@ -21789,6 +22293,11 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: true + /response-iterator@0.2.6: + resolution: {integrity: sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==} + engines: {node: '>=0.8'} + dev: false + /responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} dependencies: @@ -22837,6 +23346,11 @@ packages: engines: {node: '>=0.10'} dev: false + /symbol-observable@4.0.0: + resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} + engines: {node: '>=0.10'} + dev: false + /synckit@0.8.5: resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} engines: {node: ^14.18.0 || >=16.0.0} @@ -23119,6 +23633,13 @@ packages: /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + /ts-invariant@0.10.3: + resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==} + engines: {node: '>=8'} + dependencies: + tslib: 2.5.0 + dev: false + /ts-log@2.2.5: resolution: {integrity: sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==} dev: true @@ -24758,6 +25279,16 @@ packages: engines: {node: '>=12.20'} dev: true + /zen-observable-ts@1.2.5: + resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} + dependencies: + zen-observable: 0.8.15 + dev: false + + /zen-observable@0.8.15: + resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + dev: false + /zod-to-json-schema@3.21.4(zod@3.21.4): resolution: {integrity: sha512-fjUZh4nQ1s6HMccgIeE0VP4QG/YRGPmyjO9sAh890aQKPEk3nqbfUXhMFaC+Dr5KvYBm8BCyvfpZf2jY9aGSsw==} peerDependencies: diff --git a/public/integrations/lensprotocol-dark.svg b/public/integrations/lensprotocol-dark.svg new file mode 100644 index 00000000..e8733fae --- /dev/null +++ b/public/integrations/lensprotocol-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/integrations/lensprotocol-light.svg b/public/integrations/lensprotocol-light.svg new file mode 100644 index 00000000..bca241f5 --- /dev/null +++ b/public/integrations/lensprotocol-light.svg @@ -0,0 +1,3 @@ + + + From 7f5d51c790e81d66d3f66178fc53458410fadbc1 Mon Sep 17 00:00:00 2001 From: Q Date: Sun, 27 Aug 2023 11:27:58 +0330 Subject: [PATCH 02/13] feat: profile publications --- .../components/profile/owned-profiles.tsx | 5 ++- .../profile/profile-publications.tsx | 37 +++++++++++++++++++ .../components/profile/profile.tsx | 21 ++++++++++- .../components/publications/actions/like.tsx | 4 +- .../publications/publication-card.tsx | 2 +- .../publications/search-publications.tsx | 1 + pnpm-lock.yaml | 35 +++++++++++------- 7 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 integrations/lens-protocol/components/profile/profile-publications.tsx diff --git a/integrations/lens-protocol/components/profile/owned-profiles.tsx b/integrations/lens-protocol/components/profile/owned-profiles.tsx index 8863a7f0..74e6b4fc 100644 --- a/integrations/lens-protocol/components/profile/owned-profiles.tsx +++ b/integrations/lens-protocol/components/profile/owned-profiles.tsx @@ -40,7 +40,10 @@ export const OwnedProfiles = () => { diff --git a/integrations/lens-protocol/components/profile/profile-publications.tsx b/integrations/lens-protocol/components/profile/profile-publications.tsx new file mode 100644 index 00000000..3c12d125 --- /dev/null +++ b/integrations/lens-protocol/components/profile/profile-publications.tsx @@ -0,0 +1,37 @@ +import { Post, ProfileId, PublicationTypes, useActiveProfile, usePublications } from "@lens-protocol/react-web" +import { PublicationCard } from "../publications/publication-card" +import { Spinner } from "../spinner" + +export const ProfilePublications =({profileId, publicationTypes, title}: {profileId: ProfileId, publicationTypes: PublicationTypes[]; title: string})=> { + const { data: activeProfile } = useActiveProfile() + const { + data: publications, + loading, + hasMore, + next, + } = usePublications({ + profileId, + observerId: activeProfile?.id, + publicationTypes, + limit: 10, + }) + return ( +
+

{title}

+ {publications?.map((publication) => ( + + ))} + {hasMore && ( + + )} + {loading && ( +
+ +
+ )} + {publications?.length === 0 && No {title} yet.} +
+ ) +} \ No newline at end of file diff --git a/integrations/lens-protocol/components/profile/profile.tsx b/integrations/lens-protocol/components/profile/profile.tsx index 40e709d5..5d61960f 100644 --- a/integrations/lens-protocol/components/profile/profile.tsx +++ b/integrations/lens-protocol/components/profile/profile.tsx @@ -1,4 +1,4 @@ -import { useActiveProfile, useProfile } from '@lens-protocol/react-web' +import { PublicationTypes, useActiveProfile, useProfile } from '@lens-protocol/react-web' import { LinkComponent } from '@/components/shared/link-component' import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' @@ -12,6 +12,8 @@ import { Spinner } from '../spinner' import { FollowUnfollowButton } from './follow-unfollow-button' import { ProfileRevenue } from './profile-revenue' import { ProfileStats } from './profile-stats' +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' +import { ProfilePublications } from './profile-publications' export const Profile = ({ handle }: { handle: string }) => { const activeProfile = useActiveProfile() @@ -61,6 +63,15 @@ export const Profile = ({ handle }: { handle: string }) => {
+ +
+ + Feed + Posts + Replies + +
+ @@ -68,6 +79,14 @@ export const Profile = ({ handle }: { handle: string }) => {
You need to login to see the profile feed.
+
+ + + + + + +
) diff --git a/integrations/lens-protocol/components/publications/actions/like.tsx b/integrations/lens-protocol/components/publications/actions/like.tsx index 12fab61c..bdf453a9 100644 --- a/integrations/lens-protocol/components/publications/actions/like.tsx +++ b/integrations/lens-protocol/components/publications/actions/like.tsx @@ -22,7 +22,7 @@ const UnAuthorizedLikeButton = ({ publication, hideCount }: IActionButton) => { return ( showErrorToast()} hideCount={hideCount} @@ -62,7 +62,7 @@ const AuthorizedLikeButton = ({ publication, hideCount, profile }: IActionButton return (
-
{publication.metadata.content}
+
{publication.metadata?.content}
{moment(publication.createdAt).format('HH:mm YY MMM DD')}
diff --git a/integrations/lens-protocol/components/publications/search-publications.tsx b/integrations/lens-protocol/components/publications/search-publications.tsx index e8ae70da..e8a62483 100644 --- a/integrations/lens-protocol/components/publications/search-publications.tsx +++ b/integrations/lens-protocol/components/publications/search-publications.tsx @@ -21,6 +21,7 @@ export const SearchPublications = ({ query }: { query: string }) => {
)} + {!publications?.length && No publications found.} ) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8bc27826..8e2f3b43 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7134,8 +7134,8 @@ packages: resolution: {integrity: sha512-Q9Leppzyb9Y2jwe+i8btAUkTXqgnu21PFql83v6N70dkELSC+fKBzRSRqUpFqruW7dcrG8mNWsOCQbQ0kL/w/w==} dev: false - /@lit/reactive-element@1.6.2: - resolution: {integrity: sha512-rDfl+QnCYjuIGf5xI2sVJWdYIi56CTCwWa+nidKYX6oIuBYwUbT/vX4qbUDlHiZKJ/3FRNQ/tWJui44p6/stSA==} + /@lit/reactive-element@1.6.1: + resolution: {integrity: sha512-va15kYZr7KZNNPZdxONGQzpUr+4sxVu7V/VG7a8mRfPPXUyhEYj5RzXCQmGrlP3tAh0L3HHm5AjBMFYRqlM9SA==} dependencies: '@lit-labs/ssr-dom-shim': 1.1.1 @@ -7240,7 +7240,7 @@ packages: '@ethereumjs/block': 3.6.3 ethereumjs-util: 7.1.5 merkle-patricia-tree: 4.2.4 - node-fetch: 2.6.9 + node-fetch: 2.6.12 transitivePeerDependencies: - encoding dev: false @@ -7252,7 +7252,7 @@ packages: '@ethereumjs/block': 3.6.3 ethereumjs-util: 7.1.5 merkle-patricia-tree: 4.2.4 - node-fetch: 2.6.9 + node-fetch: 2.6.12 transitivePeerDependencies: - encoding dev: false @@ -11311,8 +11311,8 @@ packages: resolution: {integrity: sha512-xUeFPpElybgn1a+lknqtHleei4VyuV/4qWgB1nP8qQUAO6a5pNsioODrnB2VAPdUHJYBdx2dCt2maRk6g53IPQ==} dependencies: '@walletconnect/heartbeat': 1.2.1 - '@walletconnect/jsonrpc-provider': 1.0.12 - '@walletconnect/jsonrpc-utils': 1.0.7 + '@walletconnect/jsonrpc-provider': 1.0.13 + '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/jsonrpc-ws-connection': 1.0.11 '@walletconnect/keyvaluestorage': 1.0.2 '@walletconnect/logger': 2.0.1 @@ -11512,6 +11512,7 @@ packages: dependencies: keyvaluestorage-interface: 1.0.0 tslib: 1.14.1 + dev: false /@walletconnect/jsonrpc-types@1.0.3: resolution: {integrity: sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw==} @@ -11537,7 +11538,7 @@ packages: /@walletconnect/jsonrpc-ws-connection@1.0.11: resolution: {integrity: sha512-TiFJ6saasKXD+PwGkm5ZGSw0837nc6EeFmurSPgIT/NofnOV4Tv7CVJqGQN0rQYoJUSYu21cwHNYaFkzNpUN+w==} dependencies: - '@walletconnect/jsonrpc-utils': 1.0.7 + '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/safe-json': 1.0.2 events: 3.3.0 tslib: 1.14.1 @@ -11667,7 +11668,7 @@ packages: /@walletconnect/relay-api@1.0.9: resolution: {integrity: sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg==} dependencies: - '@walletconnect/jsonrpc-types': 1.0.2 + '@walletconnect/jsonrpc-types': 1.0.3 tslib: 1.14.1 /@walletconnect/relay-auth@1.0.4: @@ -17518,8 +17519,8 @@ packages: it-to-stream: 1.0.0 merge-options: 3.0.4 nanoid: 3.3.6 - native-fetch: 3.0.0(node-fetch@2.6.9) - node-fetch: 2.6.9 + native-fetch: 3.0.0(node-fetch@2.6.12) + node-fetch: 2.6.12 react-native-fetch-api: 3.0.0 stream-to-it: 0.2.4 transitivePeerDependencies: @@ -20281,6 +20282,14 @@ packages: resolution: {integrity: sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==} dev: false + /native-fetch@3.0.0(node-fetch@2.6.12): + resolution: {integrity: sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==} + peerDependencies: + node-fetch: '*' + dependencies: + node-fetch: 2.6.12 + dev: false + /native-fetch@3.0.0(node-fetch@2.6.9): resolution: {integrity: sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==} peerDependencies: @@ -20731,8 +20740,8 @@ packages: tslib: 2.5.0 dev: false - /optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + /optionator@0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} dependencies: '@aashutoshrathi/word-wrap': 1.2.6 @@ -21657,7 +21666,7 @@ packages: bl: 5.1.0 debug: 4.3.4(supports-color@5.5.0) minimist: 1.2.8 - node-fetch: 2.6.9 + node-fetch: 2.6.12 readable-stream: 3.6.2 transitivePeerDependencies: - encoding From 440061165098da33bacde9ace3070706d03f0fef Mon Sep 17 00:00:00 2001 From: Q Date: Sun, 27 Aug 2023 11:33:33 +0330 Subject: [PATCH 03/13] chore: removed debug comment --- integrations/lens-protocol/components/feed.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/integrations/lens-protocol/components/feed.tsx b/integrations/lens-protocol/components/feed.tsx index 1755b39a..ac381559 100644 --- a/integrations/lens-protocol/components/feed.tsx +++ b/integrations/lens-protocol/components/feed.tsx @@ -10,7 +10,6 @@ export const Feed = ({ profileId }: { profileId: ProfileId }) => { profileId, limit: 10, }) - console.error(data) if (loading) return return (
From 1d6dbd11d9bb567ec46e4b84dbe2f03d7ab4ea2d Mon Sep 17 00:00:00 2001 From: Q Date: Sun, 27 Aug 2023 12:41:47 +0330 Subject: [PATCH 04/13] chore: lens-protocol directory lint-fixed --- .../lens-protocol/components/feed.tsx | 6 +- .../lens-protocol/components/navbar.tsx | 22 ++--- .../components/profile/address-profiles.tsx | 12 +-- .../components/profile/explore-profiles.tsx | 10 +- .../components/profile/owned-profiles.tsx | 22 ++--- .../components/profile/profile-card.tsx | 10 +- .../components/profile/profile-list-modal.tsx | 14 +-- .../profile/profile-publications.tsx | 29 ++++-- .../components/profile/profile-revenue.tsx | 10 +- .../components/profile/profile-stats.tsx | 2 +- .../components/profile/profile.tsx | 94 ++++++++++--------- .../components/profile/search-profiles.tsx | 10 +- .../publications/actions/button.tsx | 3 +- .../components/publications/actions/like.tsx | 2 +- .../publications/actions/mirror.tsx | 2 +- .../components/publications/commnets.tsx | 8 +- .../publications/explore-publications.tsx | 8 +- .../publication-actions-and-stats.tsx | 4 +- .../publications/publication-card.tsx | 14 +-- .../publications/publication-revenue.tsx | 10 +- .../components/publications/publication.tsx | 22 ++--- .../publications/search-publications.tsx | 8 +- .../components/publications/stats/index.tsx | 4 +- 23 files changed, 171 insertions(+), 155 deletions(-) diff --git a/integrations/lens-protocol/components/feed.tsx b/integrations/lens-protocol/components/feed.tsx index ac381559..7c7b0b94 100644 --- a/integrations/lens-protocol/components/feed.tsx +++ b/integrations/lens-protocol/components/feed.tsx @@ -13,7 +13,7 @@ export const Feed = ({ profileId }: { profileId: ProfileId }) => { if (loading) return return (
-

Feed

+

Feed

{data?.map((feedItem) => ( { /> ))} {hasMore && ( - )} {loading && ( -
+
)} diff --git a/integrations/lens-protocol/components/navbar.tsx b/integrations/lens-protocol/components/navbar.tsx index a55610c1..3abca951 100644 --- a/integrations/lens-protocol/components/navbar.tsx +++ b/integrations/lens-protocol/components/navbar.tsx @@ -6,11 +6,11 @@ import { useRouter } from 'next/navigation' import { LinkComponent } from '@/components/shared/link-component' import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' -import { getProfilePictureSrc } from '../utils' import { IsUserAuthenticated } from './auth/is-user-authenticated' import { LoginButton } from './auth/login-button' import { LogoutButton } from './auth/logout-button' import { NotAuthenticatedYet } from './auth/not-authenticated-yet' +import { getProfilePictureSrc } from '../utils' export const Navbar = () => { const [searchQuery, setSearchQuery] = useState('') @@ -20,22 +20,22 @@ export const Navbar = () => { }, [searchQuery]) const { data: activeProfile } = useActiveProfile() return ( -