diff --git a/package.json b/package.json
index f58b8eab..b8396c0f 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,7 @@
"@types/node-forge": "^1.3.10",
"classnames": "^2.3.2",
"core-js": "^3.34.0",
+ "detect-browser": "^5.3.0",
"dompurify": "^3.0.6",
"flag-icons": "^7.1.0",
"focus-trap-react": "^10.2.3",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index a0e60397..329390b5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -48,6 +48,9 @@ dependencies:
core-js:
specifier: ^3.34.0
version: 3.34.0
+ detect-browser:
+ specifier: ^5.3.0
+ version: 5.3.0
dompurify:
specifier: ^3.0.6
version: 3.0.6
@@ -3338,6 +3341,10 @@ packages:
resolution: {integrity: sha512-M1Ob1zPSIvlARiJUkKqvAZ3VAqQY6Jcuth/pBKQ2b1dX/Qx0OnJ8Vux6J2H5PTMQeRzWrrbTu70VxBfv/OPDJA==}
dev: false
+ /detect-browser@5.3.0:
+ resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==}
+ dev: false
+
/didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
dev: true
diff --git a/src/assets/locales/en.json b/src/assets/locales/en.json
index 15038d6f..84d4e08c 100644
--- a/src/assets/locales/en.json
+++ b/src/assets/locales/en.json
@@ -232,7 +232,7 @@
"downloadSubtitle": "Download current subtitle",
"downloadPlaylist": "Download playlist",
"downloadVideo": "Download video",
- "hlsDisclaimer": "Downloads are taken directly from the provider. movie-web does not have control over how the downloads are provided.
Please note that you are downloading an HLS playlist, it is not recommended to download if you are not familiar with advanced streaming formats. Try different sources for different formats.",
+ "hlsDisclaimer": "Downloads are taken directly from the provider. movie-web does not have control over how the downloads are provided.
Please note that you are downloading an HLS playlist, it is not recommended to download if you are not familiar with advanced streaming formats. Try different sources for different formats.",
"onAndroid": {
"1": "To download on Android, click the download button then, on the new page, tap and hold on the video, then select save.",
"shortTitle": "Download / Android",
@@ -506,8 +506,10 @@
"extension": {
"title": "Let's start with an extension",
"explainer": "Using the browser extension, you can get the best streams we have to offer. With just a simple install.",
+ "explainerIos": "Unfortunately, the browser extension is not supported on IOS, Press Go back to choose another option.",
"extensionHelp": "If you've installed the extension but it's not detected. Open the extension through your browsers extension menu and follow the steps on screen.",
- "link": "Install extension",
+ "linkChrome": "Install Chrome extension",
+ "linkFirefox": "Install Firefox extension",
"back": "Go back",
"status": {
"loading": "Waiting for you to install the extension",
diff --git a/src/pages/onboarding/OnboardingExtension.tsx b/src/pages/onboarding/OnboardingExtension.tsx
index 3c17e3b8..5dbbecad 100644
--- a/src/pages/onboarding/OnboardingExtension.tsx
+++ b/src/pages/onboarding/OnboardingExtension.tsx
@@ -1,4 +1,4 @@
-import { ReactNode } from "react";
+import { ReactNode, useMemo } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useAsyncFn, useInterval } from "react-use";
@@ -18,6 +18,10 @@ import {
import { Card, Link } from "@/pages/onboarding/utils";
import { PageTitle } from "@/pages/parts/util/PageTitle";
import { conf } from "@/setup/config";
+import {
+ ExtensionDetectionResult,
+ detectExtensionInstall,
+} from "@/utils/detectFeatures";
type ExtensionStatus =
| "unknown"
@@ -40,6 +44,7 @@ async function getExtensionState(): Promise {
export function ExtensionStatus(props: {
status: ExtensionStatus;
loading: boolean;
+ showHelp?: boolean;
}) {
const { t } = useTranslation();
@@ -88,19 +93,119 @@ export function ExtensionStatus(props: {
{content}
-
-