Compare commits

...

13 Commits

Author SHA1 Message Date
Kvan7
1245ef96d6 Fixes error and adds basic price check (#37)
* bump for updating branding

* Bugfix/testing-potential-fix (#31)

* removes the problem

* sdfhgdf

* change to no-referrer-when-downgrade

* Start of fixes for price check (#36)

* feat: Adds new trade web api

Adds types for trade api

* fix lint

* push edits

* Add basic items to items.ndjson

* Added images from old items files

* Fix armor values

* WOOO

* bump version
2024-12-13 00:07:53 -06:00
Kvan7
ab93c8b96a Update issue templates 2024-12-12 21:31:36 -06:00
Kvan7
ab7cb30588 Update issue templates 2024-12-12 21:28:23 -06:00
kvan7
f7d686291f Add release steps to DEVELOPING 2024-12-12 07:10:08 -06:00
kvan7
4b8e2ae8cf bump to prove im not (completely) insane 2024-12-12 06:20:22 -06:00
Kvan7
3450f39381 Update README.md 2024-12-11 21:08:34 -06:00
Kvan7
854887056e Finish updating branding (#26)
* remove debugging from proxy

* Removes leftover, fixed title oops

* bump for updating branding
2024-12-11 20:56:00 -06:00
kvan7
292e2de2dd fix lint 2024-12-11 17:23:42 -06:00
kvan7
3cda3a74b8 Add lots more testing code 2024-12-11 17:21:18 -06:00
kvan7
32215e5c03 fix name 2024-12-11 17:21:18 -06:00
kvan7
fd4917ca7f style(Update to 2): Update branding
Renamed to Exalted PoE2 Trade
2024-12-11 17:21:18 -06:00
kvan7
c3d6c69d9d change to node 18 2024-12-11 17:21:18 -06:00
Kvan7
0774814912 Update issue templates 2024-12-11 06:34:12 -06:00
55 changed files with 14064 additions and 17054 deletions

View File

@@ -0,0 +1,21 @@
---
name: An error occurred while parsing the item
about: This is probably a bug and you can report it on GitHub.
title: "[Parse Error] - item name here"
labels: bug, parse error
assignees: ''
---
## Parse Error
***Put name of item here, and in the title***
### Item Text
***Please provide the item's description***
- Can be copied with `ctrl`+`shift`+`c`
- Can also be copied from below the error message
```
Please paste it HERE
```

View File

@@ -0,0 +1,24 @@
---
name: Something Broken in PoE2
about: Use this for things that worked in PoE 1 and do not in PoE 2
title: "[PoE2] - Summary"
labels: bug
assignees: Kvan7
---
**Describe the problem**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem. This is very helpful for comparing the PoE1 vs 2 problems

22
.github/ISSUE_TEMPLATE/unknown-item.md vendored Normal file
View File

@@ -0,0 +1,22 @@
---
name: Unknown Item
about: If this Item was introduced in this League, it will likely be supported in
the next app update.
title: "[Unknown Item] - item name here"
labels: bug, missing item
assignees: ''
---
## Unknown Item
***Put name of item here, and in the title***
### Item Text
***Please provide the item's description***
- Can be copied with `ctrl`+`shift`+`c`
- Can also be copied from below the error message
```
Please paste it HERE
```

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:
[.github/workflows/main.yml](https://github.com/Kvan7/Exiles-Exchange/blob/master/.github/workflows/main.yml)
[.github/workflows/main.yml](https://github.com/Kvan7/exiled-exchange-2/blob/master/.github/workflows/main.yml)
Here's what that looks like as of 2023-12-03.
@@ -41,3 +41,15 @@ npm run build
# install without errors
CSC_NAME="Certificate name in Keychain" yarn package
```
# How to release a build
1. Commit all changes
2. Bump version in `main/package.json`
3. `npm i` in renderer & main (update `package-lock.json` with new version)
4. `npm run build` in renderer & main
5. Stage & commit bumped version
6. `git push`
7. `git tag vX.X.X`
8. `git push origin vX.X.X`
9. Open release page, create release with tag & title as text of tag & save as draft

View File

@@ -1,16 +1,22 @@
# ![Exalted Orb](./renderer/dist/images/exa.png) Exile's Exchange
# ![Exalted Orb](./renderer/public/images/exa.png) Exiled Exchange 2
## Moving from POE1
## Moving from POE1/Awakened PoE Trade
1. Download latest release from [releases](https://github.com/Kvan7/Exiles-Exchange/releases)
1. Download latest release from [releases](https://github.com/Kvan7/exiled-exchange-2/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%\Exiles-Exchange` to copy your previous settings
3. Run Exiled Exchange 2
4. Launch PoE2 to generate correct files
5. Copy `apt-data` from `%APPDATA%\awakened-poe-trade` to `%APPDATA%\exiled-exchange-2` to copy your previous settings
- Resulting directory structure should look like this:
- `%APPDATA%\Exiles-Exchange\apt-data\`
- `%APPDATA%\exiled-exchange-2\apt-data\`
- `config.json`
4. Run Exiles Exchange
6. Restart Exiled Exchange 2
#### Updating from 0.0.1 -> 0.0.10
Follow same steps as tranfering from PoE1, instead of copying from `%APPDATA%\awakened-poe-trade` to `%APPDATA%\exiled-exchange-2` instead copy from `%APPDATA%\awakened-poe2-trade` or `%APPDATA%\awakened-poe2-trade2` to `%APPDATA%\exiled-exchange-2`. After copying files feel free to run the uninstaller for `awakened-poe2-trade` to remove old executables, or delete `%APPDATA%\awakened-poe2-trade` and `Local\Programs\awakened-poe2-trade`
## Tool showcase

View File

@@ -1,9 +1,9 @@
import { defineConfig } from 'vitepress'
const BASE = '/Exiles-Exchange/'
const BASE = '/exiled-exchange-2/'
export default defineConfig({
title: 'Exiles Exchange',
title: 'Exiled Exchange 2',
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/Exiles-Exchange/releases'
releasesUrl: 'https://github.com/Kvan7/exiled-exchange-2/releases'
},
socialLinks: [
{
@@ -33,7 +33,7 @@ export default defineConfig({
{
text: 'GitHub',
color: '#181717',
link: 'https://github.com/Kvan7/Exiles-Exchange'
link: 'https://github.com/Kvan7/exiled-exchange-2'
}
],
sidebar: [

View File

@@ -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}/Exiles-Exchange-Setup-${theme.appVersion}.exe`">Windows 10+ (installer)</a> | ✔ | Fast |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exiles-Exchange-${theme.appVersion}.exe`">Windows 10+ (portable)</a> | ❌ | Slower |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exiles-Exchange-${theme.appVersion}.AppImage`">Linux (AppImage)</a> | ✔ | n/a |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/Exiles-Exchange-${theme.appVersion}-universal.dmg`">macOS (dmg)</a> | ❌ | n/a |
| Download link | Automatic updates | Startup time |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------ |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-Setup-${theme.appVersion}.exe`">Windows 10+ (installer)</a> | ✔ | Fast |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${theme.appVersion}.exe`">Windows 10+ (portable)</a> | ❌ | Slower |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${theme.appVersion}.AppImage`">Linux (AppImage)</a> | ✔ | n/a |
| <a :href="`${theme.github.releasesUrl}/download/v${theme.appVersion}/exiled-exchange-2-${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 Exiles Exchange to have access to the PoE window, it must be started with Administrator rights.**
In order for Exiled Exchange 2 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.**

View File

@@ -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%\Exiles-Exchange`
4. Delete `%appdata%\exiled-exchange-2`
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 Exiles Exchange.
6. Restart Exiled Exchange 2.
*(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;"}
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 Exiles Exchange and show to you in a fancy way.
All that remains is to parse text in Exiled Exchange 2 and show to you in a fancy way.
### Usage

View File

@@ -25,8 +25,18 @@
"dist/": true
},
"editor.tabSize": 2,
"editor.insertSpaces": true,
"conventionalCommits.scopes": [
"Update to 2"
],
"cSpell.words": [
"edps",
"ilvl",
"nonunique",
"onlineleague",
"pdps",
"uniquefoil",
"WAYSTONE"
]
}
}

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:
- "github"
productName: "Exiles Exchange"
productName: "Exiled Exchange 2"
npmRebuild: false
files:
- "package.json"

11305
main/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,39 +1,38 @@
{
"name": "Exiles-Exchange",
"version": "0.0.5",
"private": true,
"scripts": {
"dev": "node build/script.mjs",
"build": "tsc --noEmit && node build/script.mjs --prod",
"package": "electron-builder build"
},
"author": {
"name": "Alexander Drozdov"
},
"repository": {
"type": "git",
"url": "https://github.com/Kvan7/Exiles-Exchange.git"
},
"main": "dist/main.js",
"dependencies": {
"electron-overlay-window": "3.3.0",
"uiohook-napi": "1.5.x"
},
"devDependencies": {
"@types/ini": "^4.1.0",
"@types/node": "20.x.x",
"@types/ws": "^8.5.3",
"@wokwi/bmp-ts": "^3.0.0",
"comlink": "^4.3.1",
"electron": "33.2.1",
"electron-builder": "25.1.8",
"electron-updater": "^6.3.0",
"esbuild": "^0.24.0",
"ini": "^5.0.0",
"typescript": "5.6.x",
"ws": "^8.16.0"
},
"engines": {
"node": ">=16"
}
"name": "exiled-exchange-2",
"version": "0.0.12",
"private": true,
"scripts": {
"dev": "node build/script.mjs",
"build": "tsc --noEmit && node build/script.mjs --prod",
"package": "electron-builder build",
"lint": "eslint src",
"fix": "eslint src --fix"
},
"author": {
"name": "Garrett Parker"
},
"repository": {
"type": "git",
"url": "https://github.com/Kvan7/exiled-exchange-2.git"
},
"main": "dist/main.js",
"dependencies": {
"electron-overlay-window": "3.3.0",
"uiohook-napi": "1.5.x"
},
"devDependencies": {
"@types/ini": "^4.1.0",
"@types/node": "20.x.x",
"@types/ws": "^8.5.3",
"@wokwi/bmp-ts": "^3.0.0",
"comlink": "^4.3.1",
"electron": "33.2.1",
"electron-builder": "25.1.8",
"electron-updater": "^6.3.0",
"esbuild": "^0.24.0",
"ini": "^5.0.0",
"typescript": "5.6.x",
"ws": "^8.16.0"
}
}

View File

@@ -23,7 +23,7 @@ export class AppTray {
}
this.tray = new Tray(trayImage);
this.tray.setToolTip(`Exiles Exchange v${app.getVersion()}`);
this.tray.setToolTip(`Exiled Exchange 2 v${app.getVersion()}`);
this.rebuildMenu();
server.onEventAnyClient("CLIENT->MAIN::user-action", ({ action }) => {

View File

@@ -18,18 +18,10 @@ export class HttpProxy {
) {
server.addListener('request', (req, res) => {
if (!req.url?.startsWith('/proxy/')) return
const host = req.url.split('/', 3)[2]
logger.write(`Incoming request to proxy: ${req.url}`); // Log incoming request
const official = PROXY_HOSTS.find(entry => entry.host === host)?.official
if (official === undefined) {
logger.write(`Host not officially supported: ${host}`);
return req.destroy() // Log rejection on unsupported host
}
// Log headers before modifying them
logger.write(`Incoming request headers: ${JSON.stringify(req.headers)}`);
if (official === undefined) return req.destroy()
for (const key in req.headers) {
if (key.startsWith('sec-') || key === 'host' || key === 'origin' || key === 'content-length') {
@@ -37,35 +29,28 @@ export class HttpProxy {
}
}
const url = req.url.slice('/proxy/'.length);
const proxyReq = net.request({
url: 'https://' + url,
url: 'https://' + req.url.slice('/proxy/'.length),
method: req.method,
headers: {
...req.headers,
'user-agent': app.userAgentFallback
},
useSessionCookies: true
useSessionCookies: true,
referrerPolicy: 'no-referrer-when-downgrade'
})
proxyReq.addListener('response', (proxyRes) => {
const resHeaders = { ...proxyRes.headers }
// Log response status and headers
logger.write(`Proxy response status: ${proxyRes.statusCode}, status message: ${proxyRes.statusMessage}`);
logger.write(`Proxy response headers: ${JSON.stringify(resHeaders)}`);
delete resHeaders['content-encoding']
res.writeHead(proxyRes.statusCode, proxyRes.statusMessage, resHeaders)
;(proxyRes as unknown as NodeJS.ReadableStream).pipe(res)
})
proxyReq.addListener('error', (err) => {
logger.write(`Error during proxy request: ${err.message} (${host}); is this a network error?`);
res.writeHead(502, 'Bad Gateway');
res.end(`Proxy error: ${err.message}`);
logger.write(`error [cors-proxy] ${err.message} (${host})`)
res.destroy(err)
})
req.pipe(proxyReq as unknown as NodeJS.WritableStream);
req.pipe(proxyReq as unknown as NodeJS.WritableStream)
})
}
}

View File

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

View File

@@ -7,7 +7,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>Exiles Exchange</title>
<title>Exiled Exchange 2</title>
</head>
<body>

12786
renderer/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,63 +1,63 @@
{
"name": "Exiles-Exchange",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"lint": "eslint --ext .ts,.vue src",
"lint-fix": "eslint --ext .ts,.vue src --fix",
"build": "vue-tsc --noEmit && vite build",
"make-index-files": "node src/assets/make-index-files.mjs"
},
"dependencies": {
"@fortawesome/fontawesome-free": "6.x.x",
"@sindresorhus/fnv1a": "^3.0.0",
"@vueuse/core": "^11.0.0",
"animate.css": "^4.1.1",
"apexcharts": "^4.0.0",
"dot-prop": "9.x.x",
"fast-deep-equal": "^3.1.3",
"fastest-levenshtein": "^1.0.16",
"luxon": "3.x.x",
"neverthrow": "^8.0.0",
"object-hash": "^3.0.0",
"sockette": "^2.0.6",
"tailwindcss": "3.x.x",
"tippy.js": "^6.2.7",
"vue": "3.2.37",
"vue-i18n": "^10.0.0",
"vue3-apexcharts": "^1.1.1",
"vuedraggable": "4.1.0"
},
"devDependencies": {
"@types/luxon": "^3.0.0",
"@types/node": "^20.0.0",
"@types/object-hash": "^3.0.0",
"@vitejs/plugin-vue": "^4.0.0",
"autoprefixer": "^10.0.2",
"postcss": "^8.2.14",
"typescript": "5.6.x",
"vite": "^5.0.0",
"vue-tsc": "^2.0.0"
},
"optionalDependencies": {
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.21.0",
"eslint-config-standard-with-typescript": "^31.0.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-n": "^15.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-vue": "^9.1.1"
},
"postcss": {
"plugins": {
"tailwindcss/nesting": {},
"tailwindcss": {},
"autoprefixer": {}
}
},
"browserslist": [
"chrome >= 101"
]
"name": "exiled-exchange-2",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"lint": "eslint --ext .ts,.vue src",
"lint-fix": "eslint --ext .ts,.vue src --fix",
"build": "vue-tsc --noEmit && vite build",
"make-index-files": "node src/assets/make-index-files.mjs"
},
"dependencies": {
"@fortawesome/fontawesome-free": "6.x.x",
"@sindresorhus/fnv1a": "^3.0.0",
"@vueuse/core": "^11.0.0",
"animate.css": "^4.1.1",
"apexcharts": "^4.0.0",
"dot-prop": "9.x.x",
"fast-deep-equal": "^3.1.3",
"fastest-levenshtein": "^1.0.16",
"luxon": "3.x.x",
"neverthrow": "^8.0.0",
"object-hash": "^3.0.0",
"sockette": "^2.0.6",
"tailwindcss": "3.x.x",
"tippy.js": "^6.2.7",
"vue": "3.2.37",
"vue-i18n": "^10.0.0",
"vue3-apexcharts": "^1.1.1",
"vuedraggable": "4.1.0"
},
"devDependencies": {
"@types/luxon": "^3.0.0",
"@types/node": "^20.0.0",
"@types/object-hash": "^3.0.0",
"@vitejs/plugin-vue": "^4.0.0",
"autoprefixer": "^10.0.2",
"postcss": "^8.2.14",
"typescript": "5.6.x",
"vite": "^5.0.0",
"vue-tsc": "^2.0.0"
},
"optionalDependencies": {
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.21.0",
"eslint-config-standard-with-typescript": "^31.0.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-n": "^15.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-vue": "^9.1.1"
},
"postcss": {
"plugins": {
"tailwindcss/nesting": {},
"tailwindcss": {},
"autoprefixer": {}
}
},
"browserslist": [
"chrome >= 101"
]
}

View File

@@ -50,6 +50,7 @@
"elemental_dps": "Elemental DPS: {0}",
"crit": "Critical Strike Chance: {0}%",
"aps": "Attacks per Second: {0}",
"spirit": "Spirit: {0}",
"has_empty_modifier": "1 Empty or Crafted Modifier",
"has_empty_affix": "Any",
"has_empty_prefix": "Prefix",
@@ -63,6 +64,8 @@
"white_sockets": "White: {0}",
"quality": "Quality: {0}",
"gem_level": "Level: {0}",
"gem_sockets": "Sockets: {0}",
"rune_sockets": "Sockets: {0}",
"sentinel_charge": "Charge: {0}",
"find_in_stash": "Find in Stash",
"parse_error": "An error occurred while parsing the item",
@@ -269,7 +272,7 @@
"stack": "Stack"
},
"settings": {
"title": "Settings - Exiles Exchange",
"title": "Settings - Exiled Exchange 2",
"language": "Language",
"private_league": "or Private League",
"account_name": "Account name",

File diff suppressed because it is too large Load Diff

View File

@@ -266,7 +266,7 @@
"stack": "스택"
},
"settings": {
"title": "세팅 - Exiles Exchange",
"title": "세팅 - Exiled Exchange 2",
"language": "언어",
"private_league": "개인리그",
"account_name": "계정명",

View File

@@ -282,7 +282,7 @@
"stack": "Стак"
},
"settings": {
"title": "Настройки - Exiles Exchange",
"title": "Настройки - Exiled Exchange 2",
"language": "Язык",
"private_league": "или Приватная лига",
"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.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -48,6 +48,9 @@ export enum ItemCategory {
Tincture = 'Tincture',
Charm = 'Charm',
Crossbow = 'Crossbow',
SkillGem = 'Skill Gem',
SupportGem = 'Support Gem',
MetaGem = 'Meta Gem',
}
export const WEAPON_ONE_HANDED_MELEE = new Set([
@@ -76,6 +79,7 @@ export const WEAPONE_TWO_HANDED_MELEE = new Set([
export const WEAPON = new Set([
ItemCategory.FishingRod,
ItemCategory.Bow,
ItemCategory.Crossbow,
...WEAPON_ONE_HANDED,
...WEAPONE_TWO_HANDED_MELEE
])

View File

@@ -76,9 +76,9 @@ export async function initConfig () {
// TODO
// dialog.showErrorBox(
// 'Exiles Exchange - Incompatible configuration',
// 'Exiled Exchange 2 - Incompatible configuration',
// // ----------------------
// 'You are trying to use an older version of Exiles Exchange with a newer incompatible configuration file.\n' +
// 'You are trying to use an older version of Exiled Exchange 2 with a newer incompatible configuration file.\n' +
// 'You need to install the latest version to continue using it.'
// )
}

View File

@@ -8,7 +8,7 @@
:class="$style.starredItem"
@click="starredItemClick($event, item)">
<ItemQuickPrice
:item-img="item.info.icon"
:item-img="item.info.icon === '%NOT_FOUND%' || item.info.icon === '' ? '/images/404.png' : item.info.icon"
:price="item.price"
currency-text
></ItemQuickPrice>

View File

@@ -4,7 +4,7 @@
<div :class="$style.widget" v-if="show">
<div :class="$style.box">
<div class="py-2 px-4">
<div class="text-base">Exiles Exchange</div>
<div class="text-base">Exiled Exchange 2</div>
<p>{{ t('app_is_ready') }}</p>
</div>
</div>
@@ -25,7 +25,9 @@ const show = shallowRef(false)
Host.onEvent('MAIN->OVERLAY::overlay-attached', () => {
if (!show.value && AppConfig().showAttachNotification) {
show.value = true
setTimeout(() => { show.value = false }, 2500)
setTimeout(() => {
show.value = false
}, 2500)
}
})
</script>
@@ -51,7 +53,7 @@ Host.onEvent('MAIN->OVERLAY::overlay-attached', () => {
.box::before {
position: absolute;
content: '';
background: url('/images/TransferOrb.png') no-repeat top right/contain;
background: url('/images/exa.png') no-repeat top right/contain;
right: 100%;
width: 100%;
height: 100%;

View File

@@ -4,9 +4,9 @@
<price-prediction v-if="showPredictedPrice" class="mb-4" :item="item" />
<price-trend v-else :item="item" :filters="itemFilters" />
<filters-block ref="filtersComponent" :filters="itemFilters" :stats="itemStats" :item="item" :presets="presets"
@preset="selectPreset" @submit="doSearch = true" />
@preset="selectPreset" @submit="doSearch = true" />
<trade-listing v-if="tradeAPI === 'trade' && doSearch" ref="tradeService" :filters="itemFilters" :stats="itemStats"
:item="item" />
:item="item" />
<trade-bulk v-if="tradeAPI === 'bulk' && doSearch" ref="tradeService" :filters="itemFilters" :item="item" />
<div v-if="!doSearch" class="flex justify-between items-center">
<div class="flex w-40" @mouseenter="handleSearchMouseenter">

View File

@@ -1,23 +1,52 @@
<template>
<div style="top: 0; left: 0; height: 100%; width: 100%; position: absolute;"
class="flex grow h-full pointer-events-none" :class="{
<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;">
}"
>
<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">
<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>
<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" />
<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 class="pl-1">
{{ i / 10 }} div {{ Math.round((stableOrbCost * i) / 10) }} c
</div>
</div>
</template>
</ui-popover>
@@ -26,33 +55,61 @@
</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;" />
<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>
<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" />
<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>
<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%" />
<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" />
<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>
@@ -81,7 +138,11 @@ 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: {
@@ -122,9 +183,13 @@ export default defineComponent({
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
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: {
@@ -146,13 +211,18 @@ export default defineComponent({
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 => ({
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
@@ -171,14 +241,17 @@ export default defineComponent({
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 || 'Exiles Exchange')
const title = computed(() => leagues.selectedId.value || 'Exiled Exchange 2')
const stableOrbCost = computed(() => (xchgRate.value) ? Math.round(xchgRate.value) : null)
const isBrowserShown = computed(() => props.config.wmFlags.includes('has-browser'))
const overlayKey = computed(() => AppConfig().overlayKey)

View File

@@ -5,7 +5,7 @@
>
<template #item>
<div class="flex">
<img v-for="icon in result.icons" class="w-8 h-8" :src="icon">
<img v-for="icon in result.icons" class="w-8 h-8" :src="icon === '%NOT_FOUND%' || icon === '' ? '/images/404.png' : icon">
</div>
</template>
</item-quick-price>

View File

@@ -48,6 +48,19 @@
: t('filters.selected_none')"
/>
</div>
<!-- Warning that many stats may not work -->
<div v-if="!statsVisibility.disabled && hasStats" class="mb-4 text-center bg-teal-800 rounded-xl" :class="(presets.length > 1) ? 'mt-1' : 'mt-4'" >
Not all stats may load (WIP)
</div>
<!-- Handled parse error -->
<div v-if="!hasStats && item.rarity !== undefined && item.rarity !== 'Normal'" class="mb-4 text-center bg-purple-800 rounded-xl" :class="(presets.length > 1) ? 'mt-1' : 'mt-4'" >
For some reason this item's stats did not parse. <br/> It likely has a mod that is not supported yet. <br/>(Potentially new or changed wording from poe1)
</div>
<!-- Warning that bulk exchange does not work -->
<div v-if="!hasStats && item.category === 'Currency'" class="mb-4 text-center bg-teal-900 rounded-xl" :class="(presets.length > 1) ? 'mt-1' : 'mt-4'" >
Bulk exchange rates are not implemented yet
</div>
<div v-if="!statsVisibility.disabled && hasStats" class="mb-4" :class="(presets.length > 1) ? 'mt-1' : 'mt-4'">
<div class="flex" v-if="presets.length > 1">
<div class="w-5 border-b border-gray-700" />
@@ -134,6 +147,8 @@ export default defineComponent({
statsVisibility.disabled = false
})
console.log(props.item)
const showUnknownMods = computed(() =>
props.item.unknownModifiers.length &&
props.item.category !== ItemCategory.Sentinel &&

View File

@@ -116,7 +116,8 @@ export const INTERNAL_TRADE_IDS = [
'item.elemental_dps',
'item.crit',
'item.aps',
'item.has_empty_modifier'
'item.has_empty_modifier',
'item.spirit'
] as const
export type InternalTradeId = typeof INTERNAL_TRADE_IDS[number]

View File

@@ -13,7 +13,7 @@
<div class="flex items-center pb-4">
<item-quick-price class="flex-1 text-base justify-center"
:price="price"
:item-img="item.info.icon"
:item-img="item.info.icon === '%NOT_FOUND%' || item.info.icon === '' ? '/images/404.png' : item.info.icon"
:item-base="item.info"
approx
/>

View File

@@ -8,7 +8,7 @@
:class="{ 'bg-gray-700': item.highlight }" class="rounded px-1">
<item-quick-price currency-text fraction class="text-base"
:price="item.price"
:item-img="item.icon" />
:item-img="item.icon === '%NOT_FOUND%' || item.icon === '' ? '/images/404.png' : item.icon" />
<div class="text-left text-gray-600 mb-1 whitespace-nowrap overflow-hidden">{{ item.name }}</div>
</div>
</div>
@@ -16,7 +16,7 @@
<div v-for="item in result.items" :key="item.name">
<item-quick-price currency-text fraction class="text-base"
:price="item.price"
:item-img="item.icon" />
:item-img="item.icon === '%NOT_FOUND%' || item.icon === '' ? '/images/404.png' : item.icon" />
<div class="text-left text-gray-600 mb-1 whitespace-nowrap overflow-hidden">{{ item.name }}</div>
</div>
</div>

View File

@@ -22,6 +22,7 @@ export type TradeResponse<T> = (T & { error?: null }) | {
}
export function apiToSatisfySearch (item: ParsedItem, stats: StatFilter[], filters: ItemFilters): 'trade' | 'bulk' {
console.log('item', item, 'filter', filters, 'stats', stats)
if (stats.some(s => !s.disabled)) {
return 'trade'
}

View File

@@ -1,4 +1,4 @@
import { ItemInfluence, ItemCategory, ParsedItem, ItemRarity } from '@/parser'
import { ItemCategory, ParsedItem, ItemRarity } from '@/parser'
import {
ItemFilters,
StatFilter,
@@ -60,7 +60,11 @@ export const CATEGORY_TO_TRADE_ID = new Map([
[ItemCategory.Trinket, 'accessory.trinket'],
[ItemCategory.SanctumRelic, 'sanctum.relic'],
[ItemCategory.Tincture, 'tincture'],
[ItemCategory.Charm, 'azmeri.charm']
[ItemCategory.Charm, 'azmeri.charm'],
[ItemCategory.Crossbow, 'weapon.crossbow'],
[ItemCategory.SkillGem, 'gem.activegem'],
[ItemCategory.SupportGem, 'gem.supportgem'],
[ItemCategory.MetaGem, 'gem.metagem']
])
const TOTAL_MODS_TEXT = {
@@ -77,14 +81,14 @@ const TOTAL_MODS_TEXT = {
TOTAL_MODIFIERS: ['# Modifiers', '# Prefix Modifiers', '# Suffix Modifiers']
}
const INFLUENCE_PSEUDO_TEXT = {
[ItemInfluence.Shaper]: 'Has Shaper Influence',
[ItemInfluence.Crusader]: 'Has Crusader Influence',
[ItemInfluence.Hunter]: 'Has Hunter Influence',
[ItemInfluence.Elder]: 'Has Elder Influence',
[ItemInfluence.Redeemer]: 'Has Redeemer Influence',
[ItemInfluence.Warlord]: 'Has Warlord Influence'
}
// const INFLUENCE_PSEUDO_TEXT = {
// [ItemInfluence.Shaper]: 'Has Shaper Influence',
// [ItemInfluence.Crusader]: 'Has Crusader Influence',
// [ItemInfluence.Hunter]: 'Has Hunter Influence',
// [ItemInfluence.Elder]: 'Has Elder Influence',
// [ItemInfluence.Redeemer]: 'Has Redeemer Influence',
// [ItemInfluence.Warlord]: 'Has Warlord Influence'
// }
interface FilterBoolean {
option?: 'true' | 'false'
@@ -123,72 +127,64 @@ interface TradeRequest {
category?: {
option?: string
}
ilvl?: FilterRange
quality?: FilterRange
}
}
socket_filters?: {
equipment_filters?: {
filters: {
links?: FilterRange
sockets?: {
w?: number
}
// Attacks per Second
aps?: FilterRange
// Armor Rating
ar?: FilterRange
// Block
block?: FilterRange
// Critical Strike Chance
crit?: FilterRange
// Damage (not used)
// damage?: FilterRange
// Damage per Second
dps?: FilterRange
// Elemental Damage per Second
edps?: FilterRange
// Energy Shield
es?: FilterRange
// Evasion Rating
ev?: FilterRange
// Physical Damage per Second
pdps?: FilterRange
// Rune Slots
rune_sockets?: FilterRange
// Spirit
spirit?: FilterRange
}
}
req_filters?: {
filters: {
dex?: FilterRange
int?: FilterRange
lvl?: FilterRange
str?: FilterRange
}
}
// WILL PROBABLY BE REMOVED SOON
map_filters?: {
filters: {
map_bonus?: FilterRange
map_tier?: FilterRange
}
}
misc_filters?: {
filters: {
ilvl?: FilterRange
quality?: FilterRange
gem_level?: FilterRange
corrupted?: FilterBoolean
fractured_item?: FilterBoolean
mirrored?: FilterBoolean
identified?: FilterBoolean
stack_size?: FilterRange
}
}
armour_filters?: {
filters: {
ar?: FilterRange
es?: FilterRange
ev?: FilterRange
ward?: FilterRange
block?: FilterRange
base_defence_percentile?: FilterRange
}
}
weapon_filters?: {
filters: {
dps?: FilterRange
pdps?: FilterRange
edps?: FilterRange
crit?: FilterRange
aps?: FilterRange
}
}
map_filters?: {
filters: {
map_tier?: FilterRange
map_blighted?: FilterBoolean
map_uberblighted?: FilterBoolean
alternate_art?: FilterBoolean
area_level?: FilterRange
}
}
heist_filters?: {
filters: {
heist_wings?: FilterRange
heist_agility?: FilterRange
heist_brute_force?: FilterRange
heist_counter_thaumaturgy?: FilterRange
heist_deception?: FilterRange
heist_demolition?: FilterRange
heist_engineering?: FilterRange
heist_lockpicking?: FilterRange
heist_perception?: FilterRange
heist_trap_disarmament?: FilterRange
}
}
sentinel_filters?: {
filters: {
sentinel_durability?: FilterRange
corrupted?: FilterBoolean
gem_level?: FilterRange
gem_sockets?: FilterRange
identified?: FilterBoolean
mirrored?: FilterBoolean
sanctum_gold?: FilterRange
unidentified_tier?: FilterRange
}
}
trade_filters?: {
@@ -320,6 +316,16 @@ export function createTradeRequest (
query.type = nameToQuery(activeSearch.baseType, filters)
}
// TYPE FILTERS
if (activeSearch.category) {
const id = CATEGORY_TO_TRADE_ID.get(activeSearch.category)
if (id) {
propSet(query.filters, 'type_filters.filters.category.option', id)
} else {
throw new Error(`Invalid category: ${activeSearch.category}`)
}
}
if (filters.foil && !filters.foil.disabled) {
propSet(query.filters, 'type_filters.filters.rarity.option', 'uniquefoil')
} else if (filters.rarity) {
@@ -330,15 +336,65 @@ export function createTradeRequest (
)
}
if (activeSearch.category) {
const id = CATEGORY_TO_TRADE_ID.get(activeSearch.category)
if (id) {
propSet(query.filters, 'type_filters.filters.category.option', id)
} else {
throw new Error(`Invalid category: ${activeSearch.category}`)
if (filters.itemLevel && !filters.itemLevel.disabled) {
propSet(
query.filters,
'type_filters.filters.ilvl.min',
filters.itemLevel.value
)
if (filters.itemLevel.max) {
propSet(
query.filters,
'type_filters.filters.ilvl.max',
filters.itemLevel.max
)
}
}
if (filters.quality && !filters.quality.disabled) {
propSet(
query.filters,
'type_filters.filters.quality.min',
filters.quality.value
)
}
// EQUIPMENT FILTERS
// REQ FILTERS
// MAP (WAYSTONE) FILTERS
if (filters.mapTier && !filters.mapTier.disabled) {
propSet(
query.filters,
'map_filters.filters.map_tier.min',
filters.mapTier.value
)
propSet(
query.filters,
'map_filters.filters.map_tier.max',
filters.mapTier.value
)
}
// MISC FILTERS
if (filters.gemLevel && !filters.gemLevel.disabled) {
propSet(
query.filters,
'misc_filters.filters.gem_level.min',
filters.gemLevel.value
)
}
if (filters.unidentified && !filters.unidentified.disabled) {
propSet(
query.filters,
'misc_filters.filters.identified.option',
String(false)
)
}
if (filters.corrupted?.value === false || filters.corrupted?.exact) {
propSet(
query.filters,
@@ -346,13 +402,7 @@ export function createTradeRequest (
String(filters.corrupted.value)
)
}
if (filters.fractured?.value === false) {
propSet(
query.filters,
'misc_filters.filters.fractured_item.option',
String(false)
)
}
if (filters.mirrored) {
if (filters.mirrored.disabled) {
propSet(
@@ -373,121 +423,9 @@ export function createTradeRequest (
)
}
if (filters.gemLevel && !filters.gemLevel.disabled) {
propSet(
query.filters,
'misc_filters.filters.gem_level.min',
filters.gemLevel.value
)
}
// TRADE FILTERS
if (filters.quality && !filters.quality.disabled) {
propSet(
query.filters,
'misc_filters.filters.quality.min',
filters.quality.value
)
}
if (filters.itemLevel && !filters.itemLevel.disabled) {
propSet(
query.filters,
'misc_filters.filters.ilvl.min',
filters.itemLevel.value
)
if (filters.itemLevel.max) {
propSet(
query.filters,
'misc_filters.filters.ilvl.max',
filters.itemLevel.max
)
}
}
if (filters.stackSize && !filters.stackSize.disabled) {
propSet(
query.filters,
'misc_filters.filters.stack_size.min',
filters.stackSize.value
)
}
if (filters.linkedSockets && !filters.linkedSockets.disabled) {
propSet(
query.filters,
'socket_filters.filters.links.min',
filters.linkedSockets.value
)
}
if (filters.whiteSockets && !filters.whiteSockets.disabled) {
propSet(
query.filters,
'socket_filters.filters.sockets.w',
filters.whiteSockets.value
)
}
if (filters.mapTier && !filters.mapTier.disabled) {
propSet(
query.filters,
'map_filters.filters.map_tier.min',
filters.mapTier.value
)
propSet(
query.filters,
'map_filters.filters.map_tier.max',
filters.mapTier.value
)
}
if (filters.mapBlighted) {
if (filters.mapBlighted.value === 'Blighted') {
propSet(
query.filters,
'map_filters.filters.map_blighted.option',
String(true)
)
} else if (filters.mapBlighted.value === 'Blight-ravaged') {
propSet(
query.filters,
'map_filters.filters.map_uberblighted.option',
String(true)
)
}
}
if (filters.unidentified && !filters.unidentified.disabled) {
propSet(
query.filters,
'misc_filters.filters.identified.option',
String(false)
)
}
if (filters.areaLevel && !filters.areaLevel.disabled) {
propSet(
query.filters,
'map_filters.filters.area_level.min',
filters.areaLevel.value
)
}
if (filters.heistWingsRevealed && !filters.heistWingsRevealed.disabled) {
propSet(
query.filters,
'heist_filters.filters.heist_wings.min',
filters.heistWingsRevealed.value
)
}
if (filters.sentinelCharge && !filters.sentinelCharge.disabled) {
propSet(
query.filters,
'sentinel_filters.filters.sentinel_durability.min',
filters.sentinelCharge.value
)
}
// BREAK ==============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
for (const stat of stats) {
if (stat.tradeId[0] === 'item.has_empty_modifier') {
@@ -557,135 +495,135 @@ export function createTradeRequest (
const input = stat.roll!
switch (stat.tradeId[0] as InternalTradeId) {
case 'item.base_percentile':
propSet(
query.filters,
'armour_filters.filters.base_defence_percentile.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'armour_filters.filters.base_defence_percentile.max',
typeof input.max === 'number' ? input.max : undefined
)
break
// case 'item.base_percentile':
// propSet(
// query.filters,
// 'equipment_filters.filters.base_defence_percentile.min',
// typeof input.min === 'number' ? input.min : undefined
// )
// propSet(
// query.filters,
// 'equipment_filters.filters.base_defence_percentile.max',
// typeof input.max === 'number' ? input.max : undefined
// )
// break
case 'item.armour':
propSet(
query.filters,
'armour_filters.filters.ar.min',
'equipment_filters.filters.ar.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'armour_filters.filters.ar.max',
'equipment_filters.filters.ar.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.evasion_rating':
propSet(
query.filters,
'armour_filters.filters.ev.min',
'equipment_filters.filters.ev.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'armour_filters.filters.ev.max',
'equipment_filters.filters.ev.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.energy_shield':
propSet(
query.filters,
'armour_filters.filters.es.min',
'equipment_filters.filters.es.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'armour_filters.filters.es.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.ward':
propSet(
query.filters,
'armour_filters.filters.ward.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'armour_filters.filters.ward.max',
'equipment_filters.filters.es.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.block':
propSet(
query.filters,
'armour_filters.filters.block.min',
'equipment_filters.filters.block.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'armour_filters.filters.block.max',
'equipment_filters.filters.block.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.total_dps':
propSet(
query.filters,
'weapon_filters.filters.dps.min',
'equipment_filters.filters.dps.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'weapon_filters.filters.dps.max',
'equipment_filters.filters.dps.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.physical_dps':
propSet(
query.filters,
'weapon_filters.filters.pdps.min',
'equipment_filters.filters.pdps.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'weapon_filters.filters.pdps.max',
'equipment_filters.filters.pdps.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.elemental_dps':
propSet(
query.filters,
'weapon_filters.filters.edps.min',
'equipment_filters.filters.edps.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'weapon_filters.filters.edps.max',
'equipment_filters.filters.edps.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.crit':
propSet(
query.filters,
'weapon_filters.filters.crit.min',
'equipment_filters.filters.crit.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'weapon_filters.filters.crit.max',
'equipment_filters.filters.crit.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.aps':
propSet(
query.filters,
'weapon_filters.filters.aps.min',
'equipment_filters.filters.aps.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'weapon_filters.filters.aps.max',
'equipment_filters.filters.aps.max',
typeof input.max === 'number' ? input.max : undefined
)
break
case 'item.spirit':
propSet(
query.filters,
'equipment_filters.filters.spirit.min',
typeof input.min === 'number' ? input.min : undefined
)
propSet(
query.filters,
'equipment_filters.filters.spirit.max',
typeof input.max === 'number' ? input.max : undefined
)
break
@@ -695,33 +633,33 @@ export function createTradeRequest (
stats = stats.filter(
(stat) => !INTERNAL_TRADE_IDS.includes(stat.tradeId[0] as any)
)
if (filters.veiled) {
for (const statRef of filters.veiled.statRefs) {
stats.push({
disabled: filters.veiled.disabled,
statRef: undefined!,
text: undefined!,
tag: undefined!,
sources: undefined!,
tradeId: STAT_BY_REF(statRef)!.trade.ids[ModifierType.Veiled]
})
}
}
// if (filters.veiled) {
// for (const statRef of filters.veiled.statRefs) {
// stats.push({
// disabled: filters.veiled.disabled,
// statRef: undefined!,
// text: undefined!,
// tag: undefined!,
// sources: undefined!,
// tradeId: STAT_BY_REF(statRef)!.trade.ids[ModifierType.Veiled]
// })
// }
// }
if (filters.influences) {
for (const influence of filters.influences) {
stats.push({
disabled: influence.disabled,
statRef: undefined!,
text: undefined!,
tag: undefined!,
sources: undefined!,
tradeId: STAT_BY_REF(INFLUENCE_PSEUDO_TEXT[influence.value])!.trade.ids[
ModifierType.Pseudo
]
})
}
}
// if (filters.influences) {
// for (const influence of filters.influences) {
// stats.push({
// disabled: influence.disabled,
// statRef: undefined!,
// text: undefined!,
// tag: undefined!,
// sources: undefined!,
// tradeId: STAT_BY_REF(INFLUENCE_PSEUDO_TEXT[influence.value])!.trade.ids[
// ModifierType.Pseudo
// ]
// })
// }
// }
const qAnd = query.stats[0]
for (const stat of stats) {

View File

@@ -10,7 +10,7 @@
<item-quick-price class="flex-1 text-base justify-center"
:price="trend.price"
:fraction="filters.stackSize != null"
:item-img="item.info.icon"
:item-img="item.info.icon === '%NOT_FOUND%' || item.info.icon === '' ? '/images/404.png' : item.info.icon"
:item-base="item.info"
>
<template #item v-if="isValuableBasetype">
@@ -53,7 +53,7 @@
<div v-else-if="!item.info.craftable" class="flex items-center pb-4" style="min-height: 3rem;">
<item-quick-price class="flex-1 text-base justify-center"
currency-text
:item-img="item.info.icon"
:item-img="item.info.icon === '%NOT_FOUND%' || item.info.icon === '' ? '/images/404.png' : item.info.icon"
:item-base="item.info" />
</div>
</template>

View File

@@ -6,7 +6,7 @@
<div class="grid grid-cols-2 gap-2 overflow-auto pb-4 px-4">
<div v-for="item in identifiedVariants" :key="item.name" class="flex">
<button @click="select(item)" class="bg-gray-700 rounded flex gap-x-3 items-center p-2 w-full">
<img :src="item.icon" class="w-12" />
<img :src="item.icon === '%NOT_FOUND%' || item.icon === '' ? '/images/404.png' : item.icon" class="w-12" />
<div class="leading-tight text-left">{{ item.name }}</div>
</button>
</div>

View File

@@ -2,12 +2,12 @@
<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">Exiles Exchange</p>
<p class="text-base">Exiled Exchange 2</p>
<p class="">{{ t('app.version', [version]) }}</p>
<div class="flex gap-2">
<a class="border-b" href="https://github.com/Kvan7/Exiles-Exchange/releases" target="_blank">{{
<a class="border-b" href="https://github.com/Kvan7/exiled-exchange-2/releases" target="_blank">{{
t('app.release_notes') }}</a>
<a class="border-b" href="https://github.com/Kvan7/Exiles-Exchange/issues" target="_blank">{{
<a class="border-b" href="https://github.com/Kvan7/exiled-exchange-2/issues" target="_blank">{{
t('app.report_bug') }}</a>
</div>
</div>
@@ -43,7 +43,7 @@ function checkForUpdates () {
}
function openDownloadPage () {
window.open('https://github.com/Kvan7/Exiles-Exchange/releases')
window.open('https://github.com/Kvan7/exiled-exchange-2/releases')
}
function quitAndInstall () {
@@ -67,19 +67,50 @@ export default defineComponent({
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') }
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') }
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') }
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') }
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 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')
}
}
})

22
testUpdate.sh Normal file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
# Remove ./renderer/dist if it exists
rm -rf ./renderer/dist
# Remove ./main/dist if it exists
rm -rf ./main/dist
cd ./renderer
npm install
npm run make-index-files
npm run build
cd ..
cd ./main
npm install
npm run build
npm run package