From 21bf779f244742394b9bfc99b8d5fb380f3367ad Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Sun, 27 Nov 2022 14:45:36 +0300 Subject: [PATCH 01/60] Chat list [WiP] --- src/components/Inbox/DialogCard.tsx | 19 ++++++++++--------- src/components/Views/Inbox.tsx | 1 + 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index 5d19919e..e921ba45 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -1,6 +1,6 @@ import styles from './DialogCard.module.scss' import DialogAvatar from './DialogAvatar' -import type { Author, User } from '../../graphql/types.gen' +import type { Author, Chat, User } from '../../graphql/types.gen' import { apiClient } from '../../utils/apiClient' import { t } from '../../utils/intl' import { useInbox } from '../../context/inbox' @@ -9,21 +9,22 @@ type DialogProps = { online?: boolean message?: string counter?: number - users: User[] - ownSlug: User['slug'] + users: unknown[] + ownSlug: string } const DialogCard = (props: DialogProps) => { - // @ts-ignore - const participants = props.users.filter((user) => user !== props.ownSlug) - console.log('!!! participants:', participants) - // @ts-ignore + const companions = props.users.filter((user) => user !== props.ownSlug) + console.log('!!! companions:', companions) return ( - //DialogCardView - подумать
{/**/}
- {/*
{participants[0]}
*/} + {/*{companions.length > 1 && (*/} + {/*
*/} + {/* */} + {/*
*/} + {/*)}*/}
Указать предпочтительные языки для результатов поиска можно в разделе
diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index f339cc84..92b25463 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -112,6 +112,7 @@ export const InboxView = () => { try { const response = await loadChats() setChats(response as unknown as Chat[]) + console.log('!!! response:', response) } catch (error) { console.log(error) } From 737a77ae9a1cbac793cdb69c647059e2893f86bb Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Sun, 27 Nov 2022 21:08:11 +0300 Subject: [PATCH 02/60] [WiP] intermediate merge --- src/components/Inbox/DialogCard.tsx | 13 +++++-------- src/components/Views/Inbox.tsx | 4 ++-- src/graphql/query/chats-load.ts | 7 ++++++- src/graphql/types.gen.ts | 20 +++++++------------- src/styles/Inbox.scss | 1 - 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index e921ba45..63696d21 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -1,6 +1,6 @@ import styles from './DialogCard.module.scss' import DialogAvatar from './DialogAvatar' -import type { Author, Chat, User } from '../../graphql/types.gen' +import type { Author, Chat, ChatMember, User } from '../../graphql/types.gen' import { apiClient } from '../../utils/apiClient' import { t } from '../../utils/intl' import { useInbox } from '../../context/inbox' @@ -9,22 +9,19 @@ type DialogProps = { online?: boolean message?: string counter?: number - users: unknown[] + theme?: string ownSlug: string + members: ChatMember[] } const DialogCard = (props: DialogProps) => { - const companions = props.users.filter((user) => user !== props.ownSlug) + const companions = props.members.filter((member) => member.slug !== props.ownSlug) console.log('!!! companions:', companions) return (
{/**/}
- {/*{companions.length > 1 && (*/} - {/*
*/} - {/* */} - {/*
*/} - {/*)}*/} + {companions.length > 1 ?
Group
:
{companions[0].name}
}
Указать предпочтительные языки для результатов поиска можно в разделе
diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index 92b25463..62ab81dd 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -112,7 +112,7 @@ export const InboxView = () => { try { const response = await loadChats() setChats(response as unknown as Chat[]) - console.log('!!! response:', response) + console.log('!!! chats:', response) } catch (error) { console.log(error) } @@ -168,7 +168,7 @@ export const InboxView = () => {
- {(chat) => } + {(chat) => }
diff --git a/src/graphql/query/chats-load.ts b/src/graphql/query/chats-load.ts index c5b87093..2e2ac02a 100644 --- a/src/graphql/query/chats-load.ts +++ b/src/graphql/query/chats-load.ts @@ -6,8 +6,13 @@ export default gql` error chats { id + title admins - users + members { + slug + name + userpic + } unread description updatedAt diff --git a/src/graphql/types.gen.ts b/src/graphql/types.gen.ts index 142fb840..39afa866 100644 --- a/src/graphql/types.gen.ts +++ b/src/graphql/types.gen.ts @@ -54,17 +54,18 @@ export type AuthorsBy = { } export type Chat = { - admins?: Maybe>> + admins?: Maybe>> createdAt: Scalars['Int'] - createdBy: User + createdBy: Scalars['String'] description?: Maybe id: Scalars['String'] - messages: Array> + members?: Maybe>> + messages?: Maybe>> private?: Maybe title?: Maybe unread?: Maybe updatedAt: Scalars['Int'] - users: Array> + users?: Maybe>> } export type ChatInput = { @@ -75,8 +76,6 @@ export type ChatInput = { export type ChatMember = { id: Scalars['Int'] - invitedAt?: Maybe - invitedBy?: Maybe lastSeen?: Maybe name: Scalars['String'] slug: Scalars['String'] @@ -136,6 +135,7 @@ export type LoadShoutsOptions = { offset?: InputMaybe order_by?: InputMaybe order_by_desc?: InputMaybe + with_author_captions?: InputMaybe } export type Message = { @@ -178,7 +178,6 @@ export type Mutation = { follow: Result getSession: AuthResult inviteAuthor: Result - inviteChat: Result markAsRead: Result rateUser: Result registerUser: AuthResult @@ -214,7 +213,7 @@ export type MutationCreateReactionArgs = { } export type MutationCreateShoutArgs = { - inp: ShoutInput + input: ShoutInput } export type MutationCreateTopicArgs = { @@ -252,11 +251,6 @@ export type MutationInviteAuthorArgs = { shout: Scalars['String'] } -export type MutationInviteChatArgs = { - chatId: Scalars['String'] - userslug: Scalars['String'] -} - export type MutationMarkAsReadArgs = { chatId: Scalars['String'] ids: Array> diff --git a/src/styles/Inbox.scss b/src/styles/Inbox.scss index ea766bbe..1b6f0a0c 100644 --- a/src/styles/Inbox.scss +++ b/src/styles/Inbox.scss @@ -17,7 +17,6 @@ main { flex: 1; flex-direction: column; position: fixed; - z-index: 900; .row { flex: 1; From afef6d3639c0aae996479f6b509f3eee07581cc0 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Mon, 28 Nov 2022 07:10:13 +0300 Subject: [PATCH 03/60] [WiP] messages render --- src/components/Inbox/CreateModalContent.tsx | 3 +-- src/components/Inbox/DialogCard.tsx | 13 ++++++++++--- src/components/Views/Inbox.tsx | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/components/Inbox/CreateModalContent.tsx b/src/components/Inbox/CreateModalContent.tsx index c1f927c8..c34b6158 100644 --- a/src/components/Inbox/CreateModalContent.tsx +++ b/src/components/Inbox/CreateModalContent.tsx @@ -59,12 +59,11 @@ const CreateModalContent = (props: Props) => { const { chatEntities, actions } = useInbox() - console.log('!!! chatEntities:', chatEntities) - const handleCreate = async () => { try { const initChat = await actions.createChat(slugs(), theme()) console.debug('[initChat]', initChat) + hideModal() } catch (error) { console.error(error) } diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index 63696d21..3988966f 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -9,7 +9,7 @@ type DialogProps = { online?: boolean message?: string counter?: number - theme?: string + title?: string ownSlug: string members: ChatMember[] } @@ -19,9 +19,16 @@ const DialogCard = (props: DialogProps) => { console.log('!!! companions:', companions) return (
-
{/**/}
+
+ +
+
- {companions.length > 1 ?
Group
:
{companions[0].name}
} + {companions.length > 1 ? ( +
{props.title}
+ ) : ( +
{companions[0].name}
+ )}
Указать предпочтительные языки для результатов поиска можно в разделе
diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index 62ab81dd..df975df0 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -168,7 +168,7 @@ export const InboxView = () => {
- {(chat) => } + {(chat) => }
From 9de323b752191593448ad1cf04edcb6f6a462e43 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Tue, 29 Nov 2022 08:36:32 +0300 Subject: [PATCH 04/60] Grouped avatar --- src/components/Inbox/DialogAvatar.module.scss | 4 ++ src/components/Inbox/DialogAvatar.tsx | 5 +- src/components/Inbox/DialogCard.tsx | 8 +++- .../Inbox/GroupDialogAvatar.module.scss | 46 +++++++++++++++++++ src/components/Inbox/GroupDialogAvatar.tsx | 38 +++++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/components/Inbox/GroupDialogAvatar.module.scss create mode 100644 src/components/Inbox/GroupDialogAvatar.tsx diff --git a/src/components/Inbox/DialogAvatar.module.scss b/src/components/Inbox/DialogAvatar.module.scss index 626aa88a..e9bfbb58 100644 --- a/src/components/Inbox/DialogAvatar.module.scss +++ b/src/components/Inbox/DialogAvatar.module.scss @@ -47,4 +47,8 @@ font-size: 14px; } } + + &.bordered { + border: 2px solid #fff; + } } diff --git a/src/components/Inbox/DialogAvatar.tsx b/src/components/Inbox/DialogAvatar.tsx index fd0ebdc0..88217b90 100644 --- a/src/components/Inbox/DialogAvatar.tsx +++ b/src/components/Inbox/DialogAvatar.tsx @@ -8,6 +8,8 @@ type Props = { url?: string online?: boolean size?: 'small' + bordered?: boolean + className: string } const colors = [ @@ -36,8 +38,9 @@ const DialogAvatar = (props: Props) => { return (
{ const companions = props.members.filter((member) => member.slug !== props.ownSlug) - console.log('!!! companions:', companions) return (
- + {companions.length > 1 ? ( + + ) : ( + + )}
diff --git a/src/components/Inbox/GroupDialogAvatar.module.scss b/src/components/Inbox/GroupDialogAvatar.module.scss new file mode 100644 index 00000000..e053442d --- /dev/null +++ b/src/components/Inbox/GroupDialogAvatar.module.scss @@ -0,0 +1,46 @@ +.GroupDialogAvatar { + position: relative; + height: 40px; + width: 40px; + .grouped { + position: absolute; + + &:nth-child(1) { + top: 0; + left: 50%; + transform: translateX(-50%); + } + + &:nth-child(2) { + bottom: 0; + left: 0; + } + + &:nth-child(3) { + bottom: 0; + right: 0; + } + } + + .counter { + width: 23px; + height: 23px; + position: absolute; + bottom: 0; + right: 0; + text-align: center; + line-height: 21px; + background: #fff; + border: 2px solid #fff; + box-shadow: inset 0 0 0 2px #000; + border-radius: 50%; + box-sizing: border-box; + font-size: 12px; + font-weight: 600; + + &.hundred { + font-size: 7px; + line-height: 20px; + } + } +} diff --git a/src/components/Inbox/GroupDialogAvatar.tsx b/src/components/Inbox/GroupDialogAvatar.tsx new file mode 100644 index 00000000..ec81df57 --- /dev/null +++ b/src/components/Inbox/GroupDialogAvatar.tsx @@ -0,0 +1,38 @@ +import './DialogCard.module.scss' +import styles from './GroupDialogAvatar.module.scss' +import { clsx } from 'clsx' +import type { ChatMember } from '../../graphql/types.gen' +import DialogAvatar from './DialogAvatar' + +type Props = { + users: ChatMember[] +} + +const GroupDialogAvatar = (props: Props) => { + const slicedUsers = () => { + if (props.users.length > 3) { + return props.users.slice(0, 2) + } + return props.users.slice(0, 3) + } + return ( +
+ {slicedUsers().map((user) => ( + + ))} + {props.users.length > 3 && ( +
= 100 })}> + {++props.users.length} +
+ )} +
+ ) +} + +export default GroupDialogAvatar From a6a0b804b755c658a9fdb180652845d0f04004e7 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Tue, 29 Nov 2022 09:04:23 +0300 Subject: [PATCH 05/60] Linter fix --- .../Inbox/GroupDialogAvatar.module.scss | 4 ++-- src/components/Inbox/GroupDialogAvatar.tsx | 21 +++++++++++-------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/components/Inbox/GroupDialogAvatar.module.scss b/src/components/Inbox/GroupDialogAvatar.module.scss index e053442d..feb5ea84 100644 --- a/src/components/Inbox/GroupDialogAvatar.module.scss +++ b/src/components/Inbox/GroupDialogAvatar.module.scss @@ -23,8 +23,8 @@ } .counter { - width: 23px; - height: 23px; + width: 24px; + height: 24px; position: absolute; bottom: 0; right: 0; diff --git a/src/components/Inbox/GroupDialogAvatar.tsx b/src/components/Inbox/GroupDialogAvatar.tsx index ec81df57..f68a4b17 100644 --- a/src/components/Inbox/GroupDialogAvatar.tsx +++ b/src/components/Inbox/GroupDialogAvatar.tsx @@ -1,3 +1,4 @@ +import { For } from 'solid-js' import './DialogCard.module.scss' import styles from './GroupDialogAvatar.module.scss' import { clsx } from 'clsx' @@ -17,15 +18,17 @@ const GroupDialogAvatar = (props: Props) => { } return (
- {slicedUsers().map((user) => ( - - ))} + + {(user) => ( + + )} + {props.users.length > 3 && (
= 100 })}> {++props.users.length} From a31940485177f99792b595393e8ec535c7fb7d41 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Tue, 29 Nov 2022 10:04:38 +0300 Subject: [PATCH 06/60] Chat list filters --- src/components/Inbox/CreateModalContent.tsx | 6 --- src/components/Inbox/DialogAvatar.tsx | 2 +- src/components/Inbox/DialogCard.tsx | 8 +--- src/components/Views/Inbox.tsx | 48 +++++++++++++++++---- src/styles/Inbox.scss | 14 +++--- 5 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/components/Inbox/CreateModalContent.tsx b/src/components/Inbox/CreateModalContent.tsx index c34b6158..d9a04d0a 100644 --- a/src/components/Inbox/CreateModalContent.tsx +++ b/src/components/Inbox/CreateModalContent.tsx @@ -7,12 +7,6 @@ import { hideModal } from '../../stores/ui' import { useInbox } from '../../context/inbox' type inviteUser = Author & { selected: boolean } -type query = - | { - theme: string - members: string[] - } - | undefined type Props = { users: Author[] } diff --git a/src/components/Inbox/DialogAvatar.tsx b/src/components/Inbox/DialogAvatar.tsx index 88217b90..38368ce1 100644 --- a/src/components/Inbox/DialogAvatar.tsx +++ b/src/components/Inbox/DialogAvatar.tsx @@ -9,7 +9,7 @@ type Props = { online?: boolean size?: 'small' bordered?: boolean - className: string + className?: string } const colors = [ diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index c36ac98b..ef9ae13c 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -1,9 +1,6 @@ import styles from './DialogCard.module.scss' import DialogAvatar from './DialogAvatar' -import type { Author, Chat, ChatMember, User } from '../../graphql/types.gen' -import { apiClient } from '../../utils/apiClient' -import { t } from '../../utils/intl' -import { useInbox } from '../../context/inbox' +import type { ChatMember } from '../../graphql/types.gen' import GroupDialogAvatar from './GroupDialogAvatar' type DialogProps = { @@ -20,13 +17,12 @@ const DialogCard = (props: DialogProps) => { return (
- {companions.length > 1 ? ( + {companions.length > 2 ? ( ) : ( )}
-
{companions.length > 1 ? (
{props.title}
diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index df975df0..2108c579 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -10,12 +10,11 @@ import { createClient } from '@urql/core' import Message from '../Inbox/Message' import { loadRecipients, loadChats } from '../../stores/inbox' import { t } from '../../utils/intl' -import '../../styles/Inbox.scss' -import { useInbox } from '../../context/inbox' import { Modal } from '../Nav/Modal' import { showModal } from '../../stores/ui' -import InviteUser from '../Inbox/InviteUser' import CreateModalContent from '../Inbox/CreateModalContent' +import { clsx } from 'clsx' +import '../../styles/Inbox.scss' const OWNER_ID = '501' const client = createClient({ @@ -65,6 +64,8 @@ export const InboxView = () => { const [cashedRecipients, setCashedRecipients] = createSignal([]) const [postMessageText, setPostMessageText] = createSignal('') const [loading, setLoading] = createSignal(false) + const [sortByGroup, setSortByGroup] = createSignal(false) + const [sortByPerToPer, setSortByPerToPer] = createSignal(false) const { session } = useSession() const currentSlug = createMemo(() => session()?.user?.slug) @@ -112,7 +113,6 @@ export const InboxView = () => { try { const response = await loadChats() setChats(response as unknown as Chat[]) - console.log('!!! chats:', response) } catch (error) { console.log(error) } @@ -158,16 +158,46 @@ export const InboxView = () => {
    -
  • - {t('All')} +
  • { + setSortByPerToPer(false) + setSortByGroup(false) + }} + > + {t('All')} +
  • +
  • { + setSortByPerToPer(true) + setSortByGroup(false) + }} + > + {t('Personal')} +
  • +
  • { + setSortByGroup(true) + setSortByPerToPer(false) + }} + > + {t('Groups')}
  • -
  • {t('Personal')}
  • -
  • {t('Groups')}
- + chat.title.length === 0) + : sortByGroup() + ? chats().filter((chat) => chat.title.length > 0) + : chats() + } + > {(chat) => }
diff --git a/src/styles/Inbox.scss b/src/styles/Inbox.scss index 1b6f0a0c..812a9dae 100644 --- a/src/styles/Inbox.scss +++ b/src/styles/Inbox.scss @@ -111,12 +111,14 @@ main { li { margin-right: 1em; color: #696969; - } - - strong { - border-bottom: 3px solid; - font-weight: normal; - color: #000; + cursor: pointer; + &.selected { + span { + border-bottom: 3px solid; + font-weight: normal; + color: #000; + } + } } } From 4e889a2c67022080e67c4a78f59d4748909f0ecc Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Wed, 30 Nov 2022 18:25:02 +0300 Subject: [PATCH 07/60] Chats in store --- src/components/Inbox/CreateModalContent.tsx | 12 +++--- src/components/Inbox/DialogCard.tsx | 4 +- src/components/Views/Inbox.tsx | 45 ++++++++++----------- src/context/inbox.tsx | 32 ++++++++++----- src/graphql/query/chat-messages-load-by.ts | 2 +- src/stores/inbox.ts | 5 ++- src/utils/apiClient.ts | 9 +++-- 7 files changed, 65 insertions(+), 44 deletions(-) diff --git a/src/components/Inbox/CreateModalContent.tsx b/src/components/Inbox/CreateModalContent.tsx index d9a04d0a..6f8146fe 100644 --- a/src/components/Inbox/CreateModalContent.tsx +++ b/src/components/Inbox/CreateModalContent.tsx @@ -13,7 +13,7 @@ type Props = { const CreateModalContent = (props: Props) => { const inviteUsers: inviteUser[] = props.users.map((user) => ({ ...user, selected: false })) - const [theme, setTheme] = createSignal('') + const [theme, setTheme] = createSignal(' ') const [slugs, setSlugs] = createSignal([]) const [collectionToInvite, setCollectionToInvite] = createSignal(inviteUsers) let textInput: HTMLInputElement @@ -34,7 +34,8 @@ const CreateModalContent = (props: Props) => { return user['slug'] }) }) - if (slugs().length > 2 && theme().length === 0) { + + if (slugs().length > 1 && theme().length === 1) { setTheme(t('group_chat')) } }) @@ -51,13 +52,14 @@ const CreateModalContent = (props: Props) => { }) } - const { chatEntities, actions } = useInbox() + const { actions } = useInbox() const handleCreate = async () => { try { const initChat = await actions.createChat(slugs(), theme()) console.debug('[initChat]', initChat) hideModal() + await actions.loadChats() } catch (error) { console.error(error) } @@ -66,7 +68,7 @@ const CreateModalContent = (props: Props) => { return (

{t('create_chat')}

- {slugs().length > 2 && ( + {slugs().length > 1 && ( { onClick={handleCreate} disabled={slugs().length === 0} > - {slugs().length > 2 ? t('create_group') : t('create_chat')} + {slugs().length > 1 ? t('create_group') : t('create_chat')}
diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index ef9ae13c..557dcb0b 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -10,12 +10,14 @@ type DialogProps = { title?: string ownSlug: string members: ChatMember[] + onClick: () => void } const DialogCard = (props: DialogProps) => { + if (!props.members) return const companions = props.members.filter((member) => member.slug !== props.ownSlug) return ( -
+
{companions.length > 2 ? ( diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index 2108c579..93fb5cd6 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -8,13 +8,14 @@ import Search from '../Inbox/Search' import { useSession } from '../../context/session' import { createClient } from '@urql/core' import Message from '../Inbox/Message' -import { loadRecipients, loadChats } from '../../stores/inbox' +import { loadRecipients, loadMessages } from '../../stores/inbox' import { t } from '../../utils/intl' import { Modal } from '../Nav/Modal' import { showModal } from '../../stores/ui' import CreateModalContent from '../Inbox/CreateModalContent' import { clsx } from 'clsx' import '../../styles/Inbox.scss' +import { useInbox } from '../../context/inbox' const OWNER_ID = '501' const client = createClient({ @@ -58,9 +59,12 @@ const postMessage = async (msg: string) => { } export const InboxView = () => { + const { + chats, + actions: { loadChats } + } = useInbox() const [messages, setMessages] = createSignal([]) const [recipients, setRecipients] = createSignal([]) - const [chats, setChats] = createSignal([]) const [cashedRecipients, setCashedRecipients] = createSignal([]) const [postMessageText, setPostMessageText] = createSignal('') const [loading, setLoading] = createSignal(false) @@ -79,29 +83,21 @@ export const InboxView = () => { } } - const fetchMessages = async (query) => { - const response = await client - .query(query, { - options: { slice: { start: 0, end: 3 } } - }) - .toPromise() - if (response.error) console.debug('getMessages', response.error) - setMessages(response.data.comments.data) - } - let chatWindow - onMount(async () => { + const handleOpenChat = async (chatId) => { setLoading(true) try { - await fetchMessages(messageQuery) + await loadMessages({ chat: chatId }) } catch (error) { setLoading(false) - console.error([fetchMessages], error) + console.error('[loadMessages]', error) } finally { setLoading(false) chatWindow.scrollTop = chatWindow.scrollHeight } - + } + onMount(async () => { + setLoading(true) try { const response = await loadRecipients({ days: 365 }) setRecipients(response as unknown as Author[]) @@ -110,12 +106,8 @@ export const InboxView = () => { console.log(error) } - try { - const response = await loadChats() - setChats(response as unknown as Chat[]) - } catch (error) { - console.log(error) - } + await loadChats() + console.log('!!! chats:', chats()) }) const handleSubmit = async () => { @@ -198,7 +190,14 @@ export const InboxView = () => { : chats() } > - {(chat) => } + {(chat) => ( + handleOpenChat(chat.id)} + title={chat.title} + members={chat.members} + ownSlug={currentSlug()} + /> + )}
diff --git a/src/context/inbox.tsx b/src/context/inbox.tsx index e3b41d44..e9969c6f 100644 --- a/src/context/inbox.tsx +++ b/src/context/inbox.tsx @@ -1,13 +1,14 @@ -import type { JSX } from 'solid-js' -import { createContext, useContext } from 'solid-js' -import type { Message } from '../graphql/types.gen' +import type { Accessor, JSX } from 'solid-js' +import { createContext, createSignal, useContext } from 'solid-js' +import type { Chat } from '../graphql/types.gen' import { apiClient } from '../utils/apiClient' import { createStore } from 'solid-js/store' type InboxContextType = { - chatEntities: { [chatId: string]: Message[] } + chats: Accessor actions: { createChat: (members: string[], title: string) => Promise + loadChats: () => Promise } } @@ -18,20 +19,33 @@ export function useInbox() { } export const InboxProvider = (props: { children: JSX.Element }) => { - const [chatEntities, setChatEntities] = createStore({}) + const [chats, setChats] = createSignal([]) + const loadChats = async () => { + try { + const chats = await apiClient.getChats({ limit: 50, offset: 0 }) + setChats( + chats.sort((x, y) => { + return x.updatedAt < y.updatedAt ? 1 : -1 + }) + ) + } catch (error) { + console.log(error) + } + } const createChat = async (members: string[], title: string) => { const chat = await apiClient.createChat({ members, title }) - setChatEntities((s) => { - s[chat.id] = chat + setChats((prevChats) => { + return [chat, ...prevChats] }) return chat } const actions = { - createChat + createChat, + loadChats } - const value: InboxContextType = { chatEntities, actions } + const value: InboxContextType = { chats, actions } return {props.children} } diff --git a/src/graphql/query/chat-messages-load-by.ts b/src/graphql/query/chat-messages-load-by.ts index 48796e30..cfba1e55 100644 --- a/src/graphql/query/chat-messages-load-by.ts +++ b/src/graphql/query/chat-messages-load-by.ts @@ -8,8 +8,8 @@ export default gql` author body createdAt + id updatedAt - seen } } } diff --git a/src/stores/inbox.ts b/src/stores/inbox.ts index 9cc59067..08c764a7 100644 --- a/src/stores/inbox.ts +++ b/src/stores/inbox.ts @@ -1,9 +1,10 @@ import { apiClient } from '../utils/apiClient' +import type { MessagesBy } from '../graphql/types.gen' export const loadRecipients = async (by = {}): Promise => { return await apiClient.getRecipients(by) } -export const loadChats = async (): Promise => { - return await apiClient.getChats({ limit: 50, offset: 0 }) +export const loadMessages = async (by: MessagesBy): Promise => { + return await apiClient.getChatMessages({ by, limit: 50, offset: 0 }) } diff --git a/src/utils/apiClient.ts b/src/utils/apiClient.ts index 243a44f3..eee44d50 100644 --- a/src/utils/apiClient.ts +++ b/src/utils/apiClient.ts @@ -10,7 +10,8 @@ import type { QueryLoadMessagesByArgs, MutationCreateChatArgs, MutationCreateMessageArgs, - QueryLoadRecipientsArgs + QueryLoadRecipientsArgs, + Chat } from '../graphql/types.gen' import { publicGraphQLClient } from '../graphql/publicGraphQLClient' import { getToken, privateGraphQLClient } from '../graphql/privateGraphQLClient' @@ -270,7 +271,7 @@ export const apiClient = { }, // inbox - getChats: async (options: QueryLoadChatsArgs) => { + getChats: async (options: QueryLoadChatsArgs): Promise => { const resp = await privateGraphQLClient.query(myChats, options).toPromise() return resp.data.loadChats.chats }, @@ -287,8 +288,10 @@ export const apiClient = { getChatMessages: async (options: QueryLoadMessagesByArgs) => { const resp = await privateGraphQLClient.query(chatMessagesLoadBy, options).toPromise() - return resp.data.loadChat + console.log('!!! resp:', resp) + // return resp.data.loadChat }, + getRecipients: async (options: QueryLoadRecipientsArgs) => { const resp = await privateGraphQLClient.query(loadRecipients, options).toPromise() return resp.data.loadRecipients.members From 15ad8bf8dd16e1db6eb6a33ebbefc0be140d1062 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Thu, 1 Dec 2022 06:26:44 +0300 Subject: [PATCH 08/60] Linter fixies --- src/components/Inbox/DialogCard.tsx | 52 +++++++++++++++-------------- src/components/Views/Inbox.tsx | 21 ++++++------ src/context/inbox.tsx | 4 +-- 3 files changed, 40 insertions(+), 37 deletions(-) diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index 557dcb0b..45483cf5 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -2,6 +2,7 @@ import styles from './DialogCard.module.scss' import DialogAvatar from './DialogAvatar' import type { ChatMember } from '../../graphql/types.gen' import GroupDialogAvatar from './GroupDialogAvatar' +import { Show } from 'solid-js' type DialogProps = { online?: boolean @@ -14,34 +15,35 @@ type DialogProps = { } const DialogCard = (props: DialogProps) => { - if (!props.members) return - const companions = props.members.filter((member) => member.slug !== props.ownSlug) + const companions = props.members && props.members.filter((member) => member.slug !== props.ownSlug) return ( -
-
- {companions.length > 2 ? ( - - ) : ( - - )} -
-
- {companions.length > 1 ? ( -
{props.title}
- ) : ( -
{companions[0].name}
- )} -
- Указать предпочтительные языки для результатов поиска можно в разделе + +
+
+ {companions.length > 2 ? ( + + ) : ( + + )} +
+
+ {companions.length > 1 ? ( +
{props.title}
+ ) : ( +
{companions[0].name}
+ )} +
+ Указать предпочтительные языки для результатов поиска можно в разделе +
+
+
+
22:22
+
+ 12 +
-
-
22:22
-
- 12 -
-
-
+ ) } diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index 93fb5cd6..497604c5 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -105,7 +105,6 @@ export const InboxView = () => { } catch (error) { console.log(error) } - await loadChats() console.log('!!! chats:', chats()) }) @@ -134,6 +133,16 @@ export const InboxView = () => { showModal('inviteToChat') } + const chatsToShow = () => { + if (sortByPerToPer()) { + return chats().filter((chat) => chat.title.trim().length === 0) + } else if (sortByGroup()) { + return chats().filter((chat) => chat.title.trim().length > 0) + } else { + return chats() + } + } + return (
@@ -181,15 +190,7 @@ export const InboxView = () => {
- chat.title.length === 0) - : sortByGroup() - ? chats().filter((chat) => chat.title.length > 0) - : chats() - } - > + {(chat) => ( handleOpenChat(chat.id)} diff --git a/src/context/inbox.tsx b/src/context/inbox.tsx index e9969c6f..f502e24d 100644 --- a/src/context/inbox.tsx +++ b/src/context/inbox.tsx @@ -22,9 +22,9 @@ export const InboxProvider = (props: { children: JSX.Element }) => { const [chats, setChats] = createSignal([]) const loadChats = async () => { try { - const chats = await apiClient.getChats({ limit: 50, offset: 0 }) + const newChats = await apiClient.getChats({ limit: 50, offset: 0 }) setChats( - chats.sort((x, y) => { + newChats.sort((x, y) => { return x.updatedAt < y.updatedAt ? 1 : -1 }) ) From f98c849ed9728e9d14f68aa15f10d10a33e728f4 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Thu, 1 Dec 2022 09:00:51 +0300 Subject: [PATCH 09/60] Chat Header --- src/components/Inbox/DialogCard.module.scss | 2 + src/components/Inbox/DialogCard.tsx | 56 ++++++++++++------- src/components/Inbox/DialogHeader.module.scss | 9 +++ src/components/Inbox/DialogHeader.tsx | 23 ++++++++ src/components/Views/Inbox.tsx | 16 +++--- src/styles/Inbox.scss | 41 +------------- 6 files changed, 79 insertions(+), 68 deletions(-) create mode 100644 src/components/Inbox/DialogHeader.module.scss create mode 100644 src/components/Inbox/DialogHeader.tsx diff --git a/src/components/Inbox/DialogCard.module.scss b/src/components/Inbox/DialogCard.module.scss index a3b62656..0bd82c0f 100644 --- a/src/components/Inbox/DialogCard.module.scss +++ b/src/components/Inbox/DialogCard.module.scss @@ -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; diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index 45483cf5..a35d5196 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -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 ( -
+
- {companions.length > 2 ? ( - - ) : ( - - )} + }> + 2}> + + +
- {companions.length > 1 ? ( -
{props.title}
- ) : ( -
{companions[0].name}
- )} + {companions()[0].name}
}> + 1}> +
{props.title}
+
+
- Указать предпочтительные языки для результатов поиска можно в разделе + + 1}>{names} +
-
-
22:22
-
- 12 + +
+
22:22
+
+ 12 +
-
+
) diff --git a/src/components/Inbox/DialogHeader.module.scss b/src/components/Inbox/DialogHeader.module.scss new file mode 100644 index 00000000..346311ed --- /dev/null +++ b/src/components/Inbox/DialogHeader.module.scss @@ -0,0 +1,9 @@ +.DialogHeader { + display: flex; + align-items: center; + border-bottom: 3px solid #141414; + + .avatar { + width: 40px; + } +} diff --git a/src/components/Inbox/DialogHeader.tsx b/src/components/Inbox/DialogHeader.tsx new file mode 100644 index 00000000..7d98d259 --- /dev/null +++ b/src/components/Inbox/DialogHeader.tsx @@ -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 ( +
+ +
+ ) +} + +export default DialogHeader diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index 497604c5..09c48f1a 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -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(false) const [sortByGroup, setSortByGroup] = createSignal(false) const [sortByPerToPer, setSortByPerToPer] = createSignal(false) + const [selectedChat, setSelectedChat] = createSignal(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 = () => { {(chat) => ( handleOpenChat(chat.id)} + onClick={() => handleOpenChat(chat)} title={chat.title} members={chat.members} ownSlug={currentSlug()} @@ -205,10 +208,9 @@ export const InboxView = () => {
-
- -
Online
-
+ + +
diff --git a/src/styles/Inbox.scss b/src/styles/Inbox.scss index 812a9dae..cda39ebb 100644 --- a/src/styles/Inbox.scss +++ b/src/styles/Inbox.scss @@ -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; From bbabb69555d0e20d0d194e982697efbe9662632d Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Thu, 1 Dec 2022 09:09:29 +0300 Subject: [PATCH 10/60] Fix linter --- src/components/Inbox/DialogCard.tsx | 1 - src/components/Views/Inbox.tsx | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index a35d5196..2a94cd45 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -25,7 +25,6 @@ const DialogCard = (props: DialogProps) => { .map((companion) => companion.name) .join(', ') ) - console.log('!!! names:', names()) return (
diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index 09c48f1a..b39e7255 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -71,7 +71,7 @@ export const InboxView = () => { const [loading, setLoading] = createSignal(false) const [sortByGroup, setSortByGroup] = createSignal(false) const [sortByPerToPer, setSortByPerToPer] = createSignal(false) - const [selectedChat, setSelectedChat] = createSignal(undefined) + const [selectedChat, setSelectedChat] = createSignal() const { session } = useSession() const currentSlug = createMemo(() => session()?.user?.slug) From c124cfc97154c44c9726c65063b730871a12c1be Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Sat, 3 Dec 2022 17:34:15 +0300 Subject: [PATCH 11/60] Refactoring after backend update --- codegen.yml | 3 +- src/components/Inbox/CreateModalContent.tsx | 21 +++++---- src/components/Inbox/DialogCard.tsx | 15 +++---- src/components/Inbox/DialogHeader.tsx | 4 +- src/components/Views/Inbox.tsx | 23 +++++----- src/context/inbox.tsx | 5 +-- src/graphql/mutation/create-chat.ts | 2 +- src/graphql/query/chat-recipients.ts | 1 + src/graphql/query/chats-load.ts | 1 + src/graphql/types.gen.ts | 47 ++++++++++++--------- src/utils/apiClient.ts | 2 +- 11 files changed, 68 insertions(+), 56 deletions(-) diff --git a/codegen.yml b/codegen.yml index 44d1e541..da015e44 100644 --- a/codegen.yml +++ b/codegen.yml @@ -1,5 +1,6 @@ overwrite: true -schema: 'http://localhost:8080' +#schema: 'http://localhost:8080' +schema: 'https://v2.discours.io' generates: src/graphql/introspec.gen.ts: plugins: diff --git a/src/components/Inbox/CreateModalContent.tsx b/src/components/Inbox/CreateModalContent.tsx index 6f8146fe..3e0b3054 100644 --- a/src/components/Inbox/CreateModalContent.tsx +++ b/src/components/Inbox/CreateModalContent.tsx @@ -14,28 +14,27 @@ type Props = { const CreateModalContent = (props: Props) => { const inviteUsers: inviteUser[] = props.users.map((user) => ({ ...user, selected: false })) const [theme, setTheme] = createSignal(' ') - const [slugs, setSlugs] = createSignal([]) + const [usersId, setUsersId] = createSignal([]) const [collectionToInvite, setCollectionToInvite] = createSignal(inviteUsers) let textInput: HTMLInputElement const reset = () => { setTheme('') - setSlugs([]) + setUsersId([]) hideModal() } createEffect(() => { - setSlugs(() => { + setUsersId(() => { return collectionToInvite() .filter((user) => { return user.selected === true }) .map((user) => { - return user['slug'] + return user['id'] }) }) - - if (slugs().length > 1 && theme().length === 1) { + if (usersId().length > 1 && theme().length === 1) { setTheme(t('group_chat')) } }) @@ -47,7 +46,7 @@ const CreateModalContent = (props: Props) => { const handleClick = (user) => { setCollectionToInvite((userCollection) => { return userCollection.map((clickedUser) => - user.slug === clickedUser.slug ? { ...clickedUser, selected: !clickedUser.selected } : clickedUser + user.id === clickedUser.id ? { ...clickedUser, selected: !clickedUser.selected } : clickedUser ) }) } @@ -56,7 +55,7 @@ const CreateModalContent = (props: Props) => { const handleCreate = async () => { try { - const initChat = await actions.createChat(slugs(), theme()) + const initChat = await actions.createChat(usersId(), theme()) console.debug('[initChat]', initChat) hideModal() await actions.loadChats() @@ -68,7 +67,7 @@ const CreateModalContent = (props: Props) => { return (

{t('create_chat')}

- {slugs().length > 1 && ( + {usersId().length > 1 && ( { type="button" class="btn btn-lg fs-3 btn-outline-primary" onClick={handleCreate} - disabled={slugs().length === 0} + disabled={usersId().length === 0} > - {slugs().length > 1 ? t('create_group') : t('create_chat')} + {usersId().length > 1 ? t('create_group') : t('create_chat')}
diff --git a/src/components/Inbox/DialogCard.tsx b/src/components/Inbox/DialogCard.tsx index 2a94cd45..41394545 100644 --- a/src/components/Inbox/DialogCard.tsx +++ b/src/components/Inbox/DialogCard.tsx @@ -10,7 +10,7 @@ type DialogProps = { message?: string counter?: number title?: string - ownSlug: string + ownId: number members: ChatMember[] onClick?: () => void isChatHeader?: boolean @@ -18,13 +18,12 @@ type DialogProps = { const DialogCard = (props: DialogProps) => { const companions = createMemo( - () => props.members && props.members.filter((member) => member.slug !== props.ownSlug) - ) - const names = createMemo(() => - companions() - .map((companion) => companion.name) - .join(', ') + () => props.members && props.members.filter((member) => member.id !== props.ownId) ) + const names = companions() + ?.map((companion) => companion.name) + .join(', ') + return (
@@ -37,7 +36,7 @@ const DialogCard = (props: DialogProps) => {
{companions()[0].name}
}> - 1}> + 2}>
{props.title}
diff --git a/src/components/Inbox/DialogHeader.tsx b/src/components/Inbox/DialogHeader.tsx index 7d98d259..7c2ecf17 100644 --- a/src/components/Inbox/DialogHeader.tsx +++ b/src/components/Inbox/DialogHeader.tsx @@ -4,7 +4,7 @@ import DialogCard from './DialogCard' type DialogHeader = { chat: Chat - currentSlug: string + ownId: number } const DialogHeader = (props: DialogHeader) => { @@ -14,7 +14,7 @@ const DialogHeader = (props: DialogHeader) => { isChatHeader={true} title={props.chat.title} members={props.chat.members} - ownSlug={props.currentSlug} + ownId={props.ownId} /> ) diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index b39e7255..b8985a7e 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -73,16 +73,16 @@ export const InboxView = () => { const [sortByPerToPer, setSortByPerToPer] = createSignal(false) const [selectedChat, setSelectedChat] = createSignal() const { session } = useSession() - const currentSlug = createMemo(() => session()?.user?.slug) + const currentUserId = createMemo(() => session()?.user?.id) // Поиск по диалогам const getQuery = (query) => { - if (query().length >= 2) { - const match = userSearch(recipients(), query()) - setRecipients(match) - } else { - setRecipients(cashedRecipients()) - } + // if (query().length >= 2) { + // const match = userSearch(recipients(), query()) + // setRecipients(match) + // } else { + // setRecipients(cashedRecipients()) + // } } let chatWindow @@ -109,7 +109,6 @@ export const InboxView = () => { console.log(error) } await loadChats() - console.log('!!! chats:', chats()) }) const handleSubmit = async () => { @@ -136,6 +135,10 @@ export const InboxView = () => { showModal('inviteToChat') } + createEffect(() => { + console.log('!!! chats():', chats()) + }) + const chatsToShow = () => { if (sortByPerToPer()) { return chats().filter((chat) => chat.title.trim().length === 0) @@ -199,7 +202,7 @@ export const InboxView = () => { onClick={() => handleOpenChat(chat)} title={chat.title} members={chat.members} - ownSlug={currentSlug()} + ownId={currentUserId()} /> )} @@ -209,7 +212,7 @@ export const InboxView = () => {
- +
diff --git a/src/context/inbox.tsx b/src/context/inbox.tsx index f502e24d..d9c445bb 100644 --- a/src/context/inbox.tsx +++ b/src/context/inbox.tsx @@ -2,12 +2,11 @@ import type { Accessor, JSX } from 'solid-js' import { createContext, createSignal, useContext } from 'solid-js' import type { Chat } from '../graphql/types.gen' import { apiClient } from '../utils/apiClient' -import { createStore } from 'solid-js/store' type InboxContextType = { chats: Accessor actions: { - createChat: (members: string[], title: string) => Promise + createChat: (members: number[], title: string) => Promise loadChats: () => Promise } } @@ -33,7 +32,7 @@ export const InboxProvider = (props: { children: JSX.Element }) => { } } - const createChat = async (members: string[], title: string) => { + const createChat = async (members: number[], title: string) => { const chat = await apiClient.createChat({ members, title }) setChats((prevChats) => { return [chat, ...prevChats] diff --git a/src/graphql/mutation/create-chat.ts b/src/graphql/mutation/create-chat.ts index b700707b..46993794 100644 --- a/src/graphql/mutation/create-chat.ts +++ b/src/graphql/mutation/create-chat.ts @@ -1,7 +1,7 @@ import { gql } from '@urql/core' export default gql` - mutation CreateChat($title: String, $members: [String]!) { + mutation CreateChat($title: String, $members: [Int]!) { createChat(title: $title, members: $members) { error chat { diff --git a/src/graphql/query/chat-recipients.ts b/src/graphql/query/chat-recipients.ts index 7acf3588..2feb0081 100644 --- a/src/graphql/query/chat-recipients.ts +++ b/src/graphql/query/chat-recipients.ts @@ -5,6 +5,7 @@ export default gql` loadRecipients(limit: $limit, offset: $offset) { members { name + id slug userpic } diff --git a/src/graphql/query/chats-load.ts b/src/graphql/query/chats-load.ts index 2e2ac02a..b7c4cc48 100644 --- a/src/graphql/query/chats-load.ts +++ b/src/graphql/query/chats-load.ts @@ -9,6 +9,7 @@ export default gql` title admins members { + id slug name userpic diff --git a/src/graphql/types.gen.ts b/src/graphql/types.gen.ts index 39afa866..5dd514cf 100644 --- a/src/graphql/types.gen.ts +++ b/src/graphql/types.gen.ts @@ -84,10 +84,10 @@ export type ChatMember = { export type Collab = { authors: Array> - body?: Maybe - createdAt: Scalars['DateTime'] + chat?: Maybe + createdAt: Scalars['Int'] invites?: Maybe>> - title?: Maybe + shout?: Maybe } export type Collection = { @@ -164,6 +164,7 @@ export type MessagesBy = { } export type Mutation = { + acceptCoauthor: Result confirmEmail: AuthResult createChat: Result createMessage: Result @@ -177,11 +178,11 @@ export type Mutation = { destroyTopic: Result follow: Result getSession: AuthResult - inviteAuthor: Result + inviteCoauthor: Result markAsRead: Result rateUser: Result registerUser: AuthResult - removeAuthor: Result + removeCoauthor: Result sendLink: Result unfollow: Result updateChat: Result @@ -193,19 +194,23 @@ export type Mutation = { updateTopic: Result } +export type MutationAcceptCoauthorArgs = { + shout: Scalars['Int'] +} + export type MutationConfirmEmailArgs = { token: Scalars['String'] } export type MutationCreateChatArgs = { - members: Array> + members: Array> title?: InputMaybe } export type MutationCreateMessageArgs = { body: Scalars['String'] chat: Scalars['String'] - replyTo?: InputMaybe + replyTo?: InputMaybe } export type MutationCreateReactionArgs = { @@ -213,7 +218,7 @@ export type MutationCreateReactionArgs = { } export type MutationCreateShoutArgs = { - input: ShoutInput + inp: ShoutInput } export type MutationCreateTopicArgs = { @@ -246,9 +251,9 @@ export type MutationFollowArgs = { what: FollowingEntity } -export type MutationInviteAuthorArgs = { +export type MutationInviteCoauthorArgs = { author: Scalars['String'] - shout: Scalars['String'] + shout: Scalars['Int'] } export type MutationMarkAsReadArgs = { @@ -267,14 +272,15 @@ export type MutationRegisterUserArgs = { password?: InputMaybe } -export type MutationRemoveAuthorArgs = { +export type MutationRemoveCoauthorArgs = { author: Scalars['String'] - shout: Scalars['String'] + shout: Scalars['Int'] } export type MutationSendLinkArgs = { email: Scalars['String'] lang?: InputMaybe + template?: InputMaybe } export type MutationUnfollowArgs = { @@ -301,7 +307,7 @@ export type MutationUpdateReactionArgs = { } export type MutationUpdateShoutArgs = { - input: ShoutInput + inp: ShoutInput } export type MutationUpdateTopicArgs = { @@ -320,14 +326,16 @@ export type Operation = { } export type Permission = { - operation_id: Scalars['Int'] - resource_id: Scalars['Int'] + operation: Scalars['Int'] + resource: Scalars['Int'] } export type ProfileInput = { + about?: InputMaybe bio?: InputMaybe links?: InputMaybe>> name?: InputMaybe + slug?: InputMaybe userpic?: InputMaybe } @@ -461,7 +469,7 @@ export type Reaction = { old_id?: Maybe old_thread?: Maybe range?: Maybe - replyTo?: Maybe + replyTo?: Maybe shout: Shout stat?: Maybe updatedAt?: Maybe @@ -576,13 +584,14 @@ export type Shout = { } export type ShoutInput = { + authors?: InputMaybe>> body: Scalars['String'] - community: Scalars['String'] + community?: InputMaybe mainTopic?: InputMaybe - slug: Scalars['String'] + slug?: InputMaybe subtitle?: InputMaybe title?: InputMaybe - topic_slugs?: InputMaybe>> + topics?: InputMaybe>> versionOf?: InputMaybe visibleForRoles?: InputMaybe>> visibleForUsers?: InputMaybe>> diff --git a/src/utils/apiClient.ts b/src/utils/apiClient.ts index eee44d50..562feed5 100644 --- a/src/utils/apiClient.ts +++ b/src/utils/apiClient.ts @@ -289,7 +289,7 @@ export const apiClient = { getChatMessages: async (options: QueryLoadMessagesByArgs) => { const resp = await privateGraphQLClient.query(chatMessagesLoadBy, options).toPromise() console.log('!!! resp:', resp) - // return resp.data.loadChat + return resp.data.loadChat }, getRecipients: async (options: QueryLoadRecipientsArgs) => { From 24be8aa01658ac7c946d2cb1400a7e7940e23874 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Sun, 4 Dec 2022 05:48:24 +0300 Subject: [PATCH 12/60] Refactoring after backend update --- src/utils/apiClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/apiClient.ts b/src/utils/apiClient.ts index 562feed5..c3e4774c 100644 --- a/src/utils/apiClient.ts +++ b/src/utils/apiClient.ts @@ -289,7 +289,7 @@ export const apiClient = { getChatMessages: async (options: QueryLoadMessagesByArgs) => { const resp = await privateGraphQLClient.query(chatMessagesLoadBy, options).toPromise() console.log('!!! resp:', resp) - return resp.data.loadChat + return resp.data }, getRecipients: async (options: QueryLoadRecipientsArgs) => { From 75f928a71b1fa3b59dfedcda9dd3f40260e6800b Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Sun, 4 Dec 2022 12:47:41 +0300 Subject: [PATCH 13/60] [WiP] chat messages load --- src/graphql/mutation/create-chat-message.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphql/mutation/create-chat-message.ts b/src/graphql/mutation/create-chat-message.ts index 9fda159a..9f7d1174 100644 --- a/src/graphql/mutation/create-chat-message.ts +++ b/src/graphql/mutation/create-chat-message.ts @@ -7,6 +7,7 @@ export default gql` author { slug id + chat } } } From 61a598e0bbf0f62e3bd3516d8aaec9e21423f6d5 Mon Sep 17 00:00:00 2001 From: ilya-bkv Date: Mon, 5 Dec 2022 08:41:53 +0300 Subject: [PATCH 14/60] [WiP] messages update --- src/components/Inbox/Message.tsx | 28 ++++++-- src/components/Views/Inbox.tsx | 80 ++++++--------------- src/graphql/mutation/create-chat-message.ts | 9 ++- src/utils/apiClient.ts | 5 +- 4 files changed, 50 insertions(+), 72 deletions(-) diff --git a/src/components/Inbox/Message.tsx b/src/components/Inbox/Message.tsx index 2b31935b..d31c12cf 100644 --- a/src/components/Inbox/Message.tsx +++ b/src/components/Inbox/Message.tsx @@ -1,12 +1,15 @@ -import { Show } from 'solid-js' +import { createMemo, Show } from 'solid-js' import MarkdownIt from 'markdown-it' import { clsx } from 'clsx' import styles from './Message.module.scss' import DialogAvatar from './DialogAvatar' +import { locale } from '../../stores/ui' +import type { Message, ChatMember } from '../../graphql/types.gen' type Props = { - body: string - isOwn: boolean + content: Message + ownId: number + members: ChatMember[] } const md = new MarkdownIt({ @@ -14,18 +17,29 @@ const md = new MarkdownIt({ }) const Message = (props: Props) => { + const formattedTime = createMemo(() => { + return new Date(props.content.createdAt * 1000).toLocaleTimeString(locale(), { + hour: 'numeric', + minute: 'numeric' + }) + }) + + console.log('!!! props.ownId:', props.ownId) + // возвращать ID автора + const isOwn = props.ownId === Number(props.content.author) + return ( -
- +
+
Message Author
-
+
-
12:24
+
{formattedTime()}
) } diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index b8985a7e..9e96d100 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -1,8 +1,6 @@ import { For, createSignal, Show, onMount, createEffect, createMemo } from 'solid-js' -import type { Author, Chat } from '../../graphql/types.gen' -import { AuthorCard } from '../Author/Card' +import type { Author, Chat, Message as MessageType } from '../../graphql/types.gen' import { Icon } from '../_shared/Icon' -import { Loading } from '../Loading' import DialogCard from '../Inbox/DialogCard' import Search from '../Inbox/Search' import { useSession } from '../../context/session' @@ -17,35 +15,7 @@ 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({ - url: 'https://graphqlzero.almansi.me/api' -}) - -const messageQuery = ` -query Comments ($options: PageQueryOptions) { - comments(options: $options) { - data { - id - body - email - } - } -} -` -const newMessageQuery = ` -mutation postComment($messageBody: String!) { - createComment( - input: { body: $messageBody, email: "test@test.com", name: "User" } - ) { - id - body - name - email - } -} -` +import { apiClient } from '../../utils/apiClient' const userSearch = (array: Author[], keyword: string) => { const searchTerm = keyword.toLowerCase() @@ -54,24 +24,17 @@ const userSearch = (array: Author[], keyword: string) => { }) } -const postMessage = async (msg: string) => { - const response = await client.mutation(newMessageQuery, { messageBody: msg }).toPromise() - return response.data.createComment -} - export const InboxView = () => { const { chats, actions: { loadChats } } = useInbox() - const [messages, setMessages] = createSignal([]) + const [messages, setMessages] = createSignal([]) const [recipients, setRecipients] = createSignal([]) - const [cashedRecipients, setCashedRecipients] = createSignal([]) const [postMessageText, setPostMessageText] = createSignal('') - const [loading, setLoading] = createSignal(false) const [sortByGroup, setSortByGroup] = createSignal(false) const [sortByPerToPer, setSortByPerToPer] = createSignal(false) - const [selectedChat, setSelectedChat] = createSignal() + const [currentDialog, setCurrentDialog] = createSignal() const { session } = useSession() const currentUserId = createMemo(() => session()?.user?.id) @@ -87,24 +50,19 @@ export const InboxView = () => { let chatWindow const handleOpenChat = async (chat) => { - setLoading(true) - setSelectedChat(chat) + setCurrentDialog(chat) try { await loadMessages({ chat: chat.id }) } catch (error) { - setLoading(false) console.error('[loadMessages]', error) } finally { - setLoading(false) chatWindow.scrollTop = chatWindow.scrollHeight } } onMount(async () => { - setLoading(true) try { const response = await loadRecipients({ days: 365 }) setRecipients(response as unknown as Author[]) - setCashedRecipients(response as unknown as Author[]) } catch (error) { console.log(error) } @@ -113,8 +71,11 @@ export const InboxView = () => { const handleSubmit = async () => { try { - const post = await postMessage(postMessageText()) - setMessages((prev) => [...prev, post]) + const post = await apiClient.createMessage({ + body: postMessageText().toString(), + chat: currentDialog().id.toString() + }) + setMessages((prev) => [...prev, post.message]) setPostMessageText('') chatWindow.scrollTop = chatWindow.scrollHeight } catch (error) { @@ -135,10 +96,6 @@ export const InboxView = () => { showModal('inviteToChat') } - createEffect(() => { - console.log('!!! chats():', chats()) - }) - const chatsToShow = () => { if (sortByPerToPer()) { return chats().filter((chat) => chat.title.trim().length === 0) @@ -149,6 +106,11 @@ export const InboxView = () => { } } + createEffect(() => { + console.log('!!! messages():', messages()) + console.log('!!! currentDialog():', currentDialog()) + }) + return (
@@ -211,18 +173,15 @@ export const InboxView = () => {
- - + +
- - - - {(comment: { body: string; id: string; email: string }) => ( - + {(message) => ( + )} @@ -240,6 +199,7 @@ export const InboxView = () => { rows={1} onInput={(event) => handleChangeMessage(event)} placeholder="Написать сообщение" + disabled={!currentDialog()?.id} />
+ +
+
+ ) +} + +export default MessagesFallback diff --git a/src/components/Views/Inbox.tsx b/src/components/Views/Inbox.tsx index 9e96d100..ec87fe6e 100644 --- a/src/components/Views/Inbox.tsx +++ b/src/components/Views/Inbox.tsx @@ -16,6 +16,7 @@ import '../../styles/Inbox.scss' import { useInbox } from '../../context/inbox' import DialogHeader from '../Inbox/DialogHeader' import { apiClient } from '../../utils/apiClient' +import MessagesFallback from '../Inbox/MessagesFallback' const userSearch = (array: Author[], keyword: string) => { const searchTerm = keyword.toLowerCase() @@ -88,11 +89,11 @@ export const InboxView = () => { setPostMessageText(event.target.value) } createEffect(() => { + if (!textareaParent) return textareaParent.dataset.replicatedValue = postMessageText() }) - const handleOpenInviteModal = (event: Event) => { - event.preventDefault() + const handleOpenInviteModal = () => { showModal('inviteToChat') } @@ -120,9 +121,9 @@ export const InboxView = () => {
@@ -173,40 +174,47 @@ export const InboxView = () => {
- + + } + > - +
+
+ + {(message) => ( + + )} + -
-
- - {(message) => ( - - )} - - - {/*
*/} - {/* */} - {/*
*/} -
-
- -
-
-
-