Skip to content
9 changes: 4 additions & 5 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"organizeImports": {
"enabled": true
},
"$schema": "https://biomejs.dev/schemas/2.3.10/schema.json",
"assist": { "actions": { "source": { "organizeImports": "on" } } },
"linter": {
"enabled": true,
"rules": {
Expand All @@ -28,6 +26,7 @@
"lineWidth": 120
},
"files": {
"ignore": ["node_modules", "dist/**", "README.md"]
"ignoreUnknown": false,
"includes": ["src/**/*.ts", "src/**/*.tsx"]
}
}
16 changes: 12 additions & 4 deletions src/platforms/kick/kick.module.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
import type { Emitter } from "nanoevents";
import type KickApi from "$kick/apis/kick.api.ts";
import type KickUtils from "$kick/kick.utils.ts";
import type EnhancerApi from "$shared/apis/enhancer.api.ts";
import Module from "$shared/module/module.ts";
import type CommonDataService from "$shared/settings/common.service.ts";
import type SettingsService from "$shared/settings/settings.service.ts";
import type SharedStorageDataService from "$shared/settings/shared-storage.service.ts";
import type StorageRepository from "$shared/storage/storage-repository.ts";
import type UtilsRepository from "$shared/utils/utils.repository.ts";
import type WorkerService from "$shared/worker/worker.service.ts";
import type { KickEvents } from "$types/platforms/kick/kick.events.types.ts";
import type { KickSettings } from "$types/platforms/kick/kick.settings.types.ts";
import type { KickStorage } from "$types/platforms/kick/kick.storage.types.ts";
import type { Emitter } from "nanoevents";

