Skip to content

Commit dc3b4a7

Browse files
swyxioseanoliver
andauthored
working settings menu and fullscreenpopout behavior (#136)
Co-authored-by: Sean Oliver <[email protected]>
1 parent 7c9723a commit dc3b4a7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2161
-200
lines changed

assets/icon.icns

-16 KB
Binary file not shown.

assets/icon.ico

-361 KB
Binary file not shown.

assets/icon.png

100755100644
-26.4 KB
Loading
File renamed without changes.
File renamed without changes.
File renamed without changes.

images/godmode.icns

-933 KB
Binary file not shown.

images/godmode.ico

-63.9 KB
Binary file not shown.

images/godmode.png

-515 KB
Binary file not shown.

images/godmodeicon.icns

-933 KB
Binary file not shown.

images/icon.icns

-93.3 KB
Binary file not shown.

images/icon.png

-5.29 KB
Binary file not shown.

package-lock.json

+1,165-87
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
"dependencies": {
3232
"@headlessui/react": "^1.7.16",
3333
"@heroicons/react": "^2.0.18",
34+
"@radix-ui/react-dialog": "^1.0.4",
35+
"@radix-ui/react-icons": "^1.3.0",
36+
"@radix-ui/react-slot": "^1.0.2",
37+
"@radix-ui/react-tooltip": "^1.0.6",
38+
"class-variance-authority": "^0.7.0",
39+
"clsx": "^2.0.0",
3440
"electron-debug": "^3.2.0",
3541
"electron-log": "^4.4.8",
3642
"electron-store": "^8.1.0",
@@ -39,7 +45,8 @@
3945
"react-beautiful-dnd": "^13.1.1",
4046
"react-dom": "^18.2.0",
4147
"react-router-dom": "^6.11.2",
42-
"react-split": "^2.0.14"
48+
"react-split": "^2.0.14",
49+
"tailwind-merge": "^1.14.0"
4350
},
4451
"repository": {
4552
"type": "git",

scripts/configs/webpack.config.renderer.dev.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ if (
3232
) {
3333
console.log(
3434
chalk.black.bgYellow.bold(
35-
'The DLL files are missing. Sit back while we build them for you with "npm run build-dll"',
36-
),
35+
'The DLL files are missing. Sit back while we build them for you with "npm run build-dll"'
36+
)
3737
);
3838
execSync('npm run postinstall');
3939
}
@@ -205,7 +205,7 @@ const configuration: webpack.Configuration = {
205205
let args = ['run', 'start:main'];
206206
if (process.env.MAIN_ARGS) {
207207
args = args.concat(
208-
['--', ...process.env.MAIN_ARGS.matchAll(/"[^"]+"|[^\s"]+/g)].flat(),
208+
['--', ...process.env.MAIN_ARGS.matchAll(/"[^"]+"|[^\s"]+/g)].flat()
209209
);
210210
}
211211
spawn('npm', args, {

scripts/scripts/check-build-exists.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ const rendererPath = path.join(webpackPaths.distRendererPath, 'renderer.js');
1010
if (!fs.existsSync(mainPath)) {
1111
throw new Error(
1212
chalk.whiteBright.bgRed.bold(
13-
'The main process is not built yet. Build it by running "npm run build:main"',
14-
),
13+
'The main process is not built yet. Build it by running "npm run build:main"'
14+
)
1515
);
1616
}
1717

1818
if (!fs.existsSync(rendererPath)) {
1919
throw new Error(
2020
chalk.whiteBright.bgRed.bold(
21-
'The renderer process is not built yet. Build it by running "npm run build:renderer"',
22-
),
21+
'The renderer process is not built yet. Build it by running "npm run build:renderer"'
22+
)
2323
);
2424
}

