diff --git a/public/person_placeholder.svg b/public/person_placeholder.svg
new file mode 100644
index 000000000..bedd0694b
--- /dev/null
+++ b/public/person_placeholder.svg
@@ -0,0 +1,16 @@
+
diff --git a/public/verified_twitter.svg b/public/verified_twitter.svg
new file mode 100644
index 000000000..d5fcfc837
--- /dev/null
+++ b/public/verified_twitter.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/components/AddNodeModal/SourceUrl/index.tsx b/src/components/AddNodeModal/SourceUrl/index.tsx
index 9b27c8093..334c5125a 100644
--- a/src/components/AddNodeModal/SourceUrl/index.tsx
+++ b/src/components/AddNodeModal/SourceUrl/index.tsx
@@ -1,12 +1,12 @@
-import React, { useState, FC } from 'react'
+import { FC, useState } from 'react'
+import { FaCheck } from 'react-icons/fa'
import styled from 'styled-components'
import { Flex } from '~/components/common/Flex'
import { colors } from '~/utils/colors'
-import { requiredRule } from '../index'
import { TagInput } from '../TagInput'
import { TextArea } from '../TextArea'
import { TextInput } from '../TextInput'
-import { FaCheck } from 'react-icons/fa'
+import { requiredRule } from '../index'
type Props = {
startTime?: string
diff --git a/src/components/App/Providers/MuiButton.ts b/src/components/App/Providers/MuiButton.ts
index a2b781737..8aa7ea275 100644
--- a/src/components/App/Providers/MuiButton.ts
+++ b/src/components/App/Providers/MuiButton.ts
@@ -19,7 +19,7 @@ export const MuiButton = {
fontSize: '12px',
fontStyle: 'normal',
fontWeight: '400',
- lineHeight: 'normal',
+ lineHeight: '8px',
cursor: 'pointer',
columnGap: '6px',
'&:hover': {
diff --git a/src/components/App/Providers/index.tsx b/src/components/App/Providers/index.tsx
index d08a9aa16..b83a63ed3 100644
--- a/src/components/App/Providers/index.tsx
+++ b/src/components/App/Providers/index.tsx
@@ -8,6 +8,7 @@ import { FC, PropsWithChildren } from 'react'
import { ThemeProvider as StyleThemeProvider } from 'styled-components'
import { colors } from '~/utils/colors'
import { breakpoints } from '~/utils/media'
+import { MuiButton } from './MuiButton'
const palette = createPalette({
mode: 'dark',
@@ -16,89 +17,16 @@ const palette = createPalette({
},
})
-const MuiButton = {
- defaultProps: {
- disableElevation: true,
- disableRipple: true,
- },
- styleOverrides: {
- root: {
- display: 'inline-flex',
- padding: '12px 20px',
- justifyContent: 'center',
- alignItems: 'center',
- gap: '10px',
- borderRadius: '200px',
- background: colors.BUTTON1,
- color: 'var(--Primary-Text, #fff)',
- fontFamily: 'Barlow',
- fontSize: '12px',
- fontStyle: 'normal',
- fontWeight: '400',
- lineHeight: 'normal',
- cursor: 'pointer',
- columnGap: '6px',
- '&:hover': {
- background: colors.BUTTON1_HOVER,
- color: colors.GRAY3,
- outline: 'none',
- boxShadow: 'none',
- },
- '&:focus': {
- outline: 'none',
- boxShadow: 'none',
- background: colors.BUTTON1_PRESS,
- color: colors.GRAY6,
- },
- '&:active': {
- outline: 'none',
- boxShadow: 'none',
- background: colors.BUTTON1_PRESS,
- color: colors.GRAY6,
- },
- '&.MuiButton-sizeSmall': {
- padding: '7px 16px',
- fontSize: '11px',
- fontWeight: 500,
- },
- '&.MuiButton-sizeLarge': {
- padding: '12px 24px',
- fontSize: '1.2rem',
- },
-
- '&.MuiButton-outlined': {},
- },
- outlined: {
- // Add your custom styles here for the outlined variant
- borderColor: colors.BUTTON1,
- borderWidth: '1px',
- backgroundColor: 'transparent',
- '&:hover': {
- borderColor: colors.BUTTON1_HOVER,
- backgroundColor: 'transparent',
- color: colors.GRAY3,
- },
- '&:active': {
- backgroundColor: colors.BUTTON1_PRESS,
- color: colors.GRAY6,
- },
- },
- startIcon: {
- // Define the size of the icon (adjust as needed)
- fontSize: '1em',
- },
- endIcon: {
- // Define the size of the icon (adjust as needed)
- fontSize: '1em',
- },
- },
-}
-
export const appTheme = createTheme({
palette,
components: {
MuiButton,
},
+ typography: {
+ button: {
+ textTransform: 'none',
+ },
+ },
breakpoints: {
values: {
xs: breakpoints.small,
diff --git a/src/components/App/SideBar/Relevance/Episode/TypePerson/index.tsx b/src/components/App/SideBar/Relevance/Episode/TypePerson/index.tsx
new file mode 100644
index 000000000..82fa4a5b6
--- /dev/null
+++ b/src/components/App/SideBar/Relevance/Episode/TypePerson/index.tsx
@@ -0,0 +1,38 @@
+import styled from 'styled-components'
+import { Avatar } from '~/components/common/Avatar'
+import { Flex } from '~/components/common/Flex'
+import { colors } from '~/utils/colors'
+
+type Props = {
+ title: string
+ imageUrl?: string
+ name: string
+}
+
+export const TypePerson = ({ title, imageUrl, name }: Props) => (
+
+
+
+
+ {(title || name) && {title || name}}
+
+)
+
+const PictureWrapper = styled(Flex)`
+ img {
+ width: 64px;
+ height: 64px
+ border-radius: 50%;
+ object-fit: cover;
+ }
+ margin-right: 16px;
+`
+
+const Name = styled(Flex)`
+ color: ${colors.white};
+ font-family: Barlow;
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 17px;
+`
diff --git a/src/components/App/SideBar/Relevance/Episode/TypeTweet/index.tsx b/src/components/App/SideBar/Relevance/Episode/TypeTweet/index.tsx
new file mode 100644
index 000000000..80ad068fc
--- /dev/null
+++ b/src/components/App/SideBar/Relevance/Episode/TypeTweet/index.tsx
@@ -0,0 +1,91 @@
+import moment from 'moment'
+import styled from 'styled-components'
+import { Avatar } from '~/components/common/Avatar'
+import { Flex } from '~/components/common/Flex'
+import { colors } from '~/utils/colors'
+import { Date } from '..'
+
+type Props = {
+ text: string
+ imageUrl?: string
+ twitterHandle?: string
+ date: number
+ name: string
+ verified: boolean
+}
+
+export const TypeTweet = ({ text, imageUrl, date, twitterHandle, name, verified }: Props) => (
+
+
+
+
+
+
+
+ {name}
+ {verified && (
+
+
+
+ )}
+
+ {twitterHandle && @{twitterHandle}}
+
+
+
+
+ {text}
+
+ {Boolean(date) && {moment.unix(date).format('ll')}}
+
+
+
+)
+
+const PictureWrapper = styled(Flex)`
+ img {
+ width: 64px;
+ height: 64px
+ border-radius: 50%;
+ object-fit: cover;
+ }
+ margin-right: 16px;
+`
+
+const Name = styled(Flex)`
+ color: ${colors.white};
+ font-family: Barlow;
+ font-size: 11px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
+ letter-spacing: -0.22px;
+ .verification {
+ margin-left: 4px;
+ }
+`
+
+const TwitterHandle = styled(Flex)`
+ color: ${colors.GRAY7};
+ font-family: Barlow;
+ font-size: 9px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: normal;
+`
+
+const TwitText = styled(Flex)`
+ color: ${colors.white};
+ font-family: Barlow;
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 130%;
+ letter-spacing: -0.39px;
+ margin: 8px 0;
+ display: -webkit-box;
+ -webkit-line-clamp: 2; /* Limit to two lines */
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ white-space: normal;
+`
diff --git a/src/components/App/SideBar/Relevance/Episode/index.tsx b/src/components/App/SideBar/Relevance/Episode/index.tsx
index 4573740eb..d3cbc8b03 100644
--- a/src/components/App/SideBar/Relevance/Episode/index.tsx
+++ b/src/components/App/SideBar/Relevance/Episode/index.tsx
@@ -8,6 +8,8 @@ import { Text } from '~/components/common/Text'
import { TypeBadge } from '~/components/common/TypeBadge'
import { useDataStore } from '~/stores/useDataStore'
import { colors } from '~/utils/colors'
+import { TypePerson } from './TypePerson'
+import { TypeTweet } from './TypeTweet'
type EpisodeWrapperProps = FlexboxProps & {
isSelected?: boolean
@@ -45,7 +47,12 @@ type Props = {
id?: string
imageUrl: string
title?: string
+ text?: string
type?: string
+ name?: string
+ verified?: boolean
+ twitterHandle?: string
+ profilePicture?: string
className?: string
onClick: () => void
}
@@ -59,6 +66,11 @@ export const Episode = ({
imageUrl,
title,
type,
+ text,
+ name,
+ profilePicture,
+ verified = false,
+ twitterHandle,
className = 'episode-wrapper',
onClick,
}: Props) => {
@@ -67,35 +79,50 @@ export const Episode = ({
return (
-
- {!isSelectedView && (
-
-
+ {type !== 'tweet' && type !== 'person' && type !== 'guest' && (
+
+ {!isSelectedView && (
+
+
- {false && }
-
- )}
+ {false && }
+
+ )}
-
-
-
- {type && }
+
+
+
+ {type && }
+
-
- {description}
-
- {Boolean(date) && {moment.unix(date).format('ll')}}
- {Boolean(title) && {title}}
- {false && }
+ {description}
+
+ {Boolean(date) && {moment.unix(date).format('ll')}}
+ {Boolean(title) && {title}}
+ {false && }
+
-
+ )}
+ {['person', 'guest'].includes(type as string) && (
+
+ )}
+ {type === 'tweet' && (
+
+ )}
)
}
-const Description = styled(Flex)`
+export const Description = styled(Flex)`
font-family: Barlow;
font-size: 13px;
font-style: normal;
@@ -110,7 +137,7 @@ const Description = styled(Flex)`
white-space: normal;
`
-const Date = styled(Text)`
+export const Date = styled(Text)`
overflow: hidden;
color: ${colors.GRAY6};
text-overflow: ellipsis;
@@ -123,7 +150,7 @@ const Date = styled(Text)`
flex-shrink: 0;
`
-const Title = styled(Date)`
+export const Title = styled(Date)`
display: flex;
flex-direction: row;
align-items: center;
diff --git a/src/components/App/SideBar/Relevance/EpisodeSkeleton/index.tsx b/src/components/App/SideBar/Relevance/EpisodeSkeleton/index.tsx
new file mode 100644
index 000000000..12783b864
--- /dev/null
+++ b/src/components/App/SideBar/Relevance/EpisodeSkeleton/index.tsx
@@ -0,0 +1,116 @@
+import { Skeleton } from '@mui/material'
+import styled from 'styled-components'
+import { Flex } from '~/components/common/Flex'
+import { FlexboxProps } from '~/components/common/Flex/flexbox'
+import { Text } from '~/components/common/Text'
+import { colors } from '~/utils/colors'
+
+type EpisodeWrapperProps = FlexboxProps & {
+ isSelected?: boolean
+}
+
+const EpisodeWrapper = styled(Flex).attrs({
+ direction: 'column',
+})`
+ padding: 24px;
+ cursor: pointer;
+ border-top: 1px solid #101317;
+ background: ${colors.BG1};
+
+ .type-image {
+ width: 20px;
+ height: 20px;
+ border-radius: 50%;
+ margin-right: 8px;
+ }
+
+ .booster__pill {
+ margin-right: 0;
+ margin-top: 8px;
+ }
+ .player-controls {
+ margin-left: 4px;
+ }
+
+ .title {
+ margin: 20px 0 8px;
+ }
+`
+
+const StyledSkeleton = styled(Skeleton)`
+ && {
+ background: rgba(0, 0, 0, 0.15);
+ }
+`
+
+export const EpisodeSkeleton = () => (
+ <>
+ {Array(7)
+ .fill(null)
+ .map((val, index) => (
+ // eslint-disable-next-line react/no-array-index-key
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+ >
+)
+
+export const Description = styled(Flex)`
+ font-family: Barlow;
+ font-size: 13px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 17px;
+ color: ${colors.white};
+ margin: 16px 0;
+ display: -webkit-box;
+ -webkit-line-clamp: 2; /* Limit to two lines */
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ white-space: normal;
+`
+
+export const Date = styled(Text)`
+ overflow: hidden;
+ color: ${colors.GRAY6};
+ text-overflow: ellipsis;
+ font-family: Barlow;
+ font-size: 11px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 18px;
+ margin-right: 8px;
+ flex-shrink: 0;
+`
+
+export const Title = styled(Date)`
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ flex-shrink: 1;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ &:before {
+ content: '';
+ display: block;
+ border-radius: 2px;
+ margin-right: 8px;
+ width: 4px;
+ flex-shrink: 0;
+ height: 4px;
+ background: ${colors.GRAY6};
+ }
+`
diff --git a/src/components/App/SideBar/Relevance/index.tsx b/src/components/App/SideBar/Relevance/index.tsx
index c371b7465..1bc683709 100644
--- a/src/components/App/SideBar/Relevance/index.tsx
+++ b/src/components/App/SideBar/Relevance/index.tsx
@@ -1,8 +1,9 @@
+import { Button } from '@mui/material'
import { ReactNode, useCallback, useMemo, useRef, useState } from 'react'
+import styled from 'styled-components'
import { useGraphData } from '~/components/DataRetriever'
import { ScrollView } from '~/components/ScrollView'
import { Flex } from '~/components/common/Flex'
-import { Pill } from '~/components/common/Pill'
import { useAppStore } from '~/stores/useAppStore'
import { useDataStore } from '~/stores/useDataStore'
import { NodeExtended } from '~/types'
@@ -36,11 +37,10 @@ export const Relevance = ({ header = null }: Props) => {
const endSlice = startSlice + pageSize
const hasNext = data.nodes.length - 1 > endSlice
- const hasPrevious = startSlice > 0
const isMobile = useIsMatchBreakpoint('sm', 'down')
- const currentNodes = useMemo(() => data.nodes.slice(startSlice, endSlice), [data.nodes, endSlice, startSlice])
+ const currentNodes = useMemo(() => data.nodes.slice(0, endSlice), [data.nodes, endSlice])
const handleNodeClick = useCallback(
(node: NodeExtended) => {
@@ -70,6 +70,11 @@ export const Relevance = ({ header = null }: Props) => {
id,
episode_title: episodeTitle,
node_type: nodeType,
+ text,
+ name,
+ profile_picture: profilePicture,
+ verified = false,
+ twitter_handle: twitterHandle,
} = n || {}
return (
@@ -81,26 +86,20 @@ export const Relevance = ({ header = null }: Props) => {
description={formatDescription(description)}
id={id}
imageUrl={imageUrl || 'audio_default.svg'}
+ name={name || ''}
onClick={() => handleNodeClick(n)}
+ profilePicture={profilePicture}
+ text={text || ''}
title={episodeTitle}
+ twitterHandle={twitterHandle}
type={type || nodeType}
+ verified={verified}
/>
)
})}
-
- {
- if (hasPrevious) {
- setCurrentPage(currentPage - 1)
- scrollViewRef.current?.scrollTo(0, 0)
- }
- }}
- >
- Previous
-
-
+
-
+ Load More
+
+
>
)
}
+
+const LoadMoreWrapper = styled(Flex)`
+ flex: 0 0 86px;
+`
diff --git a/src/components/App/SideBar/SelectedNodeView/index.tsx b/src/components/App/SideBar/SelectedNodeView/index.tsx
index fb1951291..6f0130a16 100644
--- a/src/components/App/SideBar/SelectedNodeView/index.tsx
+++ b/src/components/App/SideBar/SelectedNodeView/index.tsx
@@ -6,11 +6,11 @@ import { Creator } from '../Creator'
import { Data } from '../Data'
import { Messages } from '../Messages'
import { Person } from '../Person'
-import { YouTube } from '../Relevance/YouTube'
import { Show } from '../Show'
import { Topic } from '../Topic'
import { TwitData } from '../TwitData'
import { Twitter } from '../Twitter'
+import { YouTube } from '../YouTube'
// eslint-disable-next-line no-underscore-dangle
const _View = () => {
diff --git a/src/components/App/SideBar/TwitData/index.tsx b/src/components/App/SideBar/TwitData/index.tsx
index 07907bba2..497d4ccbd 100644
--- a/src/components/App/SideBar/TwitData/index.tsx
+++ b/src/components/App/SideBar/TwitData/index.tsx
@@ -19,7 +19,7 @@ export const TwitData = () => {
-
+
diff --git a/src/components/App/SideBar/Relevance/YouTube/index.tsx b/src/components/App/SideBar/YouTube/index.tsx
similarity index 95%
rename from src/components/App/SideBar/Relevance/YouTube/index.tsx
rename to src/components/App/SideBar/YouTube/index.tsx
index c7320cb14..31c8a27fc 100644
--- a/src/components/App/SideBar/Relevance/YouTube/index.tsx
+++ b/src/components/App/SideBar/YouTube/index.tsx
@@ -5,8 +5,8 @@ import { Flex } from '~/components/common/Flex'
import { useSelectedNode } from '~/stores/useDataStore'
import { formatDescription } from '~/utils/formatDescription'
import { videoTimetoSeconds } from '~/utils/videoTimetoSeconds'
-import { Transcript } from '../../Transcript'
-import { Episode } from '../Episode'
+import { Episode } from '../Relevance/Episode'
+import { Transcript } from '../Transcript'
export const YouTube = () => {
const selectedNode = useSelectedNode()
diff --git a/src/components/App/SideBar/index.tsx b/src/components/App/SideBar/index.tsx
index 46861e1a1..7c1c9f582 100644
--- a/src/components/App/SideBar/index.tsx
+++ b/src/components/App/SideBar/index.tsx
@@ -1,20 +1,21 @@
-import { Slide } from '@mui/material'
+import { Button, Slide } from '@mui/material'
import { forwardRef, useEffect, useRef, useState } from 'react'
import { useFormContext } from 'react-hook-form'
import styled from 'styled-components'
import { SearchBar } from '~/components/SearchBar'
import { Flex } from '~/components/common/Flex'
-import { Loader } from '~/components/common/Loader'
import { useAppStore } from '~/stores/useAppStore'
import { useDataStore, useSelectedNode } from '~/stores/useDataStore'
import { colors } from '~/utils/colors'
import clsx from 'clsx'
+import { ClipLoader } from 'react-spinners'
import { useGraphData } from '~/components/DataRetriever'
import ChevronLeftIcon from '~/components/Icons/ChevronLeftIcon'
import ClearIcon from '~/components/Icons/ClearIcon'
import SearchIcon from '~/components/Icons/SearchIcon'
import { LatestView } from './Latest'
+import { EpisodeSkeleton } from './Relevance/EpisodeSkeleton'
import { SideBarSubView } from './SidebarSubView'
import { Tab } from './Tab'
import { Trending } from './Trending'
@@ -65,14 +66,17 @@ const Content = forwardRef(({ onSubmit, subViewOpen
-
{
setValue('search', '')
clearSearch()
}}
>
- {searchTerm ? : }
+ {!isLoading ? (
+ <>{searchTerm ? : }>
+ ) : (
+
+ )}
{searchTerm && (
@@ -82,7 +86,7 @@ const Content = forwardRef(({ onSubmit, subViewOpen
results
)}
@@ -102,7 +106,7 @@ const Content = forwardRef(({ onSubmit, subViewOpen
)}
- {isLoading ? : }
+ {isLoading ? : }
)
@@ -182,38 +186,6 @@ const SearchDetails = styled(Flex).attrs({
}
`
-const ActionButton = styled(Flex)`
- display: inline-flex;
- padding: 12px 20px;
- justify-content: center;
- align-items: center;
- gap: 10px;
- border-radius: 200px;
- background: ${colors.BUTTON1};
- color: var(--Primary-Text, #fff);
- text-align: center;
- font-family: Barlow;
- font-size: 12px;
- font-style: normal;
- font-weight: 400;
- line-height: normal;
- cursor: pointer;
-
- & + & {
- margin-left: 8px;
- }
-
- &:hover {
- background: ${colors.BUTTON1_HOVER};
- color: ${colors.GRAY3};
- }
-
- &:active {
- background: ${colors.BUTTON1_PRESS};
- color: ${colors.GRAY6};
- }
-`
-
const InputButton = styled(Flex).attrs({
align: 'center',
justify: 'center',
@@ -268,7 +240,7 @@ const CollapseButton = styled(Flex).attrs({
const ScrollWrapper = styled(Flex)(() => ({
overflow: 'auto',
- height: 'calc(100% - 158px)',
+ flex: 1,
width: '100%',
}))
diff --git a/src/components/common/Avatar/index.tsx b/src/components/common/Avatar/index.tsx
index 2f321a629..1f29f84e0 100644
--- a/src/components/common/Avatar/index.tsx
+++ b/src/components/common/Avatar/index.tsx
@@ -1,9 +1,10 @@
import styled from 'styled-components'
type Props = {
- size?: 45 | 80 | 130 | 188
+ size?: 45 | 80 | 130 | 188 | 64 | 27
src: string
type: string
+ rounded?: boolean
}
type TTypeMapper = {
@@ -13,7 +14,10 @@ type TTypeMapper = {
const TypesMapper: TTypeMapper = {
youtube: 'video',
podcast: 'audio',
+ clip: 'audio',
tweet: 'tweet',
+ person: 'person',
+ twitter_space: 'audio',
}
export const Avatar = styled.div`
@@ -22,5 +26,5 @@ export const Avatar = styled.div`
background-repeat: no-repeat;
width: ${({ size = 45 }) => size}px;
height: ${({ size = 45 }) => size}px;
- border-radius: 2px;
+ border-radius: ${({ rounded }) => (rounded ? '50%' : '2px')};
`
diff --git a/src/components/common/TypeBadge/index.tsx b/src/components/common/TypeBadge/index.tsx
index 42535d451..a9b5acaf7 100644
--- a/src/components/common/TypeBadge/index.tsx
+++ b/src/components/common/TypeBadge/index.tsx
@@ -12,8 +12,9 @@ type EpisodeTypeImage = {
}
const EpisodeTypeImages: EpisodeTypeImage = {
- podcast: { img: 'audio_badge.svg', label: 'clip' },
+ podcast: { img: 'audio_badge.svg', label: 'podcast' },
clip: { img: 'audio_badge.svg', label: 'clip' },
+ show: { img: 'audio_badge.svg', label: 'show' },
tweet: { img: 'twitter_badge.svg', label: 'tweet' },
twitter_space: { img: 'audio_badge.svg', label: 'twitter_space' },
youtube: { img: 'video_badge.svg', label: 'episode' },
diff --git a/src/types/index.ts b/src/types/index.ts
index bd32d546d..40cc8014a 100644
--- a/src/types/index.ts
+++ b/src/types/index.ts
@@ -52,6 +52,7 @@ export type Node = {
weight?: number
tweet_id?: string
twitter_handle?: string
+ profile_picture?: string
verified?: boolean
unique_id?: string
}