fix Reply view

This commit is contained in:
ilya-bkv 2022-12-14 15:15:56 +03:00
parent 1badb74f6f
commit 4d57d63d11
7 changed files with 94 additions and 38 deletions

View File

@ -12,6 +12,7 @@ $actionsWidth: 32px * 2;
.text {
display: inline-flex;
flex-direction: column;
max-width: 60%;
margin-right: auto;
background: #f6f6f6;

View File

@ -55,7 +55,7 @@ const Message = (props: Props) => {
/>
</div>
<Show when={props.replyBody}>
<QuotedMessage body={props.replyBody} variant="inline" />
<QuotedMessage body={props.replyBody} variant="inline" isOwn={isOwn} />
</Show>
<div innerHTML={md.render(props.content.body)} />
</div>

View File

@ -2,18 +2,33 @@
display: flex;
flex-direction: row;
align-items: center;
border-top: 2px solid #ccc;
padding: 12px 0;
gap: 12px;
font-size: 14px;
.icon {
width: 40px;
height: 40px;
flex-basis: 40px;
&.inline {
color: #696969;
border-left: 2px solid #404040;
padding-left: 12px;
margin-bottom: 8px;
&.cancel {
cursor: pointer;
&.own {
color: #9fa1a7;
border-color: #fff;
}
}
&.reply {
border-top: 2px solid #ccc;
padding: 12px 0;
gap: 12px;
.icon {
width: 40px;
height: 40px;
flex-basis: 40px;
&.cancel {
cursor: pointer;
}
}
}

View File

@ -8,21 +8,30 @@ type QuotedMessage = {
cancel?: () => void
author?: string
variant: 'inline' | 'reply'
isOwn?: boolean
}
const QuotedMessage = (props: QuotedMessage) => {
return (
<div class={styles.QuotedMessage}>
<div class={styles.icon}>
<Icon name="chat-reply" />
</div>
<div
class={clsx(styles.QuotedMessage, {
[styles.reply]: props.variant === 'reply',
[styles.inline]: props.variant === 'inline',
[styles.own]: props.isOwn
})}
>
<Show when={props.variant === 'reply'}>
<div class={styles.icon}>
<Icon name="chat-reply" />
</div>
</Show>
<div class={styles.body}>
<Show when={props.author}>
<div class={styles.author}>{props.author}</div>
</Show>
<div class={styles.quote}>{props.body}</div>
</div>
<Show when={props.cancel && props.variant !== 'inline'}>
<Show when={props.cancel && props.variant === 'reply'}>
<div class={clsx(styles.cancel, styles.icon)} onClick={props.cancel}>
<Icon name="close-gray" />
</div>

View File

@ -29,9 +29,11 @@ const { changeSearchParam } = useRouter()
export const InboxView = () => {
const {
chats,
actions: { loadChats } // setListener
messages,
actions: { loadChats, getMessages } // setListener
} = useInbox()
const [messages, setMessages] = createSignal<MessageType[]>([])
// const [messages, setMessages] = createSignal<MessageType[]>([])
const [recipients, setRecipients] = createSignal<Author[]>([])
const [postMessageText, setPostMessageText] = createSignal('')
const [sortByGroup, setSortByGroup] = createSignal<boolean>(false)
@ -56,15 +58,26 @@ export const InboxView = () => {
setCurrentDialog(chat)
changeSearchParam('chat', `${chat.id}`)
try {
const response = await loadMessages({ chat: chat.id })
setMessages(response as unknown as MessageType[])
await getMessages(chat.id)
} catch (error) {
console.error('[loadMessages]', error)
console.error('[getMessages]', error)
} finally {
chatWindow.scrollTop = chatWindow.scrollHeight
}
// try {
// const response = await loadMessages({ chat: chat.id })
// setMessages(response as unknown as MessageType[])
// } catch (error) {
// console.error('[loadMessages]', error)
// } finally {
// chatWindow.scrollTop = chatWindow.scrollHeight
// }
}
createEffect(() => {
console.log('!!! messages:', messages())
})
onMount(async () => {
try {
const response = await loadRecipients({ days: 365 })
@ -77,12 +90,13 @@ export const InboxView = () => {
const handleSubmit = async () => {
try {
console.log('!!! post:')
const post = await apiClient.createMessage({
body: postMessageText().toString(),
chat: currentDialog().id.toString(),
replyTo: messageToReply()?.id
})
setMessages((prev) => [...prev, post.message])
// setMessages((prev) => [...prev, post.message])
setPostMessageText('')
setMessageToReply(null)
chatWindow.scrollTop = chatWindow.scrollHeight

View File

@ -6,12 +6,15 @@ import { apiClient } from '../utils/apiClient'
import newMessage from '../graphql/subs/new-message'
import type { Client } from '@urql/core'
import { pipe, subscribe } from 'wonka'
import { loadMessages } from '../stores/inbox'
type InboxContextType = {
chats: Accessor<Chat[]>
messages?: Accessor<Message[]>
actions: {
createChat: (members: number[], title: string) => Promise<{ chat: Chat }>
loadChats: () => Promise<void>
getMessages?: (chatId: string) => Promise<void>
unsubscribe: () => void
}
}
@ -24,6 +27,7 @@ export function useInbox() {
export const InboxProvider = (props: { children: JSX.Element }) => {
const [chats, setChats] = createSignal<Chat[]>([])
const [messages, setMessages] = createSignal<Message[]>([])
const subclient = createMemo<Client>(() => createChatClient())
const loadChats = async () => {
try {
@ -38,6 +42,15 @@ export const InboxProvider = (props: { children: JSX.Element }) => {
}
}
const getMessages = async (chatId: string) => {
try {
const response = await loadMessages({ chat: chatId })
setMessages(response as unknown as Message[])
} catch (error) {
console.log('[loadMessages]', error)
}
}
const createChat = async (members: number[], title: string) => {
const chat = await apiClient.createChat({ members, title })
setChats((prevChats) => {
@ -57,9 +70,10 @@ export const InboxProvider = (props: { children: JSX.Element }) => {
const actions = {
createChat,
loadChats,
getMessages,
unsubscribe // TODO: call unsubscribe some time!
}
const value: InboxContextType = { chats, actions }
const value: InboxContextType = { chats, messages, actions }
return <InboxContext.Provider value={value}>{props.children}</InboxContext.Provider>
}

View File

@ -55,9 +55,9 @@ export type AuthorsBy = {
}
export type Chat = {
admins?: Maybe<Array<Maybe<Scalars['String']>>>
admins?: Maybe<Array<Maybe<Scalars['Int']>>>
createdAt: Scalars['Int']
createdBy: Scalars['String']
createdBy: Scalars['Int']
description?: Maybe<Scalars['String']>
id: Scalars['String']
members?: Maybe<Array<Maybe<ChatMember>>>
@ -66,7 +66,7 @@ export type Chat = {
title?: Maybe<Scalars['String']>
unread?: Maybe<Scalars['Int']>
updatedAt: Scalars['Int']
users?: Maybe<Array<Maybe<Scalars['String']>>>
users?: Maybe<Array<Maybe<Scalars['Int']>>>
}
export type ChatInput = {
@ -79,6 +79,7 @@ export type ChatMember = {
id: Scalars['Int']
lastSeen?: Maybe<Scalars['DateTime']>
name: Scalars['String']
online?: Maybe<Scalars['Boolean']>
slug: Scalars['String']
userpic?: Maybe<Scalars['String']>
}
@ -140,12 +141,13 @@ export type LoadShoutsOptions = {
}
export type Message = {
author: Scalars['String']
author: Scalars['Int']
body: Scalars['String']
chatId: Scalars['String']
createdAt: Scalars['Int']
id: Scalars['Int']
replyTo?: Maybe<Scalars['String']>
replyTo?: Maybe<Scalars['Int']>
seen?: Maybe<Scalars['Boolean']>
updatedAt?: Maybe<Scalars['Int']>
}
@ -354,6 +356,7 @@ export type Query = {
loadShout?: Maybe<Shout>
loadShouts: Array<Maybe<Shout>>
markdownBody: Scalars['String']
searchMessages: Result
searchRecipients: Result
signIn: AuthResult
signOut: AuthResult
@ -418,6 +421,12 @@ export type QueryMarkdownBodyArgs = {
body: Scalars['String']
}
export type QuerySearchMessagesArgs = {
by: MessagesBy
limit?: InputMaybe<Scalars['Int']>
offset?: InputMaybe<Scalars['Int']>
}
export type QuerySearchRecipientsArgs = {
limit?: InputMaybe<Scalars['Int']>
offset?: InputMaybe<Scalars['Int']>
@ -621,19 +630,12 @@ export type Stat = {
}
export type Subscription = {
newMessage: Message
onlineUpdated: Array<User>
reactionUpdated: ReactionUpdating
shoutUpdated: Shout
userUpdated: User
collabUpdate?: Maybe<Reaction>
newMessage?: Maybe<Message>
}
export type SubscriptionNewMessageArgs = {
chats?: InputMaybe<Array<Scalars['Int']>>
}
export type SubscriptionReactionUpdatedArgs = {
shout: Scalars['String']
export type SubscriptionCollabUpdateArgs = {
collab: Scalars['Int']
}
export type Token = {
@ -670,6 +672,7 @@ export type TopicStat = {
}
export type User = {
about?: Maybe<Scalars['String']>
bio?: Maybe<Scalars['String']>
communities?: Maybe<Array<Maybe<Scalars['Int']>>>
createdAt: Scalars['DateTime']