mirror of
https://github.com/Kvan7/Exiled-Exchange-2.git
synced 2026-09-20 11:45:42 +00:00
price check refactor
This commit is contained in:
+6
-1
@@ -4,11 +4,12 @@ import { app, protocol, ipcMain, screen } from 'electron'
|
||||
import { installVueDevtools } from 'vue-cli-plugin-electron-builder/lib'
|
||||
import { setupShortcuts } from './main/shortcuts'
|
||||
import { createTray } from './main/tray'
|
||||
import { setupShowHide } from './main/positioning'
|
||||
import { setupShowHide } from './main/price-check'
|
||||
import { setupConfigEvents, config } from './main/config'
|
||||
import { CLOSE_SETTINGS_WINDOW } from '@/ipc/ipc-event'
|
||||
import { closeWindow as closeSettings } from './main/SettingsWindow'
|
||||
import { logger } from './main/logger'
|
||||
import { checkForUpdates } from './main/updates'
|
||||
import os from 'os'
|
||||
import { createOverlayWindow } from './main/overlay-window'
|
||||
import { setupAltVisibility } from './main/alt-visibility'
|
||||
@@ -64,6 +65,10 @@ app.on('ready', async () => {
|
||||
process.platform === 'linux' ? 1000 : 0
|
||||
)
|
||||
|
||||
if (!isDevelopment) {
|
||||
checkForUpdates()
|
||||
}
|
||||
|
||||
ipcMain.on(CLOSE_SETTINGS_WINDOW, closeSettings)
|
||||
})
|
||||
|
||||
|
||||
@@ -15,6 +15,13 @@ export const FOCUS_CHANGE = 'OVERLAY::focus-change'
|
||||
|
||||
export const DPR_CHANGE = 'OVERLAY->MAIN::devicePixelRatio-change'
|
||||
|
||||
export const PRICE_CHECK = 'MAIN->OVERLAY::price-check'
|
||||
export const PRICE_CHECK_CANCELED = 'MAIN->OVERLAY::price-check-canceled'
|
||||
export interface IpcPriceCheck {
|
||||
clipboard: string
|
||||
position: { x: number, y: number }
|
||||
}
|
||||
|
||||
|
||||
export const SHOW_BROWSER = 'OVERLAY->MAIN::show-browser'
|
||||
export interface IpcShowBrowser {
|
||||
|
||||
@@ -48,9 +48,9 @@ class MainProcessBinding extends EventTarget {
|
||||
}
|
||||
}
|
||||
|
||||
selfEmitPriceCheck (data: { clipboard: string, position: string }) {
|
||||
this.dispatchEvent(new CustomEvent('price-check', {
|
||||
detail: data
|
||||
selfEmitPriceCheck (e: ipcEvent.IpcPriceCheck) {
|
||||
this.dispatchEvent(new CustomEvent(ipcEvent.PRICE_CHECK, {
|
||||
detail: e
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@@ -33,14 +33,6 @@ class PoeWindowClass extends EventEmitter {
|
||||
return Math.round(this.bounds!.height * ratio)
|
||||
}
|
||||
|
||||
getPoeUiPosition (mousePos: Point) {
|
||||
if (mousePos.x > (this.bounds!.x + this.bounds!.width / 2)) {
|
||||
return 'inventory'
|
||||
} else {
|
||||
return 'stash' // or chat/vendor/center of screen
|
||||
}
|
||||
}
|
||||
|
||||
attach (window: BrowserWindow) {
|
||||
OW.on('focus', () => { this.isActive = true })
|
||||
OW.on('blur', () => { this.isActive = false })
|
||||
|
||||
+39
-39
@@ -2,20 +2,25 @@ import path from 'path'
|
||||
import { BrowserWindow, ipcMain, dialog } from 'electron'
|
||||
import { PoeWindow } from './PoeWindow'
|
||||
import { logger } from './logger'
|
||||
import { OVERLAY_READY, FOCUS_CHANGE } from '@/ipc/ipc-event'
|
||||
import * as ipc from '@/ipc/ipc-event'
|
||||
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
|
||||
import { checkForUpdates } from './updates'
|
||||
import { overlayWindow as OW } from 'electron-overlay-window'
|
||||
|
||||
export let overlayWindow: BrowserWindow | undefined
|
||||
export let isInteractable = false
|
||||
export let DPR = 1
|
||||
|
||||
let _resolveOverlayReady: Function
|
||||
let _resolveOverlayReady: () => void
|
||||
export const overlayReady = new Promise<void>((resolve) => {
|
||||
_resolveOverlayReady = resolve
|
||||
})
|
||||
|
||||
export async function createOverlayWindow () {
|
||||
ipcMain.once(ipc.OVERLAY_READY, _resolveOverlayReady)
|
||||
ipcMain.on(ipc.DPR_CHANGE, (_: any, dpr: number) => handleDprChange(dpr))
|
||||
PoeWindow.on('active-change', handlePoeWindowActiveChange)
|
||||
PoeWindow.onceAttached(handleOverlayAttached)
|
||||
|
||||
overlayWindow = new BrowserWindow({
|
||||
icon: path.join(__static, 'icon.png'),
|
||||
...OW.WINDOW_OPTS,
|
||||
@@ -28,49 +33,18 @@ export async function createOverlayWindow () {
|
||||
}
|
||||
})
|
||||
|
||||
overlayWindow.setIgnoreMouseEvents(true)
|
||||
|
||||
if (process.env.WEBPACK_DEV_SERVER_URL) {
|
||||
overlayWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL + '#overlay')
|
||||
overlayWindow.webContents.openDevTools({ mode: 'detach', activate: false })
|
||||
} else {
|
||||
createProtocol('app')
|
||||
overlayWindow.loadURL('app://./index.html#overlay')
|
||||
checkForUpdates()
|
||||
}
|
||||
|
||||
overlayWindow.setIgnoreMouseEvents(true)
|
||||
|
||||
ipcMain.once(OVERLAY_READY, () => {
|
||||
_resolveOverlayReady()
|
||||
})
|
||||
|
||||
PoeWindow.on('active-change', (isActive) => {
|
||||
if (!overlayWindow) {
|
||||
logger.error('Window is not ready')
|
||||
return
|
||||
}
|
||||
|
||||
if (isActive && isInteractable) {
|
||||
isInteractable = false
|
||||
overlayWindow.setIgnoreMouseEvents(true)
|
||||
}
|
||||
overlayWindow.webContents.send(FOCUS_CHANGE, { game: isActive, overlay: isInteractable })
|
||||
})
|
||||
|
||||
PoeWindow.onceAttached((hasAccess) => {
|
||||
if (hasAccess === false) {
|
||||
dialog.showErrorBox(
|
||||
'PoE window - No access',
|
||||
// ----------------------
|
||||
'Path of Exile is running with administrator rights.\n' +
|
||||
'\n' +
|
||||
'You need to restart Awakened PoE Trade with administrator rights.'
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
const electronReadyToShow = new Promise<void>((resolve) => {
|
||||
overlayWindow!.once('ready-to-show', resolve)
|
||||
})
|
||||
const electronReadyToShow = new Promise<void>(resolve =>
|
||||
overlayWindow!.once('ready-to-show', resolve))
|
||||
await electronReadyToShow
|
||||
await overlayReady
|
||||
PoeWindow.attach(overlayWindow)
|
||||
@@ -86,7 +60,15 @@ export function toggleOverlayState () {
|
||||
} else {
|
||||
focusOverlay()
|
||||
}
|
||||
overlayWindow.webContents.send(FOCUS_CHANGE, { game: PoeWindow.isActive, overlay: isInteractable })
|
||||
overlayWindow.webContents.send(ipc.FOCUS_CHANGE, { game: PoeWindow.isActive, overlay: isInteractable })
|
||||
}
|
||||
|
||||
function handlePoeWindowActiveChange (isActive: boolean) {
|
||||
if (isActive && isInteractable) {
|
||||
isInteractable = false
|
||||
overlayWindow!.setIgnoreMouseEvents(true)
|
||||
}
|
||||
overlayWindow!.webContents.send(ipc.FOCUS_CHANGE, { game: isActive, overlay: isInteractable })
|
||||
}
|
||||
|
||||
export function assertOverlayActive () {
|
||||
@@ -118,3 +100,21 @@ function focusPoE () {
|
||||
OW.focusTarget()
|
||||
PoeWindow.isActive = true
|
||||
}
|
||||
|
||||
function handleOverlayAttached (hasAccess?: boolean) {
|
||||
if (hasAccess === false) {
|
||||
dialog.showErrorBox(
|
||||
'PoE window - No access',
|
||||
// ----------------------
|
||||
'Path of Exile is running with administrator rights.\n' +
|
||||
'\n' +
|
||||
'You need to restart Awakened PoE Trade with administrator rights.'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function handleDprChange (devicePixelRatio: number) {
|
||||
if (process.platform === 'win32') {
|
||||
DPR = devicePixelRatio
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,31 @@
|
||||
import { ipcMain, screen, Rectangle, BrowserView, Point, shell } from 'electron'
|
||||
import { ipcMain, Rectangle, Point } from 'electron'
|
||||
import { uIOhook } from 'uiohook-napi'
|
||||
import { checkPressPosition, isPollingClipboard } from './shortcuts'
|
||||
import { isPollingClipboard } from './shortcuts'
|
||||
import { PoeWindow } from './PoeWindow'
|
||||
import { PRICE_CHECK_HIDE, PRICE_CHECK_MOUSE, OPEN_LINK, OPEN_LINK_EXTERNAL, PRICE_CHECK_CANCELED, DPR_CHANGE } from '@/ipc/ipc-event'
|
||||
import * as ipc from '@/ipc/ipc-event'
|
||||
import { config } from './config'
|
||||
import { logger } from './logger'
|
||||
import { overlayWindow, isInteractable, assertOverlayActive, assertPoEActive } from './overlay-window'
|
||||
import { overlayWindow, isInteractable, assertOverlayActive, assertPoEActive, DPR } from './overlay-window'
|
||||
|
||||
const WIDTH_96DPI = 460
|
||||
const CLOSE_THRESHOLD_96DPI = 40
|
||||
let DPR = 1
|
||||
|
||||
let isPriceCheckShown = false
|
||||
let isClickedAfterLock = false
|
||||
|
||||
let checkPressPosition: Point | undefined
|
||||
let activeAreaRect: Rectangle | undefined
|
||||
let isMouseInside = false
|
||||
|
||||
let browserViewExternal: BrowserView | undefined
|
||||
export function showWidget (opts: {
|
||||
clipboard: string
|
||||
hotkeyPressPosition: Point
|
||||
lockedMode: boolean
|
||||
}) {
|
||||
checkPressPosition = opts.hotkeyPressPosition
|
||||
|
||||
overlayWindow!.webContents.send(ipc.PRICE_CHECK, { clipboard: opts.clipboard, position: checkPressPosition } as ipc.IpcPriceCheck)
|
||||
|
||||
export function showWindow () {
|
||||
const poeBounds = PoeWindow.bounds!
|
||||
activeAreaRect = {
|
||||
x: getOffsetX(checkPressPosition!, poeBounds),
|
||||
@@ -31,21 +37,9 @@ export function showWindow () {
|
||||
isPriceCheckShown = true
|
||||
isClickedAfterLock = false
|
||||
isMouseInside = false
|
||||
}
|
||||
|
||||
function hideWindow () {
|
||||
isPriceCheckShown = false
|
||||
isMouseInside = false
|
||||
activeAreaRect = undefined
|
||||
|
||||
if (isInteractable) {
|
||||
if (browserViewExternal) {
|
||||
overlayWindow!.removeBrowserView(browserViewExternal)
|
||||
// uncomment to trade performance for less memory usage (1 process & 13 MB)
|
||||
// browserViewExternal.destroy()
|
||||
// browserViewExternal = undefined
|
||||
browserViewExternal.webContents.loadURL('about:blank')
|
||||
}
|
||||
if (opts.lockedMode) {
|
||||
lockWindow(true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +50,7 @@ export function lockWindow (syntheticClick = false) {
|
||||
}
|
||||
|
||||
export function setupShowHide () {
|
||||
ipcMain.on(PRICE_CHECK_HIDE, () => {
|
||||
ipcMain.on(ipc.PRICE_CHECK_HIDE, () => {
|
||||
logger.debug('Closing', { source: 'price-check', reason: 'Close button or hotkey' })
|
||||
isPriceCheckShown = false
|
||||
assertPoEActive()
|
||||
@@ -69,13 +63,7 @@ export function setupShowHide () {
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on(DPR_CHANGE, (_: any, devicePixelRatio: number) => {
|
||||
if (process.platform === 'win32') {
|
||||
DPR = devicePixelRatio
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on(PRICE_CHECK_MOUSE, (e, name: string, modifier?: string) => {
|
||||
ipcMain.on(ipc.PRICE_CHECK_MOUSE, (e, name: string, modifier?: string) => {
|
||||
if (name === 'click') {
|
||||
isClickedAfterLock = true
|
||||
logger.debug('Clicked inside window after lock', { source: 'price-check' })
|
||||
@@ -100,30 +88,6 @@ export function setupShowHide () {
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on(OPEN_LINK, (e, link) => {
|
||||
if (!browserViewExternal) {
|
||||
browserViewExternal = new BrowserView()
|
||||
}
|
||||
|
||||
overlayWindow!.setBrowserView(browserViewExternal)
|
||||
let browserBounds = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: PoeWindow.bounds!.width - Math.floor(WIDTH_96DPI * DPR),
|
||||
height: PoeWindow.bounds!.height
|
||||
}
|
||||
if (process.platform === 'win32') {
|
||||
browserBounds = screen.screenToDipRect(overlayWindow!, browserBounds)
|
||||
}
|
||||
browserViewExternal.setBounds(browserBounds)
|
||||
browserViewExternal.webContents.loadURL(link)
|
||||
})
|
||||
|
||||
ipcMain.on(OPEN_LINK_EXTERNAL, (e, link) => {
|
||||
hideWindow()
|
||||
shell.openExternal(link)
|
||||
})
|
||||
|
||||
uIOhook.on('mousemove', (e) => {
|
||||
if (!isPriceCheckShown) return
|
||||
|
||||
@@ -134,7 +98,7 @@ export function setupShowHide () {
|
||||
|
||||
if (distance > (CLOSE_THRESHOLD_96DPI * DPR)) {
|
||||
logger.debug('Closing', { source: 'price-check', reason: 'Auto-hide on mouse move', distance, threshold: CLOSE_THRESHOLD_96DPI })
|
||||
overlayWindow!.webContents.send(PRICE_CHECK_CANCELED)
|
||||
overlayWindow!.webContents.send(ipc.PRICE_CHECK_CANCELED)
|
||||
isPriceCheckShown = false
|
||||
}
|
||||
} else if (!isMouseInside) {
|
||||
@@ -146,7 +110,7 @@ export function setupShowHide () {
|
||||
mousePos.y > activeAreaRect!.y &&
|
||||
mousePos.y < activeAreaRect!.y + activeAreaRect!.height
|
||||
) {
|
||||
ipcMain.emit(PRICE_CHECK_MOUSE, undefined, 'enter', modifier)
|
||||
ipcMain.emit(ipc.PRICE_CHECK_MOUSE, undefined, 'enter', modifier)
|
||||
}
|
||||
}
|
||||
})
|
||||
+10
-15
@@ -2,17 +2,16 @@ import { screen, Point, clipboard, globalShortcut, Notification } from 'electron
|
||||
import robotjs from 'robotjs'
|
||||
import { uIOhook, UiohookKey } from 'uiohook-napi'
|
||||
import { pollClipboard } from './PollClipboard'
|
||||
import { showWindow, lockWindow } from './positioning'
|
||||
import { showWidget as showPriceCheck } from './price-check'
|
||||
import { KeyToElectron } from '@/ipc/KeyToCode'
|
||||
import { PRICE_CHECK } from '@/ipc/ipc-event'
|
||||
import { config } from './config'
|
||||
import { PoeWindow } from './PoeWindow'
|
||||
import { openWiki } from './wiki'
|
||||
import { logger } from './logger'
|
||||
import { toggleOverlayState, overlayWindow } from './overlay-window'
|
||||
import { toggleOverlayState } from './overlay-window'
|
||||
|
||||
export let isPollingClipboard = false
|
||||
export let checkPressPosition: Point | undefined
|
||||
export let hotkeyPressPosition: Point | undefined
|
||||
|
||||
export const UiohookToName = Object.fromEntries(Object.entries(UiohookKey).map(([k, v]) => ([v, k])))
|
||||
|
||||
@@ -22,20 +21,16 @@ function priceCheck (lockedMode: boolean) {
|
||||
if (!isPollingClipboard) {
|
||||
isPollingClipboard = true
|
||||
pollClipboard(32, 500)
|
||||
.then(async (clipboard) => {
|
||||
overlayWindow!.webContents.send(PRICE_CHECK, { clipboard, position: PoeWindow.getPoeUiPosition(checkPressPosition!) })
|
||||
showWindow()
|
||||
if (lockedMode) {
|
||||
lockWindow(true)
|
||||
}
|
||||
})
|
||||
.then(clipboard =>
|
||||
showPriceCheck({ clipboard, hotkeyPressPosition: hotkeyPressPosition!, lockedMode })
|
||||
)
|
||||
.catch(() => { /* nothing bad */ })
|
||||
.finally(() => { isPollingClipboard = false })
|
||||
}
|
||||
checkPressPosition = screen.getCursorScreenPoint()
|
||||
if (process.platform === 'win32') {
|
||||
checkPressPosition = screen.dipToScreenPoint(checkPressPosition)
|
||||
}
|
||||
hotkeyPressPosition = screen.getCursorScreenPoint()
|
||||
// if (process.platform === 'win32') {
|
||||
// hotkeyPressPosition = screen.dipToScreenPoint(hotkeyPressPosition)
|
||||
// }
|
||||
|
||||
if (!lockedMode) {
|
||||
if (config.get('priceCheckKeyHold') === 'Ctrl') {
|
||||
|
||||
@@ -71,7 +71,7 @@ import BrowserMode from './BrowserMode'
|
||||
import CheckedItem from './CheckedItem'
|
||||
import AppBootstrap from './AppBootstrap'
|
||||
import { MainProcess } from '@/ipc/main-process-bindings'
|
||||
import { PRICE_CHECK_CANCELED } from '@/ipc/ipc-event'
|
||||
import { PRICE_CHECK, PRICE_CHECK_CANCELED } from '@/ipc/ipc-event'
|
||||
import { Prices, displayRounding } from './Prices'
|
||||
import { Leagues } from './Leagues'
|
||||
import { parseClipboard } from '@/parser'
|
||||
@@ -100,34 +100,29 @@ export default {
|
||||
}
|
||||
},
|
||||
created () {
|
||||
MainProcess.addEventListener('price-check', ({ detail: { position, clipboard } }) => {
|
||||
this.clickPosition = position
|
||||
this.isBrowserShown = false
|
||||
MainProcess.addEventListener(PRICE_CHECK, ({ detail: e }) => {
|
||||
this.wm.closeBrowser(this.config.wmId)
|
||||
this.wm.show(this.config.wmId)
|
||||
this.item = parseClipboard(clipboard)
|
||||
this.checkPosition = {
|
||||
x: e.position.x - window.screenX,
|
||||
y: e.position.y - window.screenY
|
||||
}
|
||||
this.item = parseClipboard(e.clipboard)
|
||||
})
|
||||
MainProcess.addEventListener(PRICE_CHECK_CANCELED, () => {
|
||||
this.wm.hide(this.config.wmId)
|
||||
})
|
||||
MainProcess.addEventListener('open-link', () => {
|
||||
this.clickPosition = 'inventory'
|
||||
this.isBrowserShown = true
|
||||
})
|
||||
window.addEventListener('resize', this.updatePoeUiWidth)
|
||||
this.updatePoeUiWidth()
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
poeUiWidth: '0px',
|
||||
clickPosition: 'stash',
|
||||
isBrowserShown: false,
|
||||
poeUiWidth: '1px',
|
||||
checkPosition: { x: 1, y: 1 },
|
||||
item: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
browserMode () {
|
||||
return !MainProcess.isElectron
|
||||
},
|
||||
title () {
|
||||
if (!Leagues.isLoaded) {
|
||||
return 'Awakened PoE Trade'
|
||||
@@ -140,6 +135,19 @@ export default {
|
||||
if (!Prices.isLoaded) return null
|
||||
|
||||
return Math.round(Prices.exaToChaos(1))
|
||||
},
|
||||
isBrowserShown () {
|
||||
return this.config.wmFlags.includes('has-browser')
|
||||
},
|
||||
clickPosition () {
|
||||
if (this.isBrowserShown) {
|
||||
return 'inventory'
|
||||
} else {
|
||||
return this.checkPosition.x > (window.innerWidth / 2)
|
||||
? 'inventory'
|
||||
: 'stash'
|
||||
// or {chat, vendor, center of screen}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
Reference in New Issue
Block a user