export default abstract class KickModule extends Module<KickEvents, KickStorage, KickSettings> {
constructor(
emitter: Emitter<KickEvents>,
storageRepository: StorageRepository<KickStorage>,
settingsService: SettingsService<KickSettings>,
commonDataService: CommonDataService,
sharedStorageDataService: SharedStorageDataService,
utilsRepository: UtilsRepository,
enhancerApi: EnhancerApi,
workerApi: WorkerService,
private readonly _kickUtils: KickUtils,
private readonly _kickApi: KickApi,
) {
super(emitter, storageRepository, settingsService, commonDataService, utilsRepository, enhancerApi, workerApi);
super(
emitter,
storageRepository,
settingsService,
sharedStorageDataService,
utilsRepository,
enhancerApi,
workerApi,
);
}

protected kickUtils() {
Expand Down
8 changes: 5 additions & 3 deletions src/platforms/kick/kick.platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ import type KickModule from "$kick/kick.module.ts";
import KickUtils from "$kick/kick.utils.ts";
import AdditionalFontsModule from "$kick/modules/additional-fonts/additional-fonts.module.tsx";
import ChannelSectionModule from "$kick/modules/channel-section/channel-section.module.tsx";
import ChatModule from "$kick/modules/chat/chat.module.ts";
import ChatAttachmentsModule from "$kick/modules/chat-attachments/chat-attachments.module.ts";
import ChatBadgesModule from "$kick/modules/chat-badges/chat-badges.module.tsx";
import ChatFixAutoScrollModule from "$kick/modules/chat-fix-auto-scroll/chat-fix-auto-scroll.module.tsx";
import ChatHighlightUserModule from "$kick/modules/chat-highlight-user/chat-highlight-user.module.tsx";
import ChatMessagePopupModule from "$kick/modules/chat-message-popup/chat-message-popup.module.tsx";
import ChatNicknameCustomizationModule from "$kick/modules/chat-nickname-customization/chat-nickname-customization.module.ts";
import ChatModule from "$kick/modules/chat/chat.module.ts";
import LocalWatchtimeCounterModule from "$kick/modules/local-watchtime-counter/local-watchtime-counter.module.tsx";
import RealVideoTimeModule from "$kick/modules/real-video-time/real-video-time.module.tsx";
import SettingsButtonModule from "$kick/modules/settings-button/settings-button.module.tsx";
import SettingsModule from "$kick/modules/settings/settings.module.tsx";
import SettingsButtonModule from "$kick/modules/settings-button/settings-button.module.tsx";
import SharedFollowsModule from "$kick/modules/shared-follows/shared-follows.module.tsx";
import StreamLatencyModule from "$kick/modules/stream-latency/stream-latency.module.tsx";
import TwitchStreamsModule from "$kick/modules/twitch-streams/twitch-streams.module.tsx";
import Platform from "$shared/platform/platform.ts";
import type { KickEvents } from "$types/platforms/kick/kick.events.types.ts";
import type { KickSettings } from "$types/platforms/kick/kick.settings.types.ts";
Expand All @@ -34,7 +35,7 @@ export default class KickPlatform extends Platform<KickModule, KickEvents, KickS
this.emitter,
this.storageRepository,
this.settingsService,
this.commonDataService,
this.sharedStorageDataService,
this.utilsRepository,
this.enhancerApi,
this.workerApi,
Expand All @@ -58,6 +59,7 @@ export default class KickPlatform extends Platform<KickModule, KickEvents, KickS
// new ChatMessageMenuModule(...dependencies),
new AdditionalFontsModule(...dependencies),
new ChatFixAutoScrollModule(...dependencies),
new TwitchStreamsModule(...dependencies),
new SharedFollowsModule(...dependencies),
];
}
Expand Down
10 changes: 8 additions & 2 deletions src/platforms/kick/kick.utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import type CommonUtils from "$shared/utils/common.utils.ts";
import type ReactUtils from "$shared/utils/react.utils.ts";
import type { KickChatMessageData } from "$types/platforms/kick/kick.events.types.ts";
import type { IsoDateProps, StreamStatusProps, VideoProgressProps } from "$types/platforms/kick/kick.utils.types.ts";
import type { ChannelChatRoom, ChannelChatRoomInfo, ChannelInfo } from "$types/platforms/kick/kick.utils.types.ts";
import type {
ChannelChatRoom,
ChannelChatRoomInfo,
ChannelInfo,
IsoDateProps,
StreamStatusProps,
VideoProgressProps,
} from "$types/platforms/kick/kick.utils.types.ts";

