Compare commits
	
		
			1 Commits
		
	
	
		
			v0.11.0
			...
			features/r
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7000dbc58c | 
@@ -11,7 +11,7 @@ Note that these 2 both depend on each other, and one cannot run without the othe
 | 
			
		||||
 | 
			
		||||
The most up-to-date instructions can always be derived from CI:
 | 
			
		||||
 | 
			
		||||
[.github/workflows/main.yml](https://github.com/Kvan7/awakened-poe2-trade2/blob/master/.github/workflows/main.yml)
 | 
			
		||||
[.github/workflows/main.yml](https://github.com/Kvan7/exalted-poe2-trade/blob/master/.github/workflows/main.yml)
 | 
			
		||||
 | 
			
		||||
Here's what that looks like as of 2023-12-03.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@@ -1,16 +1,16 @@
 | 
			
		||||
#  Awakened PoE2 Trade2
 | 
			
		||||
#  Exalted PoE2 Trade
 | 
			
		||||
 | 
			
		||||
## Moving from POE1
 | 
			
		||||
 | 
			
		||||
1. Download latest release from [releases](https://github.com/Kvan7/awakened-poe2-trade2/releases)
 | 
			
		||||
1. Download latest release from [releases](https://github.com/Kvan7/exalted-poe2-trade/releases)
 | 
			
		||||
  - Currently only Windows is supported
 | 
			
		||||
  - Only available as pre-release right now
 | 
			
		||||
2. Run installer
 | 
			
		||||
3. Copy `apt-data` from `%APPDATA%\awakened-poe-trade` to `%APPDATA%\awakened-poe2-trade2` to copy your previous settings
 | 
			
		||||
3. Copy `apt-data` from `%APPDATA%\awakened-poe-trade` to `%APPDATA%\exalted-poe2-trade` to copy your previous settings
 | 
			
		||||
  - Resulting directory structure should look like this:
 | 
			
		||||
  - `%APPDATA%\awakened-poe2-trade2\apt-data\`
 | 
			
		||||
  - `%APPDATA%\exalted-poe2-trade\apt-data\`
 | 
			
		||||
    - `config.json`
 | 
			
		||||
4. Run Awakened PoE2 Trade2
 | 
			
		||||
4. Run Exalted PoE2 Trade
 | 
			
		||||
 | 
			
		||||
## Tool showcase
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import { defineConfig } from 'vitepress'
 | 
			
		||||
 | 
			
		||||
const BASE = '/awakened-poe2-trade2/'
 | 
			
		||||
const BASE = '/exalted-poe2-trade/'
 | 
			
		||||
 | 
			
		||||
export default defineConfig({
 | 
			
		||||
  title: 'Awakened PoE2 Trade2',
 | 
			
		||||
  title: 'Exalted PoE2 Trade',
 | 
			
		||||
  description: 'App for price-checking items in Path of Exile 2',
 | 
			
		||||
  base: BASE,
 | 
			
		||||
  mpa: true,
 | 
			
		||||
@@ -22,7 +22,7 @@ export default defineConfig({
 | 
			
		||||
    // logo: 'TODO', https://github.com/vuejs/vitepress/issues/1401
 | 
			
		||||
    appVersion: '3.25.101',
 | 
			
		||||
    github: {
 | 
			
		||||
      releasesUrl: 'https://github.com/Kvan7/awakened-poe2-trade2/releases'
 | 
			
		||||
      releasesUrl: 'https://github.com/Kvan7/exalted-poe2-trade/releases'
 | 
			
		||||
    },
 | 
			
		||||
    socialLinks: [
 | 
			
		||||
      {
 | 
			
		||||
@@ -33,7 +33,7 @@ export default defineConfig({
 | 
			
		||||
      {
 | 
			
		||||
        text: 'GitHub',
 | 
			
		||||
        color: '#181717',
 | 
			
		||||
        link: 'https://github.com/Kvan7/awakened-poe2-trade2'
 | 
			
		||||
        link: 'https://github.com/Kvan7/exalted-poe2-trade'
 | 
			
		||||
      }
 | 
			
		||||
    ],
 | 
			
		||||
    sidebar: [
 | 
			
		||||
 
 | 
			
		||||
@@ -8,15 +8,15 @@ import { useData } from 'vitepress'
 | 
			
		||||
const { theme } = useData()
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
You can download Awakened Poe Trade here. Any other mirrors are not known
 | 
			
		||||
You can download Exalted Poe Trade here. Any other mirrors are not known
 | 
			
		||||
to the developer, downloading from them may be unsafe.
 | 
			
		||||
 | 
			
		||||
| Download link                                                                                                                                         | Automatic updates | Startup time |
 | 
			
		||||
| ----------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------ |
 | 
			
		||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Awakened-PoE2-Trade2-Setup-${theme.appVersion}.exe`">Windows 10+ (installer)</a> | ✔                 | Fast         |
 | 
			
		||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Awakened-PoE2-Trade2-${theme.appVersion}.exe`">Windows 10+ (portable)</a>        | ❌                 | Slower       |
 | 
			
		||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Awakened-PoE2-Trade2-${theme.appVersion}.AppImage`">Linux (AppImage)</a>         | ✔                 | n/a          |
 | 
			
		||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Awakened-PoE2-Trade2-${theme.appVersion}-universal.dmg`">macOS (dmg)</a>         | ❌                 | n/a          |
 | 
			
		||||
| Download link                                                                                                                                       | Automatic updates | Startup time |
 | 
			
		||||
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------ |
 | 
			
		||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exalted-PoE2-Trade-Setup-${theme.appVersion}.exe`">Windows 10+ (installer)</a> | ✔                 | Fast         |
 | 
			
		||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exalted-PoE2-Trade-${theme.appVersion}.exe`">Windows 10+ (portable)</a>        | ❌                 | Slower       |
 | 
			
		||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exalted-PoE2-Trade-${theme.appVersion}.AppImage`">Linux (AppImage)</a>         | ✔                 | n/a          |
 | 
			
		||||
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exalted-PoE2-Trade-${theme.appVersion}-universal.dmg`">macOS (dmg)</a>         | ❌                 | n/a          |
 | 
			
		||||
 | 
			
		||||
Latest version is <span class="bg-gray-100 border rounded px-1">{{ theme.appVersion }}</span>
 | 
			
		||||
 | 
			
		||||
@@ -36,6 +36,6 @@ warnings on Windows and [macOS](https://support.apple.com/en-us/HT202491#openany
 | 
			
		||||
 | 
			
		||||
No Administrator rights required, but\
 | 
			
		||||
⚠ **If you run PoE client as Admin, OS security boundaries take effect.
 | 
			
		||||
In order for Awakened PoE2 Trade2 to have access to the PoE window, it must be started with Administrator rights.**
 | 
			
		||||
In order for Exalted PoE2 Trade to have access to the PoE window, it must be started with Administrator rights.**
 | 
			
		||||
 | 
			
		||||
❌ **Not compatible with "GeForce Now" or any other cloud gaming service that do not forward clipboard data.**
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ title: Common issues
 | 
			
		||||
    If Awakened works for you with DirectX11/12 renderer,
 | 
			
		||||
    then problem is old Vulkan drivers for sure.
 | 
			
		||||
 | 
			
		||||
4. Delete `%appdata%\awakened-poe2-trade2`
 | 
			
		||||
4. Delete `%appdata%\exalted-poe2-trade`
 | 
			
		||||
 | 
			
		||||
    If needed, backup `apt-data` folder with your configuration inside.
 | 
			
		||||
 | 
			
		||||
@@ -22,7 +22,7 @@ title: Common issues
 | 
			
		||||
 | 
			
		||||
    Launch them later one at a time to identify **conflict**.
 | 
			
		||||
 | 
			
		||||
6. Restart Awakened PoE2 Trade2.
 | 
			
		||||
6. Restart Exalted PoE2 Trade.
 | 
			
		||||
 | 
			
		||||
    *(don't forget to quit first, otherwise launching second instance will do nothing).*
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ title: Quick Start
 | 
			
		||||
#### First of all, how does it work? {:style="margin-top: 0;"}
 | 
			
		||||
 | 
			
		||||
When you press `Ctrl + C` Path of Exile 2 copies the item's text (under cursor, if any) to the clipboard.
 | 
			
		||||
All that remains is to parse text in Awakened PoE2 Trade2 and show to you in a fancy way.
 | 
			
		||||
All that remains is to parse text in Exalted PoE2 Trade and show to you in a fancy way.
 | 
			
		||||
 | 
			
		||||
### Usage
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 841 KiB After Width: | Height: | Size: 712 KiB  | 
| 
		 Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 28 KiB  | 
| 
		 Before Width: | Height: | Size: 791 B After Width: | Height: | Size: 1.5 KiB  | 
| 
		 Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.3 KiB  | 
| 
		 Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 82 KiB  | 
| 
		 Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 3.3 KiB  | 
| 
		 Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 6.1 KiB  | 
| 
		 Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 240 KiB  | 
| 
		 Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 9.5 KiB  | 
| 
		 Before Width: | Height: | Size: 353 KiB After Width: | Height: | Size: 66 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								main/build/icons/icon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 14 KiB  | 
@@ -1,6 +1,6 @@
 | 
			
		||||
publish:
 | 
			
		||||
  - "github"
 | 
			
		||||
productName: "Awakened PoE2 Trade2"
 | 
			
		||||
productName: "Exalted PoE2 Trade"
 | 
			
		||||
npmRebuild: false
 | 
			
		||||
files:
 | 
			
		||||
  - "package.json"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "awakened-poe2-trade2",
 | 
			
		||||
  "name": "exalted-poe2-trade",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "scripts": {
 | 
			
		||||
@@ -8,11 +8,11 @@
 | 
			
		||||
    "package": "electron-builder build"
 | 
			
		||||
  },
 | 
			
		||||
  "author": {
 | 
			
		||||
    "name": "Alexander Drozdov"
 | 
			
		||||
    "name": "Garrett Parker"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "https://github.com/Kvan7/awakened-poe2-trade2.git"
 | 
			
		||||
    "url": "https://github.com/Kvan7/exalted-poe2-trade.git"
 | 
			
		||||
  },
 | 
			
		||||
  "main": "dist/main.js",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ export class AppTray {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.tray = new Tray(trayImage);
 | 
			
		||||
    this.tray.setToolTip(`Awakened PoE2 Trade2 v${app.getVersion()}`);
 | 
			
		||||
    this.tray.setToolTip(`Exalted PoE2 Trade v${app.getVersion()}`);
 | 
			
		||||
    this.rebuildMenu();
 | 
			
		||||
 | 
			
		||||
    server.onEventAnyClient("CLIENT->MAIN::user-action", ({ action }) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -161,7 +161,7 @@ export class OverlayWindow {
 | 
			
		||||
        // ----------------------
 | 
			
		||||
        "Path of Exile 2 is running with administrator rights.\n" +
 | 
			
		||||
          "\n" +
 | 
			
		||||
          "You need to restart Awakened PoE2 Trade2 with administrator rights."
 | 
			
		||||
          "You need to restart Exalted PoE2 Trade with administrator rights."
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      this.server.sendEventTo("broadcast", {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
 | 
			
		||||
    <meta name="color-scheme" content="dark">
 | 
			
		||||
    <link rel="icon" href="/icon.ico">
 | 
			
		||||
    <title>Awakened PoE Trade2</title>
 | 
			
		||||
    <title>Exalted PoE2 Trade</title>
 | 
			
		||||
  </head>
 | 
			
		||||
  <body>
 | 
			
		||||
    <div id="app"></div>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								renderer/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						@@ -1,12 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "awakened-poe2-trade2",
 | 
			
		||||
  "version": "0.0.0",
 | 
			
		||||
  "name": "exalted-poe2-trade",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "lockfileVersion": 3,
 | 
			
		||||
  "requires": true,
 | 
			
		||||
  "packages": {
 | 
			
		||||
    "": {
 | 
			
		||||
      "name": "awakened-poe2-trade2",
 | 
			
		||||
      "version": "0.0.0",
 | 
			
		||||
      "name": "exalted-poe2-trade",
 | 
			
		||||
      "version": "0.0.1",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@fortawesome/fontawesome-free": "6.x.x",
 | 
			
		||||
        "@sindresorhus/fnv1a": "^3.0.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "awakened-poe2-trade2",
 | 
			
		||||
  "name": "exalted-poe2-trade",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "private": true,
 | 
			
		||||
  "scripts": {
 | 
			
		||||
 
 | 
			
		||||
@@ -269,7 +269,7 @@
 | 
			
		||||
    "stack": "Stack"
 | 
			
		||||
  },
 | 
			
		||||
  "settings": {
 | 
			
		||||
    "title": "Settings - Awakened PoE2 Trade2",
 | 
			
		||||
    "title": "Settings - Exalted PoE2 Trade",
 | 
			
		||||
    "language": "Language",
 | 
			
		||||
    "private_league": "or Private League",
 | 
			
		||||
    "account_name": "Account name",
 | 
			
		||||
 
 | 
			
		||||
@@ -266,7 +266,7 @@
 | 
			
		||||
    "stack": "스택"
 | 
			
		||||
  },
 | 
			
		||||
  "settings": {
 | 
			
		||||
    "title": "세팅 - Awakened PoE2 Trade2",
 | 
			
		||||
    "title": "세팅 - Exalted PoE2 Trade",
 | 
			
		||||
    "language": "언어",
 | 
			
		||||
    "private_league": "개인리그",
 | 
			
		||||
    "account_name": "계정명",
 | 
			
		||||
 
 | 
			
		||||
@@ -282,7 +282,7 @@
 | 
			
		||||
    "stack": "Стак"
 | 
			
		||||
  },
 | 
			
		||||
  "settings": {
 | 
			
		||||
    "title": "Настройки - Awakened PoE2 Trade2",
 | 
			
		||||
    "title": "Настройки - Exalted PoE2 Trade",
 | 
			
		||||
    "language": "Язык",
 | 
			
		||||
    "private_league": "или Приватная лига",
 | 
			
		||||
    "account_name": "Имя учетной записи",
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 353 KiB After Width: | Height: | Size: 66 KiB  | 
| 
		 Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 14 KiB  | 
@@ -76,9 +76,9 @@ export async function initConfig() {
 | 
			
		||||
 | 
			
		||||
		// TODO
 | 
			
		||||
		// dialog.showErrorBox(
 | 
			
		||||
		//   'Awakened PoE2 Trade2 - Incompatible configuration',
 | 
			
		||||
		//   'Exalted PoE2 Trade - Incompatible configuration',
 | 
			
		||||
		//   // ----------------------
 | 
			
		||||
		//   'You are trying to use an older version of Awakened PoE2 Trade2 with a newer incompatible configuration file.\n' +
 | 
			
		||||
		//   'You are trying to use an older version of Exalted PoE2 Trade with a newer incompatible configuration file.\n' +
 | 
			
		||||
		//   'You need to install the latest version to continue using it.'
 | 
			
		||||
		// )
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,63 +1,67 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <transition enter-active-class="animate__animated animate__fadeIn"
 | 
			
		||||
    leave-active-class="animate__animated animate__backOutDown">
 | 
			
		||||
    <div :class="$style.widget" v-if="show">
 | 
			
		||||
      <div :class="$style.box">
 | 
			
		||||
        <div class="py-2 px-4">
 | 
			
		||||
          <div class="text-base">Awakened PoE2 Trade2</div>
 | 
			
		||||
          <p>{{ t('app_is_ready') }}</p>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </transition>
 | 
			
		||||
	<transition
 | 
			
		||||
		enter-active-class="animate__animated animate__fadeIn"
 | 
			
		||||
		leave-active-class="animate__animated animate__backOutDown"
 | 
			
		||||
	>
 | 
			
		||||
		<div :class="$style.widget" v-if="show">
 | 
			
		||||
			<div :class="$style.box">
 | 
			
		||||
				<div class="py-2 px-4">
 | 
			
		||||
					<div class="text-base">Exalted PoE2 Trade</div>
 | 
			
		||||
					<p>{{ t('app_is_ready') }}</p>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</transition>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts">
 | 
			
		||||
import { shallowRef } from 'vue'
 | 
			
		||||
import { useI18n } from 'vue-i18n'
 | 
			
		||||
import { Host } from '@/web/background/IPC'
 | 
			
		||||
import { AppConfig } from '@/web/Config'
 | 
			
		||||
import { shallowRef } from 'vue';
 | 
			
		||||
import { useI18n } from 'vue-i18n';
 | 
			
		||||
import { Host } from '@/web/background/IPC';
 | 
			
		||||
import { AppConfig } from '@/web/Config';
 | 
			
		||||
 | 
			
		||||
const { t } = useI18n()
 | 
			
		||||
const { t } = useI18n();
 | 
			
		||||
 | 
			
		||||
const show = shallowRef(false)
 | 
			
		||||
const show = shallowRef(false);
 | 
			
		||||
 | 
			
		||||
Host.onEvent('MAIN->OVERLAY::overlay-attached', () => {
 | 
			
		||||
  if (!show.value && AppConfig().showAttachNotification) {
 | 
			
		||||
    show.value = true
 | 
			
		||||
    setTimeout(() => { show.value = false }, 2500)
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
	if (!show.value && AppConfig().showAttachNotification) {
 | 
			
		||||
		show.value = true;
 | 
			
		||||
		setTimeout(() => {
 | 
			
		||||
			show.value = false;
 | 
			
		||||
		}, 2500);
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="postcss" module>
 | 
			
		||||
.widget {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  bottom: 20%;
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	justify-content: center;
 | 
			
		||||
	bottom: 20%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.box {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  @apply bg-gray-800;
 | 
			
		||||
  @apply text-gray-100;
 | 
			
		||||
  @apply rounded;
 | 
			
		||||
  box-shadow: 0px 0px 1px 2px rgb(255 255 255 / 20%);
 | 
			
		||||
	position: relative;
 | 
			
		||||
	display: flex;
 | 
			
		||||
	@apply bg-gray-800;
 | 
			
		||||
	@apply text-gray-100;
 | 
			
		||||
	@apply rounded;
 | 
			
		||||
	box-shadow: 0px 0px 1px 2px rgb(255 255 255 / 20%);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.box::before {
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  content: '';
 | 
			
		||||
  background: url('/images/TransferOrb.png') no-repeat top right/contain;
 | 
			
		||||
  right: 100%;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  max-width: 78px;
 | 
			
		||||
  @apply mr-2;
 | 
			
		||||
  pointer-events: none;
 | 
			
		||||
  filter: drop-shadow(2px 4px 6px #000);
 | 
			
		||||
	position: absolute;
 | 
			
		||||
	content: '';
 | 
			
		||||
	background: url('/images/exa.png') no-repeat top right/contain;
 | 
			
		||||
	right: 100%;
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	height: 100%;
 | 
			
		||||
	max-width: 78px;
 | 
			
		||||
	@apply mr-2;
 | 
			
		||||
	pointer-events: none;
 | 
			
		||||
	filter: drop-shadow(2px 4px 6px #000);
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,259 +1,356 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div style="top: 0; left: 0; height: 100%; width: 100%; position: absolute;"
 | 
			
		||||
    class="flex grow h-full pointer-events-none" :class="{
 | 
			
		||||
      'flex-row': clickPosition === 'stash',
 | 
			
		||||
      'flex-row-reverse': clickPosition === 'inventory',
 | 
			
		||||
    }">
 | 
			
		||||
    <div v-if="!isBrowserShown" class="layout-column shrink-0" style="width: var(--game-panel);">
 | 
			
		||||
    </div>
 | 
			
		||||
    <div id="price-window" class="layout-column shrink-0 text-gray-200 pointer-events-auto" style="width: 28.75rem;">
 | 
			
		||||
      <ConversionWarningBanner />
 | 
			
		||||
      <AppTitleBar @close="closePriceCheck" @click="openLeagueSelection" :title="title">
 | 
			
		||||
        <ui-popover v-if="stableOrbCost" trigger="click" boundary="#price-window">
 | 
			
		||||
          <template #target>
 | 
			
		||||
            <button><i class="fas fa-exchange-alt" /> {{ stableOrbCost }}</button>
 | 
			
		||||
          </template>
 | 
			
		||||
          <template #content>
 | 
			
		||||
            <item-quick-price class="text-base" :price="{ min: stableOrbCost, max: stableOrbCost, currency: 'chaos' }"
 | 
			
		||||
              item-img="/images/divine.png" />
 | 
			
		||||
            <div v-for="i in 9" :key="i">
 | 
			
		||||
              <div class="pl-1">{{ i / 10 }} div ⇒ {{ Math.round(stableOrbCost * i / 10) }} c</div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </template>
 | 
			
		||||
        </ui-popover>
 | 
			
		||||
        <i v-else-if="xchgRateLoading()" class="fas fa-dna fa-spin px-2" />
 | 
			
		||||
        <div v-else class="w-8" />
 | 
			
		||||
      </AppTitleBar>
 | 
			
		||||
      <div class="grow layout-column min-h-0 bg-gray-800">
 | 
			
		||||
        <background-info />
 | 
			
		||||
        <check-position-circle v-if="showCheckPos" :position="checkPosition" style="z-index: -1;" />
 | 
			
		||||
        <template v-if="item?.isErr()">
 | 
			
		||||
          <ui-error-box class="m-4">
 | 
			
		||||
            <template #name>{{ t(item.error.name) }}</template>
 | 
			
		||||
            <p>{{ t(item.error.message) }}</p>
 | 
			
		||||
          </ui-error-box>
 | 
			
		||||
          <pre class="bg-gray-900 rounded m-4 overflow-x-hidden p-2">{{ item.error.rawText }}</pre>
 | 
			
		||||
        </template>
 | 
			
		||||
        <template v-else-if="item?.isOk()">
 | 
			
		||||
          <unidentified-resolver :item="item.value" @identify="handleIdentification($event)" />
 | 
			
		||||
          <checked-item v-if="isLeagueSelected" :item="item.value" :advanced-check="advancedCheck" />
 | 
			
		||||
        </template>
 | 
			
		||||
        <div v-if="isBrowserShown" class="bg-gray-900 px-6 py-2 truncate">
 | 
			
		||||
          <i18n-t keypath="app.toggle_browser_hint" tag="div">
 | 
			
		||||
            <span class="bg-gray-400 text-gray-900 rounded px-1">{{ overlayKey }}</span>
 | 
			
		||||
          </i18n-t>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <webview v-if="isBrowserShown" ref="iframeEl" class="pointer-events-auto flex-1" 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'
 | 
			
		||||
      }">
 | 
			
		||||
        <related-items v-if="item?.isOk()" class="pointer-events-auto" :item="item.value"
 | 
			
		||||
          :click-position="clickPosition" />
 | 
			
		||||
        <rate-limiter-state class="pointer-events-auto" />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
	<div
 | 
			
		||||
		style="top: 0; left: 0; height: 100%; width: 100%; position: absolute"
 | 
			
		||||
		class="flex grow h-full pointer-events-none"
 | 
			
		||||
		:class="{
 | 
			
		||||
			'flex-row': clickPosition === 'stash',
 | 
			
		||||
			'flex-row-reverse': clickPosition === 'inventory',
 | 
			
		||||
		}"
 | 
			
		||||
	>
 | 
			
		||||
		<div
 | 
			
		||||
			v-if="!isBrowserShown"
 | 
			
		||||
			class="layout-column shrink-0"
 | 
			
		||||
			style="width: var(--game-panel)"
 | 
			
		||||
		></div>
 | 
			
		||||
		<div
 | 
			
		||||
			id="price-window"
 | 
			
		||||
			class="layout-column shrink-0 text-gray-200 pointer-events-auto"
 | 
			
		||||
			style="width: 28.75rem"
 | 
			
		||||
		>
 | 
			
		||||
			<ConversionWarningBanner />
 | 
			
		||||
			<AppTitleBar
 | 
			
		||||
				@close="closePriceCheck"
 | 
			
		||||
				@click="openLeagueSelection"
 | 
			
		||||
				:title="title"
 | 
			
		||||
			>
 | 
			
		||||
				<ui-popover
 | 
			
		||||
					v-if="stableOrbCost"
 | 
			
		||||
					trigger="click"
 | 
			
		||||
					boundary="#price-window"
 | 
			
		||||
				>
 | 
			
		||||
					<template #target>
 | 
			
		||||
						<button>
 | 
			
		||||
							<i class="fas fa-exchange-alt" /> {{ stableOrbCost }}
 | 
			
		||||
						</button>
 | 
			
		||||
					</template>
 | 
			
		||||
					<template #content>
 | 
			
		||||
						<item-quick-price
 | 
			
		||||
							class="text-base"
 | 
			
		||||
							:price="{
 | 
			
		||||
								min: stableOrbCost,
 | 
			
		||||
								max: stableOrbCost,
 | 
			
		||||
								currency: 'chaos',
 | 
			
		||||
							}"
 | 
			
		||||
							item-img="/images/divine.png"
 | 
			
		||||
						/>
 | 
			
		||||
						<div v-for="i in 9" :key="i">
 | 
			
		||||
							<div class="pl-1">
 | 
			
		||||
								{{ i / 10 }} div ⇒ {{ Math.round((stableOrbCost * i) / 10) }} c
 | 
			
		||||
							</div>
 | 
			
		||||
						</div>
 | 
			
		||||
					</template>
 | 
			
		||||
				</ui-popover>
 | 
			
		||||
				<i v-else-if="xchgRateLoading()" class="fas fa-dna fa-spin px-2" />
 | 
			
		||||
				<div v-else class="w-8" />
 | 
			
		||||
			</AppTitleBar>
 | 
			
		||||
			<div class="grow layout-column min-h-0 bg-gray-800">
 | 
			
		||||
				<background-info />
 | 
			
		||||
				<check-position-circle
 | 
			
		||||
					v-if="showCheckPos"
 | 
			
		||||
					:position="checkPosition"
 | 
			
		||||
					style="z-index: -1"
 | 
			
		||||
				/>
 | 
			
		||||
				<template v-if="item?.isErr()">
 | 
			
		||||
					<ui-error-box class="m-4">
 | 
			
		||||
						<template #name>{{ t(item.error.name) }}</template>
 | 
			
		||||
						<p>{{ t(item.error.message) }}</p>
 | 
			
		||||
					</ui-error-box>
 | 
			
		||||
					<pre class="bg-gray-900 rounded m-4 overflow-x-hidden p-2">{{
 | 
			
		||||
						item.error.rawText
 | 
			
		||||
					}}</pre>
 | 
			
		||||
				</template>
 | 
			
		||||
				<template v-else-if="item?.isOk()">
 | 
			
		||||
					<unidentified-resolver
 | 
			
		||||
						:item="item.value"
 | 
			
		||||
						@identify="handleIdentification($event)"
 | 
			
		||||
					/>
 | 
			
		||||
					<checked-item
 | 
			
		||||
						v-if="isLeagueSelected"
 | 
			
		||||
						:item="item.value"
 | 
			
		||||
						:advanced-check="advancedCheck"
 | 
			
		||||
					/>
 | 
			
		||||
				</template>
 | 
			
		||||
				<div v-if="isBrowserShown" class="bg-gray-900 px-6 py-2 truncate">
 | 
			
		||||
					<i18n-t keypath="app.toggle_browser_hint" tag="div">
 | 
			
		||||
						<span class="bg-gray-400 text-gray-900 rounded px-1">{{
 | 
			
		||||
							overlayKey
 | 
			
		||||
						}}</span>
 | 
			
		||||
					</i18n-t>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<webview
 | 
			
		||||
			v-if="isBrowserShown"
 | 
			
		||||
			ref="iframeEl"
 | 
			
		||||
			class="pointer-events-auto flex-1"
 | 
			
		||||
			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',
 | 
			
		||||
				}"
 | 
			
		||||
			>
 | 
			
		||||
				<related-items
 | 
			
		||||
					v-if="item?.isOk()"
 | 
			
		||||
					class="pointer-events-auto"
 | 
			
		||||
					:item="item.value"
 | 
			
		||||
					:click-position="clickPosition"
 | 
			
		||||
				/>
 | 
			
		||||
				<rate-limiter-state class="pointer-events-auto" />
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent, inject, PropType, shallowRef, watch, computed, nextTick, provide } from 'vue'
 | 
			
		||||
import { Result, ok, err } from 'neverthrow'
 | 
			
		||||
import { useI18n } from 'vue-i18n'
 | 
			
		||||
import UiErrorBox from '@/web/ui/UiErrorBox.vue'
 | 
			
		||||
import UiPopover from '@/web/ui/Popover.vue'
 | 
			
		||||
import CheckedItem from './CheckedItem.vue'
 | 
			
		||||
import BackgroundInfo from './BackgroundInfo.vue'
 | 
			
		||||
import { MainProcess, Host } from '@/web/background/IPC'
 | 
			
		||||
import { usePoeninja } from '../background/Prices'
 | 
			
		||||
import { useLeagues } from '@/web/background/Leagues'
 | 
			
		||||
import { AppConfig } from '@/web/Config'
 | 
			
		||||
import { ItemCategory, ItemRarity, parseClipboard, ParsedItem } from '@/parser'
 | 
			
		||||
import RelatedItems from './related-items/RelatedItems.vue'
 | 
			
		||||
import RateLimiterState from './trade/RateLimiterState.vue'
 | 
			
		||||
import UnidentifiedResolver from './unidentified-resolver/UnidentifiedResolver.vue'
 | 
			
		||||
import CheckPositionCircle from './CheckPositionCircle.vue'
 | 
			
		||||
import AppTitleBar from '@/web/ui/AppTitlebar.vue'
 | 
			
		||||
import ItemQuickPrice from '@/web/ui/ItemQuickPrice.vue'
 | 
			
		||||
import { PriceCheckWidget, WidgetManager } from '../overlay/interfaces'
 | 
			
		||||
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue";
 | 
			
		||||
import {
 | 
			
		||||
	defineComponent,
 | 
			
		||||
	inject,
 | 
			
		||||
	PropType,
 | 
			
		||||
	shallowRef,
 | 
			
		||||
	watch,
 | 
			
		||||
	computed,
 | 
			
		||||
	nextTick,
 | 
			
		||||
	provide,
 | 
			
		||||
} from 'vue';
 | 
			
		||||
import { Result, ok, err } from 'neverthrow';
 | 
			
		||||
import { useI18n } from 'vue-i18n';
 | 
			
		||||
import UiErrorBox from '@/web/ui/UiErrorBox.vue';
 | 
			
		||||
import UiPopover from '@/web/ui/Popover.vue';
 | 
			
		||||
import CheckedItem from './CheckedItem.vue';
 | 
			
		||||
import BackgroundInfo from './BackgroundInfo.vue';
 | 
			
		||||
import { MainProcess, Host } from '@/web/background/IPC';
 | 
			
		||||
import { usePoeninja } from '../background/Prices';
 | 
			
		||||
import { useLeagues } from '@/web/background/Leagues';
 | 
			
		||||
import { AppConfig } from '@/web/Config';
 | 
			
		||||
import { ItemCategory, ItemRarity, parseClipboard, ParsedItem } from '@/parser';
 | 
			
		||||
import RelatedItems from './related-items/RelatedItems.vue';
 | 
			
		||||
import RateLimiterState from './trade/RateLimiterState.vue';
 | 
			
		||||
import UnidentifiedResolver from './unidentified-resolver/UnidentifiedResolver.vue';
 | 
			
		||||
import CheckPositionCircle from './CheckPositionCircle.vue';
 | 
			
		||||
import AppTitleBar from '@/web/ui/AppTitlebar.vue';
 | 
			
		||||
import ItemQuickPrice from '@/web/ui/ItemQuickPrice.vue';
 | 
			
		||||
import { PriceCheckWidget, WidgetManager } from '../overlay/interfaces';
 | 
			
		||||
import ConversionWarningBanner from '../conversion-warn-banner/ConversionWarningBanner.vue';
 | 
			
		||||
 | 
			
		||||
type ParseError = { name: string; message: string; rawText: ParsedItem['rawText'] }
 | 
			
		||||
type ParseError = {
 | 
			
		||||
	name: string;
 | 
			
		||||
	message: string;
 | 
			
		||||
	rawText: ParsedItem['rawText'];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  components: {
 | 
			
		||||
    AppTitleBar,
 | 
			
		||||
    CheckedItem,
 | 
			
		||||
    UnidentifiedResolver,
 | 
			
		||||
    BackgroundInfo,
 | 
			
		||||
    RelatedItems,
 | 
			
		||||
    RateLimiterState,
 | 
			
		||||
    CheckPositionCircle,
 | 
			
		||||
    ItemQuickPrice,
 | 
			
		||||
    UiErrorBox,
 | 
			
		||||
    UiPopover,
 | 
			
		||||
    ConversionWarningBanner
 | 
			
		||||
  },
 | 
			
		||||
  props: {
 | 
			
		||||
    config: {
 | 
			
		||||
      type: Object as PropType<PriceCheckWidget>,
 | 
			
		||||
      required: true
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  setup(props) {
 | 
			
		||||
    const wm = inject<WidgetManager>('wm')!
 | 
			
		||||
    const { xchgRate, initialLoading: xchgRateLoading, queuePricesFetch } = usePoeninja()
 | 
			
		||||
	components: {
 | 
			
		||||
		AppTitleBar,
 | 
			
		||||
		CheckedItem,
 | 
			
		||||
		UnidentifiedResolver,
 | 
			
		||||
		BackgroundInfo,
 | 
			
		||||
		RelatedItems,
 | 
			
		||||
		RateLimiterState,
 | 
			
		||||
		CheckPositionCircle,
 | 
			
		||||
		ItemQuickPrice,
 | 
			
		||||
		UiErrorBox,
 | 
			
		||||
		UiPopover,
 | 
			
		||||
		ConversionWarningBanner,
 | 
			
		||||
	},
 | 
			
		||||
	props: {
 | 
			
		||||
		config: {
 | 
			
		||||
			type: Object as PropType<PriceCheckWidget>,
 | 
			
		||||
			required: true,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	setup(props) {
 | 
			
		||||
		const wm = inject<WidgetManager>('wm')!;
 | 
			
		||||
		const {
 | 
			
		||||
			xchgRate,
 | 
			
		||||
			initialLoading: xchgRateLoading,
 | 
			
		||||
			queuePricesFetch,
 | 
			
		||||
		} = usePoeninja();
 | 
			
		||||
 | 
			
		||||
    nextTick(() => {
 | 
			
		||||
      props.config.wmWants = 'hide'
 | 
			
		||||
      props.config.wmFlags = ['hide-on-blur', 'skip-menu']
 | 
			
		||||
    })
 | 
			
		||||
		nextTick(() => {
 | 
			
		||||
			props.config.wmWants = 'hide';
 | 
			
		||||
			props.config.wmFlags = ['hide-on-blur', 'skip-menu'];
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
    const item = shallowRef<null | Result<ParsedItem, ParseError>>(null)
 | 
			
		||||
    const advancedCheck = shallowRef(false)
 | 
			
		||||
    const checkPosition = shallowRef({ x: 1, y: 1 })
 | 
			
		||||
		const item = shallowRef<null | Result<ParsedItem, ParseError>>(null);
 | 
			
		||||
		const advancedCheck = shallowRef(false);
 | 
			
		||||
		const checkPosition = shallowRef({ x: 1, y: 1 });
 | 
			
		||||
 | 
			
		||||
    MainProcess.onEvent('MAIN->CLIENT::item-text', (e) => {
 | 
			
		||||
      if (e.target !== 'price-check') return
 | 
			
		||||
		MainProcess.onEvent('MAIN->CLIENT::item-text', (e) => {
 | 
			
		||||
			if (e.target !== 'price-check') return;
 | 
			
		||||
 | 
			
		||||
      if (Host.isElectron && !e.focusOverlay) {
 | 
			
		||||
        // everything in CSS pixels
 | 
			
		||||
        const width = 28.75 * AppConfig().fontSize
 | 
			
		||||
        const screenX = ((e.position.x - window.screenX) > window.innerWidth / 2)
 | 
			
		||||
          ? (window.screenX + window.innerWidth) - wm.poePanelWidth.value - width
 | 
			
		||||
          : window.screenX + wm.poePanelWidth.value
 | 
			
		||||
        MainProcess.sendEvent({
 | 
			
		||||
          name: 'OVERLAY->MAIN::track-area',
 | 
			
		||||
          payload: {
 | 
			
		||||
            holdKey: props.config.hotkeyHold,
 | 
			
		||||
            closeThreshold: 2.5 * AppConfig().fontSize,
 | 
			
		||||
            from: e.position,
 | 
			
		||||
            area: {
 | 
			
		||||
              x: screenX,
 | 
			
		||||
              y: window.screenY,
 | 
			
		||||
              width,
 | 
			
		||||
              height: window.innerHeight
 | 
			
		||||
            },
 | 
			
		||||
            dpr: window.devicePixelRatio
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
      closeBrowser()
 | 
			
		||||
      wm.show(props.config.wmId)
 | 
			
		||||
      checkPosition.value = e.position
 | 
			
		||||
      advancedCheck.value = e.focusOverlay
 | 
			
		||||
			if (Host.isElectron && !e.focusOverlay) {
 | 
			
		||||
				// everything in CSS pixels
 | 
			
		||||
				const width = 28.75 * AppConfig().fontSize;
 | 
			
		||||
				const screenX =
 | 
			
		||||
					e.position.x - window.screenX > window.innerWidth / 2
 | 
			
		||||
						? window.screenX +
 | 
			
		||||
							window.innerWidth -
 | 
			
		||||
							wm.poePanelWidth.value -
 | 
			
		||||
							width
 | 
			
		||||
						: window.screenX + wm.poePanelWidth.value;
 | 
			
		||||
				MainProcess.sendEvent({
 | 
			
		||||
					name: 'OVERLAY->MAIN::track-area',
 | 
			
		||||
					payload: {
 | 
			
		||||
						holdKey: props.config.hotkeyHold,
 | 
			
		||||
						closeThreshold: 2.5 * AppConfig().fontSize,
 | 
			
		||||
						from: e.position,
 | 
			
		||||
						area: {
 | 
			
		||||
							x: screenX,
 | 
			
		||||
							y: window.screenY,
 | 
			
		||||
							width,
 | 
			
		||||
							height: window.innerHeight,
 | 
			
		||||
						},
 | 
			
		||||
						dpr: window.devicePixelRatio,
 | 
			
		||||
					},
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
			closeBrowser();
 | 
			
		||||
			wm.show(props.config.wmId);
 | 
			
		||||
			checkPosition.value = e.position;
 | 
			
		||||
			advancedCheck.value = e.focusOverlay;
 | 
			
		||||
 | 
			
		||||
      item.value = (e.item ? ok(e.item as ParsedItem) : parseClipboard(e.clipboard))
 | 
			
		||||
        .andThen(item => (
 | 
			
		||||
          (item.category === ItemCategory.HeistContract && item.rarity !== ItemRarity.Unique) ||
 | 
			
		||||
          (item.category === ItemCategory.Sentinel && item.rarity !== ItemRarity.Unique))
 | 
			
		||||
          ? err('item.unknown')
 | 
			
		||||
          : ok(item))
 | 
			
		||||
        .mapErr(err => ({
 | 
			
		||||
          name: `${err}`,
 | 
			
		||||
          message: `${err}_help`,
 | 
			
		||||
          rawText: e.clipboard
 | 
			
		||||
        }))
 | 
			
		||||
			item.value = (
 | 
			
		||||
				e.item ? ok(e.item as ParsedItem) : parseClipboard(e.clipboard)
 | 
			
		||||
			)
 | 
			
		||||
				.andThen((item) =>
 | 
			
		||||
					(item.category === ItemCategory.HeistContract &&
 | 
			
		||||
						item.rarity !== ItemRarity.Unique) ||
 | 
			
		||||
					(item.category === ItemCategory.Sentinel &&
 | 
			
		||||
						item.rarity !== ItemRarity.Unique)
 | 
			
		||||
						? err('item.unknown')
 | 
			
		||||
						: ok(item)
 | 
			
		||||
				)
 | 
			
		||||
				.mapErr((err) => ({
 | 
			
		||||
					name: `${err}`,
 | 
			
		||||
					message: `${err}_help`,
 | 
			
		||||
					rawText: e.clipboard,
 | 
			
		||||
				}));
 | 
			
		||||
 | 
			
		||||
      if (item.value.isOk()) {
 | 
			
		||||
        queuePricesFetch()
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
			if (item.value.isOk()) {
 | 
			
		||||
				queuePricesFetch();
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
    function handleIdentification(identified: ParsedItem) {
 | 
			
		||||
      item.value = ok(identified)
 | 
			
		||||
    }
 | 
			
		||||
		function handleIdentification(identified: ParsedItem) {
 | 
			
		||||
			item.value = ok(identified);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    MainProcess.onEvent('MAIN->OVERLAY::hide-exclusive-widget', () => {
 | 
			
		||||
      wm.hide(props.config.wmId)
 | 
			
		||||
    })
 | 
			
		||||
		MainProcess.onEvent('MAIN->OVERLAY::hide-exclusive-widget', () => {
 | 
			
		||||
			wm.hide(props.config.wmId);
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
    watch(() => props.config.wmWants, (state) => {
 | 
			
		||||
      if (state === 'hide') {
 | 
			
		||||
        closeBrowser()
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
		watch(
 | 
			
		||||
			() => props.config.wmWants,
 | 
			
		||||
			(state) => {
 | 
			
		||||
				if (state === 'hide') {
 | 
			
		||||
					closeBrowser();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
    const leagues = useLeagues()
 | 
			
		||||
    const title = computed(() => leagues.selectedId.value || 'Awakened PoE2 Trade2')
 | 
			
		||||
    const stableOrbCost = computed(() => (xchgRate.value) ? Math.round(xchgRate.value) : null)
 | 
			
		||||
    const isBrowserShown = computed(() => props.config.wmFlags.includes('has-browser'))
 | 
			
		||||
    const overlayKey = computed(() => AppConfig().overlayKey)
 | 
			
		||||
    const showCheckPos = computed(() => wm.active.value && props.config.showCursor)
 | 
			
		||||
    const isLeagueSelected = computed(() => Boolean(leagues.selectedId.value))
 | 
			
		||||
    const clickPosition = computed(() => {
 | 
			
		||||
      if (isBrowserShown.value) {
 | 
			
		||||
        return 'inventory'
 | 
			
		||||
      } else {
 | 
			
		||||
        return checkPosition.value.x > (window.screenX + window.innerWidth / 2)
 | 
			
		||||
          ? 'inventory'
 | 
			
		||||
          : 'stash'
 | 
			
		||||
        // or {chat, vendor, center of screen}
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
		const leagues = useLeagues();
 | 
			
		||||
		const title = computed(
 | 
			
		||||
			() => leagues.selectedId.value || 'Exalted PoE2 Trade'
 | 
			
		||||
		);
 | 
			
		||||
		const stableOrbCost = computed(() =>
 | 
			
		||||
			xchgRate.value ? Math.round(xchgRate.value) : null
 | 
			
		||||
		);
 | 
			
		||||
		const isBrowserShown = computed(() =>
 | 
			
		||||
			props.config.wmFlags.includes('has-browser')
 | 
			
		||||
		);
 | 
			
		||||
		const overlayKey = computed(() => AppConfig().overlayKey);
 | 
			
		||||
		const showCheckPos = computed(
 | 
			
		||||
			() => wm.active.value && props.config.showCursor
 | 
			
		||||
		);
 | 
			
		||||
		const isLeagueSelected = computed(() => Boolean(leagues.selectedId.value));
 | 
			
		||||
		const clickPosition = computed(() => {
 | 
			
		||||
			if (isBrowserShown.value) {
 | 
			
		||||
				return 'inventory';
 | 
			
		||||
			} else {
 | 
			
		||||
				return checkPosition.value.x > window.screenX + window.innerWidth / 2
 | 
			
		||||
					? 'inventory'
 | 
			
		||||
					: 'stash';
 | 
			
		||||
				// or {chat, vendor, center of screen}
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
    watch(isBrowserShown, (isShown) => {
 | 
			
		||||
      if (isShown) {
 | 
			
		||||
        wm.setFlag(props.config.wmId, 'hide-on-blur', false)
 | 
			
		||||
        wm.setFlag(props.config.wmId, 'invisible-on-blur', true)
 | 
			
		||||
      } else {
 | 
			
		||||
        wm.setFlag(props.config.wmId, 'invisible-on-blur', false)
 | 
			
		||||
        wm.setFlag(props.config.wmId, 'hide-on-blur', true)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
		watch(isBrowserShown, (isShown) => {
 | 
			
		||||
			if (isShown) {
 | 
			
		||||
				wm.setFlag(props.config.wmId, 'hide-on-blur', false);
 | 
			
		||||
				wm.setFlag(props.config.wmId, 'invisible-on-blur', true);
 | 
			
		||||
			} else {
 | 
			
		||||
				wm.setFlag(props.config.wmId, 'invisible-on-blur', false);
 | 
			
		||||
				wm.setFlag(props.config.wmId, 'hide-on-blur', true);
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
    function closePriceCheck() {
 | 
			
		||||
      if (isBrowserShown.value || !Host.isElectron) {
 | 
			
		||||
        wm.hide(props.config.wmId)
 | 
			
		||||
      } else {
 | 
			
		||||
        Host.sendEvent({ name: 'OVERLAY->MAIN::focus-game', payload: undefined })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
		function closePriceCheck() {
 | 
			
		||||
			if (isBrowserShown.value || !Host.isElectron) {
 | 
			
		||||
				wm.hide(props.config.wmId);
 | 
			
		||||
			} else {
 | 
			
		||||
				Host.sendEvent({
 | 
			
		||||
					name: 'OVERLAY->MAIN::focus-game',
 | 
			
		||||
					payload: undefined,
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    function openLeagueSelection() {
 | 
			
		||||
      const settings = wm.widgets.value.find(w => w.wmType === 'settings')!
 | 
			
		||||
      wm.setFlag(settings.wmId, `settings:widget:${props.config.wmId}`, true)
 | 
			
		||||
      wm.show(settings.wmId)
 | 
			
		||||
    }
 | 
			
		||||
		function openLeagueSelection() {
 | 
			
		||||
			const settings = wm.widgets.value.find((w) => w.wmType === 'settings')!;
 | 
			
		||||
			wm.setFlag(settings.wmId, `settings:widget:${props.config.wmId}`, true);
 | 
			
		||||
			wm.show(settings.wmId);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    const iframeEl = shallowRef<HTMLIFrameElement | null>(null)
 | 
			
		||||
		const iframeEl = shallowRef<HTMLIFrameElement | null>(null);
 | 
			
		||||
 | 
			
		||||
    function showBrowser(url: string) {
 | 
			
		||||
      wm.setFlag(props.config.wmId, 'has-browser', true)
 | 
			
		||||
      nextTick(() => {
 | 
			
		||||
        iframeEl.value!.src = url
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
		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)
 | 
			
		||||
    }
 | 
			
		||||
		function closeBrowser() {
 | 
			
		||||
			wm.setFlag(props.config.wmId, 'has-browser', false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    provide<(url: string) => void>('builtin-browser', showBrowser)
 | 
			
		||||
		provide<(url: string) => void>('builtin-browser', showBrowser);
 | 
			
		||||
 | 
			
		||||
    const { t } = useI18n()
 | 
			
		||||
		const { t } = useI18n();
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      t,
 | 
			
		||||
      clickPosition,
 | 
			
		||||
      isBrowserShown,
 | 
			
		||||
      iframeEl,
 | 
			
		||||
      closePriceCheck,
 | 
			
		||||
      title,
 | 
			
		||||
      stableOrbCost,
 | 
			
		||||
      xchgRateLoading,
 | 
			
		||||
      showCheckPos,
 | 
			
		||||
      checkPosition,
 | 
			
		||||
      item,
 | 
			
		||||
      advancedCheck,
 | 
			
		||||
      handleIdentification,
 | 
			
		||||
      overlayKey,
 | 
			
		||||
      isLeagueSelected,
 | 
			
		||||
      openLeagueSelection
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
		return {
 | 
			
		||||
			t,
 | 
			
		||||
			clickPosition,
 | 
			
		||||
			isBrowserShown,
 | 
			
		||||
			iframeEl,
 | 
			
		||||
			closePriceCheck,
 | 
			
		||||
			title,
 | 
			
		||||
			stableOrbCost,
 | 
			
		||||
			xchgRateLoading,
 | 
			
		||||
			showCheckPos,
 | 
			
		||||
			checkPosition,
 | 
			
		||||
			item,
 | 
			
		||||
			advancedCheck,
 | 
			
		||||
			handleIdentification,
 | 
			
		||||
			overlayKey,
 | 
			
		||||
			isLeagueSelected,
 | 
			
		||||
			openLeagueSelection,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,93 +1,152 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="p-2 flex flex-col h-full items-center">
 | 
			
		||||
    <div class="flex flex-col items-center p-2 mb-4">
 | 
			
		||||
      <img class="w-12 h-12" src="/images/TransferOrb.png">
 | 
			
		||||
      <p class="text-base">Awakened PoE2 Trade2</p>
 | 
			
		||||
      <p class="">{{ t('app.version', [version]) }}</p>
 | 
			
		||||
      <div class="flex gap-2">
 | 
			
		||||
        <a class="border-b" href="https://github.com/Kvan7/awakened-poe2-trade2/releases" target="_blank">{{
 | 
			
		||||
          t('app.release_notes') }}</a>
 | 
			
		||||
        <a class="border-b" href="https://github.com/Kvan7/awakened-poe2-trade2/issues" target="_blank">{{
 | 
			
		||||
          t('app.report_bug') }}</a>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="border border-gray-600 rounded p-2 whitespace-nowrap min-w-min w-72">
 | 
			
		||||
      <p>{{ info.str1 }}</p>
 | 
			
		||||
      <p>{{ info.str2 }}</p>
 | 
			
		||||
      <button v-if="info.action" @click="info.action" class="btn w-full mt-1">{{ info.actionText }}</button>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="text-center mt-auto py-8">
 | 
			
		||||
      <p>{{ t('app.contact_me') }} <br><span
 | 
			
		||||
          class="font-sans text-gray-500 select-all"><@295216259795124225></span></p>
 | 
			
		||||
      <ul class="flex gap-4">
 | 
			
		||||
        <li><img class="rounded inline" src="/images/dc_tft.gif"> <a class="border-b" href="https://discord.gg/tftrove"
 | 
			
		||||
            target="_blank">The Forbidden Trove</a></li>
 | 
			
		||||
        <li><img class="rounded inline" src="/images/dc_reddit.png"> <a class="border-b"
 | 
			
		||||
            href="https://discord.gg/pathofexile" target="_blank">r/pathofexile</a></li>
 | 
			
		||||
      </ul>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
	<div class="p-2 flex flex-col h-full items-center">
 | 
			
		||||
		<div class="flex flex-col items-center p-2 mb-4">
 | 
			
		||||
			<img class="w-12 h-12" src="/images/exa.png" />
 | 
			
		||||
			<p class="text-base">Exalted PoE2 Trade</p>
 | 
			
		||||
			<p class="">{{ t('app.version', [version]) }}</p>
 | 
			
		||||
			<div class="flex gap-2">
 | 
			
		||||
				<a
 | 
			
		||||
					class="border-b"
 | 
			
		||||
					href="https://github.com/Kvan7/exalted-poe2-trade/releases"
 | 
			
		||||
					target="_blank"
 | 
			
		||||
					>{{ t('app.release_notes') }}</a
 | 
			
		||||
				>
 | 
			
		||||
				<a
 | 
			
		||||
					class="border-b"
 | 
			
		||||
					href="https://github.com/Kvan7/exalted-poe2-trade/issues"
 | 
			
		||||
					target="_blank"
 | 
			
		||||
					>{{ t('app.report_bug') }}</a
 | 
			
		||||
				>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div
 | 
			
		||||
			class="border border-gray-600 rounded p-2 whitespace-nowrap min-w-min w-72"
 | 
			
		||||
		>
 | 
			
		||||
			<p>{{ info.str1 }}</p>
 | 
			
		||||
			<p>{{ info.str2 }}</p>
 | 
			
		||||
			<button v-if="info.action" @click="info.action" class="btn w-full mt-1">
 | 
			
		||||
				{{ info.actionText }}
 | 
			
		||||
			</button>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="text-center mt-auto py-8">
 | 
			
		||||
			<p>
 | 
			
		||||
				{{ t('app.contact_me') }} <br /><span
 | 
			
		||||
					class="font-sans text-gray-500 select-all"
 | 
			
		||||
					><@295216259795124225></span
 | 
			
		||||
				>
 | 
			
		||||
			</p>
 | 
			
		||||
			<ul class="flex gap-4">
 | 
			
		||||
				<li>
 | 
			
		||||
					<img class="rounded inline" src="/images/dc_tft.gif" />
 | 
			
		||||
					<a class="border-b" href="https://discord.gg/tftrove" target="_blank"
 | 
			
		||||
						>The Forbidden Trove</a
 | 
			
		||||
					>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li>
 | 
			
		||||
					<img class="rounded inline" src="/images/dc_reddit.png" />
 | 
			
		||||
					<a
 | 
			
		||||
						class="border-b"
 | 
			
		||||
						href="https://discord.gg/pathofexile"
 | 
			
		||||
						target="_blank"
 | 
			
		||||
						>r/pathofexile</a
 | 
			
		||||
					>
 | 
			
		||||
				</li>
 | 
			
		||||
			</ul>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import { defineComponent, computed } from 'vue'
 | 
			
		||||
import { useI18n } from 'vue-i18n'
 | 
			
		||||
import { Host } from '@/web/background/IPC'
 | 
			
		||||
import { DateTime } from 'luxon'
 | 
			
		||||
import { defineComponent, computed } from 'vue';
 | 
			
		||||
import { useI18n } from 'vue-i18n';
 | 
			
		||||
import { Host } from '@/web/background/IPC';
 | 
			
		||||
import { DateTime } from 'luxon';
 | 
			
		||||
 | 
			
		||||
function checkForUpdates() {
 | 
			
		||||
  Host.sendEvent({
 | 
			
		||||
    name: 'CLIENT->MAIN::user-action',
 | 
			
		||||
    payload: { action: 'check-for-update' }
 | 
			
		||||
  })
 | 
			
		||||
	Host.sendEvent({
 | 
			
		||||
		name: 'CLIENT->MAIN::user-action',
 | 
			
		||||
		payload: { action: 'check-for-update' },
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function openDownloadPage() {
 | 
			
		||||
  window.open('https://snosme.github.io/awakened-poe-trade/download')
 | 
			
		||||
	// don't have this setup yet
 | 
			
		||||
	window.open('https://kvan7.github.io/exalted-poe2-trade/download');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function quitAndInstall() {
 | 
			
		||||
  Host.sendEvent({
 | 
			
		||||
    name: 'CLIENT->MAIN::user-action',
 | 
			
		||||
    payload: { action: 'update-and-restart' }
 | 
			
		||||
  })
 | 
			
		||||
	Host.sendEvent({
 | 
			
		||||
		name: 'CLIENT->MAIN::user-action',
 | 
			
		||||
		payload: { action: 'update-and-restart' },
 | 
			
		||||
	});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function fmtTime(millis: number) {
 | 
			
		||||
  return DateTime.fromMillis(millis).toRelative({ style: 'long' }) ?? 'n/a'
 | 
			
		||||
	return DateTime.fromMillis(millis).toRelative({ style: 'long' }) ?? 'n/a';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default defineComponent({
 | 
			
		||||
  name: 'settings.about',
 | 
			
		||||
  inheritAttrs: false,
 | 
			
		||||
  setup() {
 | 
			
		||||
    const { t } = useI18n()
 | 
			
		||||
	name: 'settings.about',
 | 
			
		||||
	inheritAttrs: false,
 | 
			
		||||
	setup() {
 | 
			
		||||
		const { t } = useI18n();
 | 
			
		||||
 | 
			
		||||
    const info = computed(() => {
 | 
			
		||||
      const rawInfo = Host.updateInfo.value
 | 
			
		||||
      switch (rawInfo.state) {
 | 
			
		||||
        case 'initial':
 | 
			
		||||
          return { str1: t('updates.maybe_outdated'), str2: t('updates.never_checked'), action: checkForUpdates, actionText: t('updates.check_now') }
 | 
			
		||||
        case 'checking-for-update':
 | 
			
		||||
          return { str1: t('updates.checking'), str2: t('please_wait') }
 | 
			
		||||
        case 'update-not-available':
 | 
			
		||||
          return { str1: t('updates.latest'), str2: t('updates.last_checked', [fmtTime(rawInfo.checkedAt)]), action: checkForUpdates, actionText: t('updates.check_now') }
 | 
			
		||||
        case 'error':
 | 
			
		||||
          return { str1: t('updates.maybe_outdated'), str2: t('updates.error'), action: openDownloadPage, actionText: t('updates.downloads_page') }
 | 
			
		||||
        case 'update-downloaded':
 | 
			
		||||
          return { str1: t('updates.available', [rawInfo.version]), str2: t('updates.installed_on_exit'), action: quitAndInstall, actionText: t('updates.install_now') }
 | 
			
		||||
        case 'update-available':
 | 
			
		||||
          return (rawInfo.noDownloadReason)
 | 
			
		||||
            ? { str1: t('updates.available', [rawInfo.version]), str2: (rawInfo.noDownloadReason === 'not-supported') ? t('updates.download_manually') : t('updates.download_disabled'), action: openDownloadPage, actionText: t('updates.downloads_page') }
 | 
			
		||||
            : { str1: t('updates.available', [rawInfo.version]), str2: t('updates.downloading') }
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
		const info = computed(() => {
 | 
			
		||||
			const rawInfo = Host.updateInfo.value;
 | 
			
		||||
			switch (rawInfo.state) {
 | 
			
		||||
				case 'initial':
 | 
			
		||||
					return {
 | 
			
		||||
						str1: t('updates.maybe_outdated'),
 | 
			
		||||
						str2: t('updates.never_checked'),
 | 
			
		||||
						action: checkForUpdates,
 | 
			
		||||
						actionText: t('updates.check_now'),
 | 
			
		||||
					};
 | 
			
		||||
				case 'checking-for-update':
 | 
			
		||||
					return { str1: t('updates.checking'), str2: t('please_wait') };
 | 
			
		||||
				case 'update-not-available':
 | 
			
		||||
					return {
 | 
			
		||||
						str1: t('updates.latest'),
 | 
			
		||||
						str2: t('updates.last_checked', [fmtTime(rawInfo.checkedAt)]),
 | 
			
		||||
						action: checkForUpdates,
 | 
			
		||||
						actionText: t('updates.check_now'),
 | 
			
		||||
					};
 | 
			
		||||
				case 'error':
 | 
			
		||||
					return {
 | 
			
		||||
						str1: t('updates.maybe_outdated'),
 | 
			
		||||
						str2: t('updates.error'),
 | 
			
		||||
						action: openDownloadPage,
 | 
			
		||||
						actionText: t('updates.downloads_page'),
 | 
			
		||||
					};
 | 
			
		||||
				case 'update-downloaded':
 | 
			
		||||
					return {
 | 
			
		||||
						str1: t('updates.available', [rawInfo.version]),
 | 
			
		||||
						str2: t('updates.installed_on_exit'),
 | 
			
		||||
						action: quitAndInstall,
 | 
			
		||||
						actionText: t('updates.install_now'),
 | 
			
		||||
					};
 | 
			
		||||
				case 'update-available':
 | 
			
		||||
					return rawInfo.noDownloadReason
 | 
			
		||||
						? {
 | 
			
		||||
								str1: t('updates.available', [rawInfo.version]),
 | 
			
		||||
								str2:
 | 
			
		||||
									rawInfo.noDownloadReason === 'not-supported'
 | 
			
		||||
										? t('updates.download_manually')
 | 
			
		||||
										: t('updates.download_disabled'),
 | 
			
		||||
								action: openDownloadPage,
 | 
			
		||||
								actionText: t('updates.downloads_page'),
 | 
			
		||||
							}
 | 
			
		||||
						: {
 | 
			
		||||
								str1: t('updates.available', [rawInfo.version]),
 | 
			
		||||
								str2: t('updates.downloading'),
 | 
			
		||||
							};
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      t,
 | 
			
		||||
      info,
 | 
			
		||||
      version: Host.version
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
		return {
 | 
			
		||||
			t,
 | 
			
		||||
			info,
 | 
			
		||||
			version: Host.version,
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||