Add Activity Center (#312)
* add activityCenter.ts
* use activityCenter.ts
* add "Launch via Vite Node"
* remove comments
* add comments
* type hook
* reverse order of notifications
* remove `activityCenter` from `provider.tsx`
* set `count`'s default value
* ref `ChatMessage` by id instead of object reference
* Revert "ref `ChatMessage` by id instead of object reference"
This reverts commit 1284386d22
.
* add badge `totalCount`
* add `@radix-ui/react-tabs`
* skip non-mentions
* update comments
* add `member` to `ChatMessage`
* add `MarkAllAsReadIcon`
* add `40` avatar variant
* add `initialsCount` to `Avatar`
* add `TinyReplyIcon`
* use `Popover`
* move components
* move components
* wip
* ignore clicks on tags themselves
* add root route
* use chat display name
* fix icons
* use `asChild` for tabs
* remove `vertical`
* use `value` and `onValueChange`
* use active state with `compoundVariants`
* use `&[data-state]...` instead of `compoundVarinats` and `active` prop
* fixup `chatDisplayName`
* postion badge
* prevent dragging of the whole page in either direction
* add tooltips
* change message's background on hover
* change navigation style
* add `category` to `removeNotifications`
* prevent deleting of messages that are not mentions or replies from activity center
* show members sidebar by default
* fix members layout
* add comment
* add `date-fns`
* add date separator
* comment
* move `Badge` to `/system`
* move `Tag` to `/system`
* comment `Text`
* replace `Link` for `useNavigate`
* move `Activity` to `/system`
* comment
* export `Notification`
* update fixtures in `activityCenter`
* remove fixtures
* movet `Tabs` to `/system`
* update `mapChatMessage`
* update `.eslintignore`
* resolve typecheck errors
* update `.prettierignore`
* resolve formatting error
* upgrade tooltip
* use `scrollIntoView`
* remove comments
* rename `close` to `onNavigateChange`
* revert scrolling changes in `/member-sidebar`
* rename members label from `Online` to `All`
* rename `initialsCount` and use union
* rename `MarkAllAsReadIcon`
* rename `selected`
* fix typo
* revert formatting
* close `Avatar`
* use `css` where possible without changing elements
* extract props types to interfaces
* rename `ActivityCenter`
* remove `overflow`
* replace `style` for not yet stitched elements
* revert global style changes
This commit is contained in:
parent
2b71b49e71
commit
36322d5a41
|
@ -2,3 +2,4 @@
|
||||||
**/node_modules
|
**/node_modules
|
||||||
**/protos
|
**/protos
|
||||||
**/proto
|
**/proto
|
||||||
|
**/coverage
|
||||||
|
|
|
@ -3,3 +3,4 @@
|
||||||
.parcel-cache
|
.parcel-cache
|
||||||
.github
|
.github
|
||||||
**/protos
|
**/protos
|
||||||
|
**/coverage
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
// todo?: rename to notifications (center?), inbox, or keep same as other platforms
|
// todo?: rename to notifications (center?), inbox, or keep same as other platforms
|
||||||
|
// todo: use kebab case for the file name
|
||||||
|
|
||||||
import type { ChatMessage } from './chat'
|
import type { ChatMessage } from './chat'
|
||||||
import type { Client } from './client'
|
import type { Client } from './client'
|
||||||
|
|
||||||
// todo?: rename to Activity
|
// todo?: rename to Activity
|
||||||
type Notification = {
|
export type Notification = {
|
||||||
type: 'message'
|
type: 'message'
|
||||||
value: ChatMessage
|
value: ChatMessage
|
||||||
isMention?: boolean
|
isMention?: boolean
|
||||||
|
@ -13,8 +14,9 @@ type Notification = {
|
||||||
|
|
||||||
export type ActivityCenterLatest = {
|
export type ActivityCenterLatest = {
|
||||||
notifications: Notification[]
|
notifications: Notification[]
|
||||||
// todo?: rename count to mentionsAndRepliesCount
|
// todo?: rename count to mentionsAndRepliesCount, mentionsCount
|
||||||
unreadChats: Map<string, { count: number }>
|
unreadChats: Map<string, { count: number }>
|
||||||
|
totalCount: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ActivityCenter {
|
export class ActivityCenter {
|
||||||
|
@ -33,6 +35,7 @@ export class ActivityCenter {
|
||||||
public getLatest = (): ActivityCenterLatest => {
|
public getLatest = (): ActivityCenterLatest => {
|
||||||
const notifications: Notification[] = []
|
const notifications: Notification[] = []
|
||||||
const unreadChats: Map<string, { count: number }> = new Map()
|
const unreadChats: Map<string, { count: number }> = new Map()
|
||||||
|
let totalCount = 0
|
||||||
|
|
||||||
for (const notification of this.#notifications.values()) {
|
for (const notification of this.#notifications.values()) {
|
||||||
if (notification.type === 'message') {
|
if (notification.type === 'message') {
|
||||||
|
@ -41,8 +44,10 @@ export class ActivityCenter {
|
||||||
const chat = unreadChats.get(chatUuid)
|
const chat = unreadChats.get(chatUuid)
|
||||||
let count = chat?.count ?? 0
|
let count = chat?.count ?? 0
|
||||||
|
|
||||||
if (notification.isMention || notification.isReply) {
|
const isMention = notification.isMention || notification.isReply
|
||||||
|
if (isMention) {
|
||||||
count++
|
count++
|
||||||
|
totalCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chat) {
|
if (chat) {
|
||||||
|
@ -50,6 +55,10 @@ export class ActivityCenter {
|
||||||
} else {
|
} else {
|
||||||
unreadChats.set(chatUuid, { count })
|
unreadChats.set(chatUuid, { count })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isMention) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
notifications.push(notification)
|
notifications.push(notification)
|
||||||
|
@ -67,12 +76,14 @@ export class ActivityCenter {
|
||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
|
|
||||||
// fixme!?: do not display regular messages, only mentions and replies
|
return {
|
||||||
// todo?: group notifications (all, unreads, mentions, replies, _chats.{id,count})
|
// todo?: group notifications (all, mentions, replies)
|
||||||
return { notifications, unreadChats }
|
notifications,
|
||||||
|
unreadChats,
|
||||||
|
totalCount,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: pass ids instead of values and resolve within
|
|
||||||
public addMessageNotification = (
|
public addMessageNotification = (
|
||||||
newMessage: ChatMessage,
|
newMessage: ChatMessage,
|
||||||
referencedMessage?: ChatMessage
|
referencedMessage?: ChatMessage
|
||||||
|
@ -98,15 +109,49 @@ export class ActivityCenter {
|
||||||
this.emitLatest()
|
this.emitLatest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo?: also calls `clearChatNotifications` (on non-action items/notifications)?
|
||||||
|
// markAllAsRead = () => {}
|
||||||
|
|
||||||
|
// todo?: for example from chat with red bar in UI indicating start
|
||||||
|
// markChatNotificationsAsUnreadSince = (category, id) => {}
|
||||||
|
|
||||||
|
// todo?: rename to `clearChatNotifications`; separate (button) from `markAllAsRead`?
|
||||||
|
// todo?: merge with `removeChatNotifications`; together with `notification.type` condition
|
||||||
/**
|
/**
|
||||||
* Removes all notifications.
|
* Removes all notifications.
|
||||||
*/
|
*/
|
||||||
removeNotifications = () => {
|
removeNotifications = (category: 'all' | 'mentions' | 'replies') => {
|
||||||
this.#notifications.clear()
|
// todo?: clear all non-actionable notification too
|
||||||
|
if (category === 'all') {
|
||||||
|
for (const notification of this.#notifications) {
|
||||||
|
const { isMention, isReply } = notification
|
||||||
|
|
||||||
|
if (!(isMention || isReply)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#notifications.delete(notification)
|
||||||
|
}
|
||||||
|
} else if (category === 'mentions') {
|
||||||
|
// todo: extract to a func
|
||||||
|
this.#notifications.forEach(notification => {
|
||||||
|
if (notification.isMention) {
|
||||||
|
this.#notifications.delete(notification)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (category === 'replies') {
|
||||||
|
this.#notifications.forEach(notification => {
|
||||||
|
if (notification.isReply) {
|
||||||
|
this.#notifications.delete(notification)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
this.emitLatest()
|
this.emitLatest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo?: call from UI on ESC
|
||||||
|
// todo?: call from UI if scrolled all the way to the end
|
||||||
/**
|
/**
|
||||||
* Removes chat message notifications from the Activity Center. For example,
|
* Removes chat message notifications from the Activity Center. For example,
|
||||||
* on only opening or after scrolling to the end.
|
* on only opening or after scrolling to the end.
|
||||||
|
|
|
@ -20,6 +20,7 @@ import type { MessageType } from '../protos/enums'
|
||||||
import type { Client } from './client'
|
import type { Client } from './client'
|
||||||
import type { Community } from './community/community'
|
import type { Community } from './community/community'
|
||||||
import type { Reactions } from './community/get-reactions'
|
import type { Reactions } from './community/get-reactions'
|
||||||
|
import type { Member } from './member'
|
||||||
import type { WakuMessage } from 'js-waku'
|
import type { WakuMessage } from 'js-waku'
|
||||||
|
|
||||||
export type ChatMessage = ChatMessageProto & {
|
export type ChatMessage = ChatMessageProto & {
|
||||||
|
@ -28,6 +29,9 @@ export type ChatMessage = ChatMessageProto & {
|
||||||
reactions: Reactions
|
reactions: Reactions
|
||||||
chatUuid: string
|
chatUuid: string
|
||||||
signer: string
|
signer: string
|
||||||
|
member: Member
|
||||||
|
communityDisplayName: string
|
||||||
|
chatDisplayName: string
|
||||||
responseToMessage?: ChatMessage
|
responseToMessage?: ChatMessage
|
||||||
edittedClock?: bigint
|
edittedClock?: bigint
|
||||||
pinnedClock?: bigint
|
pinnedClock?: bigint
|
||||||
|
|
|
@ -126,6 +126,8 @@ export function handleWakuMessage(
|
||||||
messageId,
|
messageId,
|
||||||
chatUuid,
|
chatUuid,
|
||||||
signerPublicKey,
|
signerPublicKey,
|
||||||
|
community,
|
||||||
|
chat,
|
||||||
})
|
})
|
||||||
|
|
||||||
// handle
|
// handle
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import type { ChatMessage as ChatMessageProto } from '../../protos/chat-message'
|
import type { ChatMessage as ChatMessageProto } from '../../protos/chat-message'
|
||||||
import type { ChatMessage } from '../chat'
|
import type { Chat, ChatMessage } from '../chat'
|
||||||
|
import type { Community } from './community'
|
||||||
|
|
||||||
export function mapChatMessage(
|
export function mapChatMessage(
|
||||||
decodedMessage: ChatMessageProto,
|
decodedMessage: ChatMessageProto,
|
||||||
|
@ -7,9 +8,11 @@ export function mapChatMessage(
|
||||||
messageId: string
|
messageId: string
|
||||||
chatUuid: string
|
chatUuid: string
|
||||||
signerPublicKey: string
|
signerPublicKey: string
|
||||||
|
community: Community
|
||||||
|
chat: Chat
|
||||||
}
|
}
|
||||||
): ChatMessage {
|
): ChatMessage {
|
||||||
const { messageId, chatUuid, signerPublicKey } = props
|
const { messageId, chatUuid, signerPublicKey, community, chat } = props
|
||||||
|
|
||||||
const message: ChatMessage = {
|
const message: ChatMessage = {
|
||||||
...decodedMessage,
|
...decodedMessage,
|
||||||
|
@ -25,6 +28,10 @@ export function mapChatMessage(
|
||||||
SAD: new Set<string>(),
|
SAD: new Set<string>(),
|
||||||
ANGRY: new Set<string>(),
|
ANGRY: new Set<string>(),
|
||||||
},
|
},
|
||||||
|
member: community.getMember(signerPublicKey)!,
|
||||||
|
// todo?: asign as .community, .community.description, .communityDescription, or .community.displayName
|
||||||
|
communityDisplayName: community.description.identity!.displayName,
|
||||||
|
chatDisplayName: chat.description.identity!.displayName,
|
||||||
}
|
}
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
|
@ -2,6 +2,7 @@ export type { Account } from './client/account'
|
||||||
export type {
|
export type {
|
||||||
ActivityCenter,
|
ActivityCenter,
|
||||||
ActivityCenterLatest,
|
ActivityCenterLatest,
|
||||||
|
Notification,
|
||||||
} from './client/activityCenter'
|
} from './client/activityCenter'
|
||||||
export type { ChatMessage as Message } from './client/chat'
|
export type { ChatMessage as Message } from './client/chat'
|
||||||
export type { Client, ClientOptions } from './client/client'
|
export type { Client, ClientOptions } from './client/client'
|
||||||
|
|
|
@ -42,11 +42,13 @@
|
||||||
"@radix-ui/react-label": "^0.1.5",
|
"@radix-ui/react-label": "^0.1.5",
|
||||||
"@radix-ui/react-popover": "^0.1.6",
|
"@radix-ui/react-popover": "^0.1.6",
|
||||||
"@radix-ui/react-separator": "^0.1.4",
|
"@radix-ui/react-separator": "^0.1.4",
|
||||||
|
"@radix-ui/react-tabs": "^1.0.0",
|
||||||
"@radix-ui/react-toggle-group": "^0.1.5",
|
"@radix-ui/react-toggle-group": "^0.1.5",
|
||||||
"@radix-ui/react-tooltip": "^0.1.7",
|
"@radix-ui/react-tooltip": "^1.0.0",
|
||||||
"@radix-ui/react-visually-hidden": "^0.1.4",
|
"@radix-ui/react-visually-hidden": "^0.1.4",
|
||||||
"@status-im/js": "0.1.0-alpha.2",
|
"@status-im/js": "0.1.0-alpha.2",
|
||||||
"@stitches/react": "^1.2.8",
|
"@stitches/react": "^1.2.8",
|
||||||
|
"date-fns": "^2.29.3",
|
||||||
"emoji-mart": "^3.0.1",
|
"emoji-mart": "^3.0.1",
|
||||||
"html-entities": "^2.3.2",
|
"html-entities": "^2.3.2",
|
||||||
"qrcode.react": "^3.0.1",
|
"qrcode.react": "^3.0.1",
|
||||||
|
|
|
@ -11,7 +11,7 @@ export const EditGroupChatDialog = () => {
|
||||||
placeholder="A catchy name"
|
placeholder="A catchy name"
|
||||||
maxLength={30}
|
maxLength={30}
|
||||||
/>
|
/>
|
||||||
<Avatar size="120" />
|
<Avatar size="120" initialsLength={1} />
|
||||||
</Dialog.Body>
|
</Dialog.Body>
|
||||||
<Dialog.Actions>
|
<Dialog.Actions>
|
||||||
<Dialog.Action>Save changes</Dialog.Action>
|
<Dialog.Action>Save changes</Dialog.Action>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { NavLink } from 'react-router-dom'
|
||||||
|
|
||||||
import { useActivityCenter } from '../../../../protocol'
|
import { useActivityCenter } from '../../../../protocol'
|
||||||
import { styled } from '../../../../styles/config'
|
import { styled } from '../../../../styles/config'
|
||||||
import { Avatar } from '../../../../system'
|
import { Avatar, Badge, Flex } from '../../../../system'
|
||||||
|
|
||||||
import type { Chat } from '../../../../protocol/use-sorted-chats'
|
import type { Chat } from '../../../../protocol/use-sorted-chats'
|
||||||
import type { Ref } from 'react'
|
import type { Ref } from 'react'
|
||||||
|
@ -30,7 +30,10 @@ const ChatItem = (props: Props, ref: Ref<HTMLAnchorElement>) => {
|
||||||
to={`/${chat.id}`}
|
to={`/${chat.id}`}
|
||||||
state={muted ? 'muted' : unread ? 'unread' : undefined}
|
state={muted ? 'muted' : unread ? 'unread' : undefined}
|
||||||
>
|
>
|
||||||
<Avatar size={24} name={displayName} color={color} />#{displayName}
|
<Flex gap={2} align="center">
|
||||||
|
<Avatar size={24} name={displayName} color={color} initialsLength={1} />
|
||||||
|
#{displayName}
|
||||||
|
</Flex>
|
||||||
{count > 0 && <Badge>{count}</Badge>}
|
{count > 0 && <Badge>{count}</Badge>}
|
||||||
</Link>
|
</Link>
|
||||||
)
|
)
|
||||||
|
@ -46,11 +49,11 @@ const Link = styled(NavLink, {
|
||||||
fontFamily: '$sans',
|
fontFamily: '$sans',
|
||||||
fontWeight: '$500',
|
fontWeight: '$500',
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
display: 'inline-flex',
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
color: '$accent-4',
|
color: '$accent-4',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
gap: '$2',
|
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
padding: 8,
|
padding: 8,
|
||||||
|
|
||||||
|
@ -75,15 +78,3 @@ const Link = styled(NavLink, {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const Badge = styled('div', {
|
|
||||||
textAlign: 'center',
|
|
||||||
position: 'absolute',
|
|
||||||
right: 8,
|
|
||||||
width: 22,
|
|
||||||
height: 22,
|
|
||||||
background: '$primary-1',
|
|
||||||
borderRadius: '$full',
|
|
||||||
fontSize: 12,
|
|
||||||
color: '$accent-11',
|
|
||||||
})
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const Chats = () => {
|
||||||
const { categories, chats } = useSortedChats()
|
const { categories, chats } = useSortedChats()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box css={{ padding: '18px 0', overflow: 'auto' }}>
|
<Box css={{ padding: '18px 0', overflowY: 'scroll' }}>
|
||||||
{chats.map(chat => (
|
{chats.map(chat => (
|
||||||
<ChatItem key={chat.id} chat={chat} />
|
<ChatItem key={chat.id} chat={chat} />
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -14,7 +14,7 @@ export const CommunityInfo = () => {
|
||||||
return (
|
return (
|
||||||
<DialogTrigger>
|
<DialogTrigger>
|
||||||
<Button>
|
<Button>
|
||||||
<Avatar size={36} name={displayName} color={color} />
|
<Avatar size={36} name={displayName} color={color} initialsLength={1} />
|
||||||
<div>
|
<div>
|
||||||
<Text>{displayName}</Text>
|
<Text>{displayName}</Text>
|
||||||
<Text color="gray" size={12}>
|
<Text color="gray" size={12}>
|
||||||
|
|
|
@ -38,7 +38,6 @@ const Wrapper = styled('div', {
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
padding: '10px 16px',
|
padding: '10px 16px',
|
||||||
backgroundColor: '$gray-4',
|
backgroundColor: '$gray-4',
|
||||||
overflowY: 'scroll',
|
|
||||||
|
|
||||||
'@large': {
|
'@large': {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
|
|
|
@ -22,7 +22,7 @@ export function MemberSidebar() {
|
||||||
<UserItem account={account} />
|
<UserItem account={account} />
|
||||||
</MemberGroup>
|
</MemberGroup>
|
||||||
)}
|
)}
|
||||||
<MemberGroup label="Online">
|
<MemberGroup label="All">
|
||||||
{members.map(member => (
|
{members.map(member => (
|
||||||
<MemberItem
|
<MemberItem
|
||||||
key={member.publicKey}
|
key={member.publicKey}
|
||||||
|
|
|
@ -17,6 +17,7 @@ export const WelcomeDialog = () => {
|
||||||
size="64"
|
size="64"
|
||||||
src={identity?.displayName}
|
src={identity?.displayName}
|
||||||
color={identity?.color}
|
color={identity?.color}
|
||||||
|
initialsLength={1}
|
||||||
/>
|
/>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Text>{identity?.description}</Text>
|
<Text>{identity?.description}</Text>
|
||||||
|
|
|
@ -28,7 +28,7 @@ const reducer: Reducer<State, Action> = (state, action) => {
|
||||||
|
|
||||||
const initialState: State = {
|
const initialState: State = {
|
||||||
state: 'loading',
|
state: 'loading',
|
||||||
showMembers: false,
|
showMembers: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|
|
@ -90,7 +90,6 @@ function parseJSON<T>(value: string | null): T | undefined {
|
||||||
try {
|
try {
|
||||||
return value === 'undefined' ? undefined : JSON.parse(value ?? '')
|
return value === 'undefined' ? undefined : JSON.parse(value ?? '')
|
||||||
} catch {
|
} catch {
|
||||||
console.log('Parse error', { value })
|
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export const DoubleTickIcon = (props: React.SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="16"
|
||||||
|
viewBox="0 0 24 16"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M22.864 0.421992C23.2086 0.651757 23.3017 1.11741 23.072 1.46206L13.1979 15.4222C13.0733 15.6091 12.8714 15.7303 12.6478 15.7525C12.4242 15.7746 12.2025 15.6953 12.0436 15.5365L6.04357 9.53646C5.75067 9.24357 5.75067 8.76869 6.04357 8.4758C6.33646 8.18291 6.81133 8.18291 7.10423 8.4758L12.4573 13.8289L21.8239 0.630005C22.0537 0.285358 22.5193 0.192228 22.864 0.421992Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M17.8555 0.383649C18.1925 0.624401 18.2706 1.09281 18.0299 1.42988L12.0524 9.7986C11.8116 10.1357 11.3432 10.2137 11.0061 9.97298C10.6691 9.73223 10.591 9.26382 10.8318 8.92676L16.8092 0.558034C17.05 0.220971 17.5184 0.142897 17.8555 0.383649Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M1.01928 8.47976C1.31098 8.18568 1.78585 8.18375 2.07993 8.47546L8.09754 14.4444C8.39162 14.7361 8.39355 15.211 8.10185 15.505C7.81015 15.7991 7.33528 15.801 7.0412 15.5093L1.02359 9.54041C0.729506 9.24871 0.727577 8.77384 1.01928 8.47976Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export const TinyChevronRightIcon = (props: React.SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width={6}
|
||||||
|
height={9}
|
||||||
|
viewBox="0 0 6 9"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M.97.97a.75.75 0 000 1.06l2.116 2.116a.5.5 0 010 .708L.97 6.97a.75.75 0 001.06 1.06l3-3a.75.75 0 000-1.06l-3-3a.75.75 0 00-1.06 0z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
// todo: add to /tiny folder
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export const TinyCommunityIcon = (props: React.SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width={12}
|
||||||
|
height={12}
|
||||||
|
viewBox="0 0 12 12"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M8 12a2 2 0 002-2 2 2 0 002-2V2a2 2 0 00-2-2C4.477 0 0 4.477 0 10a2 2 0 002 2h6zm-5.5-2a.477.477 0 01-.485-.5A8.001 8.001 0 019.5 2.015c.276-.017.5.209.5.485v1a.534.534 0 01-.5.52A6.001 6.001 0 004.02 9.5a.534.534 0 01-.52.5h-1zM10 6.5c0-.276-.225-.503-.499-.47a4.002 4.002 0 00-3.47 3.471c-.034.274.193.499.469.499h1c.276 0 .494-.227.562-.495a2.003 2.003 0 011.443-1.443c.268-.068.495-.286.495-.562v-1z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export const TinyReplyIcon = (props: React.SVGProps<SVGSVGElement>) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width={10}
|
||||||
|
height={11}
|
||||||
|
viewBox="0 0 10 11"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 2.59V1.123c0-.62.373-.812.824-.422l4.004 3.445a.449.449 0 01-.001.704L5.822 8.297C5.373 8.685 5 8.495 5 7.874V6.5c-2.502 0-3.817 1.887-4.476 3.532-.103.258-.253.258-.324-.01A5.912 5.912 0 010 8.498a5.996 5.996 0 015-5.91z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
|
@ -22,6 +22,9 @@ export const useActivityCenter = () => {
|
||||||
}, [client.activityCenter])
|
}, [client.activityCenter])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
activityCenter: client.activityCenter,
|
||||||
|
notifications: latest.notifications,
|
||||||
unreadChats: latest.unreadChats,
|
unreadChats: latest.unreadChats,
|
||||||
|
totalCount: latest.totalCount,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ export const ChatInfo = (props: Props) => {
|
||||||
size={36}
|
size={36}
|
||||||
name={chat.identity?.displayName}
|
name={chat.identity?.displayName}
|
||||||
color={chat.identity?.color}
|
color={chat.identity?.color}
|
||||||
|
initialsLength={1}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<Text>#{chat.identity?.displayName}</Text>
|
<Text>#{chat.identity?.displayName}</Text>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { useChatContext } from '../../../../contexts/chat-context'
|
||||||
// import { BellIcon } from '../../../../icons/bell-icon'
|
// import { BellIcon } from '../../../../icons/bell-icon'
|
||||||
// import { PinIcon } from '../../../../icons/pin-icon'
|
// import { PinIcon } from '../../../../icons/pin-icon'
|
||||||
import { useProtocol } from '../../../../protocol'
|
import { useProtocol } from '../../../../protocol'
|
||||||
import { styled } from '../../../../styles/config'
|
import { keyframes, styled } from '../../../../styles/config'
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
Box,
|
Box,
|
||||||
|
@ -32,6 +32,7 @@ import type { Message, Reaction } from '../../../../protocol'
|
||||||
interface Props {
|
interface Props {
|
||||||
message: Message
|
message: Message
|
||||||
prevMessage?: Message
|
prevMessage?: Message
|
||||||
|
highlight?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// const MessageLink = forwardRef(function MessageLink(
|
// const MessageLink = forwardRef(function MessageLink(
|
||||||
|
@ -60,7 +61,7 @@ export const ChatMessage = (props: Props) => {
|
||||||
const { params } = useMatch(':id')!
|
const { params } = useMatch(':id')!
|
||||||
|
|
||||||
const chatId = params.id!
|
const chatId = params.id!
|
||||||
const { message } = props
|
const { message, highlight } = props
|
||||||
|
|
||||||
const mention = false
|
const mention = false
|
||||||
const pinned = false
|
const pinned = false
|
||||||
|
@ -172,7 +173,12 @@ export const ChatMessage = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* <ContextMenuTrigger> */}
|
{/* <ContextMenuTrigger> */}
|
||||||
<Wrapper mention={mention} pinned={pinned} data-active={reacting}>
|
<Wrapper
|
||||||
|
mention={mention}
|
||||||
|
pinned={pinned}
|
||||||
|
data-active={reacting}
|
||||||
|
highlight={highlight}
|
||||||
|
>
|
||||||
{responseTo && <MessageReply messageId={responseTo} />}
|
{responseTo && <MessageReply messageId={responseTo} />}
|
||||||
<Flex gap={2}>
|
<Flex gap={2}>
|
||||||
<Box>
|
<Box>
|
||||||
|
@ -262,6 +268,15 @@ export const ChatMessage = (props: Props) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const backgroundAnimation = keyframes({
|
||||||
|
from: {
|
||||||
|
backgroundColor: '$navigate-2',
|
||||||
|
},
|
||||||
|
to: {
|
||||||
|
backgroundColor: 'revert',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// TODO: Use compound variants https://stitches.dev/docs/variants#compound-variants
|
// TODO: Use compound variants https://stitches.dev/docs/variants#compound-variants
|
||||||
const Wrapper = styled('div', {
|
const Wrapper = styled('div', {
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
|
@ -273,7 +288,7 @@ const Wrapper = styled('div', {
|
||||||
transitionDuration: '100ms',
|
transitionDuration: '100ms',
|
||||||
|
|
||||||
'&:hover, &[data-open="true"], &[data-active="true"]': {
|
'&:hover, &[data-open="true"], &[data-active="true"]': {
|
||||||
background: '$gray-4',
|
background: '$gray-2',
|
||||||
},
|
},
|
||||||
|
|
||||||
a: {
|
a: {
|
||||||
|
@ -317,6 +332,13 @@ const Wrapper = styled('div', {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
highlight: {
|
||||||
|
true: {
|
||||||
|
'@motion': {
|
||||||
|
animation: `${backgroundAnimation} 3s ease-out 0s`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
compoundVariants: [],
|
compoundVariants: [],
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
import React, { Fragment, useState } from 'react'
|
||||||
|
|
||||||
|
import format from 'date-fns/format'
|
||||||
|
import isSameDay from 'date-fns/isSameDay'
|
||||||
|
import isSameYear from 'date-fns/isSameYear'
|
||||||
|
|
||||||
|
import { BellIcon } from '../../../../../../icons/bell-icon'
|
||||||
|
import { DoubleTickIcon } from '../../../../../../icons/double-tick-icon'
|
||||||
|
import { useActivityCenter } from '../../../../../../protocol'
|
||||||
|
import {
|
||||||
|
Activity,
|
||||||
|
Badge,
|
||||||
|
IconButton,
|
||||||
|
Popover,
|
||||||
|
PopoverTrigger,
|
||||||
|
Tabs,
|
||||||
|
Text,
|
||||||
|
Tooltip,
|
||||||
|
} from '../../../../../../system'
|
||||||
|
|
||||||
|
import type { Notification } from '@status-im/js'
|
||||||
|
|
||||||
|
export const ActivityCenterPopover = () => {
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
|
const { activityCenter, notifications, totalCount } = useActivityCenter()
|
||||||
|
|
||||||
|
const initialValue: {
|
||||||
|
all: Notification[]
|
||||||
|
mentions: Notification[]
|
||||||
|
replies: Notification[]
|
||||||
|
} = {
|
||||||
|
all: notifications,
|
||||||
|
mentions: [],
|
||||||
|
replies: [],
|
||||||
|
}
|
||||||
|
const { all, mentions, replies } = notifications.reduce((acc, obj) => {
|
||||||
|
if (obj.type === 'message') {
|
||||||
|
if (obj.isMention) {
|
||||||
|
acc.mentions.push(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.isReply) {
|
||||||
|
acc.replies.push(obj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc
|
||||||
|
}, initialValue)
|
||||||
|
|
||||||
|
const createContent = (
|
||||||
|
notifications: Notification[]
|
||||||
|
): JSX.Element | JSX.Element[] => {
|
||||||
|
const mappedNotifications = notifications.map(
|
||||||
|
(currentNotification, notificationIndex, iteratedNotifications) => {
|
||||||
|
const previousNotification =
|
||||||
|
iteratedNotifications[notificationIndex - 1]
|
||||||
|
|
||||||
|
let showNewDateSeparator: boolean
|
||||||
|
if (!previousNotification) {
|
||||||
|
showNewDateSeparator = true
|
||||||
|
} else {
|
||||||
|
showNewDateSeparator = !isSameDay(
|
||||||
|
new Date(Number(currentNotification.value.timestamp)),
|
||||||
|
new Date(Number(previousNotification.value.timestamp))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let date: string | undefined
|
||||||
|
if (showNewDateSeparator) {
|
||||||
|
const _date = new Date(Number(currentNotification.value.timestamp))
|
||||||
|
|
||||||
|
const today = new Date()
|
||||||
|
const yesterday = new Date().setDate(today.getDate() - 1)
|
||||||
|
|
||||||
|
if (isSameDay(_date, today)) {
|
||||||
|
date = 'Today'
|
||||||
|
} else if (isSameDay(_date, yesterday)) {
|
||||||
|
date = 'Yesterday'
|
||||||
|
} else if (isSameYear(_date, today)) {
|
||||||
|
date = format(_date, 'iii, d MMMM')
|
||||||
|
} else {
|
||||||
|
date = format(_date, 'iii, d MMMM yyyy')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fragment key={currentNotification.value.messageId}>
|
||||||
|
{/* todo: seperate separator component */}
|
||||||
|
{showNewDateSeparator && (
|
||||||
|
<Text
|
||||||
|
color="gray"
|
||||||
|
weight={400}
|
||||||
|
css={{ height: '34px', padding: '8px 16px 4px 16px' }}
|
||||||
|
>
|
||||||
|
{date}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
<Activity onNavigateChange={() => setOpen(false)}>
|
||||||
|
{currentNotification}
|
||||||
|
</Activity>
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!mappedNotifications.length) {
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
size="15"
|
||||||
|
color="gray"
|
||||||
|
weight="400"
|
||||||
|
align="center"
|
||||||
|
css={{
|
||||||
|
margin: 'auto',
|
||||||
|
position: 'relative',
|
||||||
|
top: '50%',
|
||||||
|
transform: 'translateY(-50%)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Notifications will appear here
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mappedNotifications
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PopoverTrigger open={open} onOpenChange={setOpen}>
|
||||||
|
<Tooltip label="Activity">
|
||||||
|
<IconButton
|
||||||
|
label="Show Activity Center"
|
||||||
|
onClick={() => setOpen(!open)}
|
||||||
|
css={{ position: 'relative' }}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
<BellIcon />
|
||||||
|
{totalCount > 0 && (
|
||||||
|
<Badge
|
||||||
|
variant="border"
|
||||||
|
css={{
|
||||||
|
position: 'absolute',
|
||||||
|
left: 16,
|
||||||
|
top: -2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{totalCount}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
<Popover side="bottom" css={{ width: 600, height: 770 }}>
|
||||||
|
<Tabs
|
||||||
|
tabs={[
|
||||||
|
{ title: 'All', value: 'all', content: createContent(all) },
|
||||||
|
{
|
||||||
|
title: 'Mentions',
|
||||||
|
value: 'mentions',
|
||||||
|
content: createContent(mentions),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Replies',
|
||||||
|
value: 'replies',
|
||||||
|
content: createContent(replies),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
actions={[
|
||||||
|
{
|
||||||
|
icon: <DoubleTickIcon />,
|
||||||
|
// todo: call it "Mark as Read" since the action is relative to active tab
|
||||||
|
label: 'Mark All As Read',
|
||||||
|
method: (activeTab: string) =>
|
||||||
|
activityCenter.removeNotifications(
|
||||||
|
activeTab as 'all' | 'mentions' | 'replies'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
</PopoverTrigger>
|
||||||
|
)
|
||||||
|
}
|
|
@ -4,13 +4,13 @@ import { useMatch } from 'react-router-dom'
|
||||||
|
|
||||||
// import { ChatMenu } from '../../../../components/chat-menu'
|
// import { ChatMenu } from '../../../../components/chat-menu'
|
||||||
import { useAppState } from '../../../../contexts/app-context'
|
import { useAppState } from '../../../../contexts/app-context'
|
||||||
// import { BellIcon } from '../../../../icons/bell-icon'
|
|
||||||
// import { DotsIcon } from '../../../../icons/dots-icon'
|
// import { DotsIcon } from '../../../../icons/dots-icon'
|
||||||
import { GroupIcon } from '../../../../icons/group-icon'
|
import { GroupIcon } from '../../../../icons/group-icon'
|
||||||
import { useChat } from '../../../../protocol'
|
import { useChat } from '../../../../protocol'
|
||||||
import { styled } from '../../../../styles/config'
|
import { styled } from '../../../../styles/config'
|
||||||
import { Flex, IconButton } from '../../../../system'
|
import { Flex, IconButton, Separator } from '../../../../system'
|
||||||
import { ChatInfo } from '../chat-info'
|
import { ChatInfo } from '../chat-info'
|
||||||
|
import { ActivityCenterPopover } from './components/activity-center-popover'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
enableMembers: boolean
|
enableMembers: boolean
|
||||||
|
@ -20,6 +20,7 @@ export const Navbar = (props: Props) => {
|
||||||
const { enableMembers } = props
|
const { enableMembers } = props
|
||||||
|
|
||||||
const { state, dispatch } = useAppState()
|
const { state, dispatch } = useAppState()
|
||||||
|
|
||||||
const { params } = useMatch(':id')! // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
const { params } = useMatch(':id')! // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
||||||
|
|
||||||
const chat = useChat(params.id!)
|
const chat = useChat(params.id!)
|
||||||
|
@ -46,11 +47,9 @@ export const Navbar = (props: Props) => {
|
||||||
<ChatMenu type="dropdown" />
|
<ChatMenu type="dropdown" />
|
||||||
</DropdownMenuTrigger> */}
|
</DropdownMenuTrigger> */}
|
||||||
|
|
||||||
{/* <Separator orientation="vertical" css={{ height: 24 }} /> */}
|
<Separator orientation="vertical" css={{ height: 24 }} />
|
||||||
|
|
||||||
{/* <IconButton label="Show Activity Center">
|
<ActivityCenterPopover />
|
||||||
<BellIcon />
|
|
||||||
</IconButton> */}
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</NavbarWrapper>
|
</NavbarWrapper>
|
||||||
)
|
)
|
||||||
|
@ -60,5 +59,5 @@ const NavbarWrapper = styled('div', {
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
padding: '10px 16px',
|
padding: '10px 20px',
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useEffect, useRef } from 'react'
|
import React, { useEffect, useRef } from 'react'
|
||||||
|
|
||||||
import { useMatch } from 'react-router-dom'
|
import { useLocation, useMatch } from 'react-router-dom'
|
||||||
|
|
||||||
import { MemberSidebar } from '../../components/member-sidebar'
|
import { MemberSidebar } from '../../components/member-sidebar'
|
||||||
import { useAppState } from '../../contexts/app-context'
|
import { useAppState } from '../../contexts/app-context'
|
||||||
|
@ -23,7 +23,12 @@ const ChatStart = (props: ChatStartProps) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap="3" align="center" css={{ marginBottom: 50 }}>
|
<Flex direction="column" gap="3" align="center" css={{ marginBottom: 50 }}>
|
||||||
<Avatar size={120} name={identity?.displayName} color={identity?.color} />
|
<Avatar
|
||||||
|
size={120}
|
||||||
|
name={identity?.displayName}
|
||||||
|
color={identity?.color}
|
||||||
|
initialsLength={1}
|
||||||
|
/>
|
||||||
<Heading>{identity?.displayName}</Heading>
|
<Heading>{identity?.displayName}</Heading>
|
||||||
<Text>
|
<Text>
|
||||||
Welcome to the beginning of the #{identity?.displayName} channel!
|
Welcome to the beginning of the #{identity?.displayName} channel!
|
||||||
|
@ -43,11 +48,28 @@ const Body = () => {
|
||||||
const chat = client.community.getChat(chatId)!
|
const chat = client.community.getChat(chatId)!
|
||||||
const messages = useMessages(chatId)
|
const messages = useMessages(chatId)
|
||||||
|
|
||||||
const contentRef = useRef<HTMLDivElement>(null)
|
const location = useLocation()
|
||||||
|
const selectedMessageId = (
|
||||||
|
location.state as { selectedMessageId: string } | undefined
|
||||||
|
)?.selectedMessageId
|
||||||
|
|
||||||
|
const contentRef = useRef<HTMLDivElement | null>(null)
|
||||||
|
// todo: more scrolling conditions
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
if (selectedMessageId) {
|
||||||
|
document.getElementById(selectedMessageId)?.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'nearest',
|
||||||
|
inline: 'start',
|
||||||
|
})
|
||||||
|
// todo?: history.state clean-up
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
contentRef.current!.scrollTop = contentRef.current!.scrollHeight ?? 0
|
contentRef.current!.scrollTop = contentRef.current!.scrollHeight ?? 0
|
||||||
}, [chatId, messages.data.length])
|
}, [chatId, messages.data.length, selectedMessageId])
|
||||||
|
|
||||||
const handleMessageSubmit = (message: string) => {
|
const handleMessageSubmit = (message: string) => {
|
||||||
chat.sendTextMessage(message, state.reply?.message.messageId)
|
chat.sendTextMessage(message, state.reply?.message.messageId)
|
||||||
|
@ -57,9 +79,15 @@ const Body = () => {
|
||||||
<>
|
<>
|
||||||
<ContentWrapper ref={contentRef}>
|
<ContentWrapper ref={contentRef}>
|
||||||
<ChatStart chatId={chatId} />
|
<ChatStart chatId={chatId} />
|
||||||
{messages.data.map(message => (
|
{messages.data.map(message => {
|
||||||
<ChatMessage key={message.messageId} message={message} />
|
return (
|
||||||
))}
|
<ChatMessage
|
||||||
|
key={message.messageId}
|
||||||
|
message={message}
|
||||||
|
highlight={message.messageId === selectedMessageId}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
</ContentWrapper>
|
</ContentWrapper>
|
||||||
{account && <ChatInput onSubmit={handleMessageSubmit} />}
|
{account && <ChatInput onSubmit={handleMessageSubmit} />}
|
||||||
</>
|
</>
|
||||||
|
@ -87,14 +115,11 @@ export const Chat = () => {
|
||||||
|
|
||||||
const Wrapper = styled('div', {
|
const Wrapper = styled('div', {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
position: 'relative',
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'stretch',
|
alignItems: 'stretch',
|
||||||
|
// https://medium.com/the-crazy-coder/the-mystery-of-css-flex-layout-items-shrinking-8748145e96d9
|
||||||
|
minWidth: 0,
|
||||||
background: '$background',
|
background: '$background',
|
||||||
maxWidth: '100%',
|
|
||||||
minWidth: 1,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const ContentWrapper = styled('div', {
|
const ContentWrapper = styled('div', {
|
||||||
|
@ -103,7 +128,6 @@ const ContentWrapper = styled('div', {
|
||||||
overflowX: 'hidden',
|
overflowX: 'hidden',
|
||||||
WebkitOverflowScrolling: 'touch',
|
WebkitOverflowScrolling: 'touch',
|
||||||
overscrollBehavior: 'contain',
|
overscrollBehavior: 'contain',
|
||||||
minWidth: 1,
|
|
||||||
|
|
||||||
// scrollSnapType: 'y proximity',
|
// scrollSnapType: 'y proximity',
|
||||||
|
|
||||||
|
@ -117,5 +141,5 @@ const Main = styled('div', {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
minWidth: 1,
|
minWidth: 0,
|
||||||
})
|
})
|
||||||
|
|
|
@ -22,6 +22,20 @@ interface Props extends Config {
|
||||||
meta?: string
|
meta?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: use a better way to handle this
|
||||||
|
const RootGate = (props: { children: JSX.Element }) => {
|
||||||
|
const { client } = useProtocol()
|
||||||
|
|
||||||
|
// todo!: use sorted chats
|
||||||
|
const chat = client.community._chats[0]
|
||||||
|
|
||||||
|
if (!chat) {
|
||||||
|
return props.children
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Navigate to={`/${chat.uuid}`} replace />
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: use a better way to handle this
|
// TODO: use a better way to handle this
|
||||||
const Gate = (props: { children: JSX.Element }) => {
|
const Gate = (props: { children: JSX.Element }) => {
|
||||||
const { client } = useProtocol()
|
const { client } = useProtocol()
|
||||||
|
@ -60,8 +74,20 @@ export const Community = (props: Props) => {
|
||||||
<MainSidebar />
|
<MainSidebar />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route
|
<Route
|
||||||
path="/:id"
|
path="/"
|
||||||
element={
|
element={
|
||||||
|
<RootGate>
|
||||||
|
{/* todo?: empty state/page */}
|
||||||
|
{/* todo?: navbar at least; think community w/o chats yet, but already has members to inspect */}
|
||||||
|
<></>
|
||||||
|
</RootGate>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{/* todo?: nest under `/` route */}
|
||||||
|
<Route
|
||||||
|
path=":id"
|
||||||
|
element={
|
||||||
|
// todo?: merge with `RootGate`
|
||||||
<Gate>
|
<Gate>
|
||||||
<Chat />
|
<Chat />
|
||||||
</Gate>
|
</Gate>
|
||||||
|
|
|
@ -57,6 +57,8 @@ export const {
|
||||||
'pin-2': 'rgba(255, 159, 15, 0.2)',
|
'pin-2': 'rgba(255, 159, 15, 0.2)',
|
||||||
'pin-3': 'rgba(255, 159, 15, 0.1)',
|
'pin-3': 'rgba(255, 159, 15, 0.1)',
|
||||||
|
|
||||||
|
'navigate-2': 'rgba(255, 159, 15, 0.2)',
|
||||||
|
|
||||||
'accent-1': 'rgba(0, 0, 0, 1)',
|
'accent-1': 'rgba(0, 0, 0, 1)',
|
||||||
'accent-2': 'rgba(0, 0, 0, 0.9)',
|
'accent-2': 'rgba(0, 0, 0, 0.9)',
|
||||||
'accent-3': 'rgba(0, 0, 0, 0.8)',
|
'accent-3': 'rgba(0, 0, 0, 0.8)',
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
|
import { styled } from '../../styles/config'
|
||||||
|
import { Avatar } from '../avatar'
|
||||||
|
import { Box } from '../box'
|
||||||
|
import { EthAddress } from '../eth-address'
|
||||||
|
import { Flex } from '../flex'
|
||||||
|
import { Tag } from '../tag'
|
||||||
|
import { Text } from '../text'
|
||||||
|
|
||||||
|
import type { Notification } from '@status-im/js'
|
||||||
|
|
||||||
|
const Base = styled('div', {
|
||||||
|
display: 'flex',
|
||||||
|
flexShrink: 0,
|
||||||
|
minHeight: '60px',
|
||||||
|
maxHeight: '126px',
|
||||||
|
padding: '8px 16px',
|
||||||
|
'&:hover': {
|
||||||
|
background: '$primary-3',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: Notification
|
||||||
|
onNavigateChange: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const Activity = (props: Props) => {
|
||||||
|
const value = props.children.value
|
||||||
|
const isReply = props.children.isReply
|
||||||
|
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Base
|
||||||
|
onClick={() => {
|
||||||
|
props.onNavigateChange()
|
||||||
|
navigate(`/${value.chatUuid}`, {
|
||||||
|
// todo?: rename to `jumpedTo` or `navigateTo`
|
||||||
|
state: { selectedMessageId: value.messageId },
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
gap={2}
|
||||||
|
css={{
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box>
|
||||||
|
<Avatar
|
||||||
|
size={40}
|
||||||
|
name={value.member.username}
|
||||||
|
colorHash={value.member.colorHash}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Flex
|
||||||
|
direction="column"
|
||||||
|
css={{
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<Flex gap="1" align="center">
|
||||||
|
<Text color="primary" weight="500" size="15">
|
||||||
|
{/* todo?: ens name */}
|
||||||
|
{/* todo?: nickname */}
|
||||||
|
{value.member.username}
|
||||||
|
</Text>
|
||||||
|
<EthAddress size={10} color="gray">
|
||||||
|
{value.member.chatKey}
|
||||||
|
</EthAddress>
|
||||||
|
<Text size="10" color="gray">
|
||||||
|
•
|
||||||
|
</Text>
|
||||||
|
<Text size="10" color="gray">
|
||||||
|
{new Date(Number(value.timestamp)).toLocaleTimeString([], {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
{/* todo?: same comoponnent as for chat messages; think mention resolution */}
|
||||||
|
<Text
|
||||||
|
css={{
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
overflow: 'hidden',
|
||||||
|
textOverflow: 'ellipsis',
|
||||||
|
display: '-webkit-box',
|
||||||
|
boxOrient: 'vertical',
|
||||||
|
WebkitLineClamp: 2,
|
||||||
|
WebkitBoxOrient: 'vertical',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{value.text}
|
||||||
|
</Text>
|
||||||
|
<Flex
|
||||||
|
gap={1}
|
||||||
|
css={{
|
||||||
|
padding: '6px 0px 0px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tag
|
||||||
|
type="community"
|
||||||
|
communityDisplayName={value.communityDisplayName}
|
||||||
|
chatDisplayName={value.chatDisplayName}
|
||||||
|
chatUuid={value.chatUuid}
|
||||||
|
onNavigateChange={props.onNavigateChange}
|
||||||
|
/>
|
||||||
|
{isReply && (
|
||||||
|
<Tag
|
||||||
|
type="reply"
|
||||||
|
text={value.responseToMessage?.text ?? 'Message not available.'}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Base>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Activity }
|
|
@ -0,0 +1 @@
|
||||||
|
export { Activity } from './activity'
|
|
@ -13,10 +13,19 @@ interface Props {
|
||||||
src?: string
|
src?: string
|
||||||
color?: string
|
color?: string
|
||||||
colorHash?: number[][]
|
colorHash?: number[][]
|
||||||
|
initialsLength?: 1 | 2
|
||||||
}
|
}
|
||||||
|
|
||||||
const Avatar = (props: Props) => {
|
const Avatar = (props: Props) => {
|
||||||
const { size, name, src, color, indicator, colorHash } = props
|
const {
|
||||||
|
size,
|
||||||
|
name,
|
||||||
|
src,
|
||||||
|
color,
|
||||||
|
indicator,
|
||||||
|
colorHash,
|
||||||
|
initialsLength = 2,
|
||||||
|
} = props
|
||||||
|
|
||||||
const identiconRing = useMemo(() => {
|
const identiconRing = useMemo(() => {
|
||||||
if (colorHash) {
|
if (colorHash) {
|
||||||
|
@ -25,7 +34,7 @@ const Avatar = (props: Props) => {
|
||||||
}
|
}
|
||||||
}, [colorHash])
|
}, [colorHash])
|
||||||
|
|
||||||
const initials = name ? name.slice(0, 1) : ''
|
const initials = name ? name.slice(0, initialsLength) : ''
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Base
|
<Base
|
||||||
|
|
|
@ -11,6 +11,11 @@ export const Base = styled('div', {
|
||||||
|
|
||||||
variants: {
|
variants: {
|
||||||
size: {
|
size: {
|
||||||
|
16: {
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
padding: 1,
|
||||||
|
},
|
||||||
20: {
|
20: {
|
||||||
width: 20,
|
width: 20,
|
||||||
height: 20,
|
height: 20,
|
||||||
|
@ -31,6 +36,11 @@ export const Base = styled('div', {
|
||||||
height: 36,
|
height: 36,
|
||||||
padding: 2,
|
padding: 2,
|
||||||
},
|
},
|
||||||
|
40: {
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
padding: 2,
|
||||||
|
},
|
||||||
44: {
|
44: {
|
||||||
width: 44,
|
width: 44,
|
||||||
height: 44,
|
height: 44,
|
||||||
|
@ -71,6 +81,7 @@ export const Indicator = styled('span', {
|
||||||
|
|
||||||
variants: {
|
variants: {
|
||||||
size: {
|
size: {
|
||||||
|
16: {},
|
||||||
20: {},
|
20: {},
|
||||||
24: {},
|
24: {},
|
||||||
32: {
|
32: {
|
||||||
|
@ -78,6 +89,7 @@ export const Indicator = styled('span', {
|
||||||
height: 12,
|
height: 12,
|
||||||
},
|
},
|
||||||
36: {},
|
36: {},
|
||||||
|
40: {},
|
||||||
44: {},
|
44: {},
|
||||||
64: {},
|
64: {},
|
||||||
80: {},
|
80: {},
|
||||||
|
@ -105,10 +117,12 @@ export const Initials = styled('div', {
|
||||||
verticalAlign: 'baseline',
|
verticalAlign: 'baseline',
|
||||||
variants: {
|
variants: {
|
||||||
size: {
|
size: {
|
||||||
|
16: { fontSize: 'calc(16 * 0.5px)', lineHeight: '16px' },
|
||||||
20: { fontSize: 'calc(20 * 0.5px)', lineHeight: '20px' },
|
20: { fontSize: 'calc(20 * 0.5px)', lineHeight: '20px' },
|
||||||
24: { fontSize: 'calc(24 * 0.5px)', lineHeight: '24px' },
|
24: { fontSize: 'calc(24 * 0.5px)', lineHeight: '24px' },
|
||||||
32: { fontSize: 'calc(32 * 0.5px)', lineHeight: '32px' },
|
32: { fontSize: 'calc(32 * 0.5px)', lineHeight: '32px' },
|
||||||
36: { fontSize: 'calc(36 * 0.5px)', lineHeight: '36px' },
|
36: { fontSize: 'calc(36 * 0.5px)', lineHeight: '36px' },
|
||||||
|
40: { fontSize: 'calc(40 * 0.5px)', lineHeight: '40px' },
|
||||||
44: { fontSize: 'calc(44 * 0.5px)', lineHeight: '44px' },
|
44: { fontSize: 'calc(44 * 0.5px)', lineHeight: '44px' },
|
||||||
64: { fontSize: 'calc(64 * 0.5px)', lineHeight: '64px' },
|
64: { fontSize: 'calc(64 * 0.5px)', lineHeight: '64px' },
|
||||||
80: { fontSize: 'calc(80 * 0.5px)', lineHeight: '80px' },
|
80: { fontSize: 'calc(80 * 0.5px)', lineHeight: '80px' },
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { Text } from '../text'
|
||||||
|
import { Base } from './styles'
|
||||||
|
|
||||||
|
import type { Variants } from './styles'
|
||||||
|
import type Stitches from '@stitches/react'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: number
|
||||||
|
variant?: Variants['variant']
|
||||||
|
css?: Stitches.CSS
|
||||||
|
}
|
||||||
|
|
||||||
|
const Badge = (props: Props) => {
|
||||||
|
const { children, variant, css } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Base variant={variant} css={css}>
|
||||||
|
<Text size="12" weight="500" align="center" css={{ color: '$accent-11' }}>
|
||||||
|
{children < 100 ? children : '99+'}
|
||||||
|
</Text>
|
||||||
|
</Base>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Badge }
|
||||||
|
export type { Props as BadgeProps }
|
|
@ -0,0 +1,2 @@
|
||||||
|
export type { BadgeProps } from './badge'
|
||||||
|
export { Badge } from './badge'
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { styled } from '../../styles/config'
|
||||||
|
|
||||||
|
import type { VariantProps } from '../../styles/config'
|
||||||
|
|
||||||
|
export type Variants = VariantProps<typeof Base>
|
||||||
|
|
||||||
|
export const Base = styled('div', {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
minWidth: 22,
|
||||||
|
height: 22,
|
||||||
|
padding: '3px 7px',
|
||||||
|
background: '$primary-1',
|
||||||
|
/**
|
||||||
|
* @see https://copyprogramming.com/howto/css-set-border-radius-relative-to-height
|
||||||
|
* @see https://stackoverflow.com/a/66530702/6924883
|
||||||
|
*/
|
||||||
|
borderRadius: 9999,
|
||||||
|
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
border: {
|
||||||
|
minWidth: 18,
|
||||||
|
height: 18,
|
||||||
|
padding: '1px 5px',
|
||||||
|
// todo?: use border
|
||||||
|
outline: '2px solid $accent-11',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
|
@ -11,6 +11,7 @@ interface Props {
|
||||||
children: string
|
children: string
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
|
active?: boolean
|
||||||
type?: ButtonProps['type']
|
type?: ButtonProps['type']
|
||||||
onClick?: ButtonProps['onClick']
|
onClick?: ButtonProps['onClick']
|
||||||
variant?: Variants['variant']
|
variant?: Variants['variant']
|
||||||
|
|
|
@ -37,6 +37,19 @@ export const Base = styled('button', {
|
||||||
background: '$primary-2',
|
background: '$primary-2',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
secondary: {
|
||||||
|
background: '$transparent',
|
||||||
|
color: '$primary-1',
|
||||||
|
'&:hover': {
|
||||||
|
background: '$primary-3',
|
||||||
|
},
|
||||||
|
'&[data-state="active"]': {
|
||||||
|
background: '$primary-2',
|
||||||
|
'&:hover': {
|
||||||
|
backgroundColor: '$primary-2', // override default hover behavior
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
danger: {
|
danger: {
|
||||||
background: '$danger-3',
|
background: '$danger-3',
|
||||||
color: '$danger-1',
|
color: '$danger-1',
|
||||||
|
@ -54,8 +67,9 @@ export const Base = styled('button', {
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
small: {
|
small: {
|
||||||
|
height: '38px',
|
||||||
fontSize: '13px',
|
fontSize: '13px',
|
||||||
padding: '10px 12px',
|
padding: '0px 12px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
loading: {
|
loading: {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { Link } from 'react-router-dom'
|
||||||
import { Base } from './styles'
|
import { Base } from './styles'
|
||||||
|
|
||||||
import type { Variants } from './styles'
|
import type { Variants } from './styles'
|
||||||
|
import type Stitches from '@stitches/react'
|
||||||
import type { Ref } from 'react'
|
import type { Ref } from 'react'
|
||||||
import type { LinkProps } from 'react-router-dom'
|
import type { LinkProps } from 'react-router-dom'
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ interface Props {
|
||||||
color?: Variants['color']
|
color?: Variants['color']
|
||||||
active?: boolean
|
active?: boolean
|
||||||
to?: LinkProps['to']
|
to?: LinkProps['to']
|
||||||
|
css?: Stitches.CSS
|
||||||
}
|
}
|
||||||
|
|
||||||
const IconButton = (props: Props, ref: Ref<HTMLButtonElement>) => {
|
const IconButton = (props: Props, ref: Ref<HTMLButtonElement>) => {
|
||||||
|
@ -32,6 +34,7 @@ const IconButton = (props: Props, ref: Ref<HTMLButtonElement>) => {
|
||||||
color,
|
color,
|
||||||
active,
|
active,
|
||||||
to,
|
to,
|
||||||
|
css,
|
||||||
...buttonProps
|
...buttonProps
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
|
@ -44,6 +47,7 @@ const IconButton = (props: Props, ref: Ref<HTMLButtonElement>) => {
|
||||||
intent={intent}
|
intent={intent}
|
||||||
color={color}
|
color={color}
|
||||||
active={active}
|
active={active}
|
||||||
|
css={css}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Base>
|
</Base>
|
||||||
|
@ -60,6 +64,7 @@ const IconButton = (props: Props, ref: Ref<HTMLButtonElement>) => {
|
||||||
intent={intent}
|
intent={intent}
|
||||||
color={color}
|
color={color}
|
||||||
active={active}
|
active={active}
|
||||||
|
css={css}
|
||||||
>
|
>
|
||||||
<AccessibleIcon label={label}>{children}</AccessibleIcon>
|
<AccessibleIcon label={label}>{children}</AccessibleIcon>
|
||||||
</Base>
|
</Base>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
|
export { Activity } from './activity'
|
||||||
export { Avatar } from './avatar'
|
export { Avatar } from './avatar'
|
||||||
|
export { Badge } from './badge'
|
||||||
export { Box } from './box'
|
export { Box } from './box'
|
||||||
export { Button } from './button'
|
export { Button } from './button'
|
||||||
export { ButtonGroup } from './button-group'
|
export { ButtonGroup } from './button-group'
|
||||||
|
@ -24,6 +26,8 @@ export { IconButton } from './icon-button'
|
||||||
export { Image } from './image'
|
export { Image } from './image'
|
||||||
export { Popover, PopoverTrigger } from './popover'
|
export { Popover, PopoverTrigger } from './popover'
|
||||||
export { Separator } from './separator'
|
export { Separator } from './separator'
|
||||||
|
export { Tabs } from './tabs'
|
||||||
|
export { Tag } from './tag'
|
||||||
export { Text } from './text'
|
export { Text } from './text'
|
||||||
export { TextInput } from './text-input'
|
export { TextInput } from './text-input'
|
||||||
export { Tooltip } from './tooltip'
|
export { Tooltip } from './tooltip'
|
||||||
|
|
|
@ -5,6 +5,7 @@ import * as Primitive from '@radix-ui/react-popover'
|
||||||
import { Content } from './styles'
|
import { Content } from './styles'
|
||||||
|
|
||||||
import type { PopoverContentProps } from '@radix-ui/react-popover'
|
import type { PopoverContentProps } from '@radix-ui/react-popover'
|
||||||
|
import type Stitches from '@stitches/react'
|
||||||
import type { Ref } from 'react'
|
import type { Ref } from 'react'
|
||||||
|
|
||||||
interface TriggerProps {
|
interface TriggerProps {
|
||||||
|
@ -32,13 +33,14 @@ const _PopoverTrigger = forwardRef(PopoverTrigger)
|
||||||
|
|
||||||
interface PopoverProps extends PopoverContentProps {
|
interface PopoverProps extends PopoverContentProps {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
|
css?: Stitches.CSS
|
||||||
}
|
}
|
||||||
|
|
||||||
const Popover = (props: PopoverProps) => {
|
const Popover = (props: PopoverProps) => {
|
||||||
const { children, ...contentProps } = props
|
const { children, css, ...contentProps } = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Content as={Primitive.Content} {...contentProps}>
|
<Content as={Primitive.Content} css={css} {...contentProps}>
|
||||||
{children}
|
{children}
|
||||||
</Content>
|
</Content>
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export { Tabs } from './tabs'
|
|
@ -0,0 +1,110 @@
|
||||||
|
import React, { useState } from 'react'
|
||||||
|
|
||||||
|
import * as TabsPrimitive from '@radix-ui/react-tabs'
|
||||||
|
|
||||||
|
import { DoubleTickIcon } from '../../icons/double-tick-icon'
|
||||||
|
import { styled } from '../../styles/config'
|
||||||
|
import { Button } from '../button'
|
||||||
|
import { Flex } from '../flex'
|
||||||
|
import { IconButton } from '../icon-button'
|
||||||
|
import { Tooltip } from '../tooltip'
|
||||||
|
|
||||||
|
const TabsRoot = styled(TabsPrimitive.Root, {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
height: '100%',
|
||||||
|
})
|
||||||
|
|
||||||
|
const TabsList = styled(TabsPrimitive.List, { display: 'flex', gap: '8px' })
|
||||||
|
|
||||||
|
const TabsContent = styled(TabsPrimitive.Content, {
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
})
|
||||||
|
|
||||||
|
const ContentWrapper = styled('div', {
|
||||||
|
flex: 1,
|
||||||
|
overflowY: 'scroll',
|
||||||
|
overflowX: 'hidden',
|
||||||
|
})
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
tabs: Array<{
|
||||||
|
title: string
|
||||||
|
value: string
|
||||||
|
content: JSX.Element | JSX.Element[]
|
||||||
|
}>
|
||||||
|
actions: Array<{
|
||||||
|
icon: JSX.Element
|
||||||
|
label: string
|
||||||
|
method: (activeTab: string) => void
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
|
||||||
|
const Tabs = (props: Props) => {
|
||||||
|
const [activeTab, setActiveTab] = useState('all')
|
||||||
|
|
||||||
|
const initialValue: {
|
||||||
|
triggers: JSX.Element[]
|
||||||
|
contents: JSX.Element[]
|
||||||
|
} = {
|
||||||
|
triggers: [],
|
||||||
|
contents: [],
|
||||||
|
}
|
||||||
|
const { triggers, contents } = props.tabs.reduce((results, currentTab) => {
|
||||||
|
results.triggers.push(
|
||||||
|
<TabsPrimitive.Trigger
|
||||||
|
key={currentTab.value}
|
||||||
|
value={currentTab.value}
|
||||||
|
asChild
|
||||||
|
>
|
||||||
|
<Button size="small" variant="secondary">
|
||||||
|
{currentTab.title}
|
||||||
|
</Button>
|
||||||
|
</TabsPrimitive.Trigger>
|
||||||
|
)
|
||||||
|
results.contents.push(
|
||||||
|
<TabsContent key={currentTab.value} value={currentTab.value}>
|
||||||
|
{currentTab.content}
|
||||||
|
</TabsContent>
|
||||||
|
)
|
||||||
|
|
||||||
|
return results
|
||||||
|
}, initialValue)
|
||||||
|
|
||||||
|
const actions = props.actions.map(action => {
|
||||||
|
return (
|
||||||
|
<Tooltip key={action.label} label={action.label} arrowOffset={7}>
|
||||||
|
<IconButton
|
||||||
|
label={action.label}
|
||||||
|
onClick={() => {
|
||||||
|
action.method(activeTab)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DoubleTickIcon />
|
||||||
|
</IconButton>
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TabsRoot value={activeTab} onValueChange={setActiveTab}>
|
||||||
|
<Flex
|
||||||
|
css={{
|
||||||
|
height: '64px',
|
||||||
|
padding: '13px 16px',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* todo?: if all empty, disable other tabs */}
|
||||||
|
{/* todo?: if active, disable hover and clicks */}
|
||||||
|
<TabsList>{triggers}</TabsList>
|
||||||
|
<div>{actions}</div>
|
||||||
|
</Flex>
|
||||||
|
<ContentWrapper>{contents}</ContentWrapper>
|
||||||
|
</TabsRoot>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Tabs }
|
|
@ -0,0 +1 @@
|
||||||
|
export { Tag } from './tag'
|
|
@ -0,0 +1,128 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
|
import { TinyChevronRightIcon } from '../../icons/tiny-chevron-right-icon'
|
||||||
|
import { TinyCommunityIcon } from '../../icons/tiny-community-icon'
|
||||||
|
import { TinyReplyIcon } from '../../icons/tiny-reply-icon'
|
||||||
|
import { styled } from '../../styles/config'
|
||||||
|
import { Avatar } from '../avatar'
|
||||||
|
import { Text } from '../text'
|
||||||
|
|
||||||
|
const Base = styled('div', {
|
||||||
|
padding: '0px 6px',
|
||||||
|
border: '1px solid rgba(0, 0, 0, 0.1)',
|
||||||
|
borderRadius: '11px',
|
||||||
|
height: '22px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: 'max-content',
|
||||||
|
color: '$gray-1',
|
||||||
|
gap: '6px',
|
||||||
|
'&:hover': {
|
||||||
|
cursor: 'default',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const Segment = styled('div', {
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '4px',
|
||||||
|
})
|
||||||
|
|
||||||
|
const PathLink = styled('a', {
|
||||||
|
'&:hover': {
|
||||||
|
textDecoration: 'underline',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
interface CommunityProps {
|
||||||
|
type: 'community'
|
||||||
|
communityDisplayName: string
|
||||||
|
chatDisplayName: string
|
||||||
|
chatUuid: string
|
||||||
|
onNavigateChange: () => void
|
||||||
|
}
|
||||||
|
interface ReplyProps {
|
||||||
|
type: 'reply'
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// fixme: clicking on flex gab/space between components captures and handles click events
|
||||||
|
const Tag = (props: CommunityProps | ReplyProps) => {
|
||||||
|
const { type } = props
|
||||||
|
|
||||||
|
// todo?: extract together with `PathLink`
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'community':
|
||||||
|
return (
|
||||||
|
<Base>
|
||||||
|
<Segment
|
||||||
|
role="none"
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TinyCommunityIcon />
|
||||||
|
<Avatar
|
||||||
|
size={16}
|
||||||
|
name={props.communityDisplayName}
|
||||||
|
initialsLength={1}
|
||||||
|
/>
|
||||||
|
<Text color="current" weight="500">
|
||||||
|
{props.communityDisplayName}
|
||||||
|
</Text>
|
||||||
|
</Segment>
|
||||||
|
<Segment
|
||||||
|
role="none"
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TinyChevronRightIcon />
|
||||||
|
</Segment>
|
||||||
|
<Segment>
|
||||||
|
<PathLink
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
props.onNavigateChange()
|
||||||
|
navigate(`/${props.chatUuid}`)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text color="current" weight="500">
|
||||||
|
#{props.chatDisplayName}
|
||||||
|
</Text>
|
||||||
|
</PathLink>
|
||||||
|
</Segment>
|
||||||
|
</Base>
|
||||||
|
)
|
||||||
|
|
||||||
|
case 'reply':
|
||||||
|
return (
|
||||||
|
<Base>
|
||||||
|
<Segment
|
||||||
|
role="none"
|
||||||
|
onClick={e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TinyReplyIcon />
|
||||||
|
<Text color="current" weight="500">
|
||||||
|
{props.text}
|
||||||
|
</Text>
|
||||||
|
</Segment>
|
||||||
|
</Base>
|
||||||
|
)
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Tag }
|
|
@ -2,6 +2,7 @@ import { styled, theme } from '../../styles/config'
|
||||||
|
|
||||||
import type React from 'react'
|
import type React from 'react'
|
||||||
|
|
||||||
|
// todo?: rich variant here (e.g. mentions, format, code)
|
||||||
const Text = styled('div', {
|
const Text = styled('div', {
|
||||||
fontFamily: theme.fonts.sans,
|
fontFamily: theme.fonts.sans,
|
||||||
overflowWrap: 'break-word',
|
overflowWrap: 'break-word',
|
||||||
|
@ -35,6 +36,9 @@ const Text = styled('div', {
|
||||||
gray: {
|
gray: {
|
||||||
color: '$gray-1',
|
color: '$gray-1',
|
||||||
},
|
},
|
||||||
|
current: {
|
||||||
|
color: '$current',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
weight: {
|
weight: {
|
||||||
'400': {
|
'400': {
|
||||||
|
|
|
@ -27,7 +27,7 @@ export const Content = styled(Primitive.Content, {
|
||||||
fontWeight: '$500',
|
fontWeight: '$500',
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
padding: 8,
|
padding: 8,
|
||||||
lineHeight: 1,
|
lineHeight: '18px',
|
||||||
backgroundColor: '$accent-1',
|
backgroundColor: '$accent-1',
|
||||||
color: '$accent-11',
|
color: '$accent-11',
|
||||||
borderRadius: 8,
|
borderRadius: 8,
|
||||||
|
|
|
@ -4,7 +4,10 @@ import * as Primitive from '@radix-ui/react-tooltip'
|
||||||
|
|
||||||
import { Arrow, Content } from './styles'
|
import { Arrow, Content } from './styles'
|
||||||
|
|
||||||
import type { TooltipContentProps } from '@radix-ui/react-tooltip'
|
import type {
|
||||||
|
TooltipArrowProps,
|
||||||
|
TooltipContentProps,
|
||||||
|
} from '@radix-ui/react-tooltip'
|
||||||
import type { Ref } from 'react'
|
import type { Ref } from 'react'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -12,6 +15,8 @@ interface Props {
|
||||||
children: React.ReactElement
|
children: React.ReactElement
|
||||||
side?: TooltipContentProps['side']
|
side?: TooltipContentProps['side']
|
||||||
sideOffset?: TooltipContentProps['sideOffset']
|
sideOffset?: TooltipContentProps['sideOffset']
|
||||||
|
align?: TooltipContentProps['align']
|
||||||
|
arrowOffset?: TooltipArrowProps['offset']
|
||||||
}
|
}
|
||||||
|
|
||||||
const Tooltip = (props: Props, ref: Ref<HTMLButtonElement>) => {
|
const Tooltip = (props: Props, ref: Ref<HTMLButtonElement>) => {
|
||||||
|
@ -20,19 +25,23 @@ const Tooltip = (props: Props, ref: Ref<HTMLButtonElement>) => {
|
||||||
label,
|
label,
|
||||||
side = 'top',
|
side = 'top',
|
||||||
sideOffset = 5,
|
sideOffset = 5,
|
||||||
|
align = 'center',
|
||||||
|
arrowOffset = 0,
|
||||||
...triggerProps
|
...triggerProps
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<Primitive.Provider>
|
||||||
<Primitive.Root delayDuration={500}>
|
<Primitive.Root delayDuration={500}>
|
||||||
<Primitive.Trigger asChild>
|
<Primitive.Trigger asChild>
|
||||||
{cloneElement(children, { ref, ...triggerProps })}
|
{cloneElement(children, { ref, ...triggerProps })}
|
||||||
</Primitive.Trigger>
|
</Primitive.Trigger>
|
||||||
<Content side={side} sideOffset={sideOffset}>
|
<Content side={side} sideOffset={sideOffset} align={align}>
|
||||||
{label}
|
{label}
|
||||||
<Arrow />
|
<Arrow offset={arrowOffset} />
|
||||||
</Content>
|
</Content>
|
||||||
</Primitive.Root>
|
</Primitive.Root>
|
||||||
|
</Primitive.Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
272
yarn.lock
272
yarn.lock
|
@ -750,6 +750,26 @@
|
||||||
"@ethersproject/bytes" "^5.5.0"
|
"@ethersproject/bytes" "^5.5.0"
|
||||||
"@ethersproject/logger" "^5.5.0"
|
"@ethersproject/logger" "^5.5.0"
|
||||||
|
|
||||||
|
"@floating-ui/core@^0.7.3":
|
||||||
|
version "0.7.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-0.7.3.tgz#d274116678ffae87f6b60e90f88cc4083eefab86"
|
||||||
|
integrity sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg==
|
||||||
|
|
||||||
|
"@floating-ui/dom@^0.5.3":
|
||||||
|
version "0.5.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-0.5.4.tgz#4eae73f78bcd4bd553ae2ade30e6f1f9c73fe3f1"
|
||||||
|
integrity sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/core" "^0.7.3"
|
||||||
|
|
||||||
|
"@floating-ui/react-dom@0.7.2":
|
||||||
|
version "0.7.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-0.7.2.tgz#0bf4ceccb777a140fc535c87eb5d6241c8e89864"
|
||||||
|
integrity sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg==
|
||||||
|
dependencies:
|
||||||
|
"@floating-ui/dom" "^0.5.3"
|
||||||
|
use-isomorphic-layout-effect "^1.1.1"
|
||||||
|
|
||||||
"@hcaptcha/react-hcaptcha@^1.0.0":
|
"@hcaptcha/react-hcaptcha@^1.0.0":
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-1.1.0.tgz#ca770c9fc1f456e3c6b057bedf01a94693b2ec96"
|
resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-1.1.0.tgz#ca770c9fc1f456e3c6b057bedf01a94693b2ec96"
|
||||||
|
@ -1451,6 +1471,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/primitive@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.0.tgz#e1d8ef30b10ea10e69c76e896f608d9276352253"
|
||||||
|
integrity sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-accessible-icon@^0.1.4":
|
"@radix-ui/react-accessible-icon@^0.1.4":
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-accessible-icon/-/react-accessible-icon-0.1.4.tgz#bdbf1e3226a0e9e7778b68728b175bdc532b720c"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-accessible-icon/-/react-accessible-icon-0.1.4.tgz#bdbf1e3226a0e9e7778b68728b175bdc532b720c"
|
||||||
|
@ -1480,6 +1507,14 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
|
|
||||||
|
"@radix-ui/react-arrow@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.0.tgz#c461f4c2cab3317e3d42a1ae62910a4cbb0192a1"
|
||||||
|
integrity sha512-1MUuv24HCdepi41+qfv125EwMuxgQ+U+h0A9K3BjCO/J8nVRREKHHpkD9clwfnjEDk9hgGzCnff4aUKCPiRepw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-checkbox@^0.1.5":
|
"@radix-ui/react-checkbox@^0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-0.1.5.tgz#3a6bd54ba1720c8e5c03852acf460e35dfbe9da3"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-0.1.5.tgz#3a6bd54ba1720c8e5c03852acf460e35dfbe9da3"
|
||||||
|
@ -1522,6 +1557,17 @@
|
||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
"@radix-ui/react-slot" "0.1.2"
|
"@radix-ui/react-slot" "0.1.2"
|
||||||
|
|
||||||
|
"@radix-ui/react-collection@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.0.tgz#0ec4c72fabd35a03b5787075ac799e3b17ca5710"
|
||||||
|
integrity sha512-8i1pf5dKjnq90Z8udnnXKzdCEV3/FYrfw0n/b6NvB6piXEn3fO1bOh7HBcpG8XrnIXzxlYu2oCcR38QpyLS/mg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-context" "1.0.0"
|
||||||
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-slot" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-compose-refs@0.1.0", "@radix-ui/react-compose-refs@^0.1.0":
|
"@radix-ui/react-compose-refs@0.1.0", "@radix-ui/react-compose-refs@^0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz#cff6e780a0f73778b976acff2c2a5b6551caab95"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz#cff6e780a0f73778b976acff2c2a5b6551caab95"
|
||||||
|
@ -1529,6 +1575,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-compose-refs@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz#37595b1f16ec7f228d698590e78eeed18ff218ae"
|
||||||
|
integrity sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-context-menu@^0.1.6":
|
"@radix-ui/react-context-menu@^0.1.6":
|
||||||
version "0.1.6"
|
version "0.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-context-menu/-/react-context-menu-0.1.6.tgz#0c75f2faffec6c8697247a4b685a432b3c4d07f0"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-context-menu/-/react-context-menu-0.1.6.tgz#0c75f2faffec6c8697247a4b685a432b3c4d07f0"
|
||||||
|
@ -1548,6 +1601,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-context@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.0.tgz#f38e30c5859a9fb5e9aa9a9da452ee3ed9e0aee0"
|
||||||
|
integrity sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-dialog@0.1.7", "@radix-ui/react-dialog@^0.1.7":
|
"@radix-ui/react-dialog@0.1.7", "@radix-ui/react-dialog@^0.1.7":
|
||||||
version "0.1.7"
|
version "0.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-0.1.7.tgz#285414cf66f5bbf42bc9935314e0381abe01e7d0"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-0.1.7.tgz#285414cf66f5bbf42bc9935314e0381abe01e7d0"
|
||||||
|
@ -1569,6 +1629,13 @@
|
||||||
aria-hidden "^1.1.1"
|
aria-hidden "^1.1.1"
|
||||||
react-remove-scroll "^2.4.0"
|
react-remove-scroll "^2.4.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-direction@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.0.tgz#a2e0b552352459ecf96342c79949dd833c1e6e45"
|
||||||
|
integrity sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-dismissable-layer@0.1.5":
|
"@radix-ui/react-dismissable-layer@0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-0.1.5.tgz#9379032351e79028d472733a5cc8ba4a0ea43314"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-0.1.5.tgz#9379032351e79028d472733a5cc8ba4a0ea43314"
|
||||||
|
@ -1582,6 +1649,18 @@
|
||||||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||||
"@radix-ui/react-use-escape-keydown" "0.1.0"
|
"@radix-ui/react-use-escape-keydown" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-dismissable-layer@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz#35b7826fa262fd84370faef310e627161dffa76b"
|
||||||
|
integrity sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
|
"@radix-ui/react-use-escape-keydown" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-dropdown-menu@^0.1.6":
|
"@radix-ui/react-dropdown-menu@^0.1.6":
|
||||||
version "0.1.6"
|
version "0.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-0.1.6.tgz#3203229788cd57e552c9f19dcc7008e2b545919c"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-0.1.6.tgz#3203229788cd57e552c9f19dcc7008e2b545919c"
|
||||||
|
@ -1621,6 +1700,14 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-id@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.0.tgz#8d43224910741870a45a8c9d092f25887bb6d11e"
|
||||||
|
integrity sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-label@0.1.5", "@radix-ui/react-label@^0.1.5":
|
"@radix-ui/react-label@0.1.5", "@radix-ui/react-label@^0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-0.1.5.tgz#12cd965bfc983e0148121d4c99fb8e27a917c45c"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-0.1.5.tgz#12cd965bfc983e0148121d4c99fb8e27a917c45c"
|
||||||
|
@ -1692,6 +1779,22 @@
|
||||||
"@radix-ui/react-use-size" "0.1.1"
|
"@radix-ui/react-use-size" "0.1.1"
|
||||||
"@radix-ui/rect" "0.1.1"
|
"@radix-ui/rect" "0.1.1"
|
||||||
|
|
||||||
|
"@radix-ui/react-popper@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.0.0.tgz#fb4f937864bf39c48f27f55beee61fa9f2bef93c"
|
||||||
|
integrity sha512-k2dDd+1Wl0XWAMs9ZvAxxYsB9sOsEhrFQV4CINd7IUZf0wfdye4OHen9siwxvZImbzhgVeKTJi68OQmPRvVdMg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@floating-ui/react-dom" "0.7.2"
|
||||||
|
"@radix-ui/react-arrow" "1.0.0"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-context" "1.0.0"
|
||||||
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.0"
|
||||||
|
"@radix-ui/react-use-rect" "1.0.0"
|
||||||
|
"@radix-ui/react-use-size" "1.0.0"
|
||||||
|
"@radix-ui/rect" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-portal@0.1.4":
|
"@radix-ui/react-portal@0.1.4":
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-0.1.4.tgz#17bdce3d7f1a9a0b35cb5e935ab8bc562441a7d2"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-0.1.4.tgz#17bdce3d7f1a9a0b35cb5e935ab8bc562441a7d2"
|
||||||
|
@ -1701,6 +1804,14 @@
|
||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-portal@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.0.tgz#7220b66743394fabb50c55cb32381395cc4a276b"
|
||||||
|
integrity sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-presence@0.1.2":
|
"@radix-ui/react-presence@0.1.2":
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-0.1.2.tgz#9f11cce3df73cf65bc348e8b76d891f0d54c1fe3"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-0.1.2.tgz#9f11cce3df73cf65bc348e8b76d891f0d54c1fe3"
|
||||||
|
@ -1710,6 +1821,15 @@
|
||||||
"@radix-ui/react-compose-refs" "0.1.0"
|
"@radix-ui/react-compose-refs" "0.1.0"
|
||||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-presence@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.0.tgz#814fe46df11f9a468808a6010e3f3ca7e0b2e84a"
|
||||||
|
integrity sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-primitive@0.1.4":
|
"@radix-ui/react-primitive@0.1.4":
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz#6c233cf08b0cb87fecd107e9efecb3f21861edc1"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz#6c233cf08b0cb87fecd107e9efecb3f21861edc1"
|
||||||
|
@ -1718,6 +1838,14 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-slot" "0.1.2"
|
"@radix-ui/react-slot" "0.1.2"
|
||||||
|
|
||||||
|
"@radix-ui/react-primitive@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz#376cd72b0fcd5e0e04d252ed33eb1b1f025af2b0"
|
||||||
|
integrity sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-slot" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-roving-focus@0.1.5":
|
"@radix-ui/react-roving-focus@0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-0.1.5.tgz#cc48d17a36b56f253d54905b0fd60ee134cb97ee"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-0.1.5.tgz#cc48d17a36b56f253d54905b0fd60ee134cb97ee"
|
||||||
|
@ -1733,6 +1861,22 @@
|
||||||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||||
"@radix-ui/react-use-controllable-state" "0.1.0"
|
"@radix-ui/react-use-controllable-state" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-roving-focus@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.0.tgz#aadeb65d5dbcdbdd037078156ae1f57c2ff754ee"
|
||||||
|
integrity sha512-lHvO4MhvoWpeNbiJAoyDsEtbKqP2jkkdwsMVJ3kfqbkC71J/aXE6Th6gkZA1xHEqSku+t+UgoDjvE7Z3gsBpcg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-collection" "1.0.0"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
"@radix-ui/react-context" "1.0.0"
|
||||||
|
"@radix-ui/react-direction" "1.0.0"
|
||||||
|
"@radix-ui/react-id" "1.0.0"
|
||||||
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
|
"@radix-ui/react-use-controllable-state" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-separator@^0.1.4":
|
"@radix-ui/react-separator@^0.1.4":
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-0.1.4.tgz#383ad0f82b364d9982a978d752084af3598e4090"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-0.1.4.tgz#383ad0f82b364d9982a978d752084af3598e4090"
|
||||||
|
@ -1749,6 +1893,29 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-compose-refs" "0.1.0"
|
"@radix-ui/react-compose-refs" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-slot@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.0.tgz#7fa805b99891dea1e862d8f8fbe07f4d6d0fd698"
|
||||||
|
integrity sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-tabs@^1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.0.0.tgz#135c67f1f2bd9ada69a3f6e38dd897d459af5fe5"
|
||||||
|
integrity sha512-oKUwEDsySVC0uuSEH7SHCVt1+ijmiDFAI9p+fHCtuZdqrRDKIFs09zp5nrmu4ggP6xqSx9lj1VSblnDH+n3IBA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-context" "1.0.0"
|
||||||
|
"@radix-ui/react-direction" "1.0.0"
|
||||||
|
"@radix-ui/react-id" "1.0.0"
|
||||||
|
"@radix-ui/react-presence" "1.0.0"
|
||||||
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
|
"@radix-ui/react-roving-focus" "1.0.0"
|
||||||
|
"@radix-ui/react-use-controllable-state" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-toggle-group@^0.1.5":
|
"@radix-ui/react-toggle-group@^0.1.5":
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-0.1.5.tgz#9e4d65e22c4fc0ba3a42fbc8d5496c430e5e9852"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-0.1.5.tgz#9e4d65e22c4fc0ba3a42fbc8d5496c430e5e9852"
|
||||||
|
@ -1772,26 +1939,24 @@
|
||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
"@radix-ui/react-use-controllable-state" "0.1.0"
|
"@radix-ui/react-use-controllable-state" "0.1.0"
|
||||||
|
|
||||||
"@radix-ui/react-tooltip@^0.1.7":
|
"@radix-ui/react-tooltip@^1.0.0":
|
||||||
version "0.1.7"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-0.1.7.tgz#6f8c00d6e489565d14abf209ce0fb8853c8c8ee3"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.0.tgz#f7fcecf2bac5c31cd14666b5acd056015fc21646"
|
||||||
integrity sha512-eiBUsVOHenZ0JR16tl970bB0DafJBz6mFgSGfIGIVpflFj0LIsIDiLMsYyvYdx1KwwsIUDTEZtxcPm/sWjPzqA==
|
integrity sha512-RB06pov+O4Npy10ei1C6fsyB9QoOjz7Ubo8Sl3qdKtLgkL9iI96925DYtH0bxx6MH6YB2FuzLU6B75qn3AQQQw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/primitive" "0.1.0"
|
"@radix-ui/primitive" "1.0.0"
|
||||||
"@radix-ui/react-compose-refs" "0.1.0"
|
"@radix-ui/react-compose-refs" "1.0.0"
|
||||||
"@radix-ui/react-context" "0.1.1"
|
"@radix-ui/react-context" "1.0.0"
|
||||||
"@radix-ui/react-id" "0.1.5"
|
"@radix-ui/react-dismissable-layer" "1.0.0"
|
||||||
"@radix-ui/react-popper" "0.1.4"
|
"@radix-ui/react-id" "1.0.0"
|
||||||
"@radix-ui/react-portal" "0.1.4"
|
"@radix-ui/react-popper" "1.0.0"
|
||||||
"@radix-ui/react-presence" "0.1.2"
|
"@radix-ui/react-portal" "1.0.0"
|
||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-presence" "1.0.0"
|
||||||
"@radix-ui/react-slot" "0.1.2"
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
"@radix-ui/react-use-controllable-state" "0.1.0"
|
"@radix-ui/react-slot" "1.0.0"
|
||||||
"@radix-ui/react-use-escape-keydown" "0.1.0"
|
"@radix-ui/react-use-controllable-state" "1.0.0"
|
||||||
"@radix-ui/react-use-previous" "0.1.1"
|
"@radix-ui/react-visually-hidden" "1.0.0"
|
||||||
"@radix-ui/react-use-rect" "0.1.1"
|
|
||||||
"@radix-ui/react-visually-hidden" "0.1.4"
|
|
||||||
|
|
||||||
"@radix-ui/react-use-body-pointer-events@0.1.1":
|
"@radix-ui/react-use-body-pointer-events@0.1.1":
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
|
@ -1808,6 +1973,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-callback-ref@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz#9e7b8b6b4946fe3cbe8f748c82a2cce54e7b6a90"
|
||||||
|
integrity sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-use-controllable-state@0.1.0":
|
"@radix-ui/react-use-controllable-state@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz#4fced164acfc69a4e34fb9d193afdab973a55de1"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz#4fced164acfc69a4e34fb9d193afdab973a55de1"
|
||||||
|
@ -1816,6 +1988,14 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-controllable-state@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz#a64deaafbbc52d5d407afaa22d493d687c538b7f"
|
||||||
|
integrity sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-use-direction@0.1.0":
|
"@radix-ui/react-use-direction@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-direction/-/react-use-direction-0.1.0.tgz#97ac1d52e497c974389e7988f809238ed72e7df7"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-direction/-/react-use-direction-0.1.0.tgz#97ac1d52e497c974389e7988f809238ed72e7df7"
|
||||||
|
@ -1831,6 +2011,14 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-use-callback-ref" "0.1.0"
|
"@radix-ui/react-use-callback-ref" "0.1.0"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-escape-keydown@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz#aef375db4736b9de38a5a679f6f49b45a060e5d1"
|
||||||
|
integrity sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-use-layout-effect@0.1.0":
|
"@radix-ui/react-use-layout-effect@0.1.0":
|
||||||
version "0.1.0"
|
version "0.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz#ebf71bd6d2825de8f1fbb984abf2293823f0f223"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz#ebf71bd6d2825de8f1fbb984abf2293823f0f223"
|
||||||
|
@ -1838,6 +2026,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-layout-effect@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz#2fc19e97223a81de64cd3ba1dc42ceffd82374dc"
|
||||||
|
integrity sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@radix-ui/react-use-previous@0.1.1":
|
"@radix-ui/react-use-previous@0.1.1":
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-0.1.1.tgz#0226017f72267200f6e832a7103760e96a6db5d0"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-0.1.1.tgz#0226017f72267200f6e832a7103760e96a6db5d0"
|
||||||
|
@ -1853,6 +2048,14 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/rect" "0.1.1"
|
"@radix-ui/rect" "0.1.1"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-rect@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.0.tgz#b040cc88a4906b78696cd3a32b075ed5b1423b3e"
|
||||||
|
integrity sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/rect" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-use-size@0.1.1":
|
"@radix-ui/react-use-size@0.1.1":
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-0.1.1.tgz#f6b75272a5d41c3089ca78c8a2e48e5f204ef90f"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-0.1.1.tgz#f6b75272a5d41c3089ca78c8a2e48e5f204ef90f"
|
||||||
|
@ -1860,6 +2063,14 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/react-use-size@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz#a0b455ac826749419f6354dc733e2ca465054771"
|
||||||
|
integrity sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/react-visually-hidden@0.1.4", "@radix-ui/react-visually-hidden@^0.1.4":
|
"@radix-ui/react-visually-hidden@0.1.4", "@radix-ui/react-visually-hidden@^0.1.4":
|
||||||
version "0.1.4"
|
version "0.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-0.1.4.tgz#6c75eae34fb5d084b503506fbfc05587ced05f03"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-0.1.4.tgz#6c75eae34fb5d084b503506fbfc05587ced05f03"
|
||||||
|
@ -1868,6 +2079,14 @@
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
"@radix-ui/react-primitive" "0.1.4"
|
"@radix-ui/react-primitive" "0.1.4"
|
||||||
|
|
||||||
|
"@radix-ui/react-visually-hidden@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.0.tgz#4d69d7e3b6d21ee4678ed6de5215dcd068394401"
|
||||||
|
integrity sha512-MwAhMdX+n6S4InwRKSnpUsp+lLkYG6izQF56ul6guSX2mBBLOMV9Frx7xJlkEe2GjKLzbNuHhaCS6e5gopmZNA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/react-primitive" "1.0.0"
|
||||||
|
|
||||||
"@radix-ui/rect@0.1.1":
|
"@radix-ui/rect@0.1.1":
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-0.1.1.tgz#95b5ba51f469bea6b1b841e2d427e17e37d38419"
|
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-0.1.1.tgz#95b5ba51f469bea6b1b841e2d427e17e37d38419"
|
||||||
|
@ -1875,6 +2094,13 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "^7.13.10"
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
|
"@radix-ui/rect@1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.0.tgz#0dc8e6a829ea2828d53cbc94b81793ba6383bf3c"
|
||||||
|
integrity sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
"@rollup/pluginutils@^4.2.1":
|
"@rollup/pluginutils@^4.2.1":
|
||||||
version "4.2.1"
|
version "4.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d"
|
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d"
|
||||||
|
@ -2840,6 +3066,11 @@ datastore-core@^8.0.1:
|
||||||
it-take "^1.0.1"
|
it-take "^1.0.1"
|
||||||
uint8arrays "^3.0.0"
|
uint8arrays "^3.0.0"
|
||||||
|
|
||||||
|
date-fns@^2.29.3:
|
||||||
|
version "2.29.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8"
|
||||||
|
integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==
|
||||||
|
|
||||||
debug@^2.6.9:
|
debug@^2.6.9:
|
||||||
version "2.6.9"
|
version "2.6.9"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
|
@ -6832,6 +7063,11 @@ use-callback-ref@^1.2.3:
|
||||||
resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.5.tgz#6115ed242cfbaed5915499c0a9842ca2912f38a5"
|
resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.5.tgz#6115ed242cfbaed5915499c0a9842ca2912f38a5"
|
||||||
integrity sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==
|
integrity sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==
|
||||||
|
|
||||||
|
use-isomorphic-layout-effect@^1.1.1:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
|
||||||
|
integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
|
||||||
|
|
||||||
use-sidecar@^1.0.1:
|
use-sidecar@^1.0.1:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.5.tgz#ffff2a17c1df42e348624b699ba6e5c220527f2b"
|
resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.5.tgz#ffff2a17c1df42e348624b699ba6e5c220527f2b"
|
||||||
|
|
Loading…
Reference in New Issue