export default class KickUtils {
constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { type Signal, signal } from "@preact/signals";
import { render } from "preact";
import KickModule from "$kick/kick.module.ts";
import { ChannelSectionComponent } from "$shared/components/channel-section/channel-section.component.tsx";
import type { QuickAccessLink } from "$types/shared/components/settings.component.types.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";
import { type Signal, signal } from "@preact/signals";
import { render } from "preact";
import styled from "styled-components";

export default class ChannelSectionModule extends KickModule {
private quickAccessLinks = {} as Signal<QuickAccessLink[]>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ 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 ImageChatAttachmentHandler from "$shared/module/chat-attachments/image-chat-attachment-handler.ts";
import { ImageChatAttachmentConfig } from "$shared/module/chat-attachments/image-chat-attachment.config.ts";
import ImageChatAttachmentHandler from "$shared/module/chat-attachments/image-chat-attachment-handler.ts";
import type { KickChatMessageEvent } from "$types/platforms/kick/kick.events.types.ts";
import {
type BaseChatAttachmentData,
Expand Down Expand Up @@ -113,7 +113,11 @@ export default class ChatAttachmentsModule extends KickModule {
const attachmentData = await this.getAttachmentData(baseData.url);
if (!attachmentData?.type || !attachmentData?.size || attachmentData === undefined)
throw new Error("Couldn't get attachment data");
return { ...baseData, attachmentType: attachmentData.type, attachmentSize: Number.parseInt(attachmentData.size) };
return {
...baseData,
attachmentType: attachmentData.type,
attachmentSize: Number.parseInt(attachmentData.size, 10),
};
}

private async getAttachmentData(url: URL) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { render } from "preact";
import KickModule from "$kick/kick.module.ts";
import { BadgeComponent } from "$shared/components/badge/badge.component.tsx";
import { TooltipComponent } from "$shared/components/tooltip/tooltip.component.tsx";
import type { KickChatMessageEvent } from "$types/platforms/kick/kick.events.types.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";
import { render } from "preact";

export default class ChatBadgesModule extends KickModule {
config: KickModuleConfig = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import KickModule from "$kick/kick.module.ts";
import { BadgeComponent } from "$shared/components/badge/badge.component.tsx";
import { TooltipComponent } from "$shared/components/tooltip/tooltip.component.tsx";
import type { KickChatMessageEvent } from "$types/platforms/kick/kick.events.types.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";
import { render } from "preact";

export default class ChatFixAutoScrollModule extends KickModule {
config: KickModuleConfig = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { render } from "preact";
import KickModule from "$kick/kick.module.ts";
import {
MessageMenuComponent,
type MessageMenuEvent,
} from "$shared/components/message-menu/message-menu.component.tsx";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";
import { h, render } from "preact";

export default class MessageMenuModule extends KickModule {
config: KickModuleConfig = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import KickModule from "$kick/kick.module.ts";
import TwitchModule from "$twitch/twitch.module.ts";
import type { ChatMessagePopupEvent } from "$types/platforms/twitch/twitch.events.types.ts";
import type { KickModuleConfig, TwitchModuleConfig } from "$types/shared/module/module.types.ts";
import { h, render } from "preact";
import { render } from "preact";
import { useEffect, useRef, useState } from "preact/hooks";
import styled from "styled-components";
import KickModule from "$kick/kick.module.ts";
import type { ChatMessagePopupEvent } from "$types/platforms/twitch/twitch.events.types.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";

export default class ChatMessagePopupModule extends KickModule {
config: KickModuleConfig = {
Expand Down
9 changes: 6 additions & 3 deletions src/platforms/kick/modules/chat/chat.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,12 @@ export default class ChatModule extends KickModule {
private observer: MutationObserver | undefined;

private async run([chatRoom]: Element[]): Promise<void> {
[...chatRoom.querySelectorAll(".ntv__chat-message"), ...chatRoom.querySelectorAll("div[data-index]")].forEach(
(message) => this.handleMessage(message),
);
for (const message of [
...chatRoom.querySelectorAll(".ntv__chat-message"),
...chatRoom.querySelectorAll("div[data-index]"),
]) {
this.handleMessage(message);
}
await this.initializeChannel();
this.createObserver(chatRoom);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import KickModule from "$kick/kick.module.ts";
import { VideoCreatedAtQuery } from "$twitch/apis/twitch-queries.ts";
import TwitchModule from "$twitch/twitch.module.ts";
import type { VideoCreatedAtResponse } from "$types/platforms/twitch/twitch.api.types.ts";
import type { MediaPlayerInstance } from "$types/platforms/twitch/twitch.utils.types.ts";
import type { KickModuleConfig, TwitchModuleConfig } from "$types/shared/module/module.types.ts";
import { type Signal, signal } from "@preact/signals";
import { render } from "preact";
import styled from "styled-components";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";

export default class LocalWatchtimeCounterModule extends KickModule {
config: KickModuleConfig = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import KickModule from "$kick/kick.module.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";
import { type Signal, signal } from "@preact/signals";
import { render } from "preact";
import styled from "styled-components";
import KickModule from "$kick/kick.module.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";

export default class RealVideoTimeModule extends KickModule {
config: KickModuleConfig = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import KickModule from "$kick/kick.module.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";
import { render } from "preact";
import styled from "styled-components";
import KickModule from "$kick/kick.module.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";

export default class SettingsButtonModule extends KickModule {
readonly config: KickModuleConfig = {
Expand Down
4 changes: 2 additions & 2 deletions src/platforms/kick/modules/settings/settings.module.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { type Signal, signal } from "@preact/signals";
import { render } from "preact";
import { KICK_DEFAULT_SETTINGS } from "$kick/kick.constants.ts";
import KickModule from "$kick/kick.module.ts";
import { ExportImportComponent } from "$shared/components/export-import/export-import.component.tsx";
Expand All @@ -7,8 +9,6 @@ import { WatchtimeListComponent } from "$shared/components/watchtime-list/watcht
import type { KickSettings } from "$types/platforms/kick/kick.settings.types.ts";
import type { SettingDefinition, TabDefinition } from "$types/shared/components/settings.component.types.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";
import { type Signal, signal } from "@preact/signals";
import { render } from "preact";

export default class SettingsModule extends KickModule {
config: KickModuleConfig = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HttpClient } from "$shared/http/http-client.ts";
import FollowSyncer from "$shared/module/shared-follows/follow-syncer.ts";
import type CommonDataService from "$shared/settings/common.service.ts";
import type SharedStorageDataService from "$shared/settings/shared-storage.service.ts";
import type CommonUtils from "$shared/utils/common.utils.ts";
import type { FollowedChannelsResponse } from "$types/platforms/kick/kick.api.types.ts";

Expand All @@ -9,7 +9,7 @@ export default class KickFollowSyncer extends FollowSyncer {
private syncInProgress = false;

constructor(
private readonly commonDataService: CommonDataService,
private readonly sharedStorageDataService: SharedStorageDataService,
private readonly commonUtils: CommonUtils,
) {
super("kick");
Expand All @@ -23,7 +23,7 @@ export default class KickFollowSyncer extends FollowSyncer {
this.syncInProgress = true;
try {
const followed = await this.fetchAllFollowed();
await this.commonDataService.updateCommonNestedKey("sharedFollows", "kick", followed);
await this.sharedStorageDataService.updateStorageNestedKey("sharedFollows", "kick", followed);
this.logger.info(`Synced ${followed.length} followed channels`);
} catch (err) {
this.logger.error("Failed to sync follows", err);
Expand All @@ -33,7 +33,7 @@ export default class KickFollowSyncer extends FollowSyncer {
}

async clearFollows() {
await this.commonDataService.updateCommonNestedKey("sharedFollows", "kick", []);
await this.sharedStorageDataService.updateStorageNestedKey("sharedFollows", "kick", []);
}

private async fetchAllFollowed(): Promise<string[]> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import KickFollowSyncer from "$kick/modules/shared-follows/kick.follow-syncer.ts
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";

export default class SharedFollowsModule extends KickModule {
private readonly kickFollowsSyncer = new KickFollowSyncer(this.commonDataService(), this.commonUtils());
private static readonly SYNC_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes - centralized sync interval
private readonly kickFollowsSyncer = new KickFollowSyncer(this.sharedStorageDataService(), this.commonUtils());

config: KickModuleConfig = {
name: "shared-follows",
Expand Down Expand Up @@ -32,7 +33,10 @@ export default class SharedFollowsModule extends KickModule {

private async startSyncTimer() {
this.stopSyncTimer();
this.syncFollowsTimer = setInterval(() => this.kickFollowsSyncer.getFollows(), 120000); // 2 mins
this.syncFollowsTimer = setInterval(
() => this.kickFollowsSyncer.getFollows(),
SharedFollowsModule.SYNC_INTERVAL_MS,
);
await this.kickFollowsSyncer.getFollows();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { signal } from "@preact/signals";
import { render } from "preact";
import KickModule from "$kick/kick.module.ts";
import { LatencyComponent } from "$shared/components/latency/latency.component.tsx";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";
import { signal } from "@preact/signals";
import { render } from "preact";

export default class StreamLatencyModule extends KickModule {
private latencyCounter = signal(-1);
Expand Down
Loading
Loading