Skip to content

Commit

Permalink
Merge pull request #76 from 2skydev/dev
Browse files Browse the repository at this point in the history
v0.0.16
  • Loading branch information
2skydev authored Aug 3, 2023
2 parents 671b85c + 674bfae commit 365888c
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 27 deletions.
110 changes: 95 additions & 15 deletions src/main/modules/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { app, BrowserWindow, Menu, nativeImage, shell, Tray } from 'electron'
import {
app,
BrowserWindow,
Menu,
MenuItemConstructorOptions,
nativeImage,
shell,
Tray,
} from 'electron'

import { initializer, singleton } from '@launchtray/tsyringe-async'
import { join } from 'path'
import { match } from 'path-to-regexp'

import { productName, protocols } from '@main/../../electron-builder.json'
import { IPCHandle } from '@main/core/decorators/ipcHandle'
import { ZOOM_PERCENT_ARRAY } from '@main/modules/app/constants/size'
import { ConfigModule } from '@main/modules/config/config.module'

export type AppControlAction = 'devtools' | 'minimize' | 'maximize' | 'close'

Expand All @@ -25,9 +35,16 @@ export class AppModule {
)
readonly IS_HIDDEN_LAUNCH = process.argv.includes('--hidden')

readonly APP_WIDTH = 1800
readonly APP_HEIGHT = 1000

readonly ZOOM_PERCENT_ARRAY = ZOOM_PERCENT_ARRAY

// main window
window: BrowserWindow | null = null

tray: Tray | null = null

// deep link handlers
deepLinkHandlers: Record<string, (params: object) => void> = {}

