Skip to content

Commit

Permalink
Sidepanel implementation (#121)
Browse files Browse the repository at this point in the history
* update chrome types

* update manifest for sidepanel

* refactor

* fix action icon

* fixes
  • Loading branch information
paulclindo authored Jan 22, 2024
1 parent 1d476e4 commit 50451e5
Show file tree
Hide file tree
Showing 9 changed files with 384 additions and 246 deletions.
20 changes: 16 additions & 4 deletions apps/shinkai-visor/public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
"128": "icon128.png"
},
"action": {
"default_title": "Click to open sidepanel",
"default_icon": {
"16": "icon16.png",
"48": "icon48.png"
},
"default_popup": "src/components/installed-popup/installed-popup.html"
}
},
"minimum_chrome_version": "114",
"background": {
"service_worker": "src/service-worker/service-worker.ts"
},
Expand All @@ -37,15 +38,26 @@
"description": "Open/Close Shinkai popup"
}
},
"permissions": ["storage", "contextMenus", "scripting", "activeTab"],
"permissions": [
"storage",
"contextMenus",
"scripting",
"activeTab",
"sidePanel"
],
"side_panel": {
"default_path": "src/components/popup/popup.html"
},
"host_permissions": ["<all_urls>"],
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
},
"content_scripts": [
{
"matches": ["https://*/*", "http://*/*", "<all_urls>"],
"js": ["src/components/action-button/action-button.tsx", "src/components/popup/popup-embeder.ts", "src/components/image-capture/image-capture.tsx"]
"js": [
"src/components/image-capture/image-capture.tsx"
]
}
],
"externally_connectable": {
Expand Down
156 changes: 77 additions & 79 deletions apps/shinkai-visor/src/components/popup/popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const Popup = () => {
const history = useHistory();
const auth = useAuth((state) => state.auth);
const location = useLocation();
const [popupVisibility] = useGlobalPopupChromeMessage();
useGlobalPopupChromeMessage();
const isAuthenticated = !!auth;

useEffect(() => {
Expand All @@ -49,90 +49,88 @@ export const Popup = () => {
}, [location]);
return (
<AnimatePresence>
{popupVisibility && (
<motion.div
animate={{ opacity: 1 }}
className="flex h-full w-full flex-col rounded-lg bg-gray-500 px-6 pb-6 pt-8 shadow-xl"
data-testid="popup"
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<Switch key={location.pathname} location={location}>
<Route exact path="/">
<AnimatedRoute>
<SplashScreen />
</AnimatedRoute>
</Route>
<Route path="/welcome">
<AnimatedRoute>
<Welcome />
</AnimatedRoute>
</Route>
<motion.div
animate={{ opacity: 1 }}
className="flex h-full w-full flex-col bg-gray-500 px-6 pb-6 pt-8 shadow-xl"
data-testid="popup"
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
transition={{ duration: 0.5 }}
>
<Switch key={location.pathname} location={location}>
<Route exact path="/">
<AnimatedRoute>
<SplashScreen />
</AnimatedRoute>
</Route>
<Route path="/welcome">
<AnimatedRoute>
<Welcome />
</AnimatedRoute>
</Route>

<Route path="*">
<AnimatedRoute>
<WithNav>
<Route path="/nodes">
<AnimatedRoute>
<Switch>
<Route path="/nodes/connect/method/quick-start">
<ConnectMethodQuickStart />
</Route>
<Route path="/nodes/connect/method/restore-connection">
<ConnectMethodRestoreConnection />
</Route>
<Route path="/nodes/connect/method/qr-code">
<ConnectMethodQrCode />
</Route>
</Switch>
</AnimatedRoute>
</Route>
<Route path="/inboxes">
<Route path="*">
<AnimatedRoute>
<WithNav>
<Route path="/nodes">
<AnimatedRoute>
<Switch>
<Route path="/inboxes/create-inbox">
<CreateInbox />
<Route path="/nodes/connect/method/quick-start">
<ConnectMethodQuickStart />
</Route>
<Route path="/inboxes/create-job">
<CreateJob />
<Route path="/nodes/connect/method/restore-connection">
<ConnectMethodRestoreConnection />
</Route>
<Route path="/inboxes/:inboxId">
<Inbox />
</Route>
<Route path="/">
<Inboxes />
</Route>
</Switch>
</Route>
<Route path="/agents">
<Switch>
<Route path="/agents/add">
<AddAgent />
</Route>
<Route path="/">
<Agents />
</Route>
</Switch>
</Route>
<Route path="/settings">
<Switch>
<Route path="/settings/export-connection">
<ExportConnection />
</Route>
<Route path="/settings/create-registration-code">
<CreateRegistrationCode />
</Route>
<Route path="/">
<Settings />
<Route path="/nodes/connect/method/qr-code">
<ConnectMethodQrCode />
</Route>
</Switch>
</Route>
</WithNav>
</AnimatedRoute>
</Route>
</Switch>
</motion.div>
)}
</AnimatedRoute>
</Route>
<Route path="/inboxes">
<Switch>
<Route path="/inboxes/create-inbox">
<CreateInbox />
</Route>
<Route path="/inboxes/create-job">
<CreateJob />
</Route>
<Route path="/inboxes/:inboxId">
<Inbox />
</Route>
<Route path="/">
<Inboxes />
</Route>
</Switch>
</Route>
<Route path="/agents">
<Switch>
<Route path="/agents/add">
<AddAgent />
</Route>
<Route path="/">
<Agents />
</Route>
</Switch>
</Route>
<Route path="/settings">
<Switch>
<Route path="/settings/export-connection">
<ExportConnection />
</Route>
<Route path="/settings/create-registration-code">
<CreateRegistrationCode />
</Route>
<Route path="/">
<Settings />
</Route>
</Switch>
</Route>
</WithNav>
</AnimatedRoute>
</Route>
</Switch>
</motion.div>
</AnimatePresence>
);
};
Expand Down
81 changes: 60 additions & 21 deletions apps/shinkai-visor/src/hooks/use-global-popup-chrome-message.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,88 @@
import { useState } from "react";
import { useHistory } from "react-router-dom";
import { useState } from 'react';
import { useHistory } from 'react-router-dom';

import { dataUrlToFile } from "../helpers/blob-utils";
import { sendContentScriptMessage } from "../service-worker/communication/internal";
import { ContentScriptBridgeMessageType, ServiceWorkerInternalMessageType } from "../service-worker/communication/internal/types";
import { useAuth } from "../store/auth/auth";
import { useSettings } from "../store/settings/settings";
import { useIFrameMessage } from "./use-iframe-message";
import { dataUrlToFile } from '../helpers/blob-utils';
import { sendContentScriptMessage } from '../service-worker/communication/internal';
import {
ContentScriptBridgeMessageType,
ServiceWorkerInternalMessageType,
} from '../service-worker/communication/internal/types';
import { useAuth } from '../store/auth/auth';
import { useSettings } from '../store/settings/settings';
import { useChromeMessage } from './use-chrome-message';

export const useGlobalPopupChromeMessage = () => {
const history = useHistory();
const [popupVisibility, setPopupVisibility] = useState(false);
useIFrameMessage(async (message, sender) => {
useChromeMessage(async (message, sender) => {
switch (message.type) {
case ServiceWorkerInternalMessageType.SendToAgent: {
const params = new URLSearchParams({ context: message?.data?.textContent });
history.push({ pathname: '/inboxes/create-job', search: params.toString() });
sendContentScriptMessage({ type: ContentScriptBridgeMessageType.TogglePopupVisibility, data: true });
const params = new URLSearchParams({
context: message?.data?.textContent,
});
history.push({
pathname: '/inboxes/create-job',
search: params.toString(),
});
sendContentScriptMessage({
type: ContentScriptBridgeMessageType.TogglePopupVisibility,
data: true,
});
break;
}
case ServiceWorkerInternalMessageType.SendPageToAgent: {
const file = dataUrlToFile(message.data.fileDataUrl, message.data.filename);
history.push({ pathname: '/inboxes/create-job', state: { files: [file] } });
sendContentScriptMessage({ type: ContentScriptBridgeMessageType.TogglePopupVisibility, data: true });
const file = dataUrlToFile(
message.data.fileDataUrl,
message.data.filename,
);
history.push({
pathname: '/inboxes/create-job',
state: { files: [file] },
});
sendContentScriptMessage({
type: ContentScriptBridgeMessageType.TogglePopupVisibility,
data: true,
});
break;
}
case ServiceWorkerInternalMessageType.SendCaptureToAgent: {
const imageFile = dataUrlToFile(message.data.imageDataUrl, message.data.filename);
history.push({ pathname: '/inboxes/create-job', state: { files: [imageFile] } });
sendContentScriptMessage({ type: ContentScriptBridgeMessageType.TogglePopupVisibility, data: true });
const imageFile = dataUrlToFile(
message.data.imageDataUrl,
message.data.filename,
);
history.push({
pathname: '/inboxes/create-job',
state: { files: [imageFile] },
});
sendContentScriptMessage({
type: ContentScriptBridgeMessageType.TogglePopupVisibility,
data: true,
});
break;
}
case ServiceWorkerInternalMessageType.ContentScriptBridge:
switch (message.data.type) {
case ContentScriptBridgeMessageType.TogglePopupVisibility:
console.log('toggle popup visibility', message, sender);
setPopupVisibility(message.data.data !== undefined ? message.data.data : !popupVisibility);
setPopupVisibility(
message.data.data !== undefined
? message.data.data
: !popupVisibility,
);
break;
default:
break;
}
break;
case ServiceWorkerInternalMessageType.QuickConnectionIntent: {
history.push({ pathname: '/nodes/connect/method/quick-start', state: { nodeAddress: message.data.nodeAddress } });
sendContentScriptMessage({ type: ContentScriptBridgeMessageType.TogglePopupVisibility, data: true });
history.push({
pathname: '/nodes/connect/method/quick-start',
state: { nodeAddress: message.data.nodeAddress },
});
sendContentScriptMessage({
type: ContentScriptBridgeMessageType.TogglePopupVisibility,
data: true,
});
break;
}
case ServiceWorkerInternalMessageType.RehydrateStore:
Expand Down
Loading

0 comments on commit 50451e5

Please sign in to comment.