Render new messages

This commit is contained in:
ilya-bkv 2023-11-16 17:20:05 +03:00
parent e1a3c881e1
commit 4faafe89d5
8 changed files with 72 additions and 37 deletions

View File

@ -452,5 +452,6 @@
"video": "video", "video": "video",
"view": "view", "view": "view",
"viewsWithCount": "{count} {count, plural, one {view} other {views}}", "viewsWithCount": "{count} {count, plural, one {view} other {views}}",
"yesterday": "yesterday" "yesterday": "yesterday",
"To new messages": "To new messages"
} }

View File

@ -476,5 +476,6 @@
"video": "видео", "video": "видео",
"view": "просмотр", "view": "просмотр",
"viewsWithCount": "{count} {count, plural, one {просмотр} few {просмотрa} other {просмотров}}", "viewsWithCount": "{count} {count, plural, one {просмотр} few {просмотрa} other {просмотров}}",
"yesterday": "вчера" "yesterday": "вчера",
"To new messages": "К новым сообщениям"
} }

View File

@ -1,4 +1,4 @@
import { Show, Switch, Match, createMemo } from 'solid-js' import { Show, Switch, Match, createMemo, createEffect } from 'solid-js'
import DialogAvatar from './DialogAvatar' import DialogAvatar from './DialogAvatar'
import type { ChatMember } from '../../graphql/types.gen' import type { ChatMember } from '../../graphql/types.gen'
import GroupDialogAvatar from './GroupDialogAvatar' import GroupDialogAvatar from './GroupDialogAvatar'
@ -41,23 +41,20 @@ const DialogCard = (props: DialogProps) => {
})} })}
onClick={props.onClick} onClick={props.onClick}
> >
<Switch <Switch>
fallback={ <Match when={props.members.length === 2}>
<Show <div class={styles.avatar}>
when={props.isChatHeader} <Show
fallback={ when={props.isChatHeader}
<div class={styles.avatar}> fallback={<DialogAvatar name={companions()[0].slug} url={companions()[0].userpic} />}
<DialogAvatar name={props.members[0].slug} url={props.members[0].userpic} /> >
</div> <AuthorBadge nameOnly={true} author={companions()[0]} />
} </Show>
> </div>
<AuthorBadge nameOnly={true} author={props.members[0]} /> </Match>
</Show>
}
>
<Match when={props.members.length >= 3}> <Match when={props.members.length >= 3}>
<div class={styles.avatar}> <div class={styles.avatar}>
<GroupDialogAvatar users={props.members} /> <GroupDialogAvatar users={companions()} />
</div> </div>
</Match> </Match>
</Switch> </Switch>

View File

