diff --git a/src/components/ProfilePreview.tsx b/src/components/ProfilePreview.tsx
index 46f0a1089..3da40c028 100644
--- a/src/components/ProfilePreview.tsx
+++ b/src/components/ProfilePreview.tsx
@@ -13,6 +13,8 @@ export type ProfilePreviewProps = ComponentProps<'div'> & {
address: string
className?: string
avatarClassName?: string
+ addressesContainerClassName?: string
+ showMaxOneAddress?: boolean
withGrillAddress?: boolean
withEvmAddress?: boolean
nameClassName?: string
@@ -23,6 +25,8 @@ const ProfilePreview = ({
className,
avatarClassName,
nameClassName,
+ addressesContainerClassName,
+ showMaxOneAddress = false,
withGrillAddress = true,
withEvmAddress = true,
...props
@@ -42,25 +46,26 @@ const ProfilePreview = ({
address={address}
className={cx('h-20 w-20', avatarClassName)}
/>
-
+
{showingAnyAddress && (
-
- {withGrillAddress && (
-
-
-
-
- )}
+
+ {withGrillAddress &&
+ (!isShowingEvmAddress || !showMaxOneAddress) && (
+
+
+
+
+ )}
{isShowingEvmAddress && (
diff --git a/src/components/auth/LoginModal/LoginModal.tsx b/src/components/auth/LoginModal/LoginModal.tsx
index 74a57fd70..40e9ad381 100644
--- a/src/components/auth/LoginModal/LoginModal.tsx
+++ b/src/components/auth/LoginModal/LoginModal.tsx
@@ -13,9 +13,10 @@ const CaptchaInvisible = dynamic(
)
export type LoginModalProps = ModalFunctionalityProps & {
+ initialOpenState?: LoginModalStep
+ onBackClick?: () => void
afterLogin?: () => void
beforeLogin?: () => void
- openModal: () => void
}
type ModalTitle = {
@@ -69,15 +70,18 @@ const modalHeader: ModalTitle = {
export default function LoginModal({
afterLogin,
beforeLogin,
+ initialOpenState = 'login',
+ onBackClick,
...props
}: LoginModalProps) {
const inputRef = useRef
(null)
- const [currentStep, setCurrentStep] = useState('login')
+ const [currentStep, setCurrentStep] =
+ useState(initialOpenState)
- const onBackClick = () => setCurrentStep('login')
+ const usedOnBackClick = onBackClick || (() => setCurrentStep('login'))
useEffect(() => {
- if (props.isOpen) setCurrentStep('login')
+ if (props.isOpen) setCurrentStep(initialOpenState)
}, [props.isOpen])
const ModalContent = loginModalContents[currentStep]
@@ -91,7 +95,7 @@ export default function LoginModal({
title={title}
withCloseButton
description={desc}
- onBackClick={withBackButton ? onBackClick : undefined}
+ onBackClick={withBackButton ? usedOnBackClick : undefined}
closeModal={() => {
props.closeModal()
}}
diff --git a/src/components/auth/LoginModal/LoginModalContent.tsx b/src/components/auth/LoginModal/LoginModalContent.tsx
index 7f1f6a627..d643fdbdf 100644
--- a/src/components/auth/LoginModal/LoginModalContent.tsx
+++ b/src/components/auth/LoginModal/LoginModalContent.tsx
@@ -37,7 +37,6 @@ export type LoginModalStep =
type ContentProps = ModalFunctionalityProps & {
setCurrentStep: Dispatch>
currentStep: LoginModalStep
- openModal: () => void
runCaptcha: () => Promise
termsAndService: (className?: string) => JSX.Element
afterLogin?: () => void
diff --git a/src/components/auth/ProfileModal/contents/notifications/TelegramNotificationContent.tsx b/src/components/auth/ProfileModal/contents/notifications/TelegramNotificationContent.tsx
index 240ab36ce..5c069e45f 100644
--- a/src/components/auth/ProfileModal/contents/notifications/TelegramNotificationContent.tsx
+++ b/src/components/auth/ProfileModal/contents/notifications/TelegramNotificationContent.tsx
@@ -31,7 +31,7 @@ export default function TelegramNotificationContent(props: ContentProps) {
if (!isLoadingAccount && !firstLinkedAccount) {
return (
<>
- {!isAfterDisconnect && (
+ {isAfterDisconnect && (
You have disconnected your account from Grill's telegram bot.
diff --git a/src/components/chats/ChatItem/ChatItemMenus.tsx b/src/components/chats/ChatItem/ChatItemMenus.tsx
index 610f688b5..2e474c1f1 100644
--- a/src/components/chats/ChatItem/ChatItemMenus.tsx
+++ b/src/components/chats/ChatItem/ChatItemMenus.tsx
@@ -204,7 +204,6 @@ export default function ChatItemMenus({
)}
setModalState('login')}
closeModal={() => setModalState(null)}
beforeLogin={() => (isLoggingInWithKey.current = true)}
afterLogin={() => (isLoggingInWithKey.current = false)}
diff --git a/src/components/chats/ChatList/ChatList.tsx b/src/components/chats/ChatList/ChatList.tsx
index 9d54b643c..87355d9a3 100644
--- a/src/components/chats/ChatList/ChatList.tsx
+++ b/src/components/chats/ChatList/ChatList.tsx
@@ -73,6 +73,7 @@ function ChatListContent({
const [initialNewMessageCount, setInitialNewMessageCount] = useState(0)
const lastReadId = useFocusedLastMessageId(chatId)
+ const [recipient, setRecipient] = useState('')
const [messageModalMsgId, setMessageModalMsgId] = useState('')
const prevMessageModalMsgId = usePrevious(messageModalMsgId)
@@ -136,6 +137,7 @@ function ChatListContent({
hasScrolledToMessageRef.current = true
const messageId = getUrlQuery('messageId')
+ const recipient = getUrlQuery('targetAcc')
const isMessageIdsFetched = rawMessageIds !== undefined
if (!isMessageIdsFetched) return
@@ -160,6 +162,7 @@ function ChatListContent({
}
setMessageModalMsgId(messageId)
+ setRecipient(recipient)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [rawMessageIds, filteredMessageIdsRef, hasScrolledToMessageRef])
@@ -298,6 +301,7 @@ function ChatListContent({
closeModal={() => setMessageModalMsgId('')}
messageId={messageModalMsgId}
scrollToMessage={scrollToMessage}
+ recipient={recipient}
/>
diff --git a/src/components/modals/MessageModal.stories.tsx b/src/components/modals/MessageModal.stories.tsx
new file mode 100644
index 000000000..a9bc9da6f
--- /dev/null
+++ b/src/components/modals/MessageModal.stories.tsx
@@ -0,0 +1,50 @@
+import type { Meta, StoryObj } from '@storybook/react'
+import { useState } from 'react'
+import Button from '../Button'
+import MessageModal, { MessageModalProps } from './MessageModal'
+
+function MessageModalWrapper(
+ props: Omit
+) {
+ const [isOpen, setIsOpen] = useState(false)
+
+ return (
+ <>
+
+ setIsOpen(false)}
+ />
+ >
+ )
+}
+
+const meta = {
+ title: 'Components/MessageModal',
+ component: MessageModalWrapper,
+ tags: ['autodocs'],
+ parameters: {
+ layout: 'centered',
+ },
+ args: {
+ hubId: '1001',
+ messageId: '7687',
+ scrollToMessage: async (messageId) => {
+ alert('Scroll to message: ' + messageId)
+ },
+ },
+} satisfies Meta
+
+export default meta
+type Story = StoryObj
+
+export const Default: Story = {
+ args: {},
+}
+
+export const WithTargetAccount: Story = {
+ args: {
+ recipient: '3szaLms2V18XCr2ztvjzcPF16BxvbGeAW4fEG2yeb19XGdGV',
+ },
+}
diff --git a/src/components/modals/MessageModal.tsx b/src/components/modals/MessageModal.tsx
index 48c1c204a..7c0f44dd9 100644
--- a/src/components/modals/MessageModal.tsx
+++ b/src/components/modals/MessageModal.tsx
@@ -1,23 +1,38 @@
import { getPostQuery } from '@/services/api/query'
+import { useSendEvent } from '@/stores/analytics'
+import { useMyAccount } from '@/stores/my-account'
import { cx } from '@/utils/class-names'
import { CommentData } from '@subsocial/api/types'
-import { useRef, useState } from 'react'
+import { useEffect, useRef, useState } from 'react'
+import { HiOutlineInformationCircle } from 'react-icons/hi2'
+import LoginModal from '../auth/LoginModal'
import Button from '../Button'
+import Card from '../Card'
import ChatItem from '../chats/ChatItem'
+import PopOver from '../floating/PopOver'
+import ProfilePreview from '../ProfilePreview'
import Modal, { ModalFunctionalityProps } from './Modal'
export type MessageModalProps = ModalFunctionalityProps & {
messageId: string
scrollToMessage?: (messageId: string) => Promise
hubId: string
+ recipient?: string
}
export default function MessageModal({
messageId,
scrollToMessage,
hubId,
+ recipient,
...props
}: MessageModalProps) {
+ const myAddress = useMyAccount((state) => state.address)
+ const isInitialized = useMyAccount((state) => state.isInitialized)
+ const isDifferentRecipient = recipient !== myAddress
+
+ const [isOpenLoginModal, setIsOpenLoginModal] = useState(false)
+
const { data: message } = getPostQuery.useQuery(messageId)
const chatId = (message as unknown as CommentData)?.struct.rootPostId
const { data: chat } = getPostQuery.useQuery(chatId)
@@ -30,6 +45,17 @@ export default function MessageModal({
)
+ const sendEvent = useSendEvent()
+ useEffect(() => {
+ if (!isInitialized) return
+
+ if (props.isOpen && recipient)
+ sendEvent('open_tg_notification', {
+ isMyNotif: (myAddress === recipient) + '',
+ })
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [props.isOpen, isInitialized])
+
const handleScrollToMessage = async () => {
if (!scrollToMessage) return
@@ -41,41 +67,79 @@ export default function MessageModal({
}
return (
- Message from {chatTitle}
- }
- >
-
+ Message from {chatTitle}
+ }
>
- {message && (
-
- )}
-
- {scrollToMessage && (
-
- )}
-
+ {message && (
+
+ )}
+ {scrollToMessage && (
+
+ )}
+
+ {isDifferentRecipient && recipient && (
+
+
+
Notification recipient
+
}
+ triggerOnHover
+ panelSize='sm'
+ yOffset={6}
+ placement='top'
+ >
+
You are not currently logged in to this account.
+
+
+
+
+
+ )}
+
+ setIsOpenLoginModal(false)}
+ initialOpenState='enter-secret-key'
+ onBackClick={() => setIsOpenLoginModal(false)}
+ />
+ >
)
}
diff --git a/src/components/navbar/Navbar/Navbar.tsx b/src/components/navbar/Navbar/Navbar.tsx
index 02e0d81b0..e9b08c895 100644
--- a/src/components/navbar/Navbar/Navbar.tsx
+++ b/src/components/navbar/Navbar/Navbar.tsx
@@ -154,7 +154,6 @@ export default function Navbar({
setOpenLoginModal(true)}
closeModal={() => setOpenLoginModal(false)}
beforeLogin={() => (isLoggingInWithKey.current = true)}
afterLogin={() => (isLoggingInWithKey.current = false)}
diff --git a/src/modules/chat/ChatPage/ChatPage.tsx b/src/modules/chat/ChatPage/ChatPage.tsx
index 54e440d77..0a119a2d6 100644
--- a/src/modules/chat/ChatPage/ChatPage.tsx
+++ b/src/modules/chat/ChatPage/ChatPage.tsx
@@ -68,7 +68,7 @@ export default function ChatPage({
if (isNewChat) setIsOpenCreateSuccessModal(true)
}, [])
useEffect(() => {
- if (!isOpenCreateSuccessModal) replaceUrl(getCurrentUrlWithoutQuery())
+ if (!isOpenCreateSuccessModal) replaceUrl(getCurrentUrlWithoutQuery('new'))
}, [isOpenCreateSuccessModal])
const { data: messageIds } = useCommentIdsByPostId(chatId, {
diff --git a/src/utils/links.ts b/src/utils/links.ts
index 71e6fa7c4..506a5e1f8 100644
--- a/src/utils/links.ts
+++ b/src/utils/links.ts
@@ -22,6 +22,7 @@ export function getCurrentUrlWithoutQuery(queryNameToRemove?: string) {
return (
window.location.origin +
window.location.pathname +
+ '?' +
searchParams.toString()
)
}