Chat Header

This commit is contained in:
ilya-bkv 2022-12-01 09:00:51 +03:00
parent 15ad8bf8dd
commit f98c849ed9
6 changed files with 79 additions and 68 deletions

View File

@ -7,6 +7,7 @@
padding: 12px; padding: 12px;
transition: background 0.3s ease-in-out; transition: background 0.3s ease-in-out;
cursor: pointer; cursor: pointer;
width: 100%;
&:hover { &:hover {
background: #f7f7f7; background: #f7f7f7;
@ -24,6 +25,7 @@
.name, .name,
.message { .message {
width: 100%;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;

View File

@ -1,8 +1,9 @@
import styles from './DialogCard.module.scss' import { Show, Switch, Match, createMemo, For } 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'
import { Show } from 'solid-js' import { clsx } from 'clsx'
import styles from './DialogCard.module.scss'
type DialogProps = { type DialogProps = {
online?: boolean online?: boolean
@ -11,37 +12,50 @@ type DialogProps = {
title?: string title?: string
ownSlug: string ownSlug: string
members: ChatMember[] members: ChatMember[]
onClick: () => void onClick?: () => void
isChatHeader?: boolean
} }
const DialogCard = (props: DialogProps) => { const DialogCard = (props: DialogProps) => {
const companions = props.members && props.members.filter((member) => member.slug !== props.ownSlug) const companions = createMemo(
() => props.members && props.members.filter((member) => member.slug !== props.ownSlug)
)
const names = createMemo(() =>
companions()
.map((companion) => companion.name)
.join(', ')
)
console.log('!!! names:', names())
return ( return (
<Show when={props.members}> <Show when={props.members}>
<div class={styles.DialogCard} onClick={props.onClick}> <div class={clsx(styles.DialogCard, { [styles.header]: props.isChatHeader })} onClick={props.onClick}>
<div class={styles.avatar}> <div class={styles.avatar}>
{companions.length > 2 ? ( <Switch fallback={<DialogAvatar name={props.members[0].name} url={props.members[0].userpic} />}>
<GroupDialogAvatar users={companions} /> <Match when={companions().length > 2}>
) : ( <GroupDialogAvatar users={companions()} />
<DialogAvatar name={props.members[0].name} url={props.members[0].userpic} /> </Match>
)} </Switch>
</div> </div>
<div class={styles.row}> <div class={styles.row}>
{companions.length > 1 ? ( <Switch fallback={<div class={styles.name}>{companions()[0].name}</div>}>
<div class={styles.name}>{props.title}</div> <Match when={companions().length > 1}>
) : ( <div class={styles.name}>{props.title}</div>
<div class={styles.name}>{companions[0].name}</div> </Match>
)} </Switch>
<div class={styles.message}> <div class={styles.message}>
Указать предпочтительные языки для результатов поиска можно в разделе <Switch fallback={'Chat last message'}>
<Match when={props.isChatHeader && companions().length > 1}>{names}</Match>
</Switch>
</div> </div>
</div> </div>
<div class={styles.activity}> <Show when={!props.isChatHeader}>
<div class={styles.time}>22:22</div> <div class={styles.activity}>
<div class={styles.counter}> <div class={styles.time}>22:22</div>
<span>12</span> <div class={styles.counter}>
<span>12</span>
</div>
</div> </div>
</div> </Show>
</div> </div>
</Show> </Show>
) )

View File

@ -0,0 +1,9 @@
.DialogHeader {
display: flex;
align-items: center;
border-bottom: 3px solid #141414;
.avatar {
width: 40px;
}
}

View File

@ -0,0 +1,23 @@
import type { Chat } from '../../graphql/types.gen'
import styles from './DialogHeader.module.scss'
import DialogCard from './DialogCard'
type DialogHeader = {
chat: Chat
currentSlug: string
}
const DialogHeader = (props: DialogHeader) => {
return (
<header class={styles.DialogHeader}>
<DialogCard
isChatHeader={true}
title={props.chat.title}
members={props.chat.members}
ownSlug={props.currentSlug}
/>
</header>
)
}
export default DialogHeader

View File

@ -16,6 +16,7 @@ import CreateModalContent from '../Inbox/CreateModalContent'
import { clsx } from 'clsx' import { clsx } from 'clsx'
import '../../styles/Inbox.scss' import '../../styles/Inbox.scss'
import { useInbox } from '../../context/inbox' import { useInbox } from '../../context/inbox'
import DialogHeader from '../Inbox/DialogHeader'
const OWNER_ID = '501' const OWNER_ID = '501'
const client = createClient({ const client = createClient({
@ -70,6 +71,7 @@ export const InboxView = () => {
const [loading, setLoading] = createSignal<boolean>(false) const [loading, setLoading] = createSignal<boolean>(false)
const [sortByGroup, setSortByGroup] = createSignal<boolean>(false) const [sortByGroup, setSortByGroup] = createSignal<boolean>(false)
const [sortByPerToPer, setSortByPerToPer] = createSignal<boolean>(false) const [sortByPerToPer, setSortByPerToPer] = createSignal<boolean>(false)
const [selectedChat, setSelectedChat] = createSignal<Chat | undefined>(undefined)
const { session } = useSession() const { session } = useSession()
const currentSlug = createMemo(() => session()?.user?.slug) const currentSlug = createMemo(() => session()?.user?.slug)
@ -84,10 +86,11 @@ export const InboxView = () => {
} }
let chatWindow let chatWindow
const handleOpenChat = async (chatId) => { const handleOpenChat = async (chat) => {
setLoading(true) setLoading(true)
setSelectedChat(chat)
try { try {
await loadMessages({ chat: chatId }) await loadMessages({ chat: chat.id })
} catch (error) { } catch (error) {
setLoading(false) setLoading(false)
console.error('[loadMessages]', error) console.error('[loadMessages]', error)
@ -193,7 +196,7 @@ export const InboxView = () => {
<For each={chatsToShow()}> <For each={chatsToShow()}>
{(chat) => ( {(chat) => (
<DialogCard <DialogCard
onClick={() => handleOpenChat(chat.id)} onClick={() => handleOpenChat(chat)}
title={chat.title} title={chat.title}
members={chat.members} members={chat.members}
ownSlug={currentSlug()} ownSlug={currentSlug()}
@ -205,10 +208,9 @@ export const InboxView = () => {
</div> </div>
<div class="col-md-8 conversation"> <div class="col-md-8 conversation">
<div class="interlocutor user--online"> <Show when={selectedChat()}>
<AuthorCard author={{} as Author} hideFollow={true} /> <DialogHeader currentSlug={currentSlug()} chat={selectedChat()} />
<div class="user-status">Online</div> </Show>
</div>
<div class="conversation__messages"> <div class="conversation__messages">
<div class="conversation__messages-container" ref={chatWindow}> <div class="conversation__messages-container" ref={chatWindow}>

View File

@ -88,8 +88,7 @@ main {
} }
} }
.chat-list__search, .chat-list__search {
.interlocutor {
border-bottom: 3px solid #141414; border-bottom: 3px solid #141414;
padding: 1em 0; padding: 1em 0;
} }
@ -122,44 +121,6 @@ main {
} }
} }
.interlocutor {
height: 56px;
box-sizing: content-box;
.circlewrap {
height: 56px;
max-width: 56px;
width: 56px;
}
.author {
margin-bottom: 0;
&::before {
left: 40px !important;
height: 8px !important;
width: 8px !important;
}
}
.author__name {
@include font-size(1.7rem);
margin: 0.4em 0 0;
}
.author__details,
.user-status {
margin-left: 6.8rem;
}
.user-status {
@include font-size(1.2rem);
color: #ccc;
}
}
.conversation { .conversation {
display: flex; display: flex;
flex-direction: column; flex-direction: column;