scripts/scripts/check-native-dep.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,34 @@ if (dependencies) {
1616
// because of a devDependency then that is okay. Warn when it is installed
1717
// because of a dependency
1818
const { dependencies: dependenciesObject } = JSON.parse(
19-
execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString(),
19+
execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString()
2020
);
2121
const rootDependencies = Object.keys(dependenciesObject);
2222
const filteredRootDependencies = rootDependencies.filter((rootDependency) =>
23-
dependenciesKeys.includes(rootDependency),
23+
dependenciesKeys.includes(rootDependency)
2424
);
2525
if (filteredRootDependencies.length > 0) {
2626
const plural = filteredRootDependencies.length > 1;
2727
console.log(`
2828
${chalk.whiteBright.bgYellow.bold(
29-
'Webpack does not work with native dependencies.',
29+
'Webpack does not work with native dependencies.'
3030
)}
3131
${chalk.bold(filteredRootDependencies.join(', '))} ${
3232
plural ? 'are native dependencies' : 'is a native dependency'
3333
} and should be installed inside of the "./release/app" folder.
3434
First, uninstall the packages from "./package.json":
3535
${chalk.whiteBright.bgGreen.bold('npm uninstall your-package')}
3636
${chalk.bold(
37-
'Then, instead of installing the package to the root "./package.json":',
37+
'Then, instead of installing the package to the root "./package.json":'
3838
)}
3939
${chalk.whiteBright.bgRed.bold('npm install your-package')}
4040
${chalk.bold('Install the package to "./release/app/package.json"')}
4141
${chalk.whiteBright.bgGreen.bold(
42-
'cd ./release/app && npm install your-package',
42+
'cd ./release/app && npm install your-package'
4343
)}
4444
Read more about native dependencies at:
4545
${chalk.bold(
46-
'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure',
46+
'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure'
4747
)}
4848
`);
4949
process.exit(1);

scripts/scripts/check-node-env.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export default function checkNodeEnv(expectedEnv) {
88
if (process.env.NODE_ENV !== expectedEnv) {
99
console.log(
1010
chalk.whiteBright.bgRed.bold(
11-
`"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config`,
12-
),
11+
`"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config`
12+
)
1313
);
1414
process.exit(2);
1515
}

scripts/scripts/check-port-in-use.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ detectPort(port, (err, availablePort) => {
77
if (port !== String(availablePort)) {
88
throw new Error(
99
chalk.whiteBright.bgRed.bold(
10-
`Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 npm start`,
11-
),
10+
`Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 npm start`
11+
)
1212
);
1313
} else {
1414
process.exit(0);

scripts/scripts/notarize.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ exports.default = async function notarizeMacos(context) {
1414

1515
if (!('APPLE_ID' in process.env && 'APPLE_ID_PASS' in process.env)) {
1616
console.warn(
17-
'Skipping notarizing step. APPLE_ID and APPLE_ID_PASS env variables must be set',
17+
'Skipping notarizing step. APPLE_ID and APPLE_ID_PASS env variables must be set'
1818
);
1919
return;
2020
}

src/components/pane.tsx

+200-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,211 @@
1+
import { Button } from 'renderer/components/ui/button';
2+
import {
3+
Dialog,
4+
DialogXContent,
5+
DialogHeader,
6+
DialogTitle,
7+
} from 'renderer/components/ui/dialog';
18
import { ProviderInterface } from 'lib/types';
9+
import React from 'react';
10+
import {
11+
ArrowLeftIcon,
12+
ArrowRightIcon,
13+
ReloadIcon,
14+
ResetIcon,
15+
ZoomInIcon,
16+
ZoomOutIcon,
17+
} from '@radix-ui/react-icons';
18+
import { Input } from 'renderer/components/ui/input';
19+
import {
20+
Tooltip,
21+
TooltipContent,
22+
TooltipProvider,
23+
TooltipTrigger,
24+
} from 'renderer/components/ui/tooltip';
25+
26+
export default function Pane({
27+
provider,
28+
number,
29+
currentlyOpenPreviewPane,
30+
setOpenPreviewPane,
31+
}: {
32+
provider: ProviderInterface;
33+
number: number;
34+
currentlyOpenPreviewPane: number;
35+
setOpenPreviewPane: (num: number) => void;
36+
}) {
37+
const isPreviewOpen = currentlyOpenPreviewPane === number;
38+
const contentRef = React.useRef<HTMLDivElement>(null);
39+
40+
const [shownUrl, setShownUrl] = React.useState(null);
41+
// this did not work not sure why
42+
// set a timer effect every second to check if the webview is can go back
43+
React.useEffect(() => {
44+
const interval = setInterval(() => {
45+
// @ts-ignore
46+
const newUrl = provider.getWebview()?.src;
47+
if (newUrl !== shownUrl) setShownUrl(newUrl);
48+
}, 1000);
49+
return () => clearInterval(interval);
50+
});
51+
52+
// this did not work not sure why
53+
// // set a timer effect every second to check if the webview is can go back
54+
// const [canGoBack, setCanGoBack] = React.useState(false);
55+
// const [canGoFwd, setCanGoFwd] = React.useState(false);
56+
// React.useEffect(() => {
57+
// const interval = setInterval(() => {
58+
// console.log(
59+
// 'provider.getWebview()?.canGoBack()',
60+
// provider.getWebview(),
61+
// provider.getWebview()?.canGoBack()
62+
// );
63+
// // @ts-ignore
64+
// if (provider.getWebview()?.canGoBack()) {
65+
// setCanGoBack(true);
66+
// } else {
67+
// setCanGoBack(false);
68+
// }
69+
// // @ts-ignore
70+
// if (provider.getWebview()?.canGoForward()) {
71+
// setCanGoFwd(true);
72+
// } else {
73+
// setCanGoFwd(true);
74+
// }
75+
// }, 1000);
76+
// return () => clearInterval(interval);
77+
// });
78+
79+
function XButton({ children, tooltip, onClick, className = '' }: any) {
80+
return (
81+
<TooltipProvider delayDuration={300}>
82+
<Tooltip>
83+
<TooltipTrigger asChild>
84+
<Button
85+
variant="outline"
86+
className={`hover:bg-gray-200 ${className}`}
87+
onClick={onClick}
88+
>
89+
{children}
90+
</Button>
91+
</TooltipTrigger>
92+
<TooltipContent side="right" className="text-white bg-black">
93+
<p>{tooltip}</p>
94+
</TooltipContent>
95+
</Tooltip>
96+
</TooltipProvider>
97+
);
98+
}
299

3-
export default function Pane({ provider }: { provider: ProviderInterface }) {
4100
return (
5-
<div key={provider.paneId()} className="page darwin">
101+
<div key={provider.paneId()} className="page darwin group">
102+
<div className="hidden powerbar group-hover:block">
103+
<Button
104+
className="text-xs shadow-2xl"
105+
onClick={() => setOpenPreviewPane(number)}
106+
variant="ghost"
107+
>
108+
<svg
109+
width="15"
110+
height="15"
111+
viewBox="0 0 15 15"
112+
fill="none"
113+
xmlns="http://www.w3.org/2000/svg"
114+
>
115+
<path
116+
d="M11.5 3.04999C11.7485 3.04999 11.95 3.25146 11.95 3.49999V7.49999C11.95 7.74852 11.7485 7.94999 11.5 7.94999C11.2515 7.94999 11.05 7.74852 11.05 7.49999V4.58639L4.58638 11.05H7.49999C7.74852 11.05 7.94999 11.2515 7.94999 11.5C7.94999 11.7485 7.74852 11.95 7.49999 11.95L3.49999 11.95C3.38064 11.95 3.26618 11.9026 3.18179 11.8182C3.0974 11.7338 3.04999 11.6193 3.04999 11.5L3.04999 7.49999C3.04999 7.25146 3.25146 7.04999 3.49999 7.04999C3.74852 7.04999 3.94999 7.25146 3.94999 7.49999L3.94999 10.4136L10.4136 3.94999L7.49999 3.94999C7.25146 3.94999 7.04999 3.74852 7.04999 3.49999C7.04999 3.25146 7.25146 3.04999 7.49999 3.04999L11.5 3.04999Z"
117+
fill="currentColor"
118+
fillRule="evenodd"
119+
clipRule="evenodd"
120+
></path>
121+
</svg>{' '}
122+
Cmd + {number}
123+
</Button>
124+
</div>
125+
<Dialog open={isPreviewOpen} onOpenChange={() => setOpenPreviewPane(0)}>
126+
<DialogXContent
127+
className="bg-white pointer-events-none"
128+
ref={contentRef}
129+
>
130+
<DialogHeader>
131+
<DialogTitle className="flex items-center justify-between pr-8">
132+
{provider.fullName}
133+
<div className="flex">
134+
<XButton
135+
tooltip="Cmd + ="
136+
onClick={() => {
137+
provider
138+
.getWebview()
139+
// @ts-ignore
140+
.setZoomLevel(provider.getWebview().getZoomLevel() + 1);
141+
}}
142+
>
143+
<ZoomInIcon />
144+
</XButton>
145+
<XButton
146+
tooltip="Cmd + -"
147+
onClick={() => {
148+
provider
149+
.getWebview()
150+
// @ts-ignore
151+
.setZoomLevel(provider.getWebview().getZoomLevel() - 1);
152+
}}
153+
>
154+
<ZoomOutIcon />
155+
</XButton>
156+
</div>
157+
<Input type="url" value={shownUrl || ''} readOnly={true} />
158+
<div className="flex">
159+
<XButton
160+
tooltip="Cmd + R"
161+
className="mr-4"
162+
onClick={() => {
163+
provider.getWebview()?.refresh();
164+
}}
165+
>
166+
<ReloadIcon />
167+
</XButton>
168+
<XButton
169+
tooltip="Cmd + h"
170+
onClick={() => {
171+
provider.getWebview()?.goBack();
172+
}}
173+
>
174+
<ArrowLeftIcon />
175+
</XButton>
176+
<XButton
177+
tooltip="Cmd + ;"
178+
onClick={() => {
179+
provider.getWebview()?.goForward();
180+
}}
181+
>
182+
<ArrowRightIcon />
183+
</XButton>
184+
{provider.clearCookies && (
185+
<Button
186+
variant="outline"
187+
onClick={() => {
188+
provider.clearCookies();
189+
}}
190+
>
191+
<ResetIcon className="mr-1" /> Clear Cookies
192+
</Button>
193+
)}
194+
</div>
195+
</DialogTitle>
196+
</DialogHeader>
197+
</DialogXContent>
198+
</Dialog>
6199
<webview
7200
// @ts-ignore - we need this to be here or it will not show up in electron and then the allowpopups doesnt work
8201
allowpopups="true"
9202
id={provider.webviewId}
10203
src={provider.url}
204+
className={
205+
isPreviewOpen
206+
? 'fixed pointer-events-auto left-[5%] top-[10%] z-[100] grid w-10/12 gap-4 p-2 duration-200 sm:rounded-lg rounded-xl h-[85vh]'
207+
: ''
208+
}
11209
useragent={
12210
provider.getUserAgent() ? provider.getUserAgent() : undefined
13211
}

src/lib/types.ts

+14
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,18 @@ export interface ProviderInterface {
1616
getUserAgent(): string;
1717
isEnabled(): boolean;
1818
setEnabled(enabled: boolean): void;
19+
clearCookies(): void;
20+
}
21+
22+
export interface Settings {
23+
getGlobalShortcut: () => Promise<string>;
24+
setGlobalShortcut: (shortcut: string) => Promise<boolean>;
25+
getPlatform: () => Promise<string>;
26+
}
27+
28+
// Tell typescript that the window object has a property called settings
29+
declare global {
30+
interface Window {
31+
settings: Settings;
32+
}
1933
}

0 commit comments

Comments
 (0)