diff --git a/src/manifest.json b/src/manifest.json
index ae7e559..c5d9c72 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -31,6 +31,10 @@
"48": "assets/icon48.png",
"128": "assets/icon128.png"
},
+ "options_ui": {
+ "page": "settings.html",
+ "open_in_tab": true
+ },
"web_accessible_resources": [
"recap.html",
"assets/videos/*.mp4"
diff --git a/src/popup/HomeView.jsx b/src/popup/HomeView.jsx
index c91e119..3fe88bd 100644
--- a/src/popup/HomeView.jsx
+++ b/src/popup/HomeView.jsx
@@ -61,7 +61,7 @@ const HomeView = ({ onSelectTimeRange, loading, onOpenSettings}) => (
HomeView.propTypes = {
onSelectTimeRange: PropTypes.func.isRequired,
loading: PropTypes.bool,
- onOpenSettings: PropTypes.func // optional for now
+ onOpenSettings: PropTypes.func.isRequired
};
export default HomeView;
\ No newline at end of file
diff --git a/src/popup/popup.jsx b/src/popup/popup.jsx
index 9570b47..be5309a 100644
--- a/src/popup/popup.jsx
+++ b/src/popup/popup.jsx
@@ -11,8 +11,12 @@ const Popup = () => {
browser.tabs.create({ url });
};
+ const handleOpenSettings = () => {
+ browser.runtime.openOptionsPage();
+ };
+
return view === 'home'
- ?
+ ?
: ;
};
diff --git a/src/settings/Settings.jsx b/src/settings/Settings.jsx
new file mode 100644
index 0000000..b895fd4
--- /dev/null
+++ b/src/settings/Settings.jsx
@@ -0,0 +1,59 @@
+import React, { useState, useEffect } from 'react';
+
+const Settings = () => {
+ const [hasPermission, setHasPermission] = useState(null);
+ const [requesting, setRequesting] = useState(false);
+ const [error, setError] = useState('');
+
+ const checkPermission = async () => {
+ try {
+ const granted = await browser.permissions.contains({ permissions: ['trialML'] });
+ setHasPermission(granted);
+ } catch (err) {
+ setError('Could not check permission status.');
+ setHasPermission(false);
+ }
+ };
+
+ useEffect(() => {
+ checkPermission();
+ }, []);
+
+ const handleRequestPermission = async () => {
+ setRequesting(true);
+ setError('');
+ try {
+ const granted = await browser.permissions.request({ permissions: ['trialML'] });
+ setHasPermission(granted);
+ if (!granted) setError('Permission was not granted.');
+ } catch (err) {
+ setError('An error occurred while requesting permission.');
+ setHasPermission(false);
+ } finally {
+ setRequesting(false);
+ }
+ };
+
+ return (
+
+
Settings
+
ML Engine Permission
+ {hasPermission === null &&
Checking permission status...
}
+ {hasPermission &&
✅ trialML permission granted.
}
+ {hasPermission === false && (
+
+
❌ trialML permission is required for ML features.
+
+ {error &&
{error}
}
+
+ )}
+
+ Note: You might need to enable browser.ml.enable and extensions.ml.enabled in about:config in Firefox Nightly.
+
+
+ );
+};
+
+export default Settings;
diff --git a/src/settings/index.jsx b/src/settings/index.jsx
new file mode 100644
index 0000000..f1e491b
--- /dev/null
+++ b/src/settings/index.jsx
@@ -0,0 +1,11 @@
+import React from 'react';
+import { createRoot } from 'react-dom/client';
+import Settings from './Settings.jsx';
+
+const container = document.getElementById('root');
+if (container) {
+ const root = createRoot(container);
+ root.render();
+} else {
+ console.error('Could not find #root container for settings');
+}
\ No newline at end of file
diff --git a/src/settings/settings.html b/src/settings/settings.html
new file mode 100644
index 0000000..523a0cb
--- /dev/null
+++ b/src/settings/settings.html
@@ -0,0 +1,16 @@
+
+
+
+
+ Firefox Recap Settings
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
index 1cb3f85..99b031c 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -5,7 +5,8 @@ module.exports = {
entry: {
popup: './src/popup/index.jsx',
recap: './src/popup/recap.jsx',
- background: './src/background/background.js'
+ background: './src/background/background.js',
+ settings: './src/settings/index.jsx'
},
output: {
filename: '[name].js',
@@ -33,6 +34,7 @@ module.exports = {
{ from: 'src/manifest.json', to: 'manifest.json' },
{ from: 'src/popup/popup.html', to: 'popup.html' },
{ from: 'src/popup/recap.html', to: 'recap.html' },
+ { from: 'src/settings/settings.html', to: 'settings.html' },
{ from: 'src/assets', to: 'assets' }
]
})