Compare commits

...

1 Commits

Author SHA1 Message Date
kvan7
7000dbc58c style(Update to 2): Update branding
Renamed to Exalted PoE2 Trade
2024-12-10 15:47:06 -06:00
36 changed files with 545 additions and 3652 deletions

View File

@@ -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: 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. Here's what that looks like as of 2023-12-03.

View File

@@ -1,16 +1,16 @@
# ![Awakener's Orb](https://web.poecdn.com/image/Art/2DItems/Currency/TransferOrb.png) Awakened PoE2 Trade2 # ![Exalted Orb](./renderer/public/icon.png) Exalted PoE2 Trade
## Moving from POE1 ## 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 - Currently only Windows is supported
- Only available as pre-release right now - Only available as pre-release right now
2. Run installer 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: - Resulting directory structure should look like this:
- `%APPDATA%\awakened-poe2-trade2\apt-data\` - `%APPDATA%\exalted-poe2-trade\apt-data\`
- `config.json` - `config.json`
4. Run Awakened PoE2 Trade2 4. Run Exalted PoE2 Trade
## Tool showcase ## Tool showcase

View File

@@ -1,9 +1,9 @@
import { defineConfig } from 'vitepress' import { defineConfig } from 'vitepress'
const BASE = '/awakened-poe2-trade2/' const BASE = '/exalted-poe2-trade/'
export default defineConfig({ export default defineConfig({
title: 'Awakened PoE2 Trade2', title: 'Exalted PoE2 Trade',
description: 'App for price-checking items in Path of Exile 2', description: 'App for price-checking items in Path of Exile 2',
base: BASE, base: BASE,
mpa: true, mpa: true,
@@ -22,7 +22,7 @@ export default defineConfig({
// logo: 'TODO', https://github.com/vuejs/vitepress/issues/1401 // logo: 'TODO', https://github.com/vuejs/vitepress/issues/1401
appVersion: '3.25.101', appVersion: '3.25.101',
github: { github: {
releasesUrl: 'https://github.com/Kvan7/awakened-poe2-trade2/releases' releasesUrl: 'https://github.com/Kvan7/exalted-poe2-trade/releases'
}, },
socialLinks: [ socialLinks: [
{ {
@@ -33,7 +33,7 @@ export default defineConfig({
{ {
text: 'GitHub', text: 'GitHub',
color: '#181717', color: '#181717',
link: 'https://github.com/Kvan7/awakened-poe2-trade2' link: 'https://github.com/Kvan7/exalted-poe2-trade'
} }
], ],
sidebar: [ sidebar: [

View File

@@ -8,15 +8,15 @@ import { useData } from 'vitepress'
const { theme } = useData() const { theme } = useData()
</script> </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. to the developer, downloading from them may be unsafe.
| Download link | Automatic updates | Startup time | | 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}/Exalted-PoE2-Trade-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}/Exalted-PoE2-Trade-${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}/Exalted-PoE2-Trade-${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 | | <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> 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\ No Administrator rights required, but\
⚠ **If you run PoE client as Admin, OS security boundaries take effect. ⚠ **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.** **Not compatible with "GeForce Now" or any other cloud gaming service that do not forward clipboard data.**

View File

@@ -14,7 +14,7 @@ title: Common issues
If Awakened works for you with DirectX11/12 renderer, If Awakened works for you with DirectX11/12 renderer,
then problem is old Vulkan drivers for sure. 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. 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**. 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).* *(don't forget to quit first, otherwise launching second instance will do nothing).*

View File

@@ -5,7 +5,7 @@ title: Quick Start
#### First of all, how does it work? {:style="margin-top: 0;"} #### 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. 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 ### Usage

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 KiB

After

Width:  |  Height:  |  Size: 712 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 KiB

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 KiB

After

Width:  |  Height:  |  Size: 66 KiB

BIN
main/build/icons/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,6 +1,6 @@
publish: publish:
- "github" - "github"
productName: "Awakened PoE2 Trade2" productName: "Exalted PoE2 Trade"
npmRebuild: false npmRebuild: false
files: files:
- "package.json" - "package.json"

View File

@@ -1,5 +1,5 @@
{ {
"name": "awakened-poe2-trade2", "name": "exalted-poe2-trade",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {
@@ -8,11 +8,11 @@
"package": "electron-builder build" "package": "electron-builder build"
}, },
"author": { "author": {
"name": "Alexander Drozdov" "name": "Garrett Parker"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/Kvan7/awakened-poe2-trade2.git" "url": "https://github.com/Kvan7/exalted-poe2-trade.git"
}, },
"main": "dist/main.js", "main": "dist/main.js",
"dependencies": { "dependencies": {

View File

@@ -23,7 +23,7 @@ export class AppTray {
} }
this.tray = new Tray(trayImage); 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(); this.rebuildMenu();
server.onEventAnyClient("CLIENT->MAIN::user-action", ({ action }) => { server.onEventAnyClient("CLIENT->MAIN::user-action", ({ action }) => {

View File

@@ -161,7 +161,7 @@ export class OverlayWindow {
// ---------------------- // ----------------------
"Path of Exile 2 is running with administrator rights.\n" + "Path of Exile 2 is running with administrator rights.\n" +
"\n" + "\n" +
"You need to restart Awakened PoE2 Trade2 with administrator rights." "You need to restart Exalted PoE2 Trade with administrator rights."
); );
} else { } else {
this.server.sendEventTo("broadcast", { this.server.sendEventTo("broadcast", {

View File

@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="color-scheme" content="dark"> <meta name="color-scheme" content="dark">
<link rel="icon" href="/icon.ico"> <link rel="icon" href="/icon.ico">
<title>Awakened PoE Trade2</title> <title>Exalted PoE2 Trade</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@@ -1,12 +1,12 @@
{ {
"name": "awakened-poe2-trade2", "name": "exalted-poe2-trade",
"version": "0.0.0", "version": "0.0.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "awakened-poe2-trade2", "name": "exalted-poe2-trade",
"version": "0.0.0", "version": "0.0.1",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "6.x.x", "@fortawesome/fontawesome-free": "6.x.x",
"@sindresorhus/fnv1a": "^3.0.0", "@sindresorhus/fnv1a": "^3.0.0",

View File

@@ -1,5 +1,5 @@
{ {
"name": "awakened-poe2-trade2", "name": "exalted-poe2-trade",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"scripts": { "scripts": {

View File

@@ -269,7 +269,7 @@
"stack": "Stack" "stack": "Stack"
}, },
"settings": { "settings": {
"title": "Settings - Awakened PoE2 Trade2", "title": "Settings - Exalted PoE2 Trade",
"language": "Language", "language": "Language",
"private_league": "or Private League", "private_league": "or Private League",
"account_name": "Account name", "account_name": "Account name",

View File

@@ -266,7 +266,7 @@
"stack": "스택" "stack": "스택"
}, },
"settings": { "settings": {
"title": "세팅 - Awakened PoE2 Trade2", "title": "세팅 - Exalted PoE2 Trade",
"language": "언어", "language": "언어",
"private_league": "개인리그", "private_league": "개인리그",
"account_name": "계정명", "account_name": "계정명",

View File

@@ -282,7 +282,7 @@
"stack": "Стак" "stack": "Стак"
}, },
"settings": { "settings": {
"title": "Настройки - Awakened PoE2 Trade2", "title": "Настройки - Exalted PoE2 Trade",
"language": "Язык", "language": "Язык",
"private_league": "или Приватная лига", "private_league": "или Приватная лига",
"account_name": "Имя учетной записи", "account_name": "Имя учетной записи",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -76,9 +76,9 @@ export async function initConfig() {
// TODO // TODO
// dialog.showErrorBox( // 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.' // 'You need to install the latest version to continue using it.'
// ) // )
} }

View File

@@ -1,10 +1,12 @@
<template> <template>
<transition enter-active-class="animate__animated animate__fadeIn" <transition
leave-active-class="animate__animated animate__backOutDown"> enter-active-class="animate__animated animate__fadeIn"
leave-active-class="animate__animated animate__backOutDown"
>
<div :class="$style.widget" v-if="show"> <div :class="$style.widget" v-if="show">
<div :class="$style.box"> <div :class="$style.box">
<div class="py-2 px-4"> <div class="py-2 px-4">
<div class="text-base">Awakened PoE2 Trade2</div> <div class="text-base">Exalted PoE2 Trade</div>
<p>{{ t('app_is_ready') }}</p> <p>{{ t('app_is_ready') }}</p>
</div> </div>
</div> </div>
@@ -13,21 +15,23 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { shallowRef } from 'vue' import { shallowRef } from 'vue';
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n';
import { Host } from '@/web/background/IPC' import { Host } from '@/web/background/IPC';
import { AppConfig } from '@/web/Config' 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', () => { Host.onEvent('MAIN->OVERLAY::overlay-attached', () => {
if (!show.value && AppConfig().showAttachNotification) { if (!show.value && AppConfig().showAttachNotification) {
show.value = true show.value = true;
setTimeout(() => { show.value = false }, 2500) setTimeout(() => {
show.value = false;
}, 2500);
} }
}) });
</script> </script>
<style lang="postcss" module> <style lang="postcss" module>
@@ -51,7 +55,7 @@ Host.onEvent('MAIN->OVERLAY::overlay-attached', () => {
.box::before { .box::before {
position: absolute; position: absolute;
content: ''; content: '';
background: url('/images/TransferOrb.png') no-repeat top right/contain; background: url('/images/exa.png') no-repeat top right/contain;
right: 100%; right: 100%;
width: 100%; width: 100%;
height: 100%; height: 100%;

View File

@@ -1,23 +1,52 @@
<template> <template>
<div style="top: 0; left: 0; height: 100%; width: 100%; position: absolute;" <div
class="flex grow h-full pointer-events-none" :class="{ 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': clickPosition === 'stash',
'flex-row-reverse': clickPosition === 'inventory', 'flex-row-reverse': clickPosition === 'inventory',
}"> }"
<div v-if="!isBrowserShown" class="layout-column shrink-0" style="width: var(--game-panel);"> >
</div> <div
<div id="price-window" class="layout-column shrink-0 text-gray-200 pointer-events-auto" style="width: 28.75rem;"> 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 /> <ConversionWarningBanner />
<AppTitleBar @close="closePriceCheck" @click="openLeagueSelection" :title="title"> <AppTitleBar
<ui-popover v-if="stableOrbCost" trigger="click" boundary="#price-window"> @close="closePriceCheck"
@click="openLeagueSelection"
:title="title"
>
<ui-popover
v-if="stableOrbCost"
trigger="click"
boundary="#price-window"
>
<template #target> <template #target>
<button><i class="fas fa-exchange-alt" /> {{ stableOrbCost }}</button> <button>
<i class="fas fa-exchange-alt" /> {{ stableOrbCost }}
</button>
</template> </template>
<template #content> <template #content>
<item-quick-price class="text-base" :price="{ min: stableOrbCost, max: stableOrbCost, currency: 'chaos' }" <item-quick-price
item-img="/images/divine.png" /> class="text-base"
:price="{
min: stableOrbCost,
max: stableOrbCost,
currency: 'chaos',
}"
item-img="/images/divine.png"
/>
<div v-for="i in 9" :key="i"> <div v-for="i in 9" :key="i">
<div class="pl-1">{{ i / 10 }} div {{ Math.round(stableOrbCost * i / 10) }} c</div> <div class="pl-1">
{{ i / 10 }} div {{ Math.round((stableOrbCost * i) / 10) }} c
</div>
</div> </div>
</template> </template>
</ui-popover> </ui-popover>
@@ -26,33 +55,61 @@
</AppTitleBar> </AppTitleBar>
<div class="grow layout-column min-h-0 bg-gray-800"> <div class="grow layout-column min-h-0 bg-gray-800">
<background-info /> <background-info />
<check-position-circle v-if="showCheckPos" :position="checkPosition" style="z-index: -1;" /> <check-position-circle
v-if="showCheckPos"
:position="checkPosition"
style="z-index: -1"
/>
<template v-if="item?.isErr()"> <template v-if="item?.isErr()">
<ui-error-box class="m-4"> <ui-error-box class="m-4">
<template #name>{{ t(item.error.name) }}</template> <template #name>{{ t(item.error.name) }}</template>
<p>{{ t(item.error.message) }}</p> <p>{{ t(item.error.message) }}</p>
</ui-error-box> </ui-error-box>
<pre class="bg-gray-900 rounded m-4 overflow-x-hidden p-2">{{ item.error.rawText }}</pre> <pre class="bg-gray-900 rounded m-4 overflow-x-hidden p-2">{{
item.error.rawText
}}</pre>
</template> </template>
<template v-else-if="item?.isOk()"> <template v-else-if="item?.isOk()">
<unidentified-resolver :item="item.value" @identify="handleIdentification($event)" /> <unidentified-resolver
<checked-item v-if="isLeagueSelected" :item="item.value" :advanced-check="advancedCheck" /> :item="item.value"
@identify="handleIdentification($event)"
/>
<checked-item
v-if="isLeagueSelected"
:item="item.value"
:advanced-check="advancedCheck"
/>
</template> </template>
<div v-if="isBrowserShown" class="bg-gray-900 px-6 py-2 truncate"> <div v-if="isBrowserShown" class="bg-gray-900 px-6 py-2 truncate">
<i18n-t keypath="app.toggle_browser_hint" tag="div"> <i18n-t keypath="app.toggle_browser_hint" tag="div">
<span class="bg-gray-400 text-gray-900 rounded px-1">{{ overlayKey }}</span> <span class="bg-gray-400 text-gray-900 rounded px-1">{{
overlayKey
}}</span>
</i18n-t> </i18n-t>
</div> </div>
</div> </div>
</div> </div>
<webview v-if="isBrowserShown" ref="iframeEl" class="pointer-events-auto flex-1" width="100%" height="100%" /> <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 v-else class="layout-column flex-1 min-w-0">
<div class="flex" :class="{ <div
class="flex"
:class="{
'flex-row': clickPosition === 'stash', 'flex-row': clickPosition === 'stash',
'flex-row-reverse': clickPosition === 'inventory' 'flex-row-reverse': clickPosition === 'inventory',
}"> }"
<related-items v-if="item?.isOk()" class="pointer-events-auto" :item="item.value" >
:click-position="clickPosition" /> <related-items
v-if="item?.isOk()"
class="pointer-events-auto"
:item="item.value"
:click-position="clickPosition"
/>
<rate-limiter-state class="pointer-events-auto" /> <rate-limiter-state class="pointer-events-auto" />
</div> </div>
</div> </div>
@@ -60,28 +117,41 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, inject, PropType, shallowRef, watch, computed, nextTick, provide } from 'vue' import {
import { Result, ok, err } from 'neverthrow' defineComponent,
import { useI18n } from 'vue-i18n' inject,
import UiErrorBox from '@/web/ui/UiErrorBox.vue' PropType,
import UiPopover from '@/web/ui/Popover.vue' shallowRef,
import CheckedItem from './CheckedItem.vue' watch,
import BackgroundInfo from './BackgroundInfo.vue' computed,
import { MainProcess, Host } from '@/web/background/IPC' nextTick,
import { usePoeninja } from '../background/Prices' provide,
import { useLeagues } from '@/web/background/Leagues' } from 'vue';
import { AppConfig } from '@/web/Config' import { Result, ok, err } from 'neverthrow';
import { ItemCategory, ItemRarity, parseClipboard, ParsedItem } from '@/parser' import { useI18n } from 'vue-i18n';
import RelatedItems from './related-items/RelatedItems.vue' import UiErrorBox from '@/web/ui/UiErrorBox.vue';
import RateLimiterState from './trade/RateLimiterState.vue' import UiPopover from '@/web/ui/Popover.vue';
import UnidentifiedResolver from './unidentified-resolver/UnidentifiedResolver.vue' import CheckedItem from './CheckedItem.vue';
import CheckPositionCircle from './CheckPositionCircle.vue' import BackgroundInfo from './BackgroundInfo.vue';
import AppTitleBar from '@/web/ui/AppTitlebar.vue' import { MainProcess, Host } from '@/web/background/IPC';
import ItemQuickPrice from '@/web/ui/ItemQuickPrice.vue' import { usePoeninja } from '../background/Prices';
import { PriceCheckWidget, WidgetManager } from '../overlay/interfaces' import { useLeagues } from '@/web/background/Leagues';
import ConversionWarningBanner from "../conversion-warn-banner/ConversionWarningBanner.vue"; 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({ export default defineComponent({
components: { components: {
@@ -95,36 +165,44 @@ export default defineComponent({
ItemQuickPrice, ItemQuickPrice,
UiErrorBox, UiErrorBox,
UiPopover, UiPopover,
ConversionWarningBanner ConversionWarningBanner,
}, },
props: { props: {
config: { config: {
type: Object as PropType<PriceCheckWidget>, type: Object as PropType<PriceCheckWidget>,
required: true required: true,
} },
}, },
setup(props) { setup(props) {
const wm = inject<WidgetManager>('wm')! const wm = inject<WidgetManager>('wm')!;
const { xchgRate, initialLoading: xchgRateLoading, queuePricesFetch } = usePoeninja() const {
xchgRate,
initialLoading: xchgRateLoading,
queuePricesFetch,
} = usePoeninja();
nextTick(() => { nextTick(() => {
props.config.wmWants = 'hide' props.config.wmWants = 'hide';
props.config.wmFlags = ['hide-on-blur', 'skip-menu'] props.config.wmFlags = ['hide-on-blur', 'skip-menu'];
}) });
const item = shallowRef<null | Result<ParsedItem, ParseError>>(null) const item = shallowRef<null | Result<ParsedItem, ParseError>>(null);
const advancedCheck = shallowRef(false) const advancedCheck = shallowRef(false);
const checkPosition = shallowRef({ x: 1, y: 1 }) const checkPosition = shallowRef({ x: 1, y: 1 });
MainProcess.onEvent('MAIN->CLIENT::item-text', (e) => { MainProcess.onEvent('MAIN->CLIENT::item-text', (e) => {
if (e.target !== 'price-check') return if (e.target !== 'price-check') return;
if (Host.isElectron && !e.focusOverlay) { if (Host.isElectron && !e.focusOverlay) {
// everything in CSS pixels // everything in CSS pixels
const width = 28.75 * AppConfig().fontSize const width = 28.75 * AppConfig().fontSize;
const screenX = ((e.position.x - window.screenX) > window.innerWidth / 2) const screenX =
? (window.screenX + window.innerWidth) - wm.poePanelWidth.value - width e.position.x - window.screenX > window.innerWidth / 2
: window.screenX + wm.poePanelWidth.value ? window.screenX +
window.innerWidth -
wm.poePanelWidth.value -
width
: window.screenX + wm.poePanelWidth.value;
MainProcess.sendEvent({ MainProcess.sendEvent({
name: 'OVERLAY->MAIN::track-area', name: 'OVERLAY->MAIN::track-area',
payload: { payload: {
@@ -135,106 +213,125 @@ export default defineComponent({
x: screenX, x: screenX,
y: window.screenY, y: window.screenY,
width, width,
height: window.innerHeight height: window.innerHeight,
}, },
dpr: window.devicePixelRatio dpr: window.devicePixelRatio,
},
});
} }
}) closeBrowser();
} wm.show(props.config.wmId);
closeBrowser() checkPosition.value = e.position;
wm.show(props.config.wmId) advancedCheck.value = e.focusOverlay;
checkPosition.value = e.position
advancedCheck.value = e.focusOverlay
item.value = (e.item ? ok(e.item as ParsedItem) : parseClipboard(e.clipboard)) item.value = (
.andThen(item => ( e.item ? ok(e.item as ParsedItem) : parseClipboard(e.clipboard)
(item.category === ItemCategory.HeistContract && item.rarity !== ItemRarity.Unique) || )
(item.category === ItemCategory.Sentinel && item.rarity !== ItemRarity.Unique)) .andThen((item) =>
(item.category === ItemCategory.HeistContract &&
item.rarity !== ItemRarity.Unique) ||
(item.category === ItemCategory.Sentinel &&
item.rarity !== ItemRarity.Unique)
? err('item.unknown') ? err('item.unknown')
: ok(item)) : ok(item)
.mapErr(err => ({ )
.mapErr((err) => ({
name: `${err}`, name: `${err}`,
message: `${err}_help`, message: `${err}_help`,
rawText: e.clipboard rawText: e.clipboard,
})) }));
if (item.value.isOk()) { if (item.value.isOk()) {
queuePricesFetch() queuePricesFetch();
} }
}) });
function handleIdentification(identified: ParsedItem) { function handleIdentification(identified: ParsedItem) {
item.value = ok(identified) item.value = ok(identified);
} }
MainProcess.onEvent('MAIN->OVERLAY::hide-exclusive-widget', () => { MainProcess.onEvent('MAIN->OVERLAY::hide-exclusive-widget', () => {
wm.hide(props.config.wmId) wm.hide(props.config.wmId);
}) });
watch(() => props.config.wmWants, (state) => { watch(
() => props.config.wmWants,
(state) => {
if (state === 'hide') { if (state === 'hide') {
closeBrowser() closeBrowser();
} }
}) }
);
const leagues = useLeagues() const leagues = useLeagues();
const title = computed(() => leagues.selectedId.value || 'Awakened PoE2 Trade2') const title = computed(
const stableOrbCost = computed(() => (xchgRate.value) ? Math.round(xchgRate.value) : null) () => leagues.selectedId.value || 'Exalted PoE2 Trade'
const isBrowserShown = computed(() => props.config.wmFlags.includes('has-browser')) );
const overlayKey = computed(() => AppConfig().overlayKey) const stableOrbCost = computed(() =>
const showCheckPos = computed(() => wm.active.value && props.config.showCursor) xchgRate.value ? Math.round(xchgRate.value) : null
const isLeagueSelected = computed(() => Boolean(leagues.selectedId.value)) );
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(() => { const clickPosition = computed(() => {
if (isBrowserShown.value) { if (isBrowserShown.value) {
return 'inventory' return 'inventory';
} else { } else {
return checkPosition.value.x > (window.screenX + window.innerWidth / 2) return checkPosition.value.x > window.screenX + window.innerWidth / 2
? 'inventory' ? 'inventory'
: 'stash' : 'stash';
// or {chat, vendor, center of screen} // or {chat, vendor, center of screen}
} }
}) });
watch(isBrowserShown, (isShown) => { watch(isBrowserShown, (isShown) => {
if (isShown) { if (isShown) {
wm.setFlag(props.config.wmId, 'hide-on-blur', false) wm.setFlag(props.config.wmId, 'hide-on-blur', false);
wm.setFlag(props.config.wmId, 'invisible-on-blur', true) wm.setFlag(props.config.wmId, 'invisible-on-blur', true);
} else { } else {
wm.setFlag(props.config.wmId, 'invisible-on-blur', false) wm.setFlag(props.config.wmId, 'invisible-on-blur', false);
wm.setFlag(props.config.wmId, 'hide-on-blur', true) wm.setFlag(props.config.wmId, 'hide-on-blur', true);
} }
}) });
function closePriceCheck() { function closePriceCheck() {
if (isBrowserShown.value || !Host.isElectron) { if (isBrowserShown.value || !Host.isElectron) {
wm.hide(props.config.wmId) wm.hide(props.config.wmId);
} else { } else {
Host.sendEvent({ name: 'OVERLAY->MAIN::focus-game', payload: undefined }) Host.sendEvent({
name: 'OVERLAY->MAIN::focus-game',
payload: undefined,
});
} }
} }
function openLeagueSelection() { function openLeagueSelection() {
const settings = wm.widgets.value.find(w => w.wmType === 'settings')! const settings = wm.widgets.value.find((w) => w.wmType === 'settings')!;
wm.setFlag(settings.wmId, `settings:widget:${props.config.wmId}`, true) wm.setFlag(settings.wmId, `settings:widget:${props.config.wmId}`, true);
wm.show(settings.wmId) wm.show(settings.wmId);
} }
const iframeEl = shallowRef<HTMLIFrameElement | null>(null) const iframeEl = shallowRef<HTMLIFrameElement | null>(null);
function showBrowser(url: string) { function showBrowser(url: string) {
wm.setFlag(props.config.wmId, 'has-browser', true) wm.setFlag(props.config.wmId, 'has-browser', true);
nextTick(() => { nextTick(() => {
iframeEl.value!.src = url iframeEl.value!.src = url;
}) });
} }
function closeBrowser() { function closeBrowser() {
wm.setFlag(props.config.wmId, 'has-browser', false) 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 { return {
t, t,
@@ -252,8 +349,8 @@ export default defineComponent({
handleIdentification, handleIdentification,
overlayKey, overlayKey,
isLeagueSelected, isLeagueSelected,
openLeagueSelection openLeagueSelection,
} };
} },
}) });
</script> </script>

View File

@@ -1,93 +1,152 @@
<template> <template>
<div class="p-2 flex flex-col h-full items-center"> <div class="p-2 flex flex-col h-full items-center">
<div class="flex flex-col items-center p-2 mb-4"> <div class="flex flex-col items-center p-2 mb-4">
<img class="w-12 h-12" src="/images/TransferOrb.png"> <img class="w-12 h-12" src="/images/exa.png" />
<p class="text-base">Awakened PoE2 Trade2</p> <p class="text-base">Exalted PoE2 Trade</p>
<p class="">{{ t('app.version', [version]) }}</p> <p class="">{{ t('app.version', [version]) }}</p>
<div class="flex gap-2"> <div class="flex gap-2">
<a class="border-b" href="https://github.com/Kvan7/awakened-poe2-trade2/releases" target="_blank">{{ <a
t('app.release_notes') }}</a> class="border-b"
<a class="border-b" href="https://github.com/Kvan7/awakened-poe2-trade2/issues" target="_blank">{{ href="https://github.com/Kvan7/exalted-poe2-trade/releases"
t('app.report_bug') }}</a> 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> </div>
<div class="border border-gray-600 rounded p-2 whitespace-nowrap min-w-min w-72"> <div
class="border border-gray-600 rounded p-2 whitespace-nowrap min-w-min w-72"
>
<p>{{ info.str1 }}</p> <p>{{ info.str1 }}</p>
<p>{{ info.str2 }}</p> <p>{{ info.str2 }}</p>
<button v-if="info.action" @click="info.action" class="btn w-full mt-1">{{ info.actionText }}</button> <button v-if="info.action" @click="info.action" class="btn w-full mt-1">
{{ info.actionText }}
</button>
</div> </div>
<div class="text-center mt-auto py-8"> <div class="text-center mt-auto py-8">
<p>{{ t('app.contact_me') }} <br><span <p>
class="font-sans text-gray-500 select-all">&lt;@295216259795124225&gt;</span></p> {{ t('app.contact_me') }} <br /><span
class="font-sans text-gray-500 select-all"
>&lt;@295216259795124225&gt;</span
>
</p>
<ul class="flex gap-4"> <ul class="flex gap-4">
<li><img class="rounded inline" src="/images/dc_tft.gif"> <a class="border-b" href="https://discord.gg/tftrove" <li>
target="_blank">The Forbidden Trove</a></li> <img class="rounded inline" src="/images/dc_tft.gif" />
<li><img class="rounded inline" src="/images/dc_reddit.png"> <a class="border-b" <a class="border-b" href="https://discord.gg/tftrove" target="_blank"
href="https://discord.gg/pathofexile" target="_blank">r/pathofexile</a></li> >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> </ul>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, computed } from 'vue' import { defineComponent, computed } from 'vue';
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n';
import { Host } from '@/web/background/IPC' import { Host } from '@/web/background/IPC';
import { DateTime } from 'luxon' import { DateTime } from 'luxon';
function checkForUpdates() { function checkForUpdates() {
Host.sendEvent({ Host.sendEvent({
name: 'CLIENT->MAIN::user-action', name: 'CLIENT->MAIN::user-action',
payload: { action: 'check-for-update' } payload: { action: 'check-for-update' },
}) });
} }
function openDownloadPage() { 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() { function quitAndInstall() {
Host.sendEvent({ Host.sendEvent({
name: 'CLIENT->MAIN::user-action', name: 'CLIENT->MAIN::user-action',
payload: { action: 'update-and-restart' } payload: { action: 'update-and-restart' },
}) });
} }
function fmtTime(millis: number) { 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({ export default defineComponent({
name: 'settings.about', name: 'settings.about',
inheritAttrs: false, inheritAttrs: false,
setup() { setup() {
const { t } = useI18n() const { t } = useI18n();
const info = computed(() => { const info = computed(() => {
const rawInfo = Host.updateInfo.value const rawInfo = Host.updateInfo.value;
switch (rawInfo.state) { switch (rawInfo.state) {
case 'initial': case 'initial':
return { str1: t('updates.maybe_outdated'), str2: t('updates.never_checked'), action: checkForUpdates, actionText: t('updates.check_now') } return {
str1: t('updates.maybe_outdated'),
str2: t('updates.never_checked'),
action: checkForUpdates,
actionText: t('updates.check_now'),
};
case 'checking-for-update': case 'checking-for-update':
return { str1: t('updates.checking'), str2: t('please_wait') } return { str1: t('updates.checking'), str2: t('please_wait') };
case 'update-not-available': case 'update-not-available':
return { str1: t('updates.latest'), str2: t('updates.last_checked', [fmtTime(rawInfo.checkedAt)]), action: checkForUpdates, actionText: t('updates.check_now') } return {
str1: t('updates.latest'),
str2: t('updates.last_checked', [fmtTime(rawInfo.checkedAt)]),
action: checkForUpdates,
actionText: t('updates.check_now'),
};
case 'error': case 'error':
return { str1: t('updates.maybe_outdated'), str2: t('updates.error'), action: openDownloadPage, actionText: t('updates.downloads_page') } return {
str1: t('updates.maybe_outdated'),
str2: t('updates.error'),
action: openDownloadPage,
actionText: t('updates.downloads_page'),
};
case 'update-downloaded': case 'update-downloaded':
return { str1: t('updates.available', [rawInfo.version]), str2: t('updates.installed_on_exit'), action: quitAndInstall, actionText: t('updates.install_now') } return {
str1: t('updates.available', [rawInfo.version]),
str2: t('updates.installed_on_exit'),
action: quitAndInstall,
actionText: t('updates.install_now'),
};
case 'update-available': case 'update-available':
return (rawInfo.noDownloadReason) 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') } 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 { return {
t, t,
info, info,
version: Host.version version: Host.version,
} };
} },
}) });
</script> </script>

File diff suppressed because it is too large Load Diff