Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import KickModule from "$kick/kick.module.ts";
import { ImagePreview } from "$shared/components/image-preview/image-preview.component";
import { HttpClient } from "$shared/http/http-client.ts";
import type ChatAttachmentHandler from "$shared/module/chat-attachments/chat-attachment-handler.ts";
import EmotesChatAttachmentHandler from "$shared/module/chat-attachments/emotes-chat-attachment-handler";
import ImageChatAttachmentHandler from "$shared/module/chat-attachments/image-chat-attachment-handler.ts";
import { ImageChatAttachmentConfig } from "$shared/module/chat-attachments/image-chat-attachment.config.ts";
import type { KickChatMessageEvent } from "$types/platforms/kick/kick.events.types.ts";
Expand Down Expand Up @@ -65,6 +66,7 @@ export default class ChatAttachmentsModule extends KickModule {

private readonly chatAttachmentHandlers: ChatAttachmentHandler[] = [
new ImageChatAttachmentHandler(this.logger, this.imageAttachmentConfig),
new EmotesChatAttachmentHandler(this.logger),
];

private async handleMessage(message: KickChatMessageEvent) {
Expand Down Expand Up @@ -126,11 +128,9 @@ export default class ChatAttachmentsModule extends KickModule {

private async getAttachmentData(url: URL) {
try {
const { response } = await this.httpClient.request(url.href, {
method: "HEAD",
responseType: "text",
});
return { type: response.headers.get("Content-Type"), size: response.headers.get("Content-Length") };
const { response } = await this.httpClient.request(url.href);

return { type: response.headers.get("Content-Type"), size: "10" };
} catch (error) {
this.logger.warn("Couldn't get attachment data", error);
}
Expand Down
16 changes: 16 additions & 0 deletions src/shared/components/emote-preview/emote-preview.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import styled from "styled-components";

export const EmotePreview = (src?: string) => {
return (
<Wrapper>
<div>Test Test Test.</div>
</Wrapper>
);
};

const Wrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import type { Logger } from "$shared/logger/logger.ts";
import type {
BaseChatAttachmentData,
ChatAttachmentData,
} from "$types/shared/module/chat-attachment/chat-attachment.types.ts";
import ChatAttachmentHandler from "./chat-attachment-handler";

export default class EmotesChatAttachmentHandler extends ChatAttachmentHandler {
constructor(protected readonly logger: Logger) {
super(logger);
}

static readonly ALLOWED_HOSTS = ["7tv.app", "old.7tv.app"];

validate(baseData: BaseChatAttachmentData): boolean {
return EmotesChatAttachmentHandler.ALLOWED_HOSTS.some((host) => baseData.url.host === host);
}

async applies(data: ChatAttachmentData): Promise<boolean> {
return true;
// throw new Error("Not implemented");
}

parseUrl(url: URL): URL {
// INPUT: https://7tv.app/emotes/01F6MDFCSR0000WDA7ERT623YT
// OUTPUT: https://7tv.io/v3/emotes/01F6MDFCSR0000WDA7ERT623YT
// TODO: Parse only single emotes for now

url.host = "7tv.io";
url.pathname = `/v3${url.pathname}`;

return url;
}

async handle(data: ChatAttachmentData) {
// ! Temporary, as alternative for not supported emote data fetching
const emoteData = await (await fetch(data.url.href)).json();

const element = data.messageElement as HTMLLinkElement;

element.classList.add("enhancer-emote-link");

const wrapper = document.createElement("div");
element.replaceChildren(wrapper);
wrapper.style.backgroundColor = "grey";
wrapper.style.borderRadius = "4px";
wrapper.style.padding = "8px";
wrapper.style.display = "flex";
wrapper.style.flexDirection = "row";
wrapper.style.gap = "8px";
wrapper.style.textDecoration = "none";

const emotePreview = document.createElement("img");
emotePreview.src = `https://cdn.7tv.app/emote/${emoteData.id}/${emoteData.host.files[0].name}`;
emotePreview.style.width = "48px";
emotePreview.style.height = "48px";
wrapper.append(emotePreview);

const emoteDataWrapper = document.createElement("div");
emoteDataWrapper.style.display = "flex";
emoteDataWrapper.style.flexDirection = "column";
emoteDataWrapper.style.justifyContent = "space-between";
wrapper.append(emoteDataWrapper);

const emoteName = document.createElement("span");
emoteName.textContent = emoteData.name || "Emote Name";
emoteName.style.color = "white";
emoteName.style.textDecoration = "none";
emoteDataWrapper.append(emoteName);

const emoteAuthor = document.createElement("span");
emoteAuthor.textContent = `Created by ${emoteData.owner.username || "unknown"}`;
emoteAuthor.style.color = "white";
emoteAuthor.style.textDecoration = "none";
emoteDataWrapper.append(emoteAuthor);
}
}