Skip to content

Commit

Permalink
send attachments
Browse files Browse the repository at this point in the history
  • Loading branch information
targoninc-alex committed Jun 29, 2024
1 parent 2281c9c commit c8e4167
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 16 deletions.
1 change: 1 addition & 0 deletions ui/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
--white-2: #e7ddda;
--white-3: #ded2ce;
--white-4: #d6c9c5;
--neutral: #7b7b7b;
--blue: #16bac5ff;
--green: #6a994eff;
--red: #bc4749ff;
Expand Down
50 changes: 45 additions & 5 deletions ui/classes.css
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,15 @@
}

.message-timestamp {
display: none;
color: var(--neutral);
font-size: 0.6em !important;
padding-left: calc(var(--message-padding-left) + 2em);
height: 0;
overflow: hidden;
}

.chat-message:hover .message-timestamp {
display: block;
height: 1em;
}

.message-note {
Expand Down Expand Up @@ -292,7 +296,7 @@

.reaction-trigger {
position: absolute;
left: 1.25em;
left: calc(var(--message-padding-left) - 1.5em);
bottom: var(--gap-h);
z-index: 999;
max-width: max-content;
Expand Down Expand Up @@ -511,7 +515,7 @@
height: var(--size);
position: absolute;
top: 0;
left: .5em;
left: calc(var(--message-padding-left) - 2.5em);
}

.small-avatar {
Expand Down Expand Up @@ -670,4 +674,40 @@
top: 0;
right: 0;
transform: translateX(50%) translateY(-50%);
}
}

.attachments {
padding-left: calc(var(--message-padding-left) - 0.25em);
}

.attachment-image {
max-height: 200px;
max-width: 200px;
height: auto;
width: auto;
border-radius: var(--input-border-radius);
cursor: zoom-in;
}

.attachment-image:hover {
transform: scale(1.02);
}

.full-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: contain;
cursor: zoom-out;
z-index: 999;
background: var(--bg);
}

.attachment-video, .attachment-audio {
max-height: 200px;
max-width: 200px;
height: auto;
width: auto;
}
84 changes: 73 additions & 11 deletions ui/components/pages/chat.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ export class ChatComponent {
}),
CommonTemplates.profileCard(message.sender, cardShown),
).build()),
create("span")
.classes("message-timestamp", "text-small")
.text(Time.ago(localTimestamp))
.build(),
create("div")
.classes("message-content", "flex", "space-between", "full-width")
.oncontextmenu((e) => {
Expand All @@ -188,6 +192,11 @@ export class ChatComponent {
.children(
ifjs(menuShown, ChatComponent.messageMenu(message, messages, messageMenuPositionX, messageMenuPositionY)),
ChatComponent.reactionTrigger(message, messages),
ifjs(message.attachments.length > 0, create("div")
.classes("flex", "align-center", "attachments", "full-width")
.children(
message.attachments.map(attachment => ChatComponent.attachment(attachment)),
).build()),
create("div")
.classes("flex-v", "message-text")
.children(
Expand All @@ -203,12 +212,8 @@ export class ChatComponent {
.classes("message-note")
.text("edited " + Time.ago(new Date(message.updatedAt).getTime() + offset))
.build()),
create("span")
.classes("message-timestamp", "text-small")
.text(Time.ago(localTimestamp))
.build(),
).build(),
).build()
).build(),
).build();
}

Expand Down Expand Up @@ -387,10 +392,14 @@ export class ChatComponent {
for (const file of input.files) {
const reader = new FileReader();
reader.onload = () => {
const base64 = reader.result.split(',')[1];
let base64 = reader.result.split(',')[1];
if (base64.constructor.name === "Buffer") {
base64 = base64.toString("base64");
}
toBeSentAttachments.value = [...toBeSentAttachments.value, {
filename: file.name,
type: file.type,
data: file.type.startsWith("image") ? `data:${file.type};base64,${base64}` : null,
data: base64,
}];
};
reader.readAsDataURL(file);
Expand All @@ -404,13 +413,66 @@ export class ChatComponent {
return create("div")
.classes("flex-v", "align-center", "relative")
.children(
create("img")
.classes("attachment-preview-image")
.src(attachment.data)
.build(),
ChatComponent.attachmentPreviewContent(attachment),
CommonTemplates.smallIconButton("delete", "Delete", () => {
toBeSentAttachments.value = toBeSentAttachments.value.filter(a => a.filename !== attachment.filename);
}, ["attachment-remove-button"]),
).build();
}

static attachmentPreviewContent(attachment) {
let tag;
switch (attachment.type.split("/")[0]) {
case "image":
tag = "img";
break;
case "video":
tag = "video";
break;
case "audio":
tag = "audio";
break;
default:
tag = "div";
break;
}
return create(tag)
.classes(`attachment-preview-${attachment.type.split("/")[0]}`)
.src(`data:${attachment.type};base64,${attachment.data}`)
.build();
}

static attachment(attachment) {
const apiUrl = sessionStorage.getItem("apiUrl");
const url = apiUrl + `/attachments/${encodeURIComponent(attachment.messageId)}/${encodeURIComponent(attachment.filename)}`;
let tag;
switch (attachment.type.split("/")[0]) {
case "image":
tag = "img";
break;
case "video":
tag = "video";
break;
case "audio":
tag = "audio";
break;
default:
tag = "div";
break;
}
const isFullImage = signal(false);
const imageClass = computedSignal(isFullImage, isFull => isFull ? "full-image" : `attachment-${attachment.type.split("/")[0]}`);

return create("div")
.classes("attachment", attachment.type.split("/")[0])
.onclick(() => {
isFullImage.value = !isFullImage.value;
})
.children(
create("img")
.classes(imageClass)
.src(url)
.build()
).build();
}
}

0 comments on commit c8e4167

Please sign in to comment.