Expand All @@ -37,9 +54,39 @@ export class AppModule {

isStarted = false

constructor() {
zoom: number

contextMenu: MenuItemConstructorOptions[] = [
{ label: 'LADA 홈 화면 보기', type: 'normal', click: () => this.createWindow() },
{
label: '앱 비율 설정',
type: 'submenu',
submenu: [
...this.ZOOM_PERCENT_ARRAY.map(
percent =>
({
label: `${percent}%`,
type: 'normal',
click: () => this.setZoom(percent / 100),
} as MenuItemConstructorOptions),
),
],
},
{ type: 'separator' },
{ label: '앱 끄기', role: 'quit', type: 'normal' },
]

constructor(private configModule: ConfigModule) {
// smooth scrolling
app.commandLine.appendSwitch(`--enable-smooth-scrolling`)

// protocol
app.setAsDefaultProtocolClient(this.PROTOCOL)

// zoom
this.zoom = this.configModule.store.get('general.zoom')
const index = this.ZOOM_PERCENT_ARRAY.findIndex(percent => percent === this.zoom * 100)
this.contextMenu[1].submenu![index].label = `${this.zoom * 100}% (현재값)`
}

@initializer()
Expand Down Expand Up @@ -80,8 +127,8 @@ export class AppModule {
}

this.window = new BrowserWindow({
width: 1800,
height: 1000,
width: this.APP_WIDTH,
height: this.APP_HEIGHT,
backgroundColor: '#36393F',
darkTheme: true,
show: false,
Expand All @@ -104,7 +151,8 @@ export class AppModule {
}

this.window.on('ready-to-show', () => {
this.window?.show()
this.applyZoom(this.zoom)
this.window!.show()
resolve()
})

Expand All @@ -122,6 +170,35 @@ export class AppModule {
})
}

setZoom(zoom: number) {
if (!this.window) return

if (this.tray) {
const beforeIndex = this.ZOOM_PERCENT_ARRAY.findIndex(percent => percent === this.zoom * 100)
const afterIndex = this.ZOOM_PERCENT_ARRAY.findIndex(percent => percent === zoom * 100)

this.contextMenu[1].submenu![beforeIndex].label = `${this.zoom * 100}%`
this.contextMenu[1].submenu![afterIndex].label = `${zoom * 100}% (현재값)`

this.tray.setContextMenu(Menu.buildFromTemplate(this.contextMenu))
}

this.zoom = zoom
this.configModule.store.set('general.zoom', zoom)

this.applyZoom(zoom)
}

private applyZoom(zoom: number) {
if (!this.window) return

// setMinimumSize를 사용하는 이유는 아래 setSize만 사용했을 때 의도된 설계인지 모르겠지만 최소 크기가 자동으로 변경되어 크기를 줄일 수 없다.
// 그래서 setMinimumSize를 사용하여 직접 최소 크기를 변경 후 setSize를 사용하여 크기를 변경한다.
this.window.setMinimumSize(this.APP_WIDTH * zoom, this.APP_HEIGHT * zoom)
this.window.setSize(this.APP_WIDTH * zoom, this.APP_HEIGHT * zoom, true)
this.window.webContents.setZoomFactor(zoom)
}

registerEvents() {
app.on('activate', () => {
this.createWindow()
Expand All @@ -141,20 +218,23 @@ export class AppModule {
app.on('open-url', (_, url) => {
this.resolveDeepLink(url)
})

this.configModule.store.onDidAnyChange(newValue => {
if (!this.window) return
this.window.webContents.send('configChanged', newValue)
})

this.configModule.onChange('general.zoom', value => {
this.setZoom(value)
})
}

createTray() {
let tray = new Tray(this.ICON.resize({ width: 20, height: 20 }))

const contextMenu = Menu.buildFromTemplate([
{ label: 'LADA 홈 화면 보기', type: 'normal', click: () => this.createWindow() },
{ type: 'separator' },
{ label: '앱 끄기', role: 'quit', type: 'normal' },
])
this.tray = new Tray(this.ICON.resize({ width: 20, height: 20 }))

tray.on('double-click', () => this.createWindow())
tray.setToolTip(productName)
tray.setContextMenu(contextMenu)
this.tray.on('double-click', () => this.createWindow())
this.tray.setToolTip(productName)
this.tray.setContextMenu(Menu.buildFromTemplate(this.contextMenu))
}

resolveDeepLink(url: string) {
Expand Down
1 change: 1 addition & 0 deletions src/main/modules/app/constants/size.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const ZOOM_PERCENT_ARRAY = [70, 75, 80, 85, 90, 95, 100]
15 changes: 15 additions & 0 deletions src/main/modules/config/config.module.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { FieldPath, FieldPathValue } from 'react-hook-form'

import { singleton } from '@launchtray/tsyringe-async'

import { IPCHandle } from '@main/core/decorators/ipcHandle'
Expand All @@ -6,6 +8,19 @@ import { configStore } from '@main/modules/config/stores/config.store'

@singleton()
export class ConfigModule {
readonly store = configStore

onChange<Key extends FieldPath<ConfigStoreValues> = FieldPath<ConfigStoreValues>>(
key: Key,
callback: (
newValue: FieldPathValue<ConfigStoreValues, Key>,
oldValue: FieldPathValue<ConfigStoreValues, Key>,
) => void,
) {
// @ts-ignore
return this.store.onDidChange(key, callback)
}

@IPCHandle()
async getConfig() {
return configStore.store
Expand Down
2 changes: 2 additions & 0 deletions src/main/modules/config/stores/config.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface ConfigStoreValues {
autoLaunch: boolean
developerMode: boolean
openWindowWhenLeagueClientLaunch: boolean
zoom: number
}
game: {
autoAccept: boolean
Expand All @@ -26,6 +27,7 @@ export const configStore = new Store<ConfigStoreValues>({
autoLaunch: false,
developerMode: IS_DEV,
openWindowWhenLeagueClientLaunch: true,
zoom: 1.0,
},
game: {
autoAccept: false,
Expand Down
6 changes: 4 additions & 2 deletions src/main/modules/developer/developer.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import log from 'electron-log'
import { singleton } from '@launchtray/tsyringe-async'

import { IPCHandle } from '@main/core/decorators/ipcHandle'
import { configStore } from '@main/modules/config/stores/config.store'
import { ConfigModule } from '@main/modules/config/config.module'

export interface Log {
size: number
Expand All @@ -13,9 +13,11 @@ export interface Log {

@singleton()
export class DeveloperModule {
constructor(private configModule: ConfigModule) {}

@IPCHandle()
async getStorePath() {
return configStore.path
return this.configModule.store.path
}

@IPCHandle()
Expand Down
9 changes: 5 additions & 4 deletions src/main/modules/league/league.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import axios from 'axios'

import { IPCHandle } from '@main/core/decorators/ipcHandle'
import { AppModule } from '@main/modules/app/app.module'
import { configStore } from '@main/modules/config/stores/config.store'
import { ConfigModule } from '@main/modules/config/config.module'
import LeagueAPIClient from '@main/modules/league/utils/leagueAPIClient'
import IPCServer from '@main/utils/IPCServer'

Expand All @@ -18,7 +18,7 @@ export class LeagueModule {
isConnected = false
clientOverlayWindow: BrowserWindow | null = null

constructor(private appModule: AppModule) {
constructor(private appModule: AppModule, private configModule: ConfigModule) {
this.server = new IPCServer('apis/league')
this.client = new LeagueAPIClient()

Expand Down Expand Up @@ -62,7 +62,7 @@ export class LeagueModule {
this.client.on('ready', () => {
// 리그 클라이언트 실행 시 LADA 창 열기
if (
configStore.get('general.openWindowWhenLeagueClientLaunch') &&
this.configModule.store.get('general.openWindowWhenLeagueClientLaunch') &&
!this.appModule.window &&
this.appModule.isStarted
) {
Expand Down Expand Up @@ -93,7 +93,8 @@ export class LeagueModule {
if (!data) return

if (data.playerResponse === 'None') {
const { autoAccept = false, autoAcceptDelaySeconds = 0 } = configStore.get('game')
const { autoAccept = false, autoAcceptDelaySeconds = 0 } =
this.configModule.store.get('game')

if (!autoAccept) return

Expand Down
14 changes: 9 additions & 5 deletions src/main/modules/migration/migration.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { initializer, singleton } from '@launchtray/tsyringe-async'
import AutoLaunch from 'auto-launch'
import { valid, gt } from 'semver'

import { configStore } from '@main/modules/config/stores/config.store'
import { ConfigModule } from '@main/modules/config/config.module'
import { migrationStore } from '@main/modules/migration/stores/migration.store'

@singleton()
export class MigrationModule {
constructor() {}
constructor(private configModule: ConfigModule) {}

@initializer()
async migrate() {
Expand Down Expand Up @@ -38,9 +38,9 @@ export class MigrationModule {
}

async 'v0.0.5'() {
configStore.set('general.openWindowWhenLeagueClientLaunch', true)
this.configModule.store.set('general.openWindowWhenLeagueClientLaunch', true)

if (configStore.get('general.autoLaunch')) {
if (this.configModule.store.get('general.autoLaunch')) {
const ladaAutoLauncher = new AutoLaunch({
name: 'LADA',
path: app.getPath('exe'),
Expand All @@ -53,6 +53,10 @@ export class MigrationModule {
}

async 'v0.0.11'() {
configStore.set('game.useCurrentPositionChampionData', true)
this.configModule.store.set('game.useCurrentPositionChampionData', true)
}

async 'v0.0.16'() {
this.configModule.store.set('general.zoom', 1.0)
}
}
6 changes: 6 additions & 0 deletions src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ const electronContext = {
setConfig: (config: ConfigStoreValues): Promise<ConfigStoreValues> =>
ipcRenderer.invoke('setConfig', config),

/**
* 설정 변경 이벤트 리스너
*/
onChangeConfig: (callback: (newValue: ConfigStoreValues) => void) =>
ipcRenderer.on('configChanged', (_, newValue) => callback(newValue)),

/**
* =================================
* UpdateModule IPCs
Expand Down
20 changes: 20 additions & 0 deletions src/renderer/src/hooks/listener/useConfigListener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEffect } from 'react'

import deepEqual from 'fast-deep-equal'
import { useSetAtom } from 'jotai'

import { defaultStore } from '@renderer/stores'
import { configAtom } from '@renderer/stores/atoms/config.atom'

const useConfigListener = () => {
const setConfig = useSetAtom(configAtom)

useEffect(() => {
window.electron.onChangeConfig(value => {
if (deepEqual(value, defaultStore.get(configAtom))) return
setConfig(value)
})
}, [])
}

export default useConfigListener
2 changes: 2 additions & 0 deletions src/renderer/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import useInGamePageAutoNavigate from '@renderer/hooks/autoNavigate/useInGamePag
import useTierListPageAutoNavigate from '@renderer/hooks/autoNavigate/useTierListPageAutoNavigate'
import useAppUpdateListener from '@renderer/hooks/listener/useAppUpdateListener'
import useChampionSelectSessionListener from '@renderer/hooks/listener/useChampionSelectSessionListener'
import useConfigListener from '@renderer/hooks/listener/useConfigListener'
import useCurrentSummonerListener from '@renderer/hooks/listener/useCurrentSummonerListener'
import useLeagueListener from '@renderer/hooks/listener/useLeagueListener'
import { useUpdateContentModal } from '@renderer/hooks/useUpdateContentModal'
Expand All @@ -23,6 +24,7 @@ const App = () => {
useUpdateContentModal({ autoOpen: !isNoLayout })

// listeners
useConfigListener()
useLeagueListener()
useAppUpdateListener()
useChampionSelectSessionListener()
Expand Down
Loading

0 comments on commit 365888c

Please sign in to comment.