mirror of
https://github.com/Kvan7/Exiled-Exchange-2.git
synced 2026-09-26 22:55:42 +00:00
back to iframes
This commit is contained in:
@@ -10,7 +10,6 @@ import { checkForUpdates } from './main/updates'
|
||||
import os from 'os'
|
||||
import { createOverlayWindow } from './main/overlay-window'
|
||||
import { setupAltVisibility } from './main/alt-visibility'
|
||||
import { setupBuiltinBrowser } from './main/builtin-browser'
|
||||
import { createFileProtocol } from './main/app-file-protocol'
|
||||
import { LogWatcher } from './main/LogWatcher'
|
||||
import { loadAndCache as loadAndCacheGameCfg } from './main/game-config'
|
||||
@@ -38,7 +37,6 @@ app.on('ready', async () => {
|
||||
setupConfigEvents()
|
||||
createTray()
|
||||
setupShowHide()
|
||||
setupBuiltinBrowser()
|
||||
loadAndCacheGameCfg()
|
||||
|
||||
setTimeout(
|
||||
|
||||
@@ -13,8 +13,6 @@ export type IpcEvent =
|
||||
IpcStashSearch |
|
||||
IpcOverlayReady |
|
||||
IpcCloseOverlay |
|
||||
IpcShowBrowser |
|
||||
IpcHideBrowser |
|
||||
IpcVisibility |
|
||||
IpcOpenWiki |
|
||||
IpcOpenCraftOfExile |
|
||||
@@ -77,16 +75,6 @@ export type IpcOverlayReady =
|
||||
export type IpcCloseOverlay =
|
||||
Event<'OVERLAY->MAIN::close-overlay'>
|
||||
|
||||
export type IpcShowBrowser =
|
||||
Event<'OVERLAY->MAIN::show-browser', {
|
||||
url?: string
|
||||
}>
|
||||
|
||||
export type IpcHideBrowser =
|
||||
Event<'OVERLAY->MAIN::hide-browser', {
|
||||
close?: boolean
|
||||
}>
|
||||
|
||||
export type IpcVisibility =
|
||||
Event<'MAIN->OVERLAY::visibility', {
|
||||
isVisible: boolean
|
||||
|
||||
+8
-29
@@ -1,4 +1,4 @@
|
||||
import type { ItemCheckWidget, PriceCheckWidget } from '@/web/overlay/interfaces'
|
||||
import * as widget from '@/web/overlay/interfaces'
|
||||
import type { IpcEvent } from './ipc-event'
|
||||
|
||||
export interface PreloadExposed {
|
||||
@@ -33,32 +33,11 @@ export interface Config {
|
||||
accountName: string
|
||||
stashScroll: boolean
|
||||
language: 'en' | 'ru'
|
||||
widgets: Widget[]
|
||||
widgets: widget.Widget[]
|
||||
fontSize: number
|
||||
disableUpdateDownload: boolean
|
||||
}
|
||||
|
||||
interface Widget {
|
||||
wmId: number
|
||||
wmType: string
|
||||
wmTitle: string
|
||||
wmWants: 'show' | 'hide'
|
||||
wmZorder: number | 'exclusive' | null
|
||||
wmFlags: Array<WidgetWellKnownFlag | string>
|
||||
// ---------------
|
||||
[key: string]: any
|
||||
}
|
||||
|
||||
type WidgetWellKnownFlag =
|
||||
'uninitialized' |
|
||||
'skip-menu' |
|
||||
'has-browser' |
|
||||
'invisible-on-blur' |
|
||||
'hide-on-blur' |
|
||||
'hide-on-blur(close)' |
|
||||
'hide-on-focus' |
|
||||
'ignore-ui-visibility'
|
||||
|
||||
export const defaultConfig = (): Config => ({
|
||||
configVersion: 11,
|
||||
wikiKey: 'Alt + W',
|
||||
@@ -120,7 +99,7 @@ export const defaultConfig = (): Config => ({
|
||||
y: 5
|
||||
},
|
||||
alwaysShow: false
|
||||
},
|
||||
} as widget.WidgetMenu,
|
||||
{
|
||||
wmId: 2,
|
||||
wmType: 'price-check',
|
||||
@@ -142,7 +121,7 @@ export const defaultConfig = (): Config => ({
|
||||
searchStatRange: 10,
|
||||
showCursor: true,
|
||||
requestPricePrediction: false
|
||||
} as PriceCheckWidget,
|
||||
} as widget.PriceCheckWidget,
|
||||
{
|
||||
wmId: 3,
|
||||
wmType: 'item-check',
|
||||
@@ -175,7 +154,7 @@ export const defaultConfig = (): Config => ({
|
||||
}
|
||||
]
|
||||
}
|
||||
} as ItemCheckWidget,
|
||||
} as widget.ItemCheckWidget,
|
||||
{
|
||||
wmId: 4,
|
||||
wmType: 'delve-grid',
|
||||
@@ -211,7 +190,7 @@ export const defaultConfig = (): Config => ({
|
||||
{ id: 3, text: '"Cannot Leech Life"' },
|
||||
{ id: 4, text: '"Cannot Leech Mana"' }
|
||||
]
|
||||
},
|
||||
} as widget.StashSearchWidget,
|
||||
{
|
||||
wmId: 102,
|
||||
wmType: 'stash-search',
|
||||
@@ -232,7 +211,7 @@ export const defaultConfig = (): Config => ({
|
||||
{ id: 5, text: '"Map Device" "Rarity: Normal"' },
|
||||
{ id: 6, text: 'Tane Laboratory' }
|
||||
]
|
||||
},
|
||||
} as widget.StashSearchWidget,
|
||||
{
|
||||
wmId: 103,
|
||||
wmType: 'image-strip',
|
||||
@@ -248,6 +227,6 @@ export const defaultConfig = (): Config => ({
|
||||
images: [
|
||||
{ id: 1, url: 'syndicate.jpg' }
|
||||
]
|
||||
}
|
||||
} as widget.ImageStripWidget
|
||||
]
|
||||
})
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
import { BrowserView, screen, shell } from 'electron'
|
||||
import { DPR, overlayWindow, handleExtraCommands, overlayOnEvent } from './overlay-window'
|
||||
import { PoeWindow } from './PoeWindow'
|
||||
import { logger } from './logger'
|
||||
import { config } from './config'
|
||||
|
||||
const WIDTH_96DPI = 460 / 16
|
||||
|
||||
let browserViewExternal: BrowserView | undefined
|
||||
|
||||
export function setupBuiltinBrowser () {
|
||||
overlayOnEvent('OVERLAY->MAIN::show-browser', (_, opts) => {
|
||||
logger.debug('Show', { source: 'builtin-browser', opts })
|
||||
if (!browserViewExternal) {
|
||||
browserViewExternal = new BrowserView()
|
||||
browserViewExternal.webContents.on('did-navigate', () => {
|
||||
browserViewExternal!.webContents.zoomFactor = config.get('fontSize') / 16
|
||||
})
|
||||
// hopefully someday this will enable subpixel AA
|
||||
// browserViewExternal.setBackgroundColor('#2d3748') // gray-800
|
||||
browserViewExternal.webContents.on('before-input-event', handleExtraCommands)
|
||||
}
|
||||
|
||||
overlayWindow!.setBrowserView(browserViewExternal)
|
||||
let browserBounds = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: PoeWindow.bounds.width - Math.floor(WIDTH_96DPI * DPR * config.get('fontSize')),
|
||||
height: PoeWindow.bounds.height
|
||||
}
|
||||
if (process.platform === 'win32') {
|
||||
browserBounds = screen.screenToDipRect(overlayWindow!, browserBounds)
|
||||
}
|
||||
browserViewExternal.setBounds(browserBounds)
|
||||
if (opts.url) {
|
||||
browserViewExternal.webContents.loadURL(opts.url)
|
||||
}
|
||||
})
|
||||
|
||||
overlayOnEvent('OVERLAY->MAIN::hide-browser', (_, opts) => {
|
||||
logger.debug('Hide', { source: 'builtin-browser', close: opts.close || false })
|
||||
if (browserViewExternal) {
|
||||
overlayWindow!.removeBrowserView(browserViewExternal)
|
||||
// uncomment to trade performance for less memory usage (1 process & 13 MB)
|
||||
// browserViewExternal.destroy()
|
||||
// browserViewExternal = undefined
|
||||
if (opts.close) {
|
||||
browserViewExternal.webContents.loadURL('about:blank')
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
+4
-2
@@ -53,7 +53,9 @@ export function batchUpdateConfig (newCfg: Config) {
|
||||
}
|
||||
}
|
||||
|
||||
function upgradeConfig (config: Config): Config {
|
||||
function upgradeConfig (_config: Config): Config {
|
||||
const config = _config as Omit<Config, 'widgets'> & { widgets: Array<Record<string, any>> }
|
||||
|
||||
if (config.configVersion < 3) {
|
||||
config.widgets.push({
|
||||
...defaultConfig().widgets.find(w => w.wmType === 'image-strip')!,
|
||||
@@ -182,5 +184,5 @@ function upgradeConfig (config: Config): Config {
|
||||
config.configVersion = 11
|
||||
}
|
||||
|
||||
return config
|
||||
return config as unknown as Config
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import path from 'path'
|
||||
import assert from 'assert'
|
||||
import { BrowserWindow, ipcMain, dialog, shell, Menu, systemPreferences, IpcMainEvent } from 'electron'
|
||||
import { BrowserWindow, ipcMain, dialog, shell, Menu, systemPreferences, IpcMainEvent, WebContents } from 'electron'
|
||||
import { PoeWindow } from './PoeWindow'
|
||||
import { logger } from './logger'
|
||||
import * as ipc from '@/ipc/ipc-event'
|
||||
import { OverlayWindow as OW } from 'electron-overlay-window'
|
||||
import { config } from './config'
|
||||
|
||||
export let overlayWindow: BrowserWindow | undefined
|
||||
let overlayWindow: BrowserWindow | undefined
|
||||
export let isInteractable = false
|
||||
export let DPR = 1
|
||||
|
||||
@@ -64,7 +64,7 @@ export async function createOverlayWindow () {
|
||||
]))
|
||||
overlayWindow.webContents.on('before-input-event', handleExtraCommands)
|
||||
|
||||
setupCfProtection()
|
||||
modifyResponseHeaders(overlayWindow.webContents)
|
||||
|
||||
overlayWindow.webContents.setWindowOpenHandler((details) => {
|
||||
shell.openExternal(details.url)
|
||||
@@ -163,7 +163,7 @@ function handleDprChange (devicePixelRatio: number) {
|
||||
}
|
||||
}
|
||||
|
||||
export function handleExtraCommands (event: Electron.Event, input: Electron.Input) {
|
||||
function handleExtraCommands (event: Electron.Event, input: Electron.Input) {
|
||||
if (input.type !== 'keyDown') return
|
||||
|
||||
let { code, control: ctrlKey, shift: shiftKey, alt: altKey } = input
|
||||
@@ -196,10 +196,16 @@ export function handleExtraCommands (event: Electron.Event, input: Electron.Inpu
|
||||
}
|
||||
}
|
||||
|
||||
function setupCfProtection () {
|
||||
overlayWindow!.webContents.session.webRequest.onHeadersReceived({
|
||||
function modifyResponseHeaders (webContents: WebContents) {
|
||||
webContents.session.webRequest.onHeadersReceived({
|
||||
urls: ['https://*.pathofexile.com/*']
|
||||
}, (details, next) => {
|
||||
// 1) allow embedding in iframe
|
||||
if (details.responseHeaders) {
|
||||
delete details.responseHeaders['x-frame-options']
|
||||
}
|
||||
|
||||
// 2) store cookies from Cloudflare
|
||||
const cookies = details.responseHeaders?.['set-cookie']
|
||||
if (cookies) {
|
||||
details.responseHeaders!['set-cookie'] = cookies.map(cookie => {
|
||||
|
||||
@@ -151,35 +151,6 @@ export default defineComponent({
|
||||
widgets.value = widgets.value.filter(_ => _.wmId !== wmId)
|
||||
}
|
||||
|
||||
function showBrowser (wmId: WMID, url?: string) {
|
||||
setFlag(wmId, 'has-browser', true)
|
||||
MainProcess.sendEvent({
|
||||
name: 'OVERLAY->MAIN::show-browser',
|
||||
payload: { url }
|
||||
})
|
||||
}
|
||||
|
||||
function closeBrowser (wmId: WMID) {
|
||||
const widget = AppConfig().widgets.find(_ => _.wmId === wmId)!
|
||||
if (widget.wmFlags.includes('has-browser')) {
|
||||
setFlag(wmId, 'has-browser', false)
|
||||
MainProcess.sendEvent({
|
||||
name: 'OVERLAY->MAIN::hide-browser',
|
||||
payload: { close: true }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function hideBrowser (wmId: WMID) {
|
||||
const widget = AppConfig().widgets.find(_ => _.wmId === wmId)!
|
||||
if (widget.wmFlags.includes('has-browser')) {
|
||||
MainProcess.sendEvent({
|
||||
name: 'OVERLAY->MAIN::hide-browser',
|
||||
payload: { close: false }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function setFlag (wmId: WMID, flag: Widget['wmFlags'][number], state: boolean) {
|
||||
const widget = AppConfig().widgets.find(_ => _.wmId === wmId)!
|
||||
const hasFlag = widget.wmFlags.includes(flag)
|
||||
@@ -231,22 +202,6 @@ export default defineComponent({
|
||||
}))
|
||||
})
|
||||
|
||||
watch(visibilityState, (stateNow, stateOld) => {
|
||||
for (const w of AppConfig().widgets) {
|
||||
if (w.wmFlags.includes('has-browser')) {
|
||||
const vNow = stateNow.find(_ => _.wmId === w.wmId)!
|
||||
const vOld = stateOld.find(_ => _.wmId === w.wmId)!
|
||||
if (vNow.isVisible === (vOld && vOld.isVisible)) return
|
||||
|
||||
if (vNow.isVisible) {
|
||||
showBrowser(w.wmId)
|
||||
} else {
|
||||
hideBrowser(w.wmId)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const topmostWidget = computed<Widget>(() => {
|
||||
// guaranteed to always exist because of the 'widget-menu'
|
||||
return AppConfig().widgets
|
||||
@@ -277,8 +232,6 @@ export default defineComponent({
|
||||
remove,
|
||||
bringToTop,
|
||||
create,
|
||||
showBrowser,
|
||||
closeBrowser,
|
||||
setFlag
|
||||
})
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ export type WellKnownFlag =
|
||||
'invisible-on-blur' |
|
||||
'hide-on-blur' |
|
||||
'hide-on-blur(close)' |
|
||||
'hide-on-focus'
|
||||
'hide-on-focus' |
|
||||
'ignore-ui-visibility'
|
||||
|
||||
export interface Anchor {
|
||||
pos: string
|
||||
@@ -34,8 +35,6 @@ export interface WidgetManager {
|
||||
remove: (wmId: number) => void
|
||||
bringToTop: (wmId: number) => void
|
||||
create: (wmType: string) => void
|
||||
showBrowser: (wmId: number, url: string) => void
|
||||
closeBrowser: (wmId: number) => void
|
||||
setFlag: (wmId: number, flag: string, state: boolean) => void
|
||||
}
|
||||
|
||||
|
||||
@@ -24,17 +24,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, inject } from 'vue'
|
||||
import { defineComponent, inject } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { Widget, WidgetManager } from '../overlay/interfaces'
|
||||
import * as Leagues from '@/web/background/Leagues'
|
||||
import { updateInfo } from '@/web/background/AutoUpdates'
|
||||
import { AppConfig } from '@/web/Config'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const wm = inject<WidgetManager>('wm')!
|
||||
const widget = computed(() => AppConfig<Widget>('price-check')!)
|
||||
const showBrowser = inject<(url: string) => void>('builtin-browser')!
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -47,7 +44,7 @@ export default defineComponent({
|
||||
Leagues.load()
|
||||
},
|
||||
openCaptcha () {
|
||||
wm.showBrowser(widget.value.wmId, 'https://api.pathofexile.com/leagues?type=main&realm=pc&compact=1')
|
||||
showBrowser('https://api.pathofexile.com/leagues?type=main&realm=pc&compact=1')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout-column flex-1 min-w-0">
|
||||
<iframe v-if="isBrowserShown" ref="iframeEl"
|
||||
class="pointer-events-auto"
|
||||
sandbox="allow-scripts allow-same-origin"
|
||||
width="100%" height="100%" />
|
||||
<div v-else class="layout-column flex-1 min-w-0">
|
||||
<div class="flex" :class="{
|
||||
'flex-row': clickPosition === 'stash',
|
||||
'flex-row-reverse': clickPosition === 'inventory'
|
||||
@@ -61,7 +65,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, inject, PropType, shallowRef, watch, computed, nextTick } from 'vue'
|
||||
import { defineComponent, inject, PropType, shallowRef, watch, computed, nextTick, provide } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import CheckedItem from './CheckedItem.vue'
|
||||
import BackgroundInfo from './BackgroundInfo.vue'
|
||||
@@ -106,7 +110,7 @@ export default defineComponent({
|
||||
const checkPosition = shallowRef({ x: 1, y: 1 })
|
||||
|
||||
MainProcess.onEvent('MAIN->OVERLAY::price-check', (e) => {
|
||||
wm.closeBrowser(props.config.wmId)
|
||||
closeBrowser()
|
||||
wm.show(props.config.wmId)
|
||||
checkPosition.value = {
|
||||
x: e.position.x - window.screenX,
|
||||
@@ -161,12 +165,28 @@ export default defineComponent({
|
||||
MainProcess.closeOverlay()
|
||||
}
|
||||
|
||||
const iframeEl = shallowRef<HTMLIFrameElement | null>(null)
|
||||
|
||||
function showBrowser (url: string) {
|
||||
wm.setFlag(props.config.wmId, 'has-browser', true)
|
||||
nextTick(() => {
|
||||
iframeEl.value!.src = url
|
||||
})
|
||||
}
|
||||
|
||||
function closeBrowser () {
|
||||
wm.setFlag(props.config.wmId, 'has-browser', false)
|
||||
}
|
||||
|
||||
provide<(url: string) => void>('builtin-browser', showBrowser)
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
t,
|
||||
clickPosition,
|
||||
isBrowserShown,
|
||||
iframeEl,
|
||||
poeUiWidth: wm.poePanelWidth,
|
||||
closePriceCheck,
|
||||
title,
|
||||
|
||||
@@ -95,7 +95,7 @@ import { selected as league } from '../../background/Leagues'
|
||||
import { AppConfig } from '@/web/Config'
|
||||
import { ItemFilters } from '../filters/interfaces'
|
||||
import { ParsedItem } from '@/parser'
|
||||
import { PriceCheckWidget, WidgetManager } from '@/web/overlay/interfaces'
|
||||
import { PriceCheckWidget } from '@/web/overlay/interfaces'
|
||||
import { artificialSlowdown } from './artificial-slowdown'
|
||||
import OnlineFilter from './OnlineFilter.vue'
|
||||
|
||||
@@ -172,7 +172,6 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const wm = inject<WidgetManager>('wm')!
|
||||
const widget = computed(() => AppConfig<PriceCheckWidget>('price-check')!)
|
||||
const { error, result, search } = useBulkApi()
|
||||
|
||||
@@ -204,6 +203,8 @@ export default defineComponent({
|
||||
}
|
||||
})
|
||||
|
||||
const showBrowser = inject<(url: string) => void>('builtin-browser')!
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
@@ -219,7 +220,7 @@ export default defineComponent({
|
||||
if (isExternal) {
|
||||
window.open(link)
|
||||
} else {
|
||||
wm.showBrowser(widget.value.wmId, link)
|
||||
showBrowser(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { requestTradeResultList, requestResults, createTradeRequest, PricingResult } from './pathofexile-trade'
|
||||
import { getTradeEndpoint, SearchResult } from './common'
|
||||
import { AppConfig } from '@/web/Config'
|
||||
import { PriceCheckWidget, WidgetManager } from '@/web/overlay/interfaces'
|
||||
import { PriceCheckWidget } from '@/web/overlay/interfaces'
|
||||
import { ItemFilters, StatFilter } from '../filters/interfaces'
|
||||
import { ParsedItem } from '@/parser'
|
||||
import { artificialSlowdown } from './artificial-slowdown'
|
||||
@@ -210,7 +210,6 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
setup (props) {
|
||||
const wm = inject<WidgetManager>('wm')!
|
||||
const widget = computed(() => AppConfig<PriceCheckWidget>('price-check')!)
|
||||
|
||||
watch(() => props.item, (item) => {
|
||||
@@ -219,6 +218,8 @@ export default defineComponent({
|
||||
|
||||
const { error, searchResult, groupedResults, search } = useTradeApi()
|
||||
|
||||
const showBrowser = inject<(url: string) => void>('builtin-browser')!
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
return {
|
||||
@@ -247,7 +248,7 @@ export default defineComponent({
|
||||
if (isExternal) {
|
||||
window.open(link)
|
||||
} else {
|
||||
wm.showBrowser(widget.value.wmId, link)
|
||||
showBrowser(link)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user