Skip to content

feat: shared followers - #85

Open
maksPodstawski wants to merge 21 commits into
masterfrom
feat/kick-streamers
Open

feat: shared followers#85
maksPodstawski wants to merge 21 commits into
masterfrom
feat/kick-streamers

Conversation

@maksPodstawski

@maksPodstawski maksPodstawski commented Aug 18, 2025

Copy link
Copy Markdown
Member

Description

Briefly explain what this PR does. Is it a bug fix, new feature, or a refactor?

Testing

Select all the environments you tested this PR with:

  • BetterTTV (BTTV)
  • FrankerFaceZ (FFZ)
  • 7TV
  • Native Twitch

Please describe how you tested this change in the selected environments.

Related Issues

If this PR addresses an issue, link it here (e.g., Closes #123).

Description by Callstackai

This PR introduces a new feature that allows sharing followed channels across platforms, specifically between Twitch and Kick. It includes the implementation of follow synchronization and settings for enabling/disabling this feature.

Diagrams of code changes
sequenceDiagram
    participant User
    participant Platform
    participant SharedFollowsModule
    participant FollowSyncer
    participant CommonDataService
    participant WorkerService
    participant CommonDatabase

    User->>Platform: Enable follow sharing
    Platform->>SharedFollowsModule: Initialize module
    SharedFollowsModule->>FollowSyncer: Start sync timer
    
    loop Every few minutes
        FollowSyncer->>Platform: Get followed channels
        Platform-->>FollowSyncer: Return channel list
        FollowSyncer->>CommonDataService: Update shared follows
        CommonDataService->>WorkerService: Send update request
        WorkerService->>CommonDatabase: Store follows data
        CommonDatabase-->>WorkerService: Confirm storage
        WorkerService-->>CommonDataService: Return success
    end

    Note over Platform,CommonDatabase: Follows are now shared between platforms
    
    User->>Platform: View follows from other platform
    Platform->>CommonDataService: Request shared follows
    CommonDataService->>WorkerService: Get common data
    WorkerService->>CommonDatabase: Retrieve follows
    CommonDatabase-->>WorkerService: Return follows data
    WorkerService-->>CommonDataService: Return data
    CommonDataService-->>Platform: Return follows list
    Platform-->>User: Display combined follows
Loading
Files Changed
FileSummary
src/platforms/kick/kick.constants.tsAdded new settings for sharing and showing follows from other platforms.
src/platforms/kick/kick.module.tsUpdated the constructor to include CommonDataService.
src/platforms/kick/kick.platform.tsImported and initialized SharedFollowsModule.
src/platforms/kick/modules/settings/settings.module.tsxAdded new settings definitions for sharing and showing follows.
src/platforms/kick/modules/shared-follows/kick.follow-syncer.tsImplemented follow synchronization logic for Kick.
src/platforms/kick/modules/shared-follows/shared-follows.module.tsxCreated SharedFollowsModule to manage follow synchronization.
src/platforms/twitch/twitch.constants.tsAdded new settings for sharing and showing follows from other platforms.
src/platforms/twitch/twitch.module.tsUpdated the constructor to include CommonDataService.
src/platforms/twitch/modules/settings/settings.module.tsxAdded new settings definitions for sharing and showing follows.
src/platforms/twitch/modules/shared-follows/shared-follows.module.tsxCreated SharedFollowsModule to manage follow synchronization.

@callstackai callstackai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Key Issues

The code lacks proper error handling, with empty catch blocks and missing try-catch wrappers for async operations, risking unhandled errors and application crashes. Unsafe type assertions and null handling could lead to runtime errors if the response structure is unexpected. There is a logic error in data labeling, where Twitch data is incorrectly marked as Kick data, potentially causing data misinterpretation.

try {
const kick = await this.commonUtils().getAssetFile(this.workerService(), "brands/kick.svg");
this.platformIcons = { kick };
} catch {}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐛 Possible Bug
The empty catch block silently ignores any errors that occur while loading platform icons. This makes it difficult to diagnose issues if the icon fails to load. The error should be logged to help with debugging.

Suggested change
} catch {}
} catch (error) { this.logger.warn('Failed to load Kick platform icon', error); }

Comment on lines +39 to +40
await this.loadStreamersFromCommon();
await this.refreshStatuses();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐛 Possible Bug
The calls to loadStreamersFromCommon() and refreshStatuses() are not wrapped in try-catch blocks. If these async operations fail, they will result in unhandled promise rejections that could crash the application.

Suggested change
await this.loadStreamersFromCommon();
await this.refreshStatuses();
try {
await this.loadStreamersFromCommon();
await this.refreshStatuses();
} catch (error) {
this.logger.error('Failed to initialize Kick streamers module', error);
}

private async loadStreamersFromCommon(): Promise<void> {
try {
const res = await this.workerService().send("getCommon", { platform: "twitch", key: "kickStreamers" });
const value = (res && (res as { value: unknown | null }).value) as unknown;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐛 Possible Bug
The type assertion and null handling for the response from workerService().send() is unsafe. The code assumes the response will have a value property without proper validation. If res is null or doesn't match the expected structure, the type assertion could cause runtime errors.

Suggested change
const value = (res && (res as { value: unknown | null }).value) as unknown;
const value = res?.value ?? null;

Comment on lines +24 to +28
await this.workerService().send("setCommon", {
platform: "kick",
key: COMMON_KEYS.kick.twitchStreamers,
value: twitchFollowList,
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐛 Possible Bug
The code is storing Twitch follow list data but setting the platform as 'kick'. This appears to be a logic error as the data source is from Twitch but is being labeled as Kick data.

Suggested change
await this.workerService().send("setCommon", {
platform: "kick",
key: COMMON_KEYS.kick.twitchStreamers,
value: twitchFollowList,
});
await this.workerService().send("setCommon", {
platform: "twitch",
key: COMMON_KEYS.kick.twitchStreamers,
value: twitchFollowList,
});

headers: { Authorization: authorization },
credentials: "include",
});
if (!res.ok) break;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🐛 Possible Bug
The code breaks the loop on any non-OK response (!res.ok) without checking the specific error. This could mask important API errors like rate limiting or auth issues, leading to incomplete data collection.

Suggested change
if (!res.ok) break;
if (!res.ok) throw new Error(`API request failed with status ${res.status}`);

@igorovh igorovh changed the title Feat/kick streamers feat/enhanced-follow-list Aug 18, 2025

@callstackai callstackai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Key Issues

The PR review highlights critical issues including the failure to create necessary database indexes during version upgrades, leading to an invalid database state; unchecked access to potentially undefined properties causing runtime errors; and a performance regression due to sequential data fetching instead of concurrent requests.

Comment thread src/shared/settings/common.service.ts Outdated
Co-authored-by: callstackai[bot] <186726322+callstackai[bot]@users.noreply.github.com>

@callstackai callstackai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Key Issues

The error handling logic is flawed as it does not differentiate between common being null or undefined and common.data being absent, potentially leading to misleading error messages.

Comment thread src/shared/settings/common.service.ts Outdated
igorovh and others added 2 commits August 23, 2025 20:17
Co-authored-by: callstackai[bot] <186726322+callstackai[bot]@users.noreply.github.com>
@igorovh
igorovh changed the base branch from master to dev October 27, 2025 22:21
@igorovh
igorovh changed the base branch from dev to master October 29, 2025 22:01
Copilot AI review requested due to automatic review settings December 29, 2025 23:02
@igorovh

igorovh commented Dec 29, 2025

Copy link
Copy Markdown
Member

@copilot

  1. i dont like how common data is named and how it work, could you refactor this?
  2. refactor how follow syncs are working, it should be one module which runs every like idk STATIC_VALUE on top
  3. then we need to move refreshStatuses from these commented files to the background script, there should be also rate limit how much often we can refresh these streamers
  4. create simple ui from currnet commented componenets

Copilot AI commented Dec 29, 2025

Copy link
Copy Markdown
Contributor

@igorovh I've opened a new pull request, #126, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a cross-platform follow sharing feature that allows users to synchronize and view their followed channels between Twitch and Kick platforms. The implementation includes a new common database for storing shared data, follow synchronization mechanisms for both platforms, and user-facing settings to control the feature.

Key Changes

  • Implemented a common database infrastructure using IndexedDB to store shared data across platforms
  • Added follow synchronization modules for both Twitch and Kick that periodically sync followed channels
  • Introduced two new settings per platform: one to share follows to other platforms and another to show follows from other platforms

Reviewed changes

Copilot reviewed 36 out of 40 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
src/types/shared/worker/worker.types.ts Added getCommonData and setCommonData worker API actions with corresponding payload/response types
src/types/shared/storage/common-database.types.ts Defined CommonDatabaseData type structure for storing shared follows across platforms
src/types/platforms/twitch/twitch.settings.types.ts Added shareFollowsToOtherPlatforms and showFollowsFromOtherPlatforms settings
src/types/platforms/twitch/twitch.api.types.ts Added TwitchChannelNode and TwitchMultiChannelResponse types for GraphQL channel queries
src/types/platforms/twitch/twitch.utils.types.ts Defined KickStreamerInfo and StreamerInfo types for cross-platform streamer data
src/types/platforms/kick/kick.settings.types.ts Added shareFollowsToOtherPlatforms and showFollowsFromOtherPlatforms settings
src/types/platforms/kick/kick.api.types.ts Enhanced type definitions with detailed interfaces for channel responses and follow data
src/types/platforms/kick/kick.utils.types.ts Added imports and duplicate streamer info types
src/shared/worker/worker.background.ts Integrated CommonService into the worker initialization and handler registry
src/shared/worker/handler.registry.ts Registered getCommonData and setCommonData handlers
src/shared/worker/common/set-common-data.handler.ts Implemented handler for setting common database data
src/shared/worker/common/get-common-data.handler.ts Implemented handler for retrieving common database data
src/shared/worker/common/common.service.ts Created service layer for common data operations
src/shared/worker/common/common.database.ts Implemented IndexedDB wrapper for persistent common data storage
src/shared/worker/common/common-database.constants.ts Defined default structure for common database
src/shared/utils/common.utils.ts Added getCookie utility method for reading browser cookies
src/shared/settings/common.service.ts Created CommonDataService for content scripts to interact with common data
src/shared/platform/platform.ts Instantiated CommonDataService in base Platform class
src/shared/module/shared-follows/follow-syncer.ts Created abstract base class for platform-specific follow synchronization
src/shared/module/module.ts Added commonDataService accessor to base Module class
src/platforms/twitch/twitch.utils.ts Added getUserFollowList method to extract followed channels from UI components
src/platforms/twitch/twitch.platform.ts Integrated SharedFollowsModule and passed commonDataService to modules
src/platforms/twitch/twitch.module.ts Updated constructor to accept and pass commonDataService
src/platforms/twitch/twitch.constants.ts Set default values for new follow sharing settings
src/platforms/twitch/modules/shared-follows/twitch.follow-syncer.ts Implemented Twitch-specific follow synchronization logic
src/platforms/twitch/modules/shared-follows/shared-follows.module.tsx Created module to manage Twitch follow sync timer and settings
src/platforms/twitch/modules/settings/settings.module.tsx Added UI definitions for new follow sharing settings
src/platforms/twitch/modules/kick-streamers/kick-streamers.module.tsx Commented-out module for displaying Kick streamers on Twitch
src/platforms/twitch/modules/expose-follows/expose-follows.module.tsx Commented-out alternative implementation for exposing follows
src/platforms/kick/modules/twitch-streams/twitch-streams.module.tsx Commented-out module for displaying Twitch streams on Kick
src/platforms/kick/modules/shared-follows/shared-follows.module.tsx Created module to manage Kick follow sync timer and settings
src/platforms/kick/modules/shared-follows/kick.follow-syncer.ts Implemented Kick-specific follow synchronization using API calls
src/platforms/kick/modules/settings/settings.module.tsx Added UI definitions for new follow sharing settings
src/platforms/kick/kick.platform.ts Integrated SharedFollowsModule and passed commonDataService to modules
src/platforms/kick/kick.module.ts Updated constructor to accept and pass commonDataService
src/platforms/kick/kick.constants.ts Set default values for new follow sharing settings
public/assets/brands/twitch.svg Added Twitch brand SVG icon
public/assets/brands/twitch.png Added Twitch brand PNG icon
public/assets/brands/kick.svg Added Kick brand SVG icon

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1 to +6
export type CommonDatabaseData = {
sharedFollows: {
twitch: string[];
kick: string[];
};
};

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The CommonDatabaseData type only contains sharedFollows with twitch and kick platforms. This design is not easily extensible if more platforms need to be added in the future. Consider using a more flexible structure like Record<string, string[]> or documenting the plan for adding additional platforms.

Copilot uses AI. Check for mistakes.
Comment thread src/types/shared/worker/worker.types.ts Outdated
Comment on lines +88 to +90
// @ts-ignore its okay here
// biome-ignore lint/complexity/noBannedTypes: it's okay here
export type GetCommonDataPayload = {};

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The ts-ignore and biome-ignore comments suggest that an empty object type is being used intentionally. However, using an empty object type {} is generally not recommended. Consider using Record<string, never> for a truly empty object, or simply omit the payload type if no payload is needed (similar to how the ping action is defined with payload?: never on line 105).

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +42
type TwitchStreamerInfo = {
username: string;
isLive: boolean;
game: string | null;
avatar: string | null;
url: string;
viewerCount: number;
};

type StreamerInfo = TwitchStreamerInfo & { platform: string };

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The type definitions TwitchStreamerInfo and StreamerInfo are defined here but appear to be unused in this file. These types duplicate the same types defined in twitch.utils.types.ts. Consider removing these duplicate type definitions and importing them from the appropriate file if needed.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +3
import KickModule from "$kick/kick.module.ts";
import type { KickModuleConfig } from "$types/shared/module/module.types.ts";

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The imports at the top of this file (KickModule and KickModuleConfig) appear to be unused since the entire file is commented out. If this file is intended to remain commented out for future use, consider removing these imports or adding a comment explaining why they're present.

Copilot uses AI. Check for mistakes.

private getAuthHeader(): string | undefined {
const token = this.commonUtils.getCookie("session_token");
if (!token) return;

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The authorization token is retrieved from cookies without any validation or error handling. If the session_token cookie is missing, undefined is returned and the sync silently fails. Consider logging a more informative message when the token is missing to help users understand why follow syncing isn't working.

Suggested change
if (!token) return;
if (!token) {
this.logger.warn("Kick follow sync: 'session_token' cookie is missing; cannot fetch followed channels.");
return;
}

Copilot uses AI. Check for mistakes.

private async startSyncTimer() {
this.stopSyncTimer();
this.syncFollowsTimer = setInterval(() => this.twitchFollowsSyncer.getFollows(), 10000); // 10 secs

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The sync interval is set to 10 seconds (10000 ms), which seems quite frequent for syncing follow lists. This could cause unnecessary API calls and performance overhead. Consider using a longer interval (e.g., 2-5 minutes) similar to what's used in the Kick implementation (120000 ms = 2 minutes).

Copilot uses AI. Check for mistakes.
Comment thread src/platforms/twitch/twitch.utils.ts Outdated
if (!login) return null;
return String(login).toLowerCase();
};
const names = [...streams, ...offline].map(extractLogin).filter((v): v is string => typeof v === "string");

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The filter condition uses a type guard (v): v is string => typeof v === "string" but this is redundant since the map already calls String() and toLowerCase() on each login value. If a login value is null or undefined, it would be converted to the string "null" or "undefined" by the String() call. Consider checking for null/undefined before the String() conversion instead.

Suggested change
const names = [...streams, ...offline].map(extractLogin).filter((v): v is string => typeof v === "string");
const names = [...streams, ...offline]
.map(extractLogin)
.filter((v): v is string => v !== null);

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +67
private async fetchFollowedRecursive(cursor: number, collected: Set<string>) {
const authorization = this.getAuthHeader();
if (!authorization) return;

try {
const url = new URL("https://kick.com/api/v2/channels/followed");
url.searchParams.set("cursor", String(cursor));

const { data } = await this.http.request<FollowedChannelsResponse>(url.href, {
method: "GET",
headers: { Authorization: authorization },
});

(data.channels ?? []).forEach((channel) => {
const name = (channel.channel_slug || channel.user_username || "").toString().trim();
if (name) {
collected.add(name.toLowerCase());
}
});

if (typeof data.nextCursor === "number") {
await this.fetchFollowedRecursive(data.nextCursor, collected);
}

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The recursive fetching doesn't have a maximum depth limit or safeguard against infinite loops. If the API returns an unexpected cursor value or enters a cycle, this could lead to infinite recursion. Consider adding a maximum depth parameter or iteration counter to prevent potential stack overflow or excessive API calls.

Copilot uses AI. Check for mistakes.
pinnedStreamersEnabled: true,
xayoWatchtimeEnabled: true,
shareFollowsToOtherPlatforms: false,
showFollowsFromOtherPlatforms: true,

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The default value for showFollowsFromOtherPlatforms is set to true, which means users will automatically see follows from other platforms without explicitly opting in. This could be surprising behavior for users. Consider setting this to false by default to make it an opt-in feature, especially since shareFollowsToOtherPlatforms is defaulted to false.

Suggested change
showFollowsFromOtherPlatforms: true,
showFollowsFromOtherPlatforms: false,

Copilot uses AI. Check for mistakes.
Comment thread src/platforms/kick/kick.constants.ts Outdated
realVideoTimeEnabled: true,
realVideoTimeFormat12h: false,
shareFollowsToOtherPlatforms: false,
showFollowsFromOtherPlatforms: true,

Copilot AI Dec 29, 2025

Copy link

Choose a reason for hiding this comment

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

The default value for showFollowsFromOtherPlatforms is set to true, which means users will automatically see follows from other platforms without explicitly opting in. This could be surprising behavior for users. Consider setting this to false by default to make it an opt-in feature, especially since shareFollowsToOtherPlatforms is defaulted to false.

Suggested change
showFollowsFromOtherPlatforms: true,
showFollowsFromOtherPlatforms: false,

Copilot uses AI. Check for mistakes.
igorovh and others added 2 commits February 9, 2026 23:33
…UI (#126)

* Initial plan

* Refactor: Rename common data to shared-storage for better clarity

Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>

* feat: Add centralized follow sync with static interval

Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>

* feat: Add streamer status manager with rate limiting to background

Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>

* feat: Uncomment and enable cross-platform streamer UI modules

Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>

* chore: Clean up code formatting and add documentation

Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>

* fix: Fix indentation in streamer-status manager

Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>

* fix: Remove follow-sync from background, run biome check

Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>

* fix: Fix all remaining biome linting errors

Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>

* Bump preact in the npm_and_yarn group across 1 directory (#129)

Bumps the npm_and_yarn group with 1 update in the / directory: [preact](https://github.com/preactjs/preact).


Updates `preact` from 10.28.1 to 10.28.2
- [Release notes](https://github.com/preactjs/preact/releases)
- [Commits](preactjs/preact@10.28.1...10.28.2)

---
updated-dependencies:
- dependency-name: preact
  dependency-version: 10.28.2
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix: update selector for channel section (#130)

* bump version

* fix: handle optional core and nested playerInstance in media player l… (#131)

* fix: handle optional core and nested playerInstance in media player logic

* fixes

* fix seekTo

* bump version

* fix version

---------

Co-authored-by: igorovh <xoxo@igor.ovh>

* feat: add stream latency reducer for kick and twitch

* Prototype of latency reducer, only for Kick

* Prototype for Twitch

* chore: lint

* feat(twitch): add mockup latency tab for latency-related options

* refactor(twitch): move stream latency display toggle to dedicated tab

* feat(twitch): add kick-identical mockup latency reducer options to latency tab

* feat(twitch): add latency reducer constants

* feat(twitch): extend twitch media player instance types to include access to raw video element

* feat(twitch): add stream latency reducer module, add core functionality with hard-coded values

* fix(twitch): fix weird commit error

* refactor(twitch): scrap first prototype for stream latency reduction by @Kaedriz

* refactor(twitch): opt for a single playback rate value instead of min/max, migrate from using hard-coded values to settings values

* feat(twitch): extend latency component to include playback rate

* feat(twitch): add getMediaPlayerPlaybackRate twitch util

* refactor(twitch): refactor stream latency reducer module to use playback rate twitch util + edit naming

* chore: cleanup

* feat: add playbackRate signal to stream latency module with video ratechange event listener

* refactor(twitch): organize latency settings declarations

* feat(twitch): re-add min/max playback rate settings, add min/max threshold settings

* feat(twitch): add latency offset for rate updates to prevent rapid updates, implement min/max rate changes depending on min/max thresholds, prevent FFZ overrides when attempting to change rate

* fix(twitch): fix twitch default settings

* chore: remove accidentally-commited vscode settings.json

* Fixes playback not limited to 2 digits

* WIP fix for twitch latency reducer

* feat(twitch): enhance fix for latency reducer

* Some changes to make it working again

* Formatting

* Fix compatibility with FFZ

* Final touches to twitch version

* style: change ordering to be more logical

* refactor: Separate Reducer logic to separate module

* Revert "feat(twitch): enhance fix for latency reducer"

This reverts commit d4112f3.

* Apply suggestion from @gemini-code-assist[bot]

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Apply suggestion from @gemini-code-assist[bot]

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Apply suggestion from @Copilot

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* style: Fix incomplete comment

* refactor: Apply suggestion from Gemini

* style: formatting fixes

* Apply Gemini suggestion

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* refactor: remove obsolete check

* refactor: optimize settings calls for reducer

* fix: add error logging

* refactor: remove redundant code

* fix: Prevent possible bug

* style: fix typo

* refactor: remove redundant code

* style: formatting

* refactor: extract part of latency getter to utils

* refactor: temporary move these new feature to experimental to test them out

* resovle conflitcs

* bump version and rename settings name

* update settings category

* comment experimental category

---------

Co-authored-by: jamie <hi@jamie.to>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: igorovh <xoxo@igor.ovh>

* feat: update ci and husky (#135)

* feat: update ci and husky

* Apply suggestions from code review

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* update

* change to matrix

* fix: regenerate lockfile for cross-platform CI compatibility

- Remove old lockfile and regenerate with bun 1.3.8
- Add .bun-version to pin bun version
- Fixes frozen-lockfile errors in Ubuntu CI environment

* update ci

* fix

* fixes

* remove lockfile

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* chore: update release.yml (#136)

* chore: update release.yml

* chore: fix name

* release: update docs (#139)

* chore: update release.yml

* chore: fix name

* ci: add merge master to develop

* docs: update docs

* docs: fix docs

* docs: update docs

* ci: add new scripts

* chore: update package.json

* ci: fix yamls

* update url

* update scripts

* update

* chore: test update package.json (#140)

* chore: update package.json

* ci: fix yamls

* update url

* update scripts

* update

* ci: update templates (#141)

* ci: fix ci (#143)

* ci: update templates

* fixes

* chore: bump version to v5.1.26

* chore: update templates (#142)

* chore: update package.json

* ci: fix yamls

* update url

* update scripts

* update

* ci: update templates (#141)

* ci: fix ci (#143)

* ci: update templates

* fixes

* chore: bump version to v5.1.26

---------

Co-authored-by: Enhancer Bot <contact@enhancer.at>

* docs: update bug report template

* ci: remove hotfix and release ci publish

* ci: fix pr title ci (#145)

* fix(twitch): fix media player instance getter for direct players (#144)

* fix(twitch): fix media player instance getter for direct players (popouts, etc.)

* chore: fix linting

* fix: fix comment

---------

Co-authored-by: igor <37638480+igorovh@users.noreply.github.com>
Co-authored-by: igorovh <xoxo@igor.ovh>

* fix: stream reducer working in vod (#147)

* fix: stream reducer working in vod

* Apply suggestions from code review

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update src/platforms/twitch/modules/stream-latency-reducer/stream-latency-reducer.module.tsx

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* ci: add upload extension (#148)

* ci: add upload extension

* fix

* ci: add release to allowed pr titles

* ci: update to GITHUB_TOKEN

* chore: bump version to v5.1.27

* release: 5.1.27 (#149)

* ci: fix pr title ci (#145)

* fix(twitch): fix media player instance getter for direct players (#144)

* fix(twitch): fix media player instance getter for direct players (popouts, etc.)

* chore: fix linting

* fix: fix comment

---------

Co-authored-by: igor <37638480+igorovh@users.noreply.github.com>
Co-authored-by: igorovh <xoxo@igor.ovh>

* fix: stream reducer working in vod (#147)

* fix: stream reducer working in vod

* Apply suggestions from code review

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update src/platforms/twitch/modules/stream-latency-reducer/stream-latency-reducer.module.tsx

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* ci: add upload extension (#148)

* ci: add upload extension

* fix

* ci: add release to allowed pr titles

* ci: update to GITHUB_TOKEN

* chore: bump version to v5.1.27

---------

Co-authored-by: jamie <hi@jamie.to>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Enhancer Bot <contact@enhancer.at>

* ci: fix publish pipeline

* chore: update LICENSE badge

* ci: add autofix-ci

* ci: fix linting

* chore: bump version

* fix: publishing ci

* ci: change retentio day when uploading artifact

* ci: update env anme

* ci: add opencode agent

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: igorovh <37638480+igorovh@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Maksymilian Podstawski <115575127+maksPodstawski@users.noreply.github.com>
Co-authored-by: igorovh <xoxo@igor.ovh>
Co-authored-by: Kaedriz <kaedriz@proton.me>
Co-authored-by: jamie <hi@jamie.to>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Enhancer Bot <contact@enhancer.at>
@igorovh
igorovh requested a review from a team May 16, 2026 11:32
@github-actions

github-actions Bot commented May 16, 2026

Copy link
Copy Markdown

❌ Invalid PR Title

Your current title does not follow the required semantic format.

Example format: feat: add login functionality
Allowed types: feat, fix, bugfix, chore, docs, style, refactor, perf, test, ci, release

@igorovh igorovh changed the title feat/enhanced-follow-list feat: shared followers May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants