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;
transition: background 0.3s ease-in-out;
cursor: pointer;
width: 100%;
&:hover {
background: #f7f7f7;
@ -24,6 +25,7 @@
.name,
.message {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
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 type { ChatMember } from '../../graphql/types.gen'
import GroupDialogAvatar from './GroupDialogAvatar'
import { Show } from 'solid-js'
import { clsx } from 'clsx'
import styles from './DialogCard.module.scss'
type DialogProps = {
online?: boolean
@ -11,37 +12,50 @@ type DialogProps = {
title?: string
ownSlug: string
members: ChatMember[]
onClick: () => void
onClick?: () => void
isChatHeader?: boolean
}
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 (
<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}>
{companions.length > 2 ? (
<GroupDialogAvatar users={companions} />
) : (
<DialogAvatar name={props.members[0].name} url={props.members[0].userpic} />
)}
<Switch fallback={<DialogAvatar name={props.members[0].name} url={props.members[0].userpic} />}>
<Match when={companions().length > 2}>
<GroupDialogAvatar users={companions()} />
</Match>
</Switch>
</div>
<div class={styles.row}>
{companions.length > 1 ? (
<div class={styles.name}>{props.title}</div>
) : (
<div class={styles.name}>{companions[0].name}</div>
)}
<Switch fallback={<div class={styles.name}>{companions()[0].name}</div>}>
<Match when={companions().length > 1}>
<div class={styles.name}>{props.title}</div>
</Match>
</Switch>
<div class={styles.message}>
Указать предпочтительные языки для результатов поиска можно в разделе
<Switch fallback={'Chat last message'}>
<Match when={props.isChatHeader && companions().length > 1}>{names}</Match>
</Switch>
</div>
</div>
<div class={styles.activity}>
<div class={styles.time}>22:22</div>
<div class={styles.counter}>
<span>12</span>
<Show when={!props.isChatHeader}>
<div class={styles.activity}>
<div class={styles.time}>22:22</div>
<div class={styles.counter}>
<span>12</span>
</div>
</div>
</div>
</Show>
</div>
</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 '../../styles/Inbox.scss'
import { useInbox } from '../../context/inbox'
import DialogHeader from '../Inbox/DialogHeader'
const OWNER_ID = '501'
const client = createClient({
@ -70,6 +71,7 @@ export const InboxView = () => {
const [loading, setLoading] = createSignal<boolean>(false)
const [sortByGroup, setSortByGroup] = createSignal<boolean>(false)
const [sortByPerToPer, setSortByPerToPer] = createSignal<boolean>(false)
const [selectedChat, setSelectedChat] = createSignal<Chat | undefined>(undefined)
const { session } = useSession()
const currentSlug = createMemo(() => session()?.user?.slug)
@ -84,10 +86,11 @@ export const InboxView = () => {
}
let chatWindow
const handleOpenChat = async (chatId) => {
const handleOpenChat = async (chat) => {
setLoading(true)
setSelectedChat(chat)
try {
await loadMessages({ chat: chatId })
await loadMessages({ chat: chat.id })
} catch (error) {
setLoading(false)
console.error('[loadMessages]', error)
@ -193,7 +196,7 @@ export const InboxView = () => {
<For each={chatsToShow()}>
{(chat) => (
<DialogCard
onClick={() => handleOpenChat(chat.id)}
onClick={() => handleOpenChat(chat)}
title={chat.title}
members={chat.members}
ownSlug={currentSlug()}
@ -205,10 +208,9 @@ export const InboxView = () => {
</div>
<div class="col-md-8 conversation">
<div class="interlocutor user--online">
<AuthorCard author={{} as Author} hideFollow={true} />
<div class="user-status">Online</div>
</div>
<Show when={selectedChat()}>
<DialogHeader currentSlug={currentSlug()} chat={selectedChat()} />
</Show>
<div class="conversation__messages">
<div class="conversation__messages-container" ref={chatWindow}>

View File

@ -88,8 +88,7 @@ main {
}
}
.chat-list__search,
.interlocutor {
.chat-list__search {
border-bottom: 3px solid #141414;
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 {
display: flex;
flex-direction: column;