@ -25,7 +25,7 @@ export const Message = (props: Props) => {
return ( return (
<div class={clsx(styles.Message, isOwn && styles.own)}> <div class={clsx(styles.Message, isOwn && styles.own)}>
<Show when={!isOwn}> <Show when={!isOwn && user}>
<div class={styles.author}> <div class={styles.author}>
<DialogAvatar size="small" name={user.name} url={user.userpic} /> <DialogAvatar size="small" name={user.name} url={user.userpic} />
<div class={styles.name}>{user.name}</div> <div class={styles.name}>{user.name}</div>

View File

@ -19,6 +19,7 @@ import { clsx } from 'clsx'
import styles from '../../styles/Inbox.module.scss' import styles from '../../styles/Inbox.module.scss'
import { useLocalize } from '../../context/localize' import { useLocalize } from '../../context/localize'
import SimplifiedEditor from '../Editor/SimplifiedEditor' import SimplifiedEditor from '../Editor/SimplifiedEditor'
import { Popover } from '../_shared/Popover'
type InboxSearchParams = { type InboxSearchParams = {
initChat: string initChat: string
@ -47,6 +48,7 @@ export const InboxView = () => {
const [currentDialog, setCurrentDialog] = createSignal<Chat>() const [currentDialog, setCurrentDialog] = createSignal<Chat>()
const [messageToReply, setMessageToReply] = createSignal<MessageType | null>(null) const [messageToReply, setMessageToReply] = createSignal<MessageType | null>(null)
const [isClear, setClear] = createSignal(false) const [isClear, setClear] = createSignal(false)
const [isScrollToNewVisible, setIsScrollToNewVisible] = createSignal(false)
const { session } = useSession() const { session } = useSession()
const currentUserId = createMemo(() => session()?.user.id) const currentUserId = createMemo(() => session()?.user.id)
const { changeSearchParam, searchParams } = useRouter<InboxSearchParams>() const { changeSearchParam, searchParams } = useRouter<InboxSearchParams>()
@ -82,20 +84,6 @@ export const InboxView = () => {
} }
} }
/*
createEffect(() => {
setInterval(async () => {
if (!currentDialog()) return
try {
await getMessages(currentDialog().id)
} catch (error) {
console.error('[getMessages]', error)
} finally {
chatWindow.scrollTop = chatWindow.scrollHeight
}
}, 2000)
})
*/
onMount(async () => { onMount(async () => {
try { try {
const response = await loadRecipients({ days: 365 }) const response = await loadRecipients({ days: 365 })
@ -166,7 +154,6 @@ export const InboxView = () => {
return return
} }
if (messagesContainerRef.current.scrollTop >= messagesContainerRef.current.scrollHeight) { if (messagesContainerRef.current.scrollTop >= messagesContainerRef.current.scrollHeight) {
//TODO: show new message arrow - bubble
return return
} }
messagesContainerRef.current.scroll({ messagesContainerRef.current.scroll({
@ -177,6 +164,24 @@ export const InboxView = () => {
), ),
{ defer: true } { defer: true }
) )
const handleScrollMessageContainer = () => {
console.log('!!! AAAA:')
if (
messagesContainerRef.current.scrollHeight - messagesContainerRef.current.scrollTop >
messagesContainerRef.current.clientHeight * 1.5
) {
setIsScrollToNewVisible(true)
} else {
setIsScrollToNewVisible(false)
}
}
const handleScrollToNew = () => {
messagesContainerRef.current.scroll({
top: messagesContainerRef.current.scrollHeight,
behavior: 'smooth'
})
setIsScrollToNewVisible(false)
}
return ( return (
<div class={clsx('container', styles.Inbox)}> <div class={clsx('container', styles.Inbox)}>
@ -247,6 +252,7 @@ export const InboxView = () => {
<div class={clsx('col-md-16', styles.conversation)}> <div class={clsx('col-md-16', styles.conversation)}>
<Show <Show
keyed={true}
when={currentDialog()} when={currentDialog()}
fallback={ fallback={
<MessagesFallback <MessagesFallback
@ -258,7 +264,20 @@ export const InboxView = () => {
> >
<DialogHeader ownId={currentUserId()} chat={currentDialog()} /> <DialogHeader ownId={currentUserId()} chat={currentDialog()} />
<div class={styles.conversationMessages}> <div class={styles.conversationMessages}>
<div class={styles.messagesContainer} ref={(el) => (messagesContainerRef.current = el)}> <Show when={isScrollToNewVisible()}>
<Popover content={t('To new messages')}>
{(triggerRef: (el) => void) => (
<div ref={triggerRef} class={styles.scrollToNew} onClick={handleScrollToNew}>
<Icon name="arrow-right" class={styles.icon} />
</div>
)}
</Popover>
</Show>
<div
class={styles.messagesContainer}
ref={(el) => (messagesContainerRef.current = el)}
onScroll={handleScrollMessageContainer}
>
<For each={messages()}> <For each={messages()}>
{(message) => ( {(message) => (
<Message <Message

View File

@ -50,7 +50,6 @@ export const InboxProvider = (props: { children: JSX.Element }) => {
const loadChats = async () => { const loadChats = async () => {
try { try {
const newChats = await inboxClient.loadChats({ limit: 50, offset: 0 }) const newChats = await inboxClient.loadChats({ limit: 50, offset: 0 })
console.log('!!! newChats:', newChats)
setChats(newChats) setChats(newChats)
} catch (error) { } catch (error) {
console.log('[loadChats]', error) console.log('[loadChats]', error)

View File

@ -114,6 +114,25 @@ main {
overflow: auto; overflow: auto;
position: relative; position: relative;
.scrollToNew {
osition: absolute;
z-index: 2;
bottom: 8px;
overflow: hidden;
right: 0;
width: 40px;
padding: 1rem;
border: 2px solid var(--black-100);
border-radius: 50%;
height: 40px;
cursor: pointer;
background: var(--background-color);
.icon {
rotate: 90deg;
}
}
.messagesContainer { .messagesContainer {
left: 0; left: 0;
height: 100%; height: 100%;

View File

@ -383,7 +383,6 @@ export const apiClient = {
export const inboxClient = { export const inboxClient = {
loadChats: async (options: QueryLoadChatsArgs): Promise<Chat[]> => { loadChats: async (options: QueryLoadChatsArgs): Promise<Chat[]> => {
const resp = await privateInboxGraphQLClient.query(myChats, options).toPromise() const resp = await privateInboxGraphQLClient.query(myChats, options).toPromise()
console.log('!!! resp:', resp)
return resp.data.loadChats.chats return resp.data.loadChats.chats
}, },