mirror of
https://github.com/younesaassila/ttv-lol-pro.git
synced 2025-04-29 22:14:27 +02:00
Merge pull request #361 from younesaassila/feat/auto-whitelist-subs
Feat/auto whitelist subs
This commit is contained in:
commit
66e0ccb309
@ -4,8 +4,7 @@ export default function isChannelWhitelisted(
|
|||||||
channelName: string | null
|
channelName: string | null
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!channelName) return false;
|
if (!channelName) return false;
|
||||||
const whitelistedChannelsLower = store.state.whitelistedChannels.map(
|
return store.state.whitelistedChannels.some(
|
||||||
channel => channel.toLowerCase()
|
c => c.toLowerCase() === channelName.toLowerCase()
|
||||||
);
|
);
|
||||||
return whitelistedChannelsLower.includes(channelName.toLowerCase());
|
|
||||||
}
|
}
|
||||||
|
10
src/common/ts/wasChannelSubscriber.ts
Normal file
10
src/common/ts/wasChannelSubscriber.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import store from "../../store";
|
||||||
|
|
||||||
|
export default function wasChannelSubscriber(
|
||||||
|
channelName: string | null
|
||||||
|
): boolean {
|
||||||
|
if (!channelName) return false;
|
||||||
|
return store.state.activeChannelSubscriptions.some(
|
||||||
|
c => c.toLowerCase() === channelName.toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
@ -2,6 +2,7 @@ import pageScriptURL from "url:../page/page.ts";
|
|||||||
import workerScriptURL from "url:../page/worker.ts";
|
import workerScriptURL from "url:../page/worker.ts";
|
||||||
import browser, { Storage } from "webextension-polyfill";
|
import browser, { Storage } from "webextension-polyfill";
|
||||||
import findChannelFromTwitchTvUrl from "../common/ts/findChannelFromTwitchTvUrl";
|
import findChannelFromTwitchTvUrl from "../common/ts/findChannelFromTwitchTvUrl";
|
||||||
|
import isChannelWhitelisted from "../common/ts/isChannelWhitelisted";
|
||||||
import isChromium from "../common/ts/isChromium";
|
import isChromium from "../common/ts/isChromium";
|
||||||
import { getStreamStatus, setStreamStatus } from "../common/ts/streamStatus";
|
import { getStreamStatus, setStreamStatus } from "../common/ts/streamStatus";
|
||||||
import store from "../store";
|
import store from "../store";
|
||||||
@ -97,66 +98,116 @@ function onBackgroundMessage(message: any): undefined {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onPageMessage(event: MessageEvent) {
|
function onPageMessage(event: MessageEvent) {
|
||||||
if (event.data?.type !== MessageType.ContentScriptMessage) return;
|
if (!event.data || event.data.type !== MessageType.ContentScriptMessage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const message = event.data?.message;
|
const { message, responseType, responseMessageType } = event.data;
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
|
|
||||||
switch (message.type) {
|
if (message.type === MessageType.GetStoreState) {
|
||||||
case MessageType.GetStoreState:
|
const sendStoreState = () => {
|
||||||
const sendStoreState = () => {
|
window.postMessage({
|
||||||
window.postMessage({
|
type: MessageType.PageScriptMessage,
|
||||||
type: MessageType.PageScriptMessage,
|
message: {
|
||||||
message: {
|
type: MessageType.GetStoreStateResponse,
|
||||||
type: MessageType.GetStoreStateResponse,
|
state: JSON.parse(JSON.stringify(store.state)),
|
||||||
state: JSON.parse(JSON.stringify(store.state)),
|
},
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
if (store.readyState === "complete") sendStoreState();
|
|
||||||
else store.addEventListener("load", sendStoreState);
|
|
||||||
break;
|
|
||||||
case MessageType.EnableFullMode:
|
|
||||||
try {
|
|
||||||
browser.runtime.sendMessage(message);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(
|
|
||||||
"[TTV LOL PRO] Failed to send EnableFullMode message",
|
|
||||||
error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MessageType.DisableFullMode:
|
|
||||||
try {
|
|
||||||
browser.runtime.sendMessage(message);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(
|
|
||||||
"[TTV LOL PRO] Failed to send DisableFullMode message",
|
|
||||||
error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MessageType.UsherResponse:
|
|
||||||
try {
|
|
||||||
browser.runtime.sendMessage(message);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(
|
|
||||||
"[TTV LOL PRO] Failed to send UsherResponse message",
|
|
||||||
error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MessageType.MultipleAdBlockersInUse:
|
|
||||||
const channelName = findChannelFromTwitchTvUrl(location.href);
|
|
||||||
if (!channelName) break;
|
|
||||||
const streamStatus = getStreamStatus(channelName);
|
|
||||||
setStreamStatus(channelName, {
|
|
||||||
...(streamStatus ?? { proxied: false }),
|
|
||||||
reason: "Another Twitch ad blocker is in use",
|
|
||||||
});
|
});
|
||||||
break;
|
};
|
||||||
case MessageType.ClearStats:
|
if (store.readyState === "complete") sendStoreState();
|
||||||
clearStats(message.channelName);
|
else store.addEventListener("load", sendStoreState);
|
||||||
break;
|
}
|
||||||
|
// ---
|
||||||
|
else if (message.type === MessageType.EnableFullMode) {
|
||||||
|
try {
|
||||||
|
browser.runtime.sendMessage(message);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"[TTV LOL PRO] Failed to send EnableFullMode message",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
else if (message.type === MessageType.DisableFullMode) {
|
||||||
|
try {
|
||||||
|
browser.runtime.sendMessage(message);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"[TTV LOL PRO] Failed to send DisableFullMode message",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
else if (message.type === MessageType.ChannelSubStatusChange) {
|
||||||
|
const { channelName, wasSubscribed, isSubscribed } = message;
|
||||||
|
const isWhitelisted = isChannelWhitelisted(channelName);
|
||||||
|
console.log("[TTV LOL PRO] ChannelSubStatusChange", {
|
||||||
|
channelName,
|
||||||
|
wasSubscribed,
|
||||||
|
isSubscribed,
|
||||||
|
isWhitelisted,
|
||||||
|
});
|
||||||
|
if (store.state.whitelistChannelSubscriptions && channelName != null) {
|
||||||
|
if (!wasSubscribed && isSubscribed) {
|
||||||
|
store.state.activeChannelSubscriptions.push(channelName);
|
||||||
|
// Add to whitelist.
|
||||||
|
if (!isWhitelisted) {
|
||||||
|
console.log(`[TTV LOL PRO] Adding '${channelName}' to whitelist.`);
|
||||||
|
store.state.whitelistedChannels.push(channelName);
|
||||||
|
}
|
||||||
|
} else if (wasSubscribed && !isSubscribed) {
|
||||||
|
store.state.activeChannelSubscriptions =
|
||||||
|
store.state.activeChannelSubscriptions.filter(
|
||||||
|
c => c.toLowerCase() !== channelName.toLowerCase()
|
||||||
|
);
|
||||||
|
// Remove from whitelist.
|
||||||
|
if (isWhitelisted) {
|
||||||
|
console.log(
|
||||||
|
`[TTV LOL PRO] Removing '${channelName}' from whitelist.`
|
||||||
|
);
|
||||||
|
store.state.whitelistedChannels =
|
||||||
|
store.state.whitelistedChannels.filter(
|
||||||
|
c => c.toLowerCase() !== channelName.toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.postMessage({
|
||||||
|
type: responseType,
|
||||||
|
message: {
|
||||||
|
type: responseMessageType,
|
||||||
|
whitelistedChannels: JSON.parse(
|
||||||
|
JSON.stringify(store.state.whitelistedChannels)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
else if (message.type === MessageType.UsherResponse) {
|
||||||
|
try {
|
||||||
|
browser.runtime.sendMessage(message);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
"[TTV LOL PRO] Failed to send UsherResponse message",
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
else if (message.type === MessageType.MultipleAdBlockersInUse) {
|
||||||
|
const channelName = findChannelFromTwitchTvUrl(location.href);
|
||||||
|
if (!channelName) return;
|
||||||
|
const streamStatus = getStreamStatus(channelName);
|
||||||
|
setStreamStatus(channelName, {
|
||||||
|
...(streamStatus ?? { proxied: false }),
|
||||||
|
reason: "Another Twitch ad blocker is in use",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// ---
|
||||||
|
else if (message.type === MessageType.ClearStats) {
|
||||||
|
clearStats(message.channelName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,9 @@ const passportLevelProxyUsageWwwElement = $(
|
|||||||
const whitelistedChannelsListElement = $(
|
const whitelistedChannelsListElement = $(
|
||||||
"#whitelisted-channels-list"
|
"#whitelisted-channels-list"
|
||||||
) as HTMLUListElement;
|
) as HTMLUListElement;
|
||||||
|
const whitelistSubscriptionsCheckboxElement = $(
|
||||||
|
"#whitelist-subscriptions-checkbox"
|
||||||
|
) as HTMLInputElement;
|
||||||
// Proxies
|
// Proxies
|
||||||
const optimizedProxiesInputElement = $("#optimized") as HTMLInputElement;
|
const optimizedProxiesInputElement = $("#optimized") as HTMLInputElement;
|
||||||
const optimizedProxiesListElement = $(
|
const optimizedProxiesListElement = $(
|
||||||
@ -163,6 +166,16 @@ function main() {
|
|||||||
return [true];
|
return [true];
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
whitelistSubscriptionsCheckboxElement.checked =
|
||||||
|
store.state.whitelistChannelSubscriptions;
|
||||||
|
whitelistSubscriptionsCheckboxElement.addEventListener("change", () => {
|
||||||
|
const { checked } = whitelistSubscriptionsCheckboxElement;
|
||||||
|
store.state.whitelistChannelSubscriptions = checked;
|
||||||
|
if (!checked) {
|
||||||
|
// Clear active channel subscriptions to free up storage space.
|
||||||
|
store.state.activeChannelSubscriptions = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
// Proxies
|
// Proxies
|
||||||
if (store.state.optimizedProxiesEnabled)
|
if (store.state.optimizedProxiesEnabled)
|
||||||
optimizedProxiesInputElement.checked = true;
|
optimizedProxiesInputElement.checked = true;
|
||||||
@ -548,6 +561,7 @@ exportButtonElement.addEventListener("click", () => {
|
|||||||
optimizedProxies: store.state.optimizedProxies,
|
optimizedProxies: store.state.optimizedProxies,
|
||||||
optimizedProxiesEnabled: store.state.optimizedProxiesEnabled,
|
optimizedProxiesEnabled: store.state.optimizedProxiesEnabled,
|
||||||
passportLevel: store.state.passportLevel,
|
passportLevel: store.state.passportLevel,
|
||||||
|
whitelistChannelSubscriptions: store.state.whitelistChannelSubscriptions,
|
||||||
whitelistedChannels: store.state.whitelistedChannels,
|
whitelistedChannels: store.state.whitelistedChannels,
|
||||||
};
|
};
|
||||||
saveFile(
|
saveFile(
|
||||||
|
@ -138,6 +138,23 @@
|
|||||||
Twitch tabs are whitelisted channels.
|
Twitch tabs are whitelisted channels.
|
||||||
</small>
|
</small>
|
||||||
<ul id="whitelisted-channels-list" class="store-list"></ul>
|
<ul id="whitelisted-channels-list" class="store-list"></ul>
|
||||||
|
<ul class="options-list">
|
||||||
|
<li>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
name="whitelist-subscriptions-checkbox"
|
||||||
|
id="whitelist-subscriptions-checkbox"
|
||||||
|
/>
|
||||||
|
<label for="whitelist-subscriptions-checkbox">
|
||||||
|
Automatically whitelist channels you're subscribed to
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<small>
|
||||||
|
This option will automatically add or remove channels from the
|
||||||
|
whitelist based on your subscriptions.
|
||||||
|
</small>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- Proxies -->
|
<!-- Proxies -->
|
||||||
|
@ -28,9 +28,11 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
// Listen for NewPlaybackAccessToken messages from the worker script.
|
// Listen for NewPlaybackAccessToken messages from the worker script.
|
||||||
if (pageState.scope === "page") {
|
if (pageState.scope === "page") {
|
||||||
self.addEventListener("message", async event => {
|
self.addEventListener("message", async event => {
|
||||||
if (event.data?.type !== MessageType.PageScriptMessage) return;
|
if (!event.data || event.data.type !== MessageType.PageScriptMessage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const message = event.data?.message;
|
const { message } = event.data;
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
|
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
@ -58,13 +60,14 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
// Listen for ClearStats messages from the page script.
|
// Listen for ClearStats messages from the page script.
|
||||||
self.addEventListener("message", event => {
|
self.addEventListener("message", event => {
|
||||||
if (
|
if (
|
||||||
event.data?.type !== MessageType.PageScriptMessage &&
|
!event.data ||
|
||||||
event.data?.type !== MessageType.WorkerScriptMessage
|
(event.data.type !== MessageType.PageScriptMessage &&
|
||||||
|
event.data.type !== MessageType.WorkerScriptMessage)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const message = event.data?.message;
|
const { message } = event.data;
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
|
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
@ -265,6 +268,36 @@ export function getFetch(pageState: PageState): typeof fetch {
|
|||||||
encodeURIComponent('"player_type":"frontpage"')
|
encodeURIComponent('"player_type":"frontpage"')
|
||||||
);
|
);
|
||||||
const channelName = findChannelFromUsherUrl(url);
|
const channelName = findChannelFromUsherUrl(url);
|
||||||
|
if (
|
||||||
|
pageState.state?.whitelistChannelSubscriptions &&
|
||||||
|
channelName != null
|
||||||
|
) {
|
||||||
|
const wasSubscribed = wasChannelSubscriber(channelName, pageState);
|
||||||
|
const isSubscribed = url.includes(
|
||||||
|
encodeURIComponent('"subscriber":true')
|
||||||
|
);
|
||||||
|
const hasSubStatusChanged =
|
||||||
|
(wasSubscribed && !isSubscribed) || (!wasSubscribed && isSubscribed);
|
||||||
|
if (hasSubStatusChanged) {
|
||||||
|
try {
|
||||||
|
const response =
|
||||||
|
await pageState.sendMessageToContentScriptAndWaitForResponse(
|
||||||
|
pageState.scope,
|
||||||
|
{
|
||||||
|
type: MessageType.ChannelSubStatusChange,
|
||||||
|
channelName,
|
||||||
|
wasSubscribed,
|
||||||
|
isSubscribed,
|
||||||
|
},
|
||||||
|
MessageType.ChannelSubStatusChangeResponse
|
||||||
|
);
|
||||||
|
if (typeof response.whitelistedChannels === "object") {
|
||||||
|
pageState.state.whitelistedChannels =
|
||||||
|
response.whitelistedChannels;
|
||||||
|
}
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
const isWhitelisted = isChannelWhitelisted(channelName, pageState);
|
const isWhitelisted = isChannelWhitelisted(channelName, pageState);
|
||||||
if (!isLivestream || isFrontpage || isWhitelisted) {
|
if (!isLivestream || isFrontpage || isWhitelisted) {
|
||||||
console.log(
|
console.log(
|
||||||
@ -616,11 +649,23 @@ function isChannelWhitelisted(
|
|||||||
pageState: PageState
|
pageState: PageState
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!channelName) return false;
|
if (!channelName) return false;
|
||||||
const whitelistedChannelsLower =
|
return (
|
||||||
pageState.state?.whitelistedChannels.map(channel =>
|
pageState.state?.whitelistedChannels.some(
|
||||||
channel.toLowerCase()
|
c => c.toLowerCase() === channelName.toLowerCase()
|
||||||
) ?? [];
|
) ?? false
|
||||||
return whitelistedChannelsLower.includes(channelName.toLowerCase());
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wasChannelSubscriber(
|
||||||
|
channelName: string | null | undefined,
|
||||||
|
pageState: PageState
|
||||||
|
): boolean {
|
||||||
|
if (!channelName) return false;
|
||||||
|
return (
|
||||||
|
pageState.state?.activeChannelSubscriptions.some(
|
||||||
|
c => c.toLowerCase() === channelName.toLowerCase()
|
||||||
|
) ?? false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function flagRequest(
|
async function flagRequest(
|
||||||
|
@ -130,9 +130,9 @@ window.addEventListener("message", event => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.data?.type !== MessageType.PageScriptMessage) return;
|
if (!event.data || event.data.type !== MessageType.PageScriptMessage) return;
|
||||||
|
|
||||||
const message = event.data?.message;
|
const { message } = event.data;
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
|
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
|
@ -13,7 +13,9 @@ function sendMessage(
|
|||||||
type: MessageType,
|
type: MessageType,
|
||||||
message: any
|
message: any
|
||||||
): void {
|
): void {
|
||||||
if (!recipient) return;
|
if (!recipient) {
|
||||||
|
return console.error("[TTV LOL PRO] Message recipient is undefined.");
|
||||||
|
}
|
||||||
recipient.postMessage({
|
recipient.postMessage({
|
||||||
type,
|
type,
|
||||||
message,
|
message,
|
||||||
@ -30,14 +32,14 @@ async function sendMessageAndWaitForResponse(
|
|||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!recipient) {
|
if (!recipient) {
|
||||||
console.warn("[TTV LOL PRO] Recipient is undefined.");
|
console.error("[TTV LOL PRO] Message recipient is undefined.");
|
||||||
resolve(undefined);
|
resolve(undefined);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const listener = (event: MessageEvent) => {
|
const listener = (event: MessageEvent) => {
|
||||||
if (event.data?.type !== responseType) return;
|
if (!event.data || event.data.type !== responseType) return;
|
||||||
const message = event.data?.message;
|
const { message } = event.data;
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
if (message.type === responseMessageType) {
|
if (message.type === responseMessageType) {
|
||||||
self.removeEventListener("message", listener);
|
self.removeEventListener("message", listener);
|
||||||
@ -46,7 +48,12 @@ async function sendMessageAndWaitForResponse(
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.addEventListener("message", listener);
|
self.addEventListener("message", listener);
|
||||||
sendMessage(recipient, type, message);
|
recipient.postMessage({
|
||||||
|
type,
|
||||||
|
message,
|
||||||
|
responseType,
|
||||||
|
responseMessageType,
|
||||||
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
self.removeEventListener("message", listener);
|
self.removeEventListener("message", listener);
|
||||||
reject(new Error("Timed out waiting for message response."));
|
reject(new Error("Timed out waiting for message response."));
|
||||||
|
@ -47,9 +47,11 @@ const pageState: PageState = {
|
|||||||
self.fetch = getFetch(pageState);
|
self.fetch = getFetch(pageState);
|
||||||
|
|
||||||
self.addEventListener("message", event => {
|
self.addEventListener("message", event => {
|
||||||
if (event.data?.type !== MessageType.WorkerScriptMessage) return;
|
if (!event.data || event.data.type !== MessageType.WorkerScriptMessage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const message = event.data?.message;
|
const { message } = event.data;
|
||||||
if (!message) return;
|
if (!message) return;
|
||||||
|
|
||||||
switch (message.type) {
|
switch (message.type) {
|
||||||
|
@ -3,6 +3,7 @@ import type { State } from "./types";
|
|||||||
|
|
||||||
export default function getDefaultState() {
|
export default function getDefaultState() {
|
||||||
const state: State = {
|
const state: State = {
|
||||||
|
activeChannelSubscriptions: [],
|
||||||
adLog: [],
|
adLog: [],
|
||||||
adLogEnabled: true,
|
adLogEnabled: true,
|
||||||
adLogLastSent: 0,
|
adLogLastSent: 0,
|
||||||
@ -18,6 +19,7 @@ export default function getDefaultState() {
|
|||||||
passportLevel: 0,
|
passportLevel: 0,
|
||||||
streamStatuses: {},
|
streamStatuses: {},
|
||||||
videoWeaverUrlsByChannel: {},
|
videoWeaverUrlsByChannel: {},
|
||||||
|
whitelistChannelSubscriptions: true,
|
||||||
whitelistedChannels: [],
|
whitelistedChannels: [],
|
||||||
};
|
};
|
||||||
return state;
|
return state;
|
||||||
|
@ -6,6 +6,7 @@ export type ReadyState = "loading" | "complete";
|
|||||||
export type StorageAreaName = "local" | "managed" | "sync";
|
export type StorageAreaName = "local" | "managed" | "sync";
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
|
activeChannelSubscriptions: string[];
|
||||||
adLog: AdLogEntry[];
|
adLog: AdLogEntry[];
|
||||||
adLogEnabled: boolean;
|
adLogEnabled: boolean;
|
||||||
adLogLastSent: number;
|
adLogLastSent: number;
|
||||||
@ -19,6 +20,7 @@ export interface State {
|
|||||||
passportLevel: number;
|
passportLevel: number;
|
||||||
streamStatuses: Record<string, StreamStatus>;
|
streamStatuses: Record<string, StreamStatus>;
|
||||||
videoWeaverUrlsByChannel: Record<string, string[]>;
|
videoWeaverUrlsByChannel: Record<string, string[]>;
|
||||||
|
whitelistChannelSubscriptions: boolean;
|
||||||
whitelistedChannels: string[];
|
whitelistedChannels: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,8 @@ export const enum MessageType {
|
|||||||
EnableFullMode = "TLP_EnableFullMode",
|
EnableFullMode = "TLP_EnableFullMode",
|
||||||
EnableFullModeResponse = "TLP_EnableFullModeResponse",
|
EnableFullModeResponse = "TLP_EnableFullModeResponse",
|
||||||
DisableFullMode = "TLP_DisableFullMode",
|
DisableFullMode = "TLP_DisableFullMode",
|
||||||
|
ChannelSubStatusChange = "TLP_ChannelSubStatusChange",
|
||||||
|
ChannelSubStatusChangeResponse = "TLP_ChannelSubStatusChangeResponse",
|
||||||
UsherResponse = "TLP_UsherResponse",
|
UsherResponse = "TLP_UsherResponse",
|
||||||
NewPlaybackAccessToken = "TLP_NewPlaybackAccessToken",
|
NewPlaybackAccessToken = "TLP_NewPlaybackAccessToken",
|
||||||
NewPlaybackAccessTokenResponse = "TLP_NewPlaybackAccessTokenResponse",
|
NewPlaybackAccessTokenResponse = "TLP_NewPlaybackAccessTokenResponse",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user