diff --git a/src/lib/components/index.ts b/src/lib/components/index.ts
index 38e85996e..a979b68dc 100644
--- a/src/lib/components/index.ts
+++ b/src/lib/components/index.ts
@@ -22,6 +22,7 @@ export { default as PopupButton } from "$lib/components/ui/PopupButton.svelte"
export { default as Modal } from "$lib/components/ui/Modal.svelte"
export { default as Titlebar } from "$lib/components/ui/Titlebar.svelte"
export { default as ContextMenu } from "$lib/components/ui/ContextMenu.svelte"
+export { default as MessageText } from "$lib/components/messaging/message/MessageText.svelte"
export { default as Message } from "$lib/components/messaging/message/Message.svelte"
export { default as MessageReactions } from "$lib/components/messaging/message/MessageReactions.svelte"
export { default as MessageGroup } from "$lib/components/messaging/MessageGroup.svelte"
diff --git a/src/lib/components/messaging/message/MessageText.svelte b/src/lib/components/messaging/message/MessageText.svelte
new file mode 100644
index 000000000..d865440c7
--- /dev/null
+++ b/src/lib/components/messaging/message/MessageText.svelte
@@ -0,0 +1,58 @@
+
+
+{#each texts as line}
+ {#if getValidPaymentRequest(line) != undefined}
+
+ {:else if type === MessageType.CDN}
+
+
+
+ {:else if type === MessageType.CALL_START}
+
+
+
+
+
+ {:else}
+
+ {/if}
+{/each}
+
+
diff --git a/src/lib/lang/en.json b/src/lib/lang/en.json
index 296e95f76..69cf328ee 100644
--- a/src/lib/lang/en.json
+++ b/src/lib/lang/en.json
@@ -353,7 +353,8 @@
"everybodyDeniedTheCall": "Everybody Denied the call. Disconnecting...",
"acceptedCall": "Joined, loading...",
"connecting": "Connecting...",
- "noResponse": "No response"
+ "noResponse": "No response",
+ "join": "Join"
},
"notifications": {
"name": "Notifications",
diff --git a/src/lib/media/Voice.ts b/src/lib/media/Voice.ts
index 404c06907..28ecdd54a 100644
--- a/src/lib/media/Voice.ts
+++ b/src/lib/media/Voice.ts
@@ -443,7 +443,7 @@ export class VoiceRTC {
* Actually making the call
*/
async makeCall(call: boolean = true) {
- if (!this.toCall) {
+ if (!this.toCall && !call) {
log.error("Calling not setup")
return
}
@@ -457,7 +457,10 @@ export class VoiceRTC {
// Create a new call room
this.createAndSetRoom()
if (call) {
- this.inviteToCall(this.toCall)
+ this.inviteToCall(this.toCall!)
+ const formattedEndTime = new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", hour12: false })
+ const text = get(_)("settings.calling.startCallMessage", { values: { value: formattedEndTime } })
+ await RaygunStoreInstance.send(this.channel!, text.split("\n"), [])
}
const timeoutWhenCallIsNull = setTimeout(() => {
if (this.call === null || this.call.empty) {
diff --git a/src/lib/mock/messages.ts b/src/lib/mock/messages.ts
index c577aac2d..5f38d1225 100644
--- a/src/lib/mock/messages.ts
+++ b/src/lib/mock/messages.ts
@@ -1,5 +1,5 @@
import { Appearance, MessageAttachmentKind, Shape } from "$lib/enums"
-import type { MessageGroup } from "$lib/types"
+import { MessageType, type MessageGroup } from "$lib/types"
import { mock_users } from "./users"
import { v4 as uuidv4 } from "uuid"
@@ -37,6 +37,7 @@ export let mock_messages: MessageGroup[] = [
},
attachments: [],
pinned: false,
+ type: MessageType.DEFAULT,
},
{
id: uuidv4(),
@@ -63,6 +64,7 @@ export let mock_messages: MessageGroup[] = [
},
],
pinned: false,
+ type: MessageType.DEFAULT,
},
{
id: uuidv4(),
@@ -83,6 +85,7 @@ export let mock_messages: MessageGroup[] = [
},
],
pinned: false,
+ type: MessageType.DEFAULT,
},
{
id: uuidv4(),
@@ -96,6 +99,7 @@ export let mock_messages: MessageGroup[] = [
reactions: {},
attachments: [],
pinned: false,
+ type: MessageType.DEFAULT,
},
{
id: uuidv4(),
@@ -109,6 +113,7 @@ export let mock_messages: MessageGroup[] = [
reactions: {},
attachments: [],
pinned: false,
+ type: MessageType.DEFAULT,
},
],
},
@@ -151,6 +156,7 @@ export let mock_messages: MessageGroup[] = [
},
],
pinned: true,
+ type: MessageType.DEFAULT,
},
{
id: uuidv4(),
@@ -171,6 +177,7 @@ export let mock_messages: MessageGroup[] = [
},
],
pinned: false,
+ type: MessageType.DEFAULT,
},
{
id: uuidv4(),
@@ -191,6 +198,7 @@ export let mock_messages: MessageGroup[] = [
},
],
pinned: false,
+ type: MessageType.DEFAULT,
},
{
id: uuidv4(),
@@ -204,6 +212,7 @@ export let mock_messages: MessageGroup[] = [
reactions: {},
attachments: [],
pinned: false,
+ type: MessageType.DEFAULT,
},
],
},
@@ -235,10 +244,12 @@ export let mock_messages: MessageGroup[] = [
reactions: {},
attachments: [],
pinned: false,
+ type: MessageType.DEFAULT,
},
reactions: {},
attachments: [],
pinned: true,
+ type: MessageType.DEFAULT,
},
],
},
diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts
index aa812690d..1f31c0a33 100644
--- a/src/lib/types/index.ts
+++ b/src/lib/types/index.ts
@@ -15,7 +15,9 @@ import {
CommunitySettingsRoute,
} from "$lib/enums"
import type { Cancellable } from "$lib/utils/CancellablePromise"
-import type { Writable } from "svelte/store"
+import { tempCDN } from "$lib/utils/CommonVariables"
+import { get, type Writable } from "svelte/store"
+import { _ } from "svelte-i18n"
export interface Serialize {
serialize(): any
@@ -359,6 +361,28 @@ export type MessageDetails = {
remote: boolean
}
+export enum MessageType {
+ DEFAULT,
+ SYSTEM, // Until warp supports some built in system message method its client sided
+ CALL_START,
+ CDN,
+}
+
+export function messageTypeFromTexts(texts: string[]): MessageType {
+ if (texts.some(text => text.includes(tempCDN))) {
+ return MessageType.CDN
+ }
+ const endCallReg = new RegExp(get(_)("settings.calling.endCallMessage", { values: { formattedEndTime: "(.*)", duration: "(.*)" } }))
+ if (texts.some(text => text.includes("giphy.com")) || texts.some(text => text.includes(get(_)("settings.calling.callMissed"))) || texts.some(text => text.match(endCallReg))) {
+ return MessageType.SYSTEM
+ }
+ const startCallReg = new RegExp(get(_)("settings.calling.startCallMessage", { values: { value: "(.*)" } }))
+ if (texts.some(text => text.match(startCallReg))) {
+ return MessageType.CALL_START
+ }
+ return MessageType.DEFAULT
+}
+
export type Message = {
id: string
details: MessageDetails
@@ -367,6 +391,7 @@ export type Message = {
attachments: Attachment[]
text: string[]
pinned: boolean
+ type: MessageType
}
export function mentions_user(message: Message, user: string): boolean {
diff --git a/src/lib/wasm/RaygunStore.ts b/src/lib/wasm/RaygunStore.ts
index 0c8304d9d..6dfb48aa0 100644
--- a/src/lib/wasm/RaygunStore.ts
+++ b/src/lib/wasm/RaygunStore.ts
@@ -6,7 +6,7 @@ import { UIStore } from "../state/ui"
import { ConversationStore } from "../state/conversation"
import { MessageOptions } from "warp-wasm"
import { ChatType, MessageAttachmentKind, Route } from "$lib/enums"
-import { type User, type Chat, defaultChat, type Message, mentions_user, type Attachment } from "$lib/types"
+import { type User, type Chat, defaultChat, type Message, mentions_user, type Attachment, messageTypeFromTexts } from "$lib/types"
import { WarpError, handleErrors } from "./HandleWarpErrors"
import { failure, success, type Result } from "$lib/utils/Result"
import { create_cancellable_handler, type Cancellable } from "$lib/utils/CancellablePromise"
@@ -769,6 +769,7 @@ class RaygunStore {
reactions: message.reactions(),
attachments: attachments.map(f => this.convertWarpAttachment(f)),
pinned: message.pinned(),
+ type: messageTypeFromTexts(message.lines()),
}
}
diff --git a/src/routes/chat/+page.svelte b/src/routes/chat/+page.svelte
index 10bfc869c..f7f248af3 100644
--- a/src/routes/chat/+page.svelte
+++ b/src/routes/chat/+page.svelte
@@ -5,11 +5,26 @@
import { animationDuration } from "$lib/globals/animations"
import { slide } from "svelte/transition"
import { Chatbar, Sidebar, Topbar, Profile } from "$lib/layouts"
- import { ImageEmbed, ChatPreview, Conversation, Message, MessageGroup, MessageReactions, MessageReplyContainer, ProfilePicture, Modal, ProfilePictureMany, ChatFilter, ContextMenu, EmojiGroup } from "$lib/components"
+ import {
+ ImageEmbed,
+ ChatPreview,
+ Conversation,
+ Message as MessageComponent,
+ MessageGroup,
+ MessageReactions,
+ MessageReplyContainer,
+ ProfilePicture,
+ Modal,
+ ProfilePictureMany,
+ ChatFilter,
+ ContextMenu,
+ EmojiGroup,
+ MessageText,
+ } from "$lib/components"
import CreateTransaction from "$lib/components/wallet/CreateTransaction.svelte"
import { Button, FileInput, Icon, Label, Text } from "$lib/elements"
import CallScreen from "$lib/components/calling/CallScreen.svelte"
- import { type MessageGroup as MessageGroupType } from "$lib/types"
+ import { MessageType, type MessageGroup as MessageGroupType } from "$lib/types"
import EncryptedNotice from "$lib/components/messaging/EncryptedNotice.svelte"
import { Store } from "$lib/state/Store"
import { derived, get } from "svelte/store"
@@ -21,19 +36,17 @@
import ViewMembers from "$lib/components/group/ViewMembers.svelte"
import Market from "$lib/components/market/Market.svelte"
import { RaygunStoreInstance } from "$lib/wasm/RaygunStore"
- import type { Attachment, FileInfo, Message as MessageType, User } from "$lib/types"
+ import type { Attachment, Message, User } from "$lib/types"
import Input from "$lib/elements/Input/Input.svelte"
import PendingMessage from "$lib/components/messaging/message/PendingMessage.svelte"
import PendingMessageGroup from "$lib/components/messaging/PendingMessageGroup.svelte"
import FileUploadPreview from "$lib/elements/FileUploadPreview.svelte"
import StoreResolver from "$lib/components/utils/StoreResolver.svelte"
- import { getValidPaymentRequest } from "$lib/utils/Wallet"
import { onMount } from "svelte"
import PinnedMessages from "$lib/components/messaging/PinnedMessages.svelte"
import { MessageEvent } from "warp-wasm"
import { debounce, getTimeAgo } from "$lib/utils/Functions"
import Controls from "$lib/layouts/Controls.svelte"
- import { tempCDN } from "$lib/utils/CommonVariables"
import { checkMobile } from "$lib/utils/Mobile"
import BrowseFiles from "../files/BrowseFiles.svelte"
import AttachmentRenderer from "$lib/components/messaging/AttachmentRenderer.svelte"
@@ -68,7 +81,7 @@
// TODO(Lucas): Need to improve that for chats when not necessary all users are friends
$: loading = get(UIStore.state.chats).length > 0 && !$activeChat.users.slice(1).some(userId => $users[userId]?.name !== undefined)
- $: chatName = $activeChat.kind === ChatType.DirectMessage ? $users[$activeChat.users[1]]?.name : $activeChat.name ?? $users[$activeChat.users[1]]?.name
+ $: chatName = $activeChat.kind === ChatType.DirectMessage ? $users[$activeChat.users[1]]?.name : ($activeChat.name ?? $users[$activeChat.users[1]]?.name)
$: statusMessage = $activeChat.kind === ChatType.DirectMessage ? $users[$activeChat.users[1]]?.profile?.status_message : $activeChat.motd
$: pinned = getPinned($conversation)
@@ -92,7 +105,7 @@
let editing_text: string | undefined = undefined
$: emojis = UIStore.getMostUsed()
$: own_user = Store.state.user
- let replyTo: MessageType | undefined = undefined
+ let replyTo: Message | undefined = undefined
let reactingTo: string | undefined
let fileUpload: FileInput
@@ -150,7 +163,7 @@
})
}
- function build_context_items(message: MessageType, file?: Attachment) {
+ function build_context_items(message: Message, file?: Attachment) {
return [
message.pinned
? {
@@ -204,11 +217,7 @@
: []),
...(message.details.origin === $own_user.key
? [
- ...(!message.text.some(text => text.includes("giphy.com")) &&
- !message.text.some(text => text.includes(tempCDN)) &&
- !message.text.some(text => text.includes(get(_)("settings.calling.callMissed"))) &&
- !message.text.some(text => text.includes(get(_)("settings.calling.endCallMessage"))) &&
- !message.text.some(text => text.includes(get(_)("settings.calling.startCallMessage")))
+ ...(message.type === MessageType.DEFAULT
? [
{
id: "edit",
@@ -222,9 +231,7 @@
},
]
: []),
- ...(!message.text.some(text => text.includes(get(_)("settings.calling.callMissed"))) &&
- !message.text.some(text => text.includes(get(_)("settings.calling.endCallMessage"))) &&
- !message.text.some(text => text.includes(get(_)("settings.calling.startCallMessage")))
+ ...(message.type === MessageType.DEFAULT
? [
{
id: "delete",
@@ -305,7 +312,7 @@
}, 500)
})
- function getPinned(conversation: ConversationMessages | undefined): MessageType[] {
+ function getPinned(conversation: ConversationMessages | undefined): Message[] {
if (!conversation) return []
return conversation!.messages.flatMap(g => g.messages.filter(m => m.pinned))
}
@@ -319,7 +326,7 @@
function splitUnreads(groups: MessageGroupType[]): [MessageGroupType[], MessageGroupType[]] {
let splitMessages = (group: MessageGroupType) => {
- return group.messages.reduce<[MessageType[], MessageType[]]>(
+ return group.messages.reduce<[Message[], Message[]]>(
([read, unreads], message) => {
if (message.details.at > $activeChat.last_view_date) {
unreads.push(message)
@@ -688,11 +695,11 @@
{#if group.messages[0].inReplyTo}
Store.getUser(v)} let:resolved>
-
+
{#each group.messages[0].inReplyTo.text as line}
{/each}
-
+
{/if}
@@ -715,17 +722,17 @@
{#if message.inReplyTo && idx !== 0}
Store.getUser(v)} let:resolved>
-
+
{#each message.inReplyTo.text as line}
{/each}
-
+
{/if}
{#if message.text.length > 0 || message.attachments.length > 0}
- edit_message(message.id, editing_text ? editing_text : "")} />
{:else}
- {#each message.text as line}
- {#if getValidPaymentRequest(line) != undefined}
-
- {:else if !line.includes(tempCDN)}
-
- {:else if line.includes(tempCDN)}
-
-
-
- {/if}
- {/each}
-
+
{#if message.attachments.length > 0}
(fileToShare = [e.detail, $activeChat.id])} />
{/if}
{/if}
-
+
reactTo(message.id, emoji, true)} close={close} on:openPicker={_ => (reactingTo = message.id)}>
@@ -1056,8 +1052,4 @@
}
}
}
-
- .sticker {
- width: var(--sticker-width-rendered);
- }