Skip to content

Commit aaf93d1

Browse files
committed
feat: add Windows support
1 parent 70fd4f4 commit aaf93d1

File tree

9 files changed

+137
-23
lines changed

9 files changed

+137
-23
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"main": "build/src/main/index.js",
66
"scripts": {
77
"dev": "tsc-watch -p tsconfig.electron.json --onSuccess 'npm run dev:server'",
8+
"dev:win": "tsc-watch -p tsconfig.electron.json",
89
"dev:server": "node build/src/scripts/dev-server.js",
910
"build:ts": "tsc -p tsconfig.electron.json",
1011
"build": "npm run build:ts && node build/src/scripts/build.js ",

src/main/index.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { app, BrowserWindow, ipcMain, Menu, shell } from 'electron'
2+
import type { Rectangle } from 'electron'
23
import path from 'path'
4+
import { platform } from 'process'
35
import { store } from './store'
46
import { checkForUpdate } from './update-check'
57
import { ImageOptimizer } from './image-compressor'
@@ -8,12 +10,21 @@ import { createMenu } from './menu'
810
const isDev = process.env.NODE_ENV === 'development'
911
let mainWindow: BrowserWindow
1012

13+
function getPlatform () {
14+
switch (platform) {
15+
case 'darwin': return 'macos'
16+
case 'win32': return 'windows'
17+
default: return 'linux'
18+
}
19+
}
20+
1121
function createWindow () {
12-
const bounds = store.app.get('bounds')
22+
const { x, y } = store.app.get('bounds') as Rectangle
1323
mainWindow = new BrowserWindow({
1424
width: 550,
1525
height: 370,
16-
...bounds,
26+
x,
27+
y,
1728
titleBarStyle: 'hidden',
1829
resizable: false,
1930
backgroundColor: '#212123',
@@ -40,6 +51,7 @@ function createWindow () {
4051
}
4152

4253
function init () {
54+
store.app.set('os', getPlatform())
4355
createWindow()
4456
checkForUpdate(mainWindow)
4557
Menu.setApplicationMenu(Menu.buildFromTemplate(createMenu(mainWindow)))
@@ -72,6 +84,14 @@ ipcMain.on('drop', (_, files = []) => {
7284
optimizer.start()
7385
})
7486

87+
ipcMain.on('toolbar', (_, type) => {
88+
switch (type) {
89+
case 'reduce': return mainWindow.minimize()
90+
case 'maximize': return mainWindow.maximize()
91+
case 'close': return mainWindow.close()
92+
}
93+
})
94+
7595
ipcMain.on('open-url', (event, url) => {
7696
shell.openExternal(url)
7797
})

src/main/store/module/app.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ export default new Store<StoreSchema>({
66
watch: true,
77

88
schema: {
9+
os: {
10+
type: 'string',
11+
default: 'macos'
12+
},
913
bounds: {
1014
type: 'object',
1115
default: {}

src/main/types/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ declare global {
2323
}
2424

2525
export interface StoreSchema {
26+
os: ['macos', 'windows', 'linux']
2627
bounds: object
2728
addToSubfolder: boolean
2829
addMinSuffix: boolean

src/renderer/App.vue

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<template>
2-
<div class="app-tool-bar" />
2+
<header>
3+
<AppTitleBar />
4+
</header>
35
<main>
46
<RouterView />
57
</main>
@@ -58,13 +60,17 @@ ipc.on('drop-from-dialog', () => {
5860
height: 100vh;
5961
overflow: hidden;
6062
display: grid;
61-
grid-template-rows: auto var(--footer-height);
63+
grid-template-rows: var(--toolbar-height) auto var(--footer-height);
6264
grid-template-areas:
65+
'header'
6366
'main'
6467
'footer';
68+
header {
69+
grid-area: header;
70+
}
6571
main {
6672
grid-area: main;
67-
padding: var(--toolbar-height) 12px 0 12px;
73+
padding: 0 12px 0 12px;
6874
}
6975
footer {
7076
grid-area: footer;
@@ -79,16 +85,4 @@ ipc.on('drop-from-dialog', () => {
7985
pointer-events: none;
8086
}
8187
}
82-
83-
.app {
84-
&-tool-bar {
85-
position: absolute;
86-
top: 0;
87-
width: 100%;
88-
height: var(--toolbar-height);
89-
-webkit-app-region: drag;
90-
z-index: 1010;
91-
transition: all 0.5s;
92-
}
93-
}
9488
</style>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<template>
2+
<div
3+
class="tool-bar"
4+
:class="platform"
5+
>
6+
<div class="drag-zone" />
7+
<div
8+
class="reduce"
9+
@click="ipc.send('toolbar', 'reduce')"
10+
/>
11+
<div
12+
class="close"
13+
@click="ipc.send('toolbar', 'close')"
14+
/>
15+
</div>
16+
</template>
17+
18+
<script setup lang="ts">
19+
import { store as electronStore, ipc } from '@/electron'
20+
21+
const platform = electronStore.get('os')
22+
</script>
23+
24+
<style lang="scss" scoped>
25+
.tool-bar {
26+
height: var(--toolbar-height);
27+
display: flex;
28+
justify-content: right;
29+
align-items: center;
30+
31+
.drag-zone {
32+
width: 100%;
33+
height: 100%;
34+
-webkit-app-region: drag;
35+
}
36+
}
37+
38+
.windows {
39+
div:not(.drag-zone) {
40+
position: relative;
41+
width: 50px;
42+
height: 100%;
43+
display: flex;
44+
align-items: center;
45+
justify-content: center;
46+
}
47+
48+
div:hover {
49+
background: rgba(255, 255, 255, 0.2);
50+
}
51+
52+
.reduce::before {
53+
content: "";
54+
position: absolute;
55+
top: 50%;
56+
left: 38%;
57+
width: 10px;
58+
border-bottom: 1px solid var(--color-gray-700);
59+
}
60+
61+
.maximize::before {
62+
content: "";
63+
position: absolute;
64+
top: 37%;
65+
left: 37%;
66+
width: 8px;
67+
height: 8px;
68+
border: 1px solid var(--color-gray-700);
69+
}
70+
71+
.close::before, .close::after {
72+
content: "";
73+
position: absolute;
74+
top: 50%;
75+
left: 32%;
76+
width: 14px;
77+
height: 0.5px;
78+
transform: rotate(45deg);
79+
background: var(--color-gray-700);
80+
}
81+
82+
.close::after {
83+
transform: rotate(-45deg);
84+
}
85+
86+
.close:hover {
87+
background: rgba(232, 17, 35, 0.8);
88+
}
89+
}
90+
</style>

src/renderer/components/ui/AppInput.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
</div>
1313
</template>
1414

15-
<script setup lang="ts">import { computed } from 'vue'
15+
<script setup lang="ts">
16+
import { computed } from 'vue'
1617
1718
interface Props {
1819
modelValue: string | number

src/renderer/types/components.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ declare module 'vue' {
1010
AppInput: typeof import('./../components/ui/AppInput.vue')['default']
1111
AppPreloader: typeof import('./../components/ui/AppPreloader.vue')['default']
1212
AppSettingRow: typeof import('./../components/AppSettingRow.vue')['default']
13+
AppTitleBar: typeof import('./../components/AppTitleBar.vue')['default']
1314
AppToggle: typeof import('./../components/ui/AppToggle.vue')['default']
1415
SvgArrowCircleUp: typeof import('~icons/svg/arrow-circle-up')['default']
1516
SvgCog: typeof import('~icons/svg/cog')['default']
@@ -18,4 +19,4 @@ declare module 'vue' {
1819
}
1920
}
2021

21-
export {}
22+
export { }

src/scripts/dev-server.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { spawn } from 'child_process'
2-
import type { ChildProcess, SpawnOptionsWithoutStdio } from 'child_process'
2+
import type { ChildProcess } from 'child_process'
33
import path from 'path'
44
import chalk from 'chalk'
55
import chokidar from 'chokidar'
@@ -23,9 +23,7 @@ async function startRenderer () {
2323
function startElectron () {
2424
if (electronProcess) return
2525

26-
const args = ['.', rendererPort] as SpawnOptionsWithoutStdio
27-
28-
electronProcess = spawn('electron', args)
26+
electronProcess = spawn('electron', ['.', (rendererPort || 0).toString()], { shell: true })
2927

3028
electronProcess?.stdout?.on('data', data => {
3129
console.log(chalk.blueBright('[Electron] ') + chalk.white(data.toString()))
@@ -34,6 +32,10 @@ function startElectron () {
3432
electronProcess?.stderr?.on('data', data => {
3533
console.log(chalk.redBright('[Electron] ') + chalk.white(data.toString()))
3634
})
35+
36+
electronProcess.on('error', error => {
37+
console.log(chalk.redBright('[Electron] ', error))
38+
})
3739
}
3840

3941
function restartElectron () {

0 commit comments

Comments
 (0)