fully functional

additional clean up

k

quick nit

k

push changes

general organization

k

k

v2

push nits

k

v3

nit
This commit is contained in:
pablodanswer
2024-12-24 15:52:30 -05:00
parent 659f71c680
commit 56048f6fed
24 changed files with 1355 additions and 314 deletions
+21 -28
View File
@@ -1,49 +1,42 @@
# Onyx Chrome Extension
This is a minimal Chrome extension for Onyx (formerly Danswer) that provides a default home screen and basic interactions with the Onyx platform.
A minimal Chrome extension for Onyx (formerly Danswer) providing:
## Features
- Embedded iframe to Onyx chat (default: http://localhost:3000/nrf)
- Configurable domain for local or remote instances
- Hotkey to open a right panel for quick access
- Default home screen
- Basic interactions with Onyx platform
- Embedded iframe to Onyx chat
- Configurable domain for local/remote instances
- Hotkey for quick access panel
## Installation
1. Clone this repository or download the source code.
2. Open Google Chrome and navigate to `chrome://extensions`.
3. Enable "Developer mode" in the top right corner.
4. Click "Load unpacked" and select the `onyx-extension` folder.
- Clone repo or download source
- Navigate to `chrome://extensions`
- Enable "Developer mode"
- Load unpacked extension
## Usage
- Click the extension icon in the Chrome toolbar to open the Onyx home page.
- Use `Ctrl+Shift+P` (or `Cmd+Shift+P` on Mac) to open the Onyx panel.
- Access the options page to configure the Onyx domain:
1. Right-click the extension icon
2. Select "Options"
3. Enter your desired Onyx domain (e.g., http://localhost:3000/nrf)
4. Click "Save"
- Click extension icon for Onyx home page
- Use hotkey for Onyx panel
- Configure domain in options page
## Development
To make changes to the extension:
1. Modify the relevant files in the `src` directory.
2. If you make changes, go to `chrome://extensions/` and click the refresh icon for the Onyx extension.
- Modify files in `src` directory
- Refresh extension in Chrome
## File Structure
- `manifest.json`: Extension configuration
- `src/pages/onyx_home.html` & `onyx_home.js`: Main extension popup
- `src/pages/options.html` & `options.js`: Options page for domain configuration
- `src/panel/panel.html` & `panel.js`: Side panel UI
- `src/service_worker.js`: Background script for handling commands
- `manifest.json`: Configuration
- `src/pages/`: Main popup and options
- `src/panel/`: Side panel UI
- `src/service_worker.js`: Background script
## Contributing
Feel free to submit issues or pull requests for any bugs or improvements.
Submit issues or pull requests for improvements
## License
[Add your chosen license here]
MIT
+30 -32
View File
@@ -1,49 +1,47 @@
{
"name": "Onyx Extension",
"version": "0.1",
"manifest_version": 3,
"description": "Minimal Onyx (Danswer) extension to embed or open the Onyx homepage and panel.",
"permissions": ["storage", "sidePanel", "contextMenus", "activeTab", "tabs"],
"host_permissions": ["http://localhost:3000/*"],
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"options_ui": {
"page": "src/pages/options.html",
"open_in_tab": true
"name": "Onyx Extension",
"version": "1.0",
"description": "Onyx integration for Chrome",
"permissions": [
"sidePanel",
"storage",
"activeTab",
"scripting",
"tabs",
"cookies"
],
"host_permissions": ["<all_urls>"],
"background": {
"service_worker": "service_worker.js",
"type": "module"
},
"action": {
"default_title": "Onyx Home",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
"16": "public/icon16.png",
"48": "public/icon48.png",
"128": "public/icon128.png"
}
},
"background": {
"service_worker": "src/service_worker.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["src/content/content.js"]
}
],
"side_panel": {
"default_path": "src/panel/panel.html"
"icons": {
"16": "public/icon16.png",
"48": "public/icon48.png",
"128": "public/icon128.png"
},
"options_page": "src/pages/options.html",
"chrome_url_overrides": {
"newtab": "src/pages/onyx_home.html"
},
"commands": {
"send-to-onyx": {
"toggle-new-tab-override": {
"suggested_key": {
"default": "Ctrl+Shift+P",
"mac": "Command+Shift+P"
"default": "Ctrl+Shift+O",
"mac": "Command+Shift+O"
},
"description": "Send selected text to Onyx"
"description": "Toggle Onyx New Tab Override"
}
},
"side_panel": {
"default_path": "src/pages/panel.html"
}
}

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 235 B

Before

Width:  |  Height:  |  Size: 551 B

After

Width:  |  Height:  |  Size: 551 B

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

+164
View File
@@ -0,0 +1,164 @@
import {
DEFAULT_ONYX_DOMAIN,
CHROME_SPECIFIC_STORAGE_KEYS,
ACTIONS,
} from "./src/utils/constants.js";
async function setupSidePanel() {
if (chrome.sidePanel) {
try {
await chrome.sidePanel.setPanelBehavior({ openPanelOnActionClick: true });
} catch (error) {
console.error("Error setting up side panel:", error);
}
}
}
async function openSidePanel(tabId) {
try {
await chrome.sidePanel.open({ tabId });
} catch (error) {
console.error("Error opening side panel:", error);
}
}
async function closeSidePanel() {
try {
await chrome.sidePanel.setOptions({ enabled: false });
} catch (error) {
console.error("Error closing side panel:", error);
}
}
async function sendToOnyx(info, tab) {
const selectedText = encodeURIComponent(info.selectionText);
const currentUrl = encodeURIComponent(tab.url);
try {
const result = await chrome.storage.local.get({
[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]: DEFAULT_ONYX_DOMAIN,
});
const url = `${
result[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]
}/chat?input=${selectedText}&url=${currentUrl}`;
await openSidePanel(tab.id);
chrome.runtime.sendMessage({
action: ACTIONS.OPEN_ONYX_WITH_INPUT,
url: url,
pageUrl: tab.url,
});
} catch (error) {
console.error("Error sending to Onyx:", error);
}
}
async function toggleNewTabOverride() {
try {
const result = await chrome.storage.local.get(
CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB
);
const newValue =
!result[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB];
await chrome.storage.local.set({
[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB]: newValue,
});
chrome.notifications.create({
type: "basic",
iconUrl: "icon.png",
title: "Onyx New Tab",
message: `New Tab Override ${newValue ? "enabled" : "disabled"}`,
});
// Send a message to inform all tabs about the change
chrome.tabs.query({}, (tabs) => {
tabs.forEach((tab) => {
chrome.tabs.sendMessage(tab.id, {
action: "newTabOverrideToggled",
value: newValue,
});
});
});
} catch (error) {
console.error("Error toggling new tab override:", error);
}
}
chrome.action.onClicked.addListener((tab) => {
openSidePanel(tab.id);
});
chrome.commands.onCommand.addListener(async (command) => {
console.log("command", command);
if (command === ACTIONS.SEND_TO_ONYX) {
try {
const [tab] = await chrome.tabs.query({
active: true,
lastFocusedWindow: true,
});
if (tab) {
const response = await chrome.tabs.sendMessage(tab.id, {
action: ACTIONS.GET_SELECTED_TEXT,
});
const selectedText = response?.selectedText || "";
sendToOnyx({ selectionText: selectedText }, tab);
}
} catch (error) {
console.error("Error sending to Onyx:", error);
}
} else if (command === ACTIONS.TOGGLE_NEW_TAB_OVERRIDE) {
toggleNewTabOverride();
} else if (command === ACTIONS.CLOSE_SIDE_PANEL) {
try {
await chrome.sidePanel.hide();
console.log("Side panel closed via command");
} catch (error) {
console.error("Error closing side panel via command:", error);
}
}
});
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === ACTIONS.GET_CURRENT_ONYX_DOMAIN) {
chrome.storage.local.get(
{ [CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]: DEFAULT_ONYX_DOMAIN },
(result) => {
sendResponse({
[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]:
result[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN],
});
}
);
return true;
}
if (request.action === ACTIONS.CLOSE_SIDE_PANEL) {
closeSidePanel();
chrome.storage.local.get(
{ [CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]: DEFAULT_ONYX_DOMAIN },
(result) => {
chrome.tabs.create({
url: `${result[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]}/auth/login`,
active: true,
});
}
);
return true;
}
});
chrome.storage.onChanged.addListener((changes, namespace) => {
if (
namespace === "local" &&
changes[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB]
) {
const newValue =
changes[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB]
.newValue;
if (newValue === false) {
chrome.runtime.openOptionsPage();
}
}
});
setupSidePanel();
BIN
View File
Binary file not shown.
+20
View File
@@ -0,0 +1,20 @@
document.addEventListener("DOMContentLoaded", () => {
// Fetch user settings for the theme and background URLs
chrome.storage.local.get(
["onyxTheme", "darkBgUrl", "lightBgUrl"],
(items) => {
const { onyxTheme, darkBgUrl, lightBgUrl } = items;
// Decide which background to use based on the stored theme
if (onyxTheme === "dark" && darkBgUrl) {
document.getElementById(
"background"
).style.backgroundImage = `url("${darkBgUrl}")`;
} else if (onyxTheme === "light" && lightBgUrl) {
document.getElementById(
"background"
).style.backgroundImage = `url("${lightBgUrl}")`;
}
}
);
});
+44 -9
View File
@@ -1,8 +1,10 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Onyx Home</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Onyx New Tab</title>
<link rel="stylesheet" href="../styles/shared.css">
<style>
body, html {
margin: 0;
@@ -11,19 +13,52 @@
height: 100vh;
overflow: hidden;
}
@media (prefers-color-scheme: dark) {
html, body {
background-color: #000;
}
}
@media (prefers-color-scheme: light) {
html, body {
background-color: #f6f6f6;
}
}
#background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
transition: opacity 0.5s ease-in-out;
}
#content {
position: relative;
width: 100%;
height: 100%;
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
iframe {
border: none;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
visibility: hidden;
}
</style>
</head>
<body>
<iframe
id="onyx-iframe"
allow="fullscreen"
allowfullscreen>
</iframe>
<script src="onyx_home.js"></script>
<div id="background"></div>
<div id="content">
<iframe id="onyx-iframe" allowfullscreen></iframe>
</div>
<script src="../utils/error-modal.js" type="module"></script>
<script src="background_loader.js" type="module"></script>
<script src="onyx_home.js" type="module"></script>
</body>
</html>
</html>
+248 -13
View File
@@ -1,13 +1,248 @@
(function() {
const iframe = document.getElementById('onyx-iframe');
// For now, we're using a static URL. In the future, this could be made configurable.
const defaultUrl = 'http://localhost:3000/nrf';
// Set the iframe src
iframe.src = defaultUrl;
// In the future, you might want to add functionality here to dynamically update the iframe src
// based on user settings stored in chrome.storage.sync
})();
import {
CHROME_MESSAGE,
CHROME_SPECIFIC_STORAGE_KEYS,
WEB_MESSAGE,
} from "../utils/constants.js";
import {
showErrorModal,
hideErrorModal,
initErrorModal,
} from "../utils/error-modal.js";
import { getOnyxDomain } from "../utils/storage.js";
(function () {
let mainIframe = document.getElementById("onyx-iframe");
let preloadedIframe = null;
const background = document.getElementById("background");
const content = document.getElementById("content");
const DEFAULT_LIGHT_BACKGROUND_IMAGE =
"https://images.unsplash.com/photo-1692520883599-d543cfe6d43d?q=80&w=2666&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
const DEFAULT_DARK_BACKGROUND_IMAGE =
"https://images.unsplash.com/photo-1692520883599-d543cfe6d43d?q=80&w=2666&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D";
let iframeLoadTimeout;
let iframeLoaded = false;
initErrorModal();
async function preloadChatInterface() {
preloadedIframe = document.createElement("iframe");
const domain = await getOnyxDomain();
preloadedIframe.src = domain + "/chat";
preloadedIframe.style.opacity = "0";
preloadedIframe.style.visibility = "hidden";
preloadedIframe.style.transition = "opacity 0.3s ease-in";
preloadedIframe.style.border = "none";
preloadedIframe.style.width = "100%";
preloadedIframe.style.height = "100%";
preloadedIframe.style.position = "absolute";
preloadedIframe.style.top = "0";
preloadedIframe.style.left = "0";
preloadedIframe.style.zIndex = "1";
content.appendChild(preloadedIframe);
}
function setIframeSrc(url) {
mainIframe.src = url;
startIframeLoadTimeout();
iframeLoaded = false;
}
function startIframeLoadTimeout() {
clearTimeout(iframeLoadTimeout);
iframeLoadTimeout = setTimeout(() => {
if (!iframeLoaded) {
try {
if (
mainIframe.contentWindow.location.pathname.includes("/auth/login")
) {
showLoginPage();
} else {
showErrorModal(mainIframe.src);
}
} catch (error) {
showErrorModal(mainIframe.src);
}
}
}, 2500);
}
function showLoginPage() {
background.style.opacity = "0";
mainIframe.style.opacity = "1";
mainIframe.style.visibility = "visible";
content.style.opacity = "1";
hideErrorModal();
}
function setTheme(theme, customBackgroundImage) {
const imageUrl =
customBackgroundImage ||
(theme === "dark"
? DEFAULT_DARK_BACKGROUND_IMAGE
: DEFAULT_LIGHT_BACKGROUND_IMAGE);
background.style.backgroundImage = `url('${imageUrl}')`;
}
function fadeInContent() {
content.style.transition = "opacity 0.5s ease-in";
mainIframe.style.transition = "opacity 0.5s ease-in";
content.style.opacity = "0";
mainIframe.style.opacity = "0";
mainIframe.style.visibility = "visible";
requestAnimationFrame(() => {
content.style.opacity = "1";
mainIframe.style.opacity = "1";
setTimeout(() => {
background.style.transition = "opacity 0.3s ease-out";
background.style.opacity = "0";
}, 500);
});
}
function checkOnyxPreference() {
chrome.storage.local.get(
[
CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB,
CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN,
],
(items) => {
let useOnyxAsDefaultNewTab =
items[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB];
if (useOnyxAsDefaultNewTab === undefined) {
useOnyxAsDefaultNewTab = !!(
localStorage.getItem(
CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB
) === "1"
);
chrome.storage.local.set({
[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB]:
useOnyxAsDefaultNewTab,
});
}
if (!useOnyxAsDefaultNewTab) {
chrome.tabs.update({
url: "chrome://new-tab-page",
});
return;
}
setIframeSrc(
items[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN] + "/chat/nrf"
);
}
);
}
function loadThemeAndBackground() {
chrome.storage.local.get(
[
CHROME_SPECIFIC_STORAGE_KEYS.THEME,
CHROME_SPECIFIC_STORAGE_KEYS.BACKGROUND_IMAGE,
CHROME_SPECIFIC_STORAGE_KEYS.DARK_BG_URL,
CHROME_SPECIFIC_STORAGE_KEYS.LIGHT_BG_URL,
],
function (result) {
const theme = result[CHROME_SPECIFIC_STORAGE_KEYS.THEME] || "light";
const customBackgroundImage =
result[CHROME_SPECIFIC_STORAGE_KEYS.BACKGROUND_IMAGE];
const darkBgUrl = result[CHROME_SPECIFIC_STORAGE_KEYS.DARK_BG_URL];
const lightBgUrl = result[CHROME_SPECIFIC_STORAGE_KEYS.LIGHT_BG_URL];
let backgroundImage;
if (customBackgroundImage) {
backgroundImage = customBackgroundImage;
} else if (theme === "dark" && darkBgUrl) {
backgroundImage = darkBgUrl;
} else if (theme === "light" && lightBgUrl) {
backgroundImage = lightBgUrl;
}
setTheme(theme, backgroundImage);
checkOnyxPreference();
}
);
}
function loadNewPage(newSrc) {
if (preloadedIframe && preloadedIframe.contentWindow) {
preloadedIframe.contentWindow.postMessage(
{ type: WEB_MESSAGE.PAGE_CHANGE, href: newSrc },
"*"
);
} else {
console.error("Preloaded iframe not available");
}
}
function completePendingPageLoad() {
if (preloadedIframe) {
preloadedIframe.style.visibility = "visible";
preloadedIframe.style.opacity = "1";
preloadedIframe.style.zIndex = "1";
mainIframe.style.zIndex = "2";
mainIframe.style.opacity = "0";
setTimeout(() => {
if (content.contains(mainIframe)) {
content.removeChild(mainIframe);
}
mainIframe = preloadedIframe;
mainIframe.id = "onyx-iframe";
mainIframe.style.zIndex = "";
iframeLoaded = true;
clearTimeout(iframeLoadTimeout);
}, 200);
} else {
console.warn("No preloaded iframe available");
}
}
chrome.storage.onChanged.addListener(function (changes, namespace) {
if (namespace === "local" && changes.useOnyxAsDefaultNewTab) {
checkOnyxPreference();
}
});
window.addEventListener("message", function (event) {
if (event.data.type === CHROME_MESSAGE.SET_DEFAULT_NEW_TAB) {
chrome.storage.local.set({ useOnyxAsDefaultNewTab: event.data.value });
} else if (event.data.type === CHROME_MESSAGE.ONYX_APP_LOADED) {
clearTimeout(iframeLoadTimeout);
hideErrorModal();
fadeInContent();
iframeLoaded = true;
} else if (event.data.type === CHROME_MESSAGE.PREFERENCES_UPDATED) {
const { theme, backgroundUrl } = event.data.payload;
chrome.storage.local.set(
{
[CHROME_SPECIFIC_STORAGE_KEYS.THEME]: theme,
[CHROME_SPECIFIC_STORAGE_KEYS.BACKGROUND_IMAGE]: backgroundUrl,
},
() => {}
);
} else if (event.data.type === CHROME_MESSAGE.LOAD_NEW_PAGE) {
loadNewPage(event.data.href);
} else if (event.data.type === CHROME_MESSAGE.LOAD_NEW_CHAT_PAGE) {
completePendingPageLoad();
}
});
mainIframe.onload = function () {
clearTimeout(iframeLoadTimeout);
startIframeLoadTimeout();
};
mainIframe.onerror = function (error) {
showErrorModal(mainIframe.src);
};
loadThemeAndBackground();
preloadChatInterface();
})();
+35 -23
View File
@@ -1,33 +1,45 @@
<!DOCTYPE html>
<html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Onyx Extension Options</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Onyx Extension Settings</title>
<link rel="stylesheet" href="../styles/shared.css">
<style>
body {
font-family: Arial, sans-serif;
padding: 20px;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="text"] {
width: 300px;
padding: 5px;
margin-bottom: 10px;
}
button {
padding: 5px 10px;
background-color: var(--background-color);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
</style>
</head>
<body>
<h1>Onyx Extension Settings</h1>
<label for="onyxDomain">Onyx Domain:</label>
<input type="text" id="onyxDomain" placeholder="http://localhost:3000/nrf" />
<button id="save">Save</button>
<p id="status"></p>
<script src="options.js"></script>
<div class="container">
<div class="card">
<h1>Onyx Extension Settings</h1>
<div class="option-group">
<label for="onyxDomain">Root Domain</label>
<input type="text" id="onyxDomain" placeholder="https://cloud.onyx.app">
</div>
<div class="option-group">
<label for="useOnyxAsDefault" class="toggle-label">
Use Onyx as default new tab
<label class="toggle-switch">
<input type="checkbox" id="useOnyxAsDefault">
<span class="slider"></span>
</label>
</label>
</div>
<button id="save" class="button primary">Save</button>
<div id="statusContainer" class="status-container" style="display: none;">
<p id="status" class="status-message"></p>
<button id="newTab" class="button secondary">Open New Tab to Test</button>
</div>
<p class="shortcut-info">Tip: Use <kbd><span id="shortcut-key"></span></kbd> to quickly toggle the New Tab Override.</p>
</div>
</div>
<script type="module" src="options.js"></script>
</body>
</html>
</html>
+99 -17
View File
@@ -1,20 +1,102 @@
(function() {
const domainInput = document.getElementById('onyxDomain');
const saveButton = document.getElementById('save');
const statusElement = document.getElementById('status');
import {
CHROME_SPECIFIC_STORAGE_KEYS,
DEFAULT_ONYX_DOMAIN,
} from "../utils/constants.js";
// Load existing value from storage
chrome.storage.sync.get({ onyxDomain: 'http://localhost:3000/nrf' }, (result) => {
domainInput.value = result.onyxDomain;
});
document.addEventListener("DOMContentLoaded", function () {
const domainInput = document.getElementById("onyxDomain");
const useOnyxAsDefaultToggle = document.getElementById("useOnyxAsDefault");
const saveButton = document.getElementById("save");
const statusContainer = document.getElementById("statusContainer");
const statusElement = document.getElementById("status");
const shortcutKeySpan = document.getElementById("shortcut-key");
const newTabButton = document.getElementById("newTab");
saveButton.addEventListener('click', () => {
function setShortcutKey() {
if (shortcutKeySpan) {
shortcutKeySpan.textContent =
navigator.platform.indexOf("Mac") === 0 ? "⌘+Shift+O" : "Ctrl+Shift+O";
}
}
function loadStoredValues() {
chrome.storage.local.get(
{
[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]: DEFAULT_ONYX_DOMAIN,
[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB]: false,
},
(result) => {
if (domainInput)
domainInput.value = result[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN];
if (useOnyxAsDefaultToggle)
useOnyxAsDefaultToggle.checked =
result[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB];
}
);
}
function saveSettings() {
const domain = domainInput.value.trim();
chrome.storage.sync.set({ onyxDomain: domain || 'http://localhost:3000/nrf' }, () => {
statusElement.textContent = 'Domain saved!';
setTimeout(() => {
statusElement.textContent = '';
}, 3000);
});
});
})();
const useOnyxAsDefault = useOnyxAsDefaultToggle
? useOnyxAsDefaultToggle.checked
: false;
console.log(domain, useOnyxAsDefault);
chrome.storage.local.set(
{
[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]: domain,
[CHROME_SPECIFIC_STORAGE_KEYS.USE_ONYX_AS_DEFAULT_NEW_TAB]:
useOnyxAsDefault,
},
showStatusMessage
);
}
function showStatusMessage() {
if (statusElement) {
const useOnyxAsDefault = useOnyxAsDefaultToggle
? useOnyxAsDefaultToggle.checked
: false;
if (useOnyxAsDefault) {
statusElement.textContent =
"Settings updated. Open a new tab to test it out. Click on the extension icon to bring up Onyx from any page.";
if (newTabButton) newTabButton.style.display = "block";
} else {
statusElement.textContent = "Settings updated.";
if (newTabButton) newTabButton.style.display = "none";
}
statusElement.style.color = "black";
}
if (statusContainer) {
statusContainer.style.display = "block";
statusContainer.style.opacity = "1";
}
if (statusElement) statusElement.style.opacity = "1";
if (newTabButton) newTabButton.style.opacity = "1";
setTimeout(hideStatusMessage, 5000);
}
function hideStatusMessage() {
if (statusContainer) statusContainer.style.opacity = "0";
if (statusElement) statusElement.style.opacity = "0";
if (newTabButton) newTabButton.style.opacity = "0";
setTimeout(() => {
if (statusContainer) statusContainer.style.display = "none";
}, 500);
}
function openNewTab() {
chrome.tabs.create({});
}
setShortcutKey();
loadStoredValues();
if (saveButton) {
saveButton.addEventListener("click", saveSettings);
}
if (newTabButton) {
newTabButton.addEventListener("click", openNewTab);
}
});
+72
View File
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Onyx Side Panel</title>
<link rel="stylesheet" href="../styles/shared.css">
<style>
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
overflow: hidden;
}
#loading-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #f5f5f5;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 1000;
transition: opacity 0.5s ease-in-out;
}
#logo {
width: 100px;
height: 100px;
background-image: url('/public/logo.png');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
#loading-text {
color: #0a0a0a;
margin-top: 20px;
font-size: 1.125rem;
font-weight: 600;
text-align: center;
}
iframe {
border: none;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: opacity 0.5s ease-in-out;
}
</style>
</head>
<body>
<div id="loading-screen">
<div id="logo"></div>
<div id="loading-text">Loading Onyx...</div>
</div>
<iframe id="onyx-panel-iframe"></iframe>
<script src="../utils/error-modal.js" type="module"></script>
<script src="panel.js" type="module"></script>
</body>
</html>
+106
View File
@@ -0,0 +1,106 @@
import { showErrorModal, showAuthModal } from "../utils/error-modal.js";
import {
ACTIONS,
CHROME_MESSAGE,
WEB_MESSAGE,
CHROME_SPECIFIC_STORAGE_KEYS,
} from "../utils/constants.js";
(function () {
const iframe = document.getElementById("onyx-panel-iframe");
const loadingScreen = document.getElementById("loading-screen");
let currentUrl = "";
let iframeLoaded = false;
let iframeLoadTimeout;
let authRequired = false;
function initializePanel() {
loadingScreen.style.display = "flex";
loadingScreen.style.opacity = "1";
iframe.style.opacity = "0";
loadOnyxDomain();
}
function setIframeSrc(url, pageUrl) {
iframe.src = url;
currentUrl = pageUrl;
}
function sendWebsiteToIframe(pageUrl) {
if (iframe.contentWindow && pageUrl !== currentUrl) {
iframe.contentWindow.postMessage(
{
type: WEB_MESSAGE.PAGE_CHANGE,
url: pageUrl,
},
"*"
);
currentUrl = pageUrl;
}
}
function startIframeLoadTimeout() {
iframeLoadTimeout = setTimeout(() => {
if (!iframeLoaded) {
if (authRequired) {
showAuthModal();
} else {
showErrorModal(iframe.src);
}
}
}, 2500);
}
function handleMessage(event) {
if (event.data.type === CHROME_MESSAGE.ONYX_APP_LOADED) {
clearTimeout(iframeLoadTimeout);
iframeLoaded = true;
showIframe();
if (iframe.contentWindow) {
iframe.contentWindow.postMessage({ type: "PANEL_READY" }, "*");
}
} else if (event.data.type === CHROME_MESSAGE.AUTH_REQUIRED) {
authRequired = true;
}
}
function showIframe() {
iframe.style.opacity = "1";
loadingScreen.style.opacity = "0";
setTimeout(() => {
loadingScreen.style.display = "none";
}, 500);
}
async function loadOnyxDomain() {
const response = await chrome.runtime.sendMessage({
action: ACTIONS.GET_CURRENT_ONYX_DOMAIN,
});
console.log("CURRENT DOMAIn");
console.log(response);
if (response && response[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]) {
setIframeSrc(
response[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN] +
"/chat?defaultSidebarOff=true",
""
);
} else {
console.warn("Onyx domain not found, using default");
const domain = await getOnyxDomain();
setIframeSrc(domain + "/chat?defaultSidebarOff=true", "");
}
}
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === "openOnyxWithInput") {
setIframeSrc(request.url, request.pageUrl);
} else if (request.action === ACTIONS.UPDATE_PAGE_URL) {
sendWebsiteToIframe(request.pageUrl);
}
});
window.addEventListener("message", handleMessage);
initializePanel();
startIframeLoadTimeout();
})();
-25
View File
@@ -1,25 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Onyx Side Panel</title>
<style>
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
overflow: hidden;
}
iframe {
border: none;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<iframe id="onyx-panel-iframe"></iframe>
<script src="panel.js"></script>
</body>
</html>
-49
View File
@@ -1,49 +0,0 @@
(function() {
const iframe = document.getElementById('onyx-panel-iframe');
function setIframeSrc(url, pageUrl) {
console.log('Setting iframe src to:', url);
iframe.src = url;
sendWebsiteToIframe(pageUrl);
}
function sendWebsiteToIframe(pageUrl) {
if (iframe.contentWindow) {
iframe.contentWindow.postMessage(
{
type: "PAGE_URL",
url: pageUrl,
},
"*"
);
console.log('Sent PAGE_URL message to iframe:', pageUrl);
} else {
console.error('iframe.contentWindow not available');
}
}
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log('Panel received message:', request);
if (request.action === "openOnyxWithInput") {
setIframeSrc(request.url, request.pageUrl);
} else if (request.action === "updatePageUrl") {
sendWebsiteToIframe(request.pageUrl);
}
});
console.log('Panel loaded');
chrome.runtime.sendMessage({action: "getCurrentOnyxDomain"}, function(response) {
if (response && response.onyxDomain) {
console.log('Onyx domain:', response.onyxDomain);
setIframeSrc(response.onyxDomain + '/chat', '');
} else {
console.log('No Onyx domain found');
console.error('Failed to get Onyx domain');
setIframeSrc('http://localhost:3000/chat', '');
}
});
iframe.onerror = function() {
console.error('Failed to load iframe');
};
})();
-96
View File
@@ -1,96 +0,0 @@
chrome.sidePanel
.setPanelBehavior({ openPanelOnActionClick: true })
.catch((error) => console.error(error));
chrome.action.onClicked.addListener((tab) => {
chrome.sidePanel.open({tabId: tab.id});
});
chrome.runtime.onInstalled.addListener(() => {
console.log('Onyx Extension installed');
chrome.contextMenus.create({
id: "sendToOnyx",
title: "Send to Onyx",
contexts: ["selection"]
});
});
function sendToOnyx(info, tab) {
const selectedText = encodeURIComponent(info.selectionText);
const currentUrl = encodeURIComponent(tab.url);
chrome.storage.sync.get({ onyxDomain: 'http://localhost:3000' }, (result) => {
const url = `${result.onyxDomain}/chat?input=${selectedText}&url=${currentUrl}`;
chrome.sidePanel.open({tabId: tab.id}).then(() => {
chrome.runtime.sendMessage({
action: "openOnyxWithInput",
url: url,
pageUrl: tab.url
});
});
console.log("sendToOnyx called with url:", url);
});
}
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "sendToOnyx") {
sendToOnyx(info, tab);
}
});
chrome.commands.onCommand.addListener((command) => {
if (command === "send-to-onyx") {
console.log("send-to-onyx command received");
chrome.tabs.query({active: true, lastFocusedWindow: true}, ([tab]) => {
if (tab) {
chrome.tabs.sendMessage(tab.id, {action: "getSelectedText"}, (response) => {
if (response && response.selectedText) {
console.log("Selected text received");
sendToOnyx({selectionText: response.selectedText}, tab);
} else {
console.log("No selected text found");
sendToOnyx({selectionText: ""}, tab);
}
});
} else {
console.error("No active tab found");
}
});
}
});
function sendPageUrlMessage() {
chrome.tabs.query({active: true, lastFocusedWindow: true}, ([tab]) => {
if (tab) {
console.log("Sending updatePageUrl message with URL:", tab.url);
chrome.runtime.sendMessage({
action: "updatePageUrl",
pageUrl: tab.url
});
} else {
console.error("No active tab found");
}
});
}
chrome.tabs.onActivated.addListener(() => {
console.log("onActivated called");
sendPageUrlMessage();
});
chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
if (changeInfo.status === 'complete') {
console.log("onUpdated called");
sendPageUrlMessage();
}
});
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log('Received message:', request);
if (request.action === "getCurrentOnyxDomain") {
chrome.storage.sync.get({ onyxDomain: 'http://localhost:3000' }, (result) => {
console.log('Sending Onyx domain:', result.onyxDomain);
sendResponse({ onyxDomain: result.onyxDomain });
});
return true; // Indicates that the response is asynchronous
}
});
+173
View File
@@ -0,0 +1,173 @@
:root {
--primary-color: #4285f4;
--primary-hover-color: #3367d6;
--secondary-color: #f1f3f4;
--secondary-hover-color: #e8eaed;
--text-color: #333;
--text-light-color: #666;
--background-color: #f1f3f4;
--card-background-color: #fff;
--border-color: #ccc;
--font-family: Arial, sans-serif;
}
body {
font-family: var(--font-family);
margin: 0;
padding: 0;
}
.container {
max-width: 500px;
width: 90%;
margin: 0 auto;
}
.card {
background-color: var(--card-background-color);
padding: 25px;
border-radius: 10px;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1);
}
h1 {
color: var(--text-color);
font-size: 24px;
font-weight: 600;
margin-top: 0;
margin-bottom: 20px;
}
.option-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 5px;
color: var(--text-light-color);
font-weight: 400;
font-size: 16px;
}
input[type="text"] {
width: 100%;
padding: 8px;
border: 1px solid var(--border-color);
border-radius: 4px;
font-size: 14px;
background-color: var(--card-background-color);
color: var(--text-color);
}
.button {
width: 100%;
padding: 10px 20px;
border-radius: 5px;
border: none;
cursor: pointer;
font-size: 16px;
font-weight: 500;
transition: background-color 0.3s;
}
.button.primary {
background-color: var(--primary-color);
color: #fff;
}
.button.primary:hover {
background-color: var(--primary-hover-color);
}
.button.secondary {
background-color: var(--secondary-color);
color: var(--text-color);
}
.button.secondary:hover {
background-color: var(--secondary-hover-color);
}
.status-container {
margin-top: 10px;
margin-bottom: 15px;
}
.status-message {
margin: 0 0 10px 0;
color: var(--text-color);
font-weight: 500;
text-align: center;
font-size: 16px;
transition: opacity 0.5s ease-in-out;
}
.shortcut-info {
margin-top: 15px;
font-size: 14px;
color: var(--text-light-color);
text-align: center;
font-weight: 400;
}
kbd {
background-color: var(--secondary-color);
border: 1px solid var(--border-color);
border-radius: 3px;
padding: 2px 5px;
font-family: monospace;
font-weight: 500;
color: var(--text-color);
}
.toggle-label {
display: flex;
justify-content: space-between;
align-items: center;
}
.toggle-switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
}
.toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--secondary-color);
transition: .4s;
border-radius: 24px;
}
.slider:before {
position: absolute;
content: "";
height: 20px;
width: 20px;
left: 2px;
bottom: 2px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: var(--primary-color);
}
input:checked + .slider:before {
transform: translateX(26px);
}
+46
View File
@@ -0,0 +1,46 @@
export const THEMES = {
LIGHT: "light",
DARK: "dark",
};
export const DEFAULT_ONYX_DOMAIN = "http://localhost:3000";
// Keyboard shortcuts
export const KEYBOARD_SHORTCUTS = {
TOGGLE_NEW_TAB_OVERRIDE: "Ctrl+Shift+O",
OPEN_SIDE_PANEL: "Ctrl+Shift+P",
};
// Actions to send to the service worker
export const ACTIONS = {
GET_SELECTED_TEXT: "getSelectedText",
GET_CURRENT_ONYX_DOMAIN: "getCurrentOnyxDomain",
UPDATE_PAGE_URL: "updatePageUrl",
SEND_TO_ONYX: "sendToOnyx",
CLOSE_SIDE_PANEL: "closeSidePanel",
};
// Chrome-extension specific storage keys
export const CHROME_SPECIFIC_STORAGE_KEYS = {
ONYX_DOMAIN: "onyxExtensionDomain",
USE_ONYX_AS_DEFAULT_NEW_TAB: "onyxExtensionDefaultNewTab",
THEME: "onyxExtensionTheme",
BACKGROUND_IMAGE: "onyxExtensionBackgroundImage",
DARK_BG_URL: "onyxExtensionDarkBgUrl",
LIGHT_BG_URL: "onyxExtensionLightBgUrl",
};
// Messages sent from the iframe to the extension
export const CHROME_MESSAGE = {
PREFERENCES_UPDATED: "PREFERENCES_UPDATED",
ONYX_APP_LOADED: "ONYX_APP_LOADED",
SET_DEFAULT_NEW_TAB: "SET_DEFAULT_NEW_TAB",
LOAD_NEW_CHAT_PAGE: "LOAD_NEW_CHAT_PAGE",
LOAD_NEW_PAGE: "LOAD_NEW_PAGE",
AUTH_REQUIRED: "AUTH_REQUIRED",
};
// Messages to send to the iframe
export const WEB_MESSAGE = {
PAGE_CHANGE: "PAGE_CHANGE",
};
+13 -22
View File
@@ -1,8 +1,8 @@
let sidePanel = null;
function createSidePanel() {
sidePanel = document.createElement('div');
sidePanel.id = 'onyx-side-panel';
sidePanel = document.createElement("div");
sidePanel.id = "onyx-side-panel";
sidePanel.style.cssText = `
position: fixed;
top: 0;
@@ -15,40 +15,31 @@ function createSidePanel() {
z-index: 9999;
`;
const iframe = document.createElement('iframe');
const iframe = document.createElement("iframe");
iframe.style.cssText = `
width: 100%;
height: 100%;
border: none;
`;
chrome.runtime.sendMessage({action: "getCurrentOnyxDomain"}, function(response) {
iframe.src = response.onyxDomain;
});
chrome.runtime.sendMessage(
{ action: ACTIONS.GET_CURRENT_ONYX_DOMAIN },
function (response) {
iframe.src = response[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN];
}
);
sidePanel.appendChild(iframe);
document.body.appendChild(sidePanel);
}
function toggleSidePanel() {
if (!sidePanel) {
createSidePanel();
}
if (sidePanel.style.right === '0px') {
sidePanel.style.right = '-400px';
} else {
sidePanel.style.right = '0px';
}
}
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
console.log('Content script received message:', request);
console.log("Content script received message:", request);
if (request.action === "openOnyxWithInput") {
chrome.runtime.sendMessage({action: "openSidePanel", url: request.url});
chrome.runtime.sendMessage({ action: "openSidePanel", url: request.url });
}
if (request.action === "getSelectedText") {
const selectedText = window.getSelection().toString();
sendResponse({selectedText: selectedText});
sendResponse({ selectedText: selectedText });
}
});
});
+260
View File
@@ -0,0 +1,260 @@
import {
CHROME_SPECIFIC_STORAGE_KEYS,
DEFAULT_ONYX_DOMAIN,
ACTIONS,
} from "./constants.js";
// Create and append error modal HTML
const errorModalHTML = `
<div id="error-modal">
<div class="modal-content">
<h2>Onyx Configuration Error</h2>
<p>The Onyx configuration needs to be updated. Please check your settings or contact your Onyx administrator.</p>
<p>Attempted to load: <span id="attempted-url"></span></p>
<div class="button-container">
<button id="open-options" class="button primary">Open Extension Options</button>
<button id="disable-override" class="button secondary">Disable New Tab Override</button>
</div>
<p class="shortcut-info">Tip: Use <kbd><span id="shortcut-key"></span></kbd> to quickly toggle the New Tab Override.</p>
</div>
</div>
`;
// Add styles for the error modal
const style = document.createElement("style");
style.textContent = `
#error-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: none;
align-items: center;
justify-content: center;
z-index: 2000;
font-family: Arial, sans-serif;
}
#error-modal .modal-content {
background-color: #fff;
padding: 20px;
border-radius: 10px;
max-width: 95%;
width: 500px;
text-align: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
#error-modal h2 {
margin-top: 0;
color: #333;
font-size: 24px;
font-weight: 600;
}
#error-modal p {
color: #666;
margin-bottom: 15px;
font-weight: 400;
font-size: 16px;
}
#error-modal #attempted-url {
word-break: break-all;
}
#error-modal .button-container {
display: flex;
flex-direction: column;
gap: 10px;
}
#error-modal .button {
padding: 10px 20px;
border-radius: 5px;
border: none;
cursor: pointer;
font-size: 16px;
font-weight: 500;
transition: background-color 0.3s;
}
#error-modal .button.primary {
background-color: #4285f4;
color: #fff;
}
#error-modal .button.primary:hover {
background-color: #3367d6;
}
#error-modal .button.secondary {
background-color: #f1f3f4;
color: #3c4043;
}
#error-modal .button.secondary:hover {
background-color: #e8eaed;
}
#error-modal .shortcut-info {
margin-top: 15px;
font-size: 14px;
color: #666;
font-weight: 400;
}
#error-modal kbd {
background-color: #f1f3f4;
border: 1px solid #ccc;
border-radius: 3px;
padding: 2px 5px;
font-family: monospace;
font-weight: 500;
}
@media (min-width: 768px) {
#error-modal .button-container {
flex-direction: row;
justify-content: center;
}
}
`;
const authModalHTML = `
<div id="error-modal">
<div class="modal-content">
<h2>Onyx Authentication Required</h2>
<p>You need to log in to access Onyx. Click the button below to authenticate.</p>
<div class="button-container">
<button id="open-auth" class="button primary">Log In to Onyx</button>
</div>
</div>
</div>
`;
let errorModal,
attemptedUrlSpan,
openOptionsButton,
disableOverrideButton,
shortcutKeySpan;
let authModal, openAuthButton;
export function initErrorModal() {
if (!document.getElementById("error-modal")) {
document.body.insertAdjacentHTML("beforeend", errorModalHTML);
document.head.appendChild(style);
errorModal = document.getElementById("error-modal");
authModal = document.getElementById("error-modal");
attemptedUrlSpan = document.getElementById("attempted-url");
openOptionsButton = document.getElementById("open-options");
disableOverrideButton = document.getElementById("disable-override");
shortcutKeySpan = document.getElementById("shortcut-key");
openOptionsButton.addEventListener("click", (e) => {
e.preventDefault();
chrome.runtime.openOptionsPage();
});
disableOverrideButton.addEventListener("click", () => {
chrome.storage.local.set({ useOnyxAsDefaultNewTab: false }, () => {
chrome.tabs.update({ url: "chrome://new-tab-page" });
});
});
shortcutKeySpan.textContent =
navigator.platform.indexOf("Mac") === 0 ? "⌘+Shift+O" : "Ctrl+Shift+O";
}
}
export function showErrorModal(url) {
if (!errorModal) {
initErrorModal();
}
if (errorModal) {
errorModal.style.display = "flex";
errorModal.style.zIndex = "9999";
errorModal.style.opacity = "1";
attemptedUrlSpan.textContent = url;
}
}
export function hideErrorModal() {
if (errorModal) {
errorModal.style.display = "none";
}
}
export function checkModalVisibility() {
return errorModal
? window.getComputedStyle(errorModal).display !== "none"
: false;
}
export function initAuthModal() {
if (!document.getElementById("error-modal")) {
document.body.insertAdjacentHTML("beforeend", authModalHTML);
document.head.appendChild(style);
authModal = document.getElementById("error-modal");
openAuthButton = document.getElementById("open-auth");
openAuthButton.addEventListener("click", (e) => {
e.preventDefault();
chrome.storage.local.get(
{ [CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]: DEFAULT_ONYX_DOMAIN },
(result) => {
const onyxDomain = result[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN];
console.log("sendinga message", ACTIONS.CLOSE_SIDE_PANEL);
chrome.runtime.sendMessage(
{ action: ACTIONS.CLOSE_SIDE_PANEL },
() => {
if (chrome.runtime.lastError) {
console.error(
"Error closing side panel:",
chrome.runtime.lastError
);
}
// Open the auth window after attempting to close the side panel
chrome.tabs.create(
{
url: `${onyxDomain}/auth/login`,
active: true,
},
(tab) => {
if (chrome.runtime.lastError) {
console.error(
"Error opening auth tab:",
chrome.runtime.lastError
);
} else {
console.log("Auth tab opened successfully:", tab.id);
// Optionally, you can focus the newly created tab
chrome.tabs.update(tab.id, { active: true });
}
}
);
}
);
}
);
});
}
}
export function showAuthModal() {
if (!authModal) {
initAuthModal();
}
if (authModal) {
authModal.style.display = "flex";
authModal.style.zIndex = "9999";
authModal.style.opacity = "1";
document.body.style.overflow = "hidden";
authModal.style.position = "fixed";
authModal.style.top = "0";
authModal.style.left = "0";
authModal.style.width = "100%";
authModal.style.height = "100%";
authModal.style.backgroundColor = "rgba(0, 0, 0, 0.5)";
}
}
export function hideAuthModal() {
if (authModal) {
authModal.style.display = "none";
document.body.style.overflow = "auto";
}
}
+24
View File
@@ -0,0 +1,24 @@
import {
DEFAULT_ONYX_DOMAIN,
CHROME_SPECIFIC_STORAGE_KEYS,
} from "./constants.js";
export async function getOnyxDomain() {
const result = await chrome.storage.local.get({
[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]: DEFAULT_ONYX_DOMAIN,
});
return result[CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN];
}
export function setOnyxDomain(domain, callback) {
chrome.storage.local.set(
{ [CHROME_SPECIFIC_STORAGE_KEYS.ONYX_DOMAIN]: domain },
callback
);
}
export function getOnyxDomainSync() {
return new Promise((resolve) => {
getOnyxDomain(resolve);
});
}