Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI Improvements #1

Merged
merged 5 commits into from
Dec 10, 2022
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
2 changes: 2 additions & 0 deletions .prettierrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
semi: false
singleQuote: true
12 changes: 9 additions & 3 deletions build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ async function deleteOldDir() {

async function runEsbuild() {
await esbuild.build({
entryPoints: ['src/content/audio.mjs', 'src/popup/index.mjs', 'src/background/index.mjs'],
entryPoints: [
'src/content/info.mjs',
'src/content/audio.mjs',
'src/popup/index.mjs',
'src/background/index.mjs',
],
jsx: 'automatic',
bundle: true,
minify: true,
Expand Down Expand Up @@ -38,18 +43,19 @@ async function build() {
{ src: 'build/background/index.js', dst: 'background/index.js' },
{ src: 'src/content/index.html', dst: 'content/index.html' },
{ src: 'build/content/audio.js', dst: 'content/audio.js' },
{ src: 'build/content/info.js', dst: 'content/info.js' },
{ src: 'src/popup/index.html', dst: 'popup/index.html' },
{ src: 'build/popup/index.js', dst: 'popup/index.js' },
{ src: 'src/styles.css', dst: 'styles.css' },
{ src: 'src/assets/logo.png', dst: 'assets/logo.png' },
{ src: 'src/assets/logo_recording.png', dst: 'assets/logo_recording.png' },
{ src: 'src/assets/logo_handling.png', dst: 'assets/logo_handling.png' }
{ src: 'src/assets/logo_handling.png', dst: 'assets/logo_handling.png' },
]

// chromium
await zipFiles(
[...commonFiles, { src: 'src/manifest.json', dst: 'manifest.json' }],
`./${outdir}/chrome.zip`,
`./${outdir}/chrome.zip`
)

// firefox
Expand Down
5 changes: 5 additions & 0 deletions src/components/Callout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from 'react'

export default function Callout({ type, children }) {
return <div className={`callout ${type}`}>{children}</div>
}
88 changes: 88 additions & 0 deletions src/components/Info.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { useEffect, useState } from 'react'
import Callout from './Callout'

export default function Info() {
const [isMicrophoneEnabled, setIsMicrophoneEnabled] = useState(false)

useEffect(async () => {
const permissions = navigator.mediaDevices.getUserMedia({
audio: true,
video: false,
})
permissions.then(() => {
setIsMicrophoneEnabled(true)
})
}, [])

return (
<main>
<h1>Welcome to ChassistantGPT!</h1>
<Callout type="info">
If you wish to use ChassistantGPT in this browsing session,
<strong>please keep this tab open</strong>
</Callout>
<h2>Status</h2>
{isMicrophoneEnabled ? (
<Callout type="success">
<div class="container">
<span class="blinking-dot"></span> ChassistantGPT is ready for your
voice commands
</div>
</Callout>
) : (
<Callout type="warning">
ChassistantGPT is requesting access to your{' '}
<strong>microphone</strong> so it may hear your voice commands
</Callout>
)}
<h2>What is ChassistantGPT?</h2>
<p>
ChassistantGPT is a ChatGPT voice assistant triggered by saying{' '}
<strong>"Hey Skynet"</strong>.
</p>
<h2>How To Use</h2>
<ul>
<li>
Say <strong>"Hey Skynet"</strong> followed by your prompt. For
example: <em>"Hey Skynet, what is love?"</em> or{' '}
<em>"Hey Skeynet... Tell me a joke"</em>.
</li>
<li>
If a prompt follows as part of the same sentence, ChassistantGPT will
forward the prompt directly to ChatGPT. If not, a "beep" sound will
follow (accompanied by switching of the popup icon to red), signifying
ChassistantGPT is waiting for input.
</li>
<li>
Before sending to ChatGPT, ChassistantGPT will say "OK, coming up".
While waiting for a response from ChatGPT, the popup icon will turn
green.
</li>
<li>
In addition to the voice response from ChatGPT, you can view the last
given answer by clicking on ChassistantGPT's popup.
</li>
<li>
You may stop ChassistantGPT's voice playback at any time by pressing{' '}
<strong>Cmd/Ctrl + B.</strong>
</li>
</ul>

<h2>Privacy</h2>
<p>
ChassistantGPT relies on your existing session with ChatGPT. If you're
not logged in, please do so at{' '}
<a target="_blank" href="https://chat.openai.com/chat">
https://chat.openai.com/chat
</a>
.
</p>
<p>
The extension's only permission is access to chat.openai.com. It{' '}
<strong>does not</strong> store any data. It <strong>does not</strong>{' '}
transmit data from your device, except for direct communication with
ChatGPT.
</p>
</main>
)
}
Empty file added src/content/app.css
Empty file.
140 changes: 107 additions & 33 deletions src/content/index.html
Original file line number Diff line number Diff line change
@@ -1,46 +1,120 @@
<html>
<style>
:root {
--background-color: rgb(255, 255, 255);
--text-color: rgb(0, 0, 0);
--success: #d1e7dd;
--success-text: #0f5132;
--warning: #fff3cd;
--warning-text: #664d03;
--info: #cfe2ff;
--info-text: #084298;
--error: #f0091e;
}

@media (prefers-color-scheme: dark) {
:root {
--background-color: rgb(52, 53, 65);
--text-color: rgb(236, 236, 241);
--success: #1a8754;
--success-text: #fff;
--warning: #e6b113;
--warning-text: #614802;
--info: #0c4fb3;
--info-text: #fff;
--error: #ff4455;
}
}

html {
background-color: var(--background-color);
}

body {
color: var(--text-color);
font-family: sans-serif;
font-size: 14px;
}

main {
width: 65%;
margin: 64px auto;
line-height: 1.5em;
}

a,
a:visited,
a:active {
color: inherit;
}

h1 {
margin-top: 40px;
}

h2 {
text-align: center;
margin-top: 24px;
}
h3 {
text-align: center;

p {
margin: 16px 0;
}

.callout {
padding: 16px;
border-radius: 4px;
margin: 8px 0;
}

.callout.info {
background-color: var(--info);
color: var(--info-text);
}

.callout.warning {
background-color: var(--warning);
color: var(--warning-text);
}

.callout.success {
background-color: var(--success);
color: var(--success-text);
}

.blinking-dot {
width: 12px;
height: 12px;
background-color: var(--error);
border-radius: 50%;
display: inline-block;
animation: blink 2s infinite;
}

.container {
display: inline-flex;
align-items: center;
gap: 8px;
}

h4 {
text-align: center;
@keyframes blink {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
</style>

<head>
<title>ChassistantGPT</title>
</head>
<h2>
Welcome! If you wish to use ChassistantGPT in this browsing session, please do not close this
tab.
</h2>
<h3>ChassistantGPT is requesting access to your microphone so it may hear your voice commands</h3>
<h4>
ChassistantGPT is a voice assistant. It can be triggered by saying "Hey Skynet". If a prompt follows as part of the same sentence, ChassistantGPT will forward the prompt directly to ChatGPT.
</h4>
<h4>
If not, a "beep" sound will follow (accompanied by switching of the popup icon to red), signifying ChassistantGPT is waiting for input.
You may then utter the prompt that will be sent to ChatGPT. Before sending, ChassistantGPT will
say "OK, coming up". While waiting for a response from ChatGPT, the popup icon will turn green.
</h4>
<h4>
In addition to the voice response from ChatGPT, you can view the last given answer by clicking
on ChassistantGPT's popup.
</h4>
<h4>You may stop ChassistantGPT's voice playback at any time by pressing Cmd/Ctrl + B.</h4>
<br />
<br />

<h4>
ChassistantGPT relies on your existing session with ChatGPT. If you're not logged in, please do
so at <a target="_blank" href="https://chat.openai.com/chat">https://chat.openai.com/chat</a>.
</h4>
<br/>
<h4>This extension does not store any data. It does not transmit data from your device, except for direct communication with ChatGPT. It has no permissions other than access to the relevant OpenAI domains.</h4>
<script src="audio.js"></script>
<body>
<div id="root"></div>
<script src="info.js"></script>
<script src="audio.js"></script>
</body>
</html>
7 changes: 7 additions & 0 deletions src/content/info.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from "react";
import ReactDOM from "react-dom";
import Info from "../components/Info";

ReactDOM.createRoot(document.getElementById("root")).render(
React.createElement(Info)
);