Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Chat): Fix chatbar messages to persist through different conversations #540

Merged
merged 4 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/lib/components/messaging/ChatPreview.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import ProfilePictureMany from "../profile/ProfilePictureMany.svelte"
import { Store } from "$lib/state/Store"
import { goto } from "$app/navigation"
import { get } from "svelte/store"
import { tempCDN } from "$lib/utils/CommonVariables"

export let chat: Chat
Expand Down Expand Up @@ -41,7 +42,7 @@

<button
data-cy="chat-preview"
class="chat-preview {cta ? 'cta' : ''}"
class="chat-preview {cta ? 'cta' : ''} {get(Store.state.activeChat)?.id === chat.id ? 'active-chat' : ''}"
on:contextmenu
on:click={_ => {
dispatch("click")
Expand Down Expand Up @@ -107,6 +108,10 @@
transition: all var(--animation-speed);
min-width: var(--min-component-width);

&.active-chat {
background-color: var(--primary-color-alt);
}

&.cta {
background-color: var(--alt-color);

Expand Down
59 changes: 32 additions & 27 deletions src/lib/elements/Input/Input.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@

let onsend: any[] = []
let editor: MarkdownEditor

if (rich) {
onMount(() => {
if (autoFocus) input.focus()
Expand Down Expand Up @@ -134,34 +135,38 @@
}
</script>

<div
class="input-group {alt ? 'alt' : ''} {highlight !== null ? `highlight-${highlight}` : ''} {tooltip ? 'tooltip' : ''} {clazz || ''} {rich ? 'multiline' : ''}"
data-tooltip={tooltip}
role="none"
on:click={async _ => {
if (copyOnInteract) {
await navigator.clipboard.writeText(`${value}`)
}
}}>
<div class="input-container {rounded ? 'rounded' : ''} {clazz || ''} {rich ? 'multiline' : ''}">
<slot></slot>
<input
data-cy={hook}
class="input {centered ? 'centered' : ''} {disabled ? 'disabled' : ''}"
type="text"
disabled={disabled}
bind:this={input}
on:focus={handleFocus}
bind:value={$writableValue}
placeholder={placeholder}
on:keydown={onKeyDown}
on:input={onInput}
on:blur={onBlur} />
{#key hook}
<div
class="input-group {alt ? 'alt' : ''} {highlight !== null ? `highlight-${highlight}` : ''} {tooltip ? 'tooltip' : ''} {clazz || ''} {rich ? 'multiline' : ''}"
data-tooltip={tooltip}
role="none"
on:click={async _ => {
if (copyOnInteract) {
await navigator.clipboard.writeText(`${value}`)
}
}}>
<div class="input-container {rounded ? 'rounded' : ''} {clazz || ''} {rich ? 'multiline' : ''}">
<slot></slot>
<!-- svelte-ignore a11y-autofocus -->
<input
id={hook}
data-cy={hook}
class="input {centered ? 'centered' : ''} {disabled ? 'disabled' : ''}"
type="text"
bind:this={input}
on:focus={handleFocus}
bind:value={$writableValue}
placeholder={placeholder}
on:keydown={onKeyDown}
on:input={onInput}
on:blur={onBlur}
autofocus={autoFocus} />
</div>
</div>
</div>
{#if errorMessage}
<Text appearance={Appearance.Warning}>{errorMessage}</Text>
{/if}
{#if errorMessage}
<Text appearance={Appearance.Warning}>{errorMessage}</Text>
{/if}
{/key}

<style lang="scss">
.input-group {
Expand Down
52 changes: 42 additions & 10 deletions src/lib/layouts/Chatbar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@
import { RaygunStoreInstance, type FileAttachment } from "$lib/wasm/RaygunStore"
import { createEventDispatcher } from "svelte"
import { ConversationStore } from "$lib/state/conversation"
import type { GiphyGif, Message } from "$lib/types"
import type { Chat, GiphyGif, Message } from "$lib/types"
import { PopupButton } from "$lib/components"
import CombinedSelector from "$lib/components/messaging/CombinedSelector.svelte"
import { checkMobile } from "$lib/utils/Mobile"
import { VoiceRTCMessageType } from "$lib/media/Voice"
import { UIStore } from "$lib/state/ui"
import { emojiList } from "$lib/components/messaging/emoji/EmojiList"
import { tempCDN } from "$lib/utils/CommonVariables"

export let replyTo: Message | undefined = undefined
export let filesSelected: [File?, string?][] = []
export let emojiClickHook: (emoji: string) => boolean
export let activeChat: Chat

const dispatch = createEventDispatcher()

Expand All @@ -30,8 +30,22 @@
$: emojiSelectorOpen = UIStore.state.emojiSelector
let gifSelectorOpen = writable(false)
let stickerSelectorOpen = writable(false)
let hackVariableToRefocusChatBar = writable("")

async function sendMessage(text: string) {
let chatMessages = writable<{ [key: string]: string }>({})

$: if (activeChat) {
message.set(get(chatMessages)[activeChat.id] || "")
}

$: if (message) {
chatMessages.update(messages => {
messages[activeChat.id] = $message
return messages
})
}

async function sendMessage(text: string, isStickerOrGif: boolean = false) {
let attachments: FileAttachment[] = []
filesSelected.forEach(([file, path]) => {
if (file) {
Expand All @@ -52,7 +66,14 @@
result.onSuccess(res => {
ConversationStore.addPendingMessages(chat.id, res.message, txt)
})
message.set("")
if (!isStickerOrGif) {
message.set("")
chatMessages.update(messages => {
messages[activeChat.id] = ""
return messages
})
}

replyTo = undefined
dispatch("onsend")
}
Expand All @@ -62,22 +83,25 @@
gifSelectorOpen.set(false)
stickerSelectorOpen.set(false)
if (emojiClickHook(emoji)) return
message.set($message + emoji)
message.update(m => m + emoji)
hackVariableToRefocusChatBar.set(Math.random().toString())
}

function handleGif(gif: GiphyGif) {
emojiSelectorOpen.set(false)
gifSelectorOpen.set(false)
stickerSelectorOpen.set(false)
sendMessage(`![${gif.title}](${gif.images.fixed_height_small.url})`)
sendMessage(`![${gif.title}](${gif.images.fixed_height_small.url})`, true)
hackVariableToRefocusChatBar.set(Math.random().toString())
}

async function handleSticker(sticker: any) {
emojiSelectorOpen.set(false)
gifSelectorOpen.set(false)
stickerSelectorOpen.set(false)
let stickerUrl = `${tempCDN}${sticker.sticker.path}`
sendMessage(`![${sticker.sticker.name}](${stickerUrl})`)
sendMessage(`![${sticker.sticker.name}](${stickerUrl})`, true)
hackVariableToRefocusChatBar.set(Math.random().toString())
}

function replaceEmojis(inputText: string) {
Expand Down Expand Up @@ -107,12 +131,20 @@
}
</script>

<div class="chatbar" data-cy="chatbar">
<div class="chatbar" data-cy="chatbar" id={activeChat.id}>
<Controls>
<slot name="pre-controls"></slot>
</Controls>

<Input hook="chatbar-input" alt placeholder={$_("generic.placeholder")} autoFocus bind:value={$message} rounded rich={markdown} on:input={_ => replaceEmojis($message)} on:enter={_ => sendMessage($message)} />
<Input
hook={`${activeChat.id}-${$hackVariableToRefocusChatBar}`}
alt
placeholder={$_("generic.placeholder")}
autoFocus={true}
bind:value={$message}
rounded
rich={markdown}
on:input={_ => replaceEmojis($message)}
on:enter={_ => sendMessage($message)} />

<slot></slot>

Expand Down
2 changes: 1 addition & 1 deletion src/lib/layouts/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
{#if open}
<div class="sidebar">
<div class="sidebar-pre">
<Input hook="input-sidebar-search" alt placeholder={$_("generic.search_placeholder")} bind:value={search} on:enter={handleEnter} on:input={handleSearch}>
<Input hook="input-sidebar-search" alt autoFocus={false} placeholder={$_("generic.search_placeholder")} bind:value={search} on:enter={handleEnter} on:input={handleSearch}>
<Icon icon={Shape.Search} />
</Input>

Expand Down
2 changes: 2 additions & 0 deletions src/routes/chat/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,8 @@
<Chatbar
filesSelected={files}
replyTo={replyTo}
activeChat={$activeChat}
typing={$activeChat.typing_indicator.users && $activeChat.typing_indicator.users().map(u => $users[u])}
emojiClickHook={emoji => {
if (reactingTo) {
reactTo(reactingTo, emoji, false)
Expand Down
Loading