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
5 changes: 5 additions & 0 deletions .changeset/calm-deserts-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"OTTPRO": minor
---

fix: prime video blocking regex and race condition
33 changes: 19 additions & 14 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { useEffect } from "react";
import type { AppConfig } from "@/lib/shared/types";
import { setCurrentAppContext } from "@/lib/posthog";
import { DEFAULT_LOG_LEVEL } from "@/lib/logger";
import {
PRODUCT_INSIGHTS_AVAILABLE,
setCurrentAppContext,
} from "@/lib/posthog";
import { RootStoreProvider, useRootStore } from "../hooks/useStore";
import { OTTModal } from "./OTTModal";

Expand Down Expand Up @@ -29,19 +33,20 @@ function AppContent() {
}

function App({ root, app }: { root: HTMLElement; app: AppConfig | undefined }) {
return (
<RootStoreProvider
initialState={{
root,
currentApp: app,
appStates: new Map(),
ruleStates: new Map(),
productInsightsEnabled: true,
}}
>
<AppContent />
</RootStoreProvider>
);
return (
<RootStoreProvider
initialState={{
root,
currentApp: app,
appStates: new Map(),
ruleStates: new Map(),
productInsightsEnabled: PRODUCT_INSIGHTS_AVAILABLE,
logLevel: DEFAULT_LOG_LEVEL,
}}
>
<AppContent />
</RootStoreProvider>
);
}

export default App;
68 changes: 54 additions & 14 deletions src/components/OTTModal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { useEffect, useState } from "react";
import { type ChangeEvent, useEffect, useState } from "react";
import { LOG_LEVEL_OPTIONS, type LogLevel } from "@/lib/logger";
import { PRODUCT_INSIGHTS_AVAILABLE } from "@/lib/posthog";
import {
useAppEnabled,
useLogLevel,
useProductInsightsEnabled,
useRootStore,
useSetLogLevel,
useToggleApp,
useToggleProductInsights,
} from "../hooks/useStore";
Expand Down Expand Up @@ -30,6 +34,8 @@ export function OTTModal() {
const currentApp = useRootStore((state) => state.currentApp);
const toggleApp = useToggleApp();
const productInsightsEnabled = useProductInsightsEnabled();
const logLevel = useLogLevel();
const setLogLevel = useSetLogLevel();
const toggleProductInsights = useToggleProductInsights();
const isAppEnabled = useAppEnabled(currentApp?.id || "");
const [hotstarView, setHotstarView] = useState<"main" | "login-transfer">(
Expand Down Expand Up @@ -66,6 +72,12 @@ export function OTTModal() {
await toggleProductInsights();
};

const handleLogLevelChange = async (
event: ChangeEvent<HTMLSelectElement>,
) => {
await setLogLevel(Number(event.target.value) as LogLevel);
};

const handleOpenLoginTransfer = () => {
setHotstarView("login-transfer");
setTransferMessage("");
Expand Down Expand Up @@ -289,7 +301,7 @@ export function OTTModal() {
onClick={handleImportSession}
type="button"
>
{isTransferBusy ? "Importing..." : "Import Session"}
{isTransferBusy ? "Importing..." : "Import Session"}
</button>
)}
{loginTransferMode === "import" && transferMessage && (
Expand Down Expand Up @@ -361,22 +373,50 @@ export function OTTModal() {
</RuleSection>
)}

<RuleSection title="Improve Product">
<div className="flex items-center justify-between">
{PRODUCT_INSIGHTS_AVAILABLE && (
<RuleSection title="Improve Product">
<div className="flex items-center justify-between">
<div className="min-w-0 flex-1 pr-3">
<p className="truncate font-medium text-sm text-white">
Share diagnostics
</p>
<p className="mt-1 text-white/60 text-xs">
Sends usage logs to improve product quality
</p>
</div>
<Switch
aria-label="Toggle improve product diagnostics"
checked={productInsightsEnabled}
className="relative h-6 w-10 cursor-pointer rounded-full border-2 border-white/10 p-1 shadow-none transition-all duration-200 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 data-[state=checked]:border-transparent data-[state=checked]:bg-white/30 data-[state=unchecked]:bg-transparent"
onCheckedChange={handleProductInsightsToggle}
/>
</div>
</RuleSection>
)}

<RuleSection title="">
<div className="flex items-center justify-between gap-3">
<div className="min-w-0 flex-1 pr-3">
<p className="truncate font-medium text-sm text-white">
Share diagnostics
</p>
<p className="mt-1 text-white/60 text-xs">
Sends usage logs to improve product quality
Log level
</p>
</div>
<Switch
aria-label="Toggle improve product diagnostics"
checked={productInsightsEnabled}
className="relative h-6 w-10 cursor-pointer rounded-full border-2 border-white/10 p-1 shadow-none transition-all duration-200 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 data-[state=checked]:border-transparent data-[state=checked]:bg-white/30 data-[state=unchecked]:bg-transparent"
onCheckedChange={handleProductInsightsToggle}
/>
<select
aria-label="Select log level"
className="min-w-24 rounded-lg border border-white/15 bg-white/5 px-3 py-2 text-white text-xs outline-none transition-colors hover:bg-white/10"
onChange={handleLogLevelChange}
value={String(logLevel)}
>
{LOG_LEVEL_OPTIONS.map((option) => (
<option
className="bg-neutral-900 text-white"
key={option.value}
value={String(option.value)}
>
{option.label}
</option>
))}
</select>
</div>
</RuleSection>
</>
Expand Down
55 changes: 47 additions & 8 deletions src/entrypoints/background.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
import { onMessage, StorageMessageType } from "@/lib/messaging";
import { AppStorageManager } from "@/lib/storage";
import { syncAllDynamicRules, syncDynamicRule } from "@/lib/dnr-rules";
import { logger } from "@/lib/logger";
import { initPostHog, setProductInsightsEnabled } from "@/lib/posthog";
import { logger, setGlobalLogLevel } from "@/lib/logger";
import {
initPostHog,
PRODUCT_INSIGHTS_AVAILABLE,
setProductInsightsEnabled,
} from "@/lib/posthog";
import { isSessionOnlyRule } from "@/lib/session-rules";
import { exportCookies, importCookies } from "@/lib/cookie-transfer-background";

import { WELCOME_URL } from "@/lib/shared/constants";

export default defineBackground(() => {
const storageManager = new AppStorageManager();
storageManager
.getProductInsightsEnabled()
.then((enabled) => {
if (enabled) {
Promise.all([
storageManager.getProductInsightsEnabled(),
storageManager.getLogLevel(),
])
.then(([enabled, logLevel]) => {
setGlobalLogLevel(logLevel);
const insightsEnabled = PRODUCT_INSIGHTS_AVAILABLE && enabled;
if (insightsEnabled) {
initPostHog();
}
setProductInsightsEnabled(enabled);
setProductInsightsEnabled(insightsEnabled);
})
.catch((error) => {
logger.error("Failed to load product insights setting", { error });
Expand Down Expand Up @@ -57,9 +65,17 @@ export default defineBackground(() => {
});

onMessage(StorageMessageType.GET_PRODUCT_INSIGHTS_ENABLED, async () => {
if (!PRODUCT_INSIGHTS_AVAILABLE) {
return false;
}

return await storageManager.getProductInsightsEnabled();
});

onMessage(StorageMessageType.GET_LOG_LEVEL, async () => {
return await storageManager.getLogLevel();
});

onMessage(StorageMessageType.SET_RULE_ENABLED, async (message) => {
const { appId, ruleId, enabled } = message.data;

Expand Down Expand Up @@ -93,7 +109,7 @@ export default defineBackground(() => {
onMessage(
StorageMessageType.SET_PRODUCT_INSIGHTS_ENABLED,
async (message) => {
const { enabled } = message.data;
const enabled = PRODUCT_INSIGHTS_AVAILABLE && message.data.enabled;
await storageManager.setProductInsightsEnabled(enabled);
if (enabled) {
initPostHog();
Expand All @@ -119,6 +135,29 @@ export default defineBackground(() => {
},
);

onMessage(StorageMessageType.SET_LOG_LEVEL, async (message) => {
const { level } = message.data;
await storageManager.setLogLevel(level);
setGlobalLogLevel(level);

const tabs = await browser.tabs.query({});
for (const tab of tabs) {
if (tab.id) {
browser.tabs
.sendMessage(tab.id, {
type: StorageMessageType.STORAGE_CHANGED,
data: { logLevel: level },
})
.catch((error) => {
logger.error("Failed to send log level message to tab", {
tabId: tab.id,
error,
});
});
}
}
});

onMessage(StorageMessageType.GET_APP_CONFIG, async (message) => {
const config = await storageManager.getAppConfig(message.data);
if (!config) {
Expand Down
16 changes: 8 additions & 8 deletions src/entrypoints/content/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import ReactDOM from "react-dom/client";
import type { ContentScriptContext } from "#imports";
import App from "@/components/App";
import { PostHogProvider } from "posthog-js/react";
import {
initPostHog,
POSTHOG_API_KEY,
posthogOptions,
PRODUCT_INSIGHTS_AVAILABLE,
setProductInsightsEnabled,
} from "@/lib/posthog";
import { ProductInsightsProvider } from "@/lib/posthog-provider";

import "@/assets/global.css";
import { StorageMessageType, sendMessage } from "@/lib/messaging";
Expand Down Expand Up @@ -103,8 +102,9 @@ async function createUi(ctx: ContentScriptContext) {
sendMessage(StorageMessageType.GET_PRODUCT_INSIGHTS_ENABLED),
]);
const configsWithSupport = withRuleSupport(allAppConfigs);
setProductInsightsEnabled(productInsightsEnabled);
if (productInsightsEnabled) {
const insightsEnabled = PRODUCT_INSIGHTS_AVAILABLE && productInsightsEnabled;
setProductInsightsEnabled(insightsEnabled);
if (insightsEnabled) {
initPostHog();
}
const app = configsWithSupport.find((config) =>
Expand All @@ -126,11 +126,11 @@ async function createUi(ctx: ContentScriptContext) {
onMount: (uiContainer, _, shadowHost) => {
if (!root) {
root = ReactDOM.createRoot(uiContainer);
if (productInsightsEnabled) {
if (insightsEnabled) {
root.render(
<PostHogProvider apiKey={POSTHOG_API_KEY} options={posthogOptions}>
<ProductInsightsProvider>
<App app={app} root={shadowHost} />
</PostHogProvider>,
</ProductInsightsProvider>,
);
} else {
root.render(<App app={app} root={shadowHost} />);
Expand Down
Loading