Skip to content
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
395 changes: 344 additions & 51 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "enhancer",
"module": "src/content/index.ts",
"type": "module",
"version": "5.1.16",
"version": "5.1.17",
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@preact/preset-vite": "^2.10.2",
Expand All @@ -13,7 +13,7 @@
"concurrently": "^9.1.2",
"husky": "^9.1.7",
"jszip": "^3.10.1",
"vite": "^7.0.5",
"vite": "^7.1.11",
"vite-plugin-generate-file": "^0.3.1",
"vite-tsconfig-paths": "^5.1.4"
},
Expand Down
1 change: 1 addition & 0 deletions public/assets/settings/experimental.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions src/platforms/kick/kick.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,5 @@ export const KICK_DEFAULT_SETTINGS: KickSettings = {
streamLatencyEnabled: true,
realVideoTimeEnabled: true,
realVideoTimeFormat12h: false,
channelSection: true,
};

export const KICK_LIVE_VIDEO_DURATION = 1073741824;
3 changes: 1 addition & 2 deletions src/platforms/kick/kick.utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { KICK_LIVE_VIDEO_DURATION } from "$kick/kick.constants.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";
Expand Down Expand Up @@ -110,6 +109,6 @@ export default class KickUtils {
}

isLiveVideo(video: HTMLVideoElement): boolean {
return video.duration === KICK_LIVE_VIDEO_DURATION;
return video.duration === Number.POSITIVE_INFINITY;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default class ChannelSectionModule extends KickModule {

readonly config: KickModuleConfig = {
name: "channel-info",
isModuleEnabledCallback: async () => this.settingsService().getSettingsKey("channelSection"),
appliers: [
{
type: "selector",
Expand Down
39 changes: 26 additions & 13 deletions src/platforms/kick/modules/settings/settings.module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,40 +50,53 @@ export default class SettingsModule extends KickModule {
title: "Channel",
iconUrl: await this.commonUtils().getAssetFile(this.workerService(), "settings/channel.svg"),
},
{
title: "Experimental",
iconUrl: await this.commonUtils().getAssetFile(this.workerService(), "settings/experimental.svg"),
},
{
title: "About",
iconUrl: await this.commonUtils().getAssetFile(this.workerService(), "settings/about.svg"),
},
];
] as const;
const tabIndexes = Object.fromEntries(this.SETTINGS_TABS.map((tab, index) => [tab.title, index]));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To improve type safety and leverage the as const assertion on SETTINGS_TABS, you can add a type assertion to tabIndexes. This will ensure that any typos when accessing tab indexes (e.g., tabIndexes.Genral) are caught at compile time.

Suggested change
const tabIndexes = Object.fromEntries(this.SETTINGS_TABS.map((tab, index) => [tab.title, index]));
const tabIndexes = Object.fromEntries(this.SETTINGS_TABS.map((tab, index) => [tab.title, index])) as Record<(typeof this.SETTINGS_TABS)[number]["title"], number>;

const brandIcons = {
website: await this.commonUtils().getAssetFile(this.workerService(), "brands/website.svg"),
github: await this.commonUtils().getAssetFile(this.workerService(), "brands/github.svg"),
twitter: await this.commonUtils().getAssetFile(this.workerService(), "brands/twitter.svg"),
discord: await this.commonUtils().getAssetFile(this.workerService(), "brands/discord.svg"),
};
} as const;
this.SETTING_DEFINITIONS = [
{
id: "streamLatencyEnabled",
title: "Enable Stream Latency",
description: "Shows the current stream delay on top of the chat.",
type: "toggle",
tabIndex: 0,
tabIndex: tabIndexes.General,
requiresRefreshToDisable: true,
},
{
id: "realVideoTimeEnabled",
title: "Enable Real Video Time",
description: "Displays the real-world time of the VOD.",
type: "toggle",
tabIndex: 0,
tabIndex: tabIndexes.General,
requiresRefreshToDisable: true,
},
{
id: "realVideoTimeFormat12h",
title: "Use 12-Hour Time Format",
description: "Display real video time in 12-hour format (AM/PM) instead of 24-hour format.",
type: "toggle",
tabIndex: 0,
tabIndex: tabIndexes.General,
},
{
id: "channelSection",
title: "Channel Section",
description: "Shows a section with watch time and quick access links.",
type: "toggle",
tabIndex: tabIndexes.General,
requiresRefreshToDisable: true,
},
{
id: "chatImagesEnabled",
Expand All @@ -93,21 +106,21 @@ export default class SettingsModule extends KickModule {
confirmOnEnable: true,
confirmationMessage:
"Enhancer is not responsible for the content of images sent in the chat by users. By enabling this option, you can see images in the chat that may not look good. We do not moderate them in any way, we simply display them. Are you sure you want to enable this option?",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatImagesOnHover",
title: "Show Images on Hover",
description: "Images are hidden until you hover your mouse to reveal them.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatImagesSize",
title: "Chat Image Size",
description: "Maximum size of images allowed in chat messages (in megabytes).",
type: "number",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
min: 1,
step: 1,
},
Expand All @@ -116,14 +129,14 @@ export default class SettingsModule extends KickModule {
title: "Enable Chat Badges",
description: "Show custom chat badges from Enhancer extension.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatNicknameCustomizationEnabled",
title: "Enable Nickname Customization",
description: "Show custom chat nickname customizations from Enhancer extension in chat.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
// {
// id: "chatMessageMenuEnabled",
Expand All @@ -137,7 +150,7 @@ export default class SettingsModule extends KickModule {
title: "Quick Access Links",
description: "Manage your quick access links with custom names and URLs",
type: "array",
tabIndex: 2,
tabIndex: tabIndexes.Channel,
arrayItemFields: [
{ name: "title", placeholder: "Enter link name..." },
{ name: "url", placeholder: "Enter URL..." },
Expand All @@ -148,7 +161,7 @@ export default class SettingsModule extends KickModule {
title: "Watchtime List",
description: "Watchtime List",
type: "text",
tabIndex: 2,
tabIndex: tabIndexes.Channel,
content: () => {
return <WatchtimeListComponent platform="kick" workerService={workerService} />;
},
Expand All @@ -159,7 +172,7 @@ export default class SettingsModule extends KickModule {
title: "About This Extension",
description: "Information about the extension",
type: "text",
tabIndex: 3,
tabIndex: tabIndexes.About,
content: () => {
return <EnhancerAboutComponent icons={brandIcons} />;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export default class StreamLatencyModule extends KickModule {
return;
}
this.setLive(true);
if (video.paused) return;
this.latencyCounter.value = this.computeLatency(video);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default class ChannelSectionModule extends TwitchModule {

readonly config: TwitchModuleConfig = {
name: "channel-info",
isModuleEnabledCallback: async () => this.settingsService().getSettingsKey("channelSection"),
appliers: [
{
type: "selector",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,7 @@ export default class PinStreamerModule extends TwitchModule {
private createPin(channelWrapper: Element) {
if (
channelWrapper.querySelector(".pin-streamer-button") ||
channelWrapper.querySelector(
'a[data-test-selector="similarity-channel"]',
) ||
channelWrapper.querySelector('a[data-test-selector="similarity-channel"]') ||
channelWrapper.querySelector(".side-nav-card__link--promoted-followed")
)
return;
Expand Down
53 changes: 33 additions & 20 deletions src/platforms/twitch/modules/settings/settings.module.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,40 +50,45 @@ export default class SettingsModule extends TwitchModule {
title: "Channel",
iconUrl: await this.commonUtils().getAssetFile(this.workerService(), "settings/channel.svg"),
},
{
title: "Experimental",
iconUrl: await this.commonUtils().getAssetFile(this.workerService(), "settings/experimental.svg"),
},
{
title: "About",
iconUrl: await this.commonUtils().getAssetFile(this.workerService(), "settings/about.svg"),
},
];
] as const;
const tabIndexes = Object.fromEntries(this.SETTINGS_TABS.map((tab, index) => [tab.title, index]));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To improve type safety and leverage the as const assertion on SETTINGS_TABS, you can add a type assertion to tabIndexes. This will ensure that any typos when accessing tab indexes (e.g., tabIndexes.Genral) are caught at compile time.

Suggested change
const tabIndexes = Object.fromEntries(this.SETTINGS_TABS.map((tab, index) => [tab.title, index]));
const tabIndexes = Object.fromEntries(this.SETTINGS_TABS.map((tab, index) => [tab.title, index])) as Record<(typeof this.SETTINGS_TABS)[number]["title"], number>;

const brandIcons = {
website: await this.commonUtils().getAssetFile(this.workerService(), "brands/website.svg"),
github: await this.commonUtils().getAssetFile(this.workerService(), "brands/github.svg"),
twitter: await this.commonUtils().getAssetFile(this.workerService(), "brands/twitter.svg"),
discord: await this.commonUtils().getAssetFile(this.workerService(), "brands/discord.svg"),
};
} as const;
this.SETTING_DEFINITIONS = [
{
id: "streamLatencyEnabled",
title: "Enable Stream Latency",
description: "Shows the current stream delay on top of the chat.",
type: "toggle",
tabIndex: 0,
tabIndex: tabIndexes.General,
requiresRefreshToDisable: true,
},
{
id: "realVideoTimeEnabled",
title: "Enable Real Video Time",
description: "Displays the real-world time of the VOD.",
type: "toggle",
tabIndex: 0,
tabIndex: tabIndexes.General,
requiresRefreshToDisable: true,
},
{
id: "pinnedStreamersEnabled",
title: "Enable Pinning Streamers",
description: "Allows you to pin your favorite streamers for easy access.",
type: "toggle",
tabIndex: 0,
tabIndex: tabIndexes.General,
requiresRefreshToDisable: true,
},
{
Expand All @@ -92,15 +97,23 @@ export default class SettingsModule extends TwitchModule {
description:
"Displays watchtime in usercards and via the /watchtime command for Polish channels by xayo.pl service.",
type: "toggle",
tabIndex: 0,
tabIndex: tabIndexes.General,
requiresRefreshToDisable: true,
},
{
id: "realVideoTimeFormat12h",
title: "12-Hour Time Format",
description: "Display real video time in 12-hour format (AM/PM) instead of 24-hour format.",
type: "toggle",
tabIndex: 0,
tabIndex: tabIndexes.General,
},
{
id: "channelSection",
title: "Channel Section",
description: "Shows a section with watch time and quick access links.",
type: "toggle",
tabIndex: tabIndexes.General,
requiresRefreshToDisable: true,
},
{
id: "chatImagesEnabled",
Expand All @@ -110,21 +123,21 @@ export default class SettingsModule extends TwitchModule {
confirmOnEnable: true,
confirmationMessage:
"Enhancer is not responsible for the content of images sent in the chat by users. By enabling this option, you can see images in the chat that may not look good. We do not moderate them in any way, we simply display them. Are you sure you want to enable this option?",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatImagesOnHover",
title: "Show Images on Hover",
description: "Images are hidden until you hover your mouse to reveal them.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatImagesSize",
title: "Chat Image Size",
description: "Maximum size of images allowed in chat messages (in megabytes).",
type: "number",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
min: 1,
step: 1,
},
Expand All @@ -133,44 +146,44 @@ export default class SettingsModule extends TwitchModule {
title: "Enable Chat Badges",
description: "Show custom chat badges from Enhancer extension.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatNicknameCustomizationEnabled",
title: "Enable Nickname Customization",
description: "Show custom chat nickname customizations from Enhancer extension in chat.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatMessageMenuEnabled",
title: "Enable Chat Message Menu",
description: "Show a menu with message options when you right-click a chat message.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatMessageMenuUseAddInsteadOfSet",
title: "Appending Content via Chat Message Menu",
description:
"When using the chat message menu, new content will be added to the message in chat input instead of replacing it.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatMentionSoundEnabled",
title: "Enable Chat Mention Sound",
description: "Turn on to receive a sound notification when someone mentions you in chat.",
type: "toggle",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatMentionSoundSource",
title: "Custom Mention Sound URL",
description:
"Set a custom audio file to play when you are mentioned in chat. Leave it empty for default sound.",
type: "input",
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "chatMentionSoundVolume",
Expand All @@ -180,15 +193,15 @@ export default class SettingsModule extends TwitchModule {
min: 0,
max: 100,
step: 1,
tabIndex: 1,
tabIndex: tabIndexes.Chat,
},
{
id: "quickAccessLinks",
title: "Quick Access Links",
description:
"Manage your quick access links. Use %username% in the URL to dynamically include the streamer's name.",
type: "array",
tabIndex: 2,
tabIndex: tabIndexes.Channel,
arrayItemFields: [
{ name: "title", placeholder: "Enter link name..." },
{ name: "url", placeholder: "Enter URL..." },
Expand All @@ -199,7 +212,7 @@ export default class SettingsModule extends TwitchModule {
title: "Watchtime List",
description: "Watchtime List",
type: "text",
tabIndex: 2,
tabIndex: tabIndexes.Channel,
content: () => {
return <WatchtimeListComponent platform="twitch" workerService={workerService} />;
},
Expand All @@ -210,7 +223,7 @@ export default class SettingsModule extends TwitchModule {
title: "About This Extension",
description: "Information about the extension",
type: "text",
tabIndex: 3,
tabIndex: tabIndexes.About,
content: () => {
return <EnhancerAboutComponent icons={brandIcons} />;
},
Expand Down
1 change: 1 addition & 0 deletions src/platforms/twitch/twitch.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export const TWITCH_DEFAULT_SETTINGS: TwitchSettings = {
realVideoTimeFormat12h: false,
pinnedStreamersEnabled: true,
xayoWatchtimeEnabled: true,
channelSection: true,
};
Loading