push working tree pseudos active

This commit is contained in:
kvan7
2025-09-09 20:55:27 -05:00
parent dc99645f9b
commit 879282f349
8 changed files with 107 additions and 117 deletions
+84 -103
View File
@@ -1,30 +1,28 @@
import { shallowRef, watch, readonly } from "vue";
import { createGlobalState } from "@vueuse/core";
// import { Host } from "@/web/background/IPC";
import { Host } from "@/web/background/IPC";
import { useLeagues } from "./Leagues";
interface NinjaDenseInfo {
chaos: number;
graph: Array<number | null>;
exalted: number;
graph?: Array<number | null>;
name: string;
variant?: string;
}
type PriceDatabase = Array<{ ns: string; url: string; lines: string }>;
const RETRY_INTERVAL_MS = 4 * 60 * 1000;
// const UPDATE_INTERVAL_MS = 31 * 60 * 1000;
// const INTEREST_SPAN_MS = 20 * 60 * 1000;
const UPDATE_INTERVAL_MS = 31 * 60 * 1000;
const INTEREST_SPAN_MS = 20 * 60 * 1000;
interface DbQuery {
ns: string;
name: string;
variant: string | undefined;
}
export interface CurrencyValue {
min: number;
max: number;
currency: "exalted" | "div";
currency: "chaos" | "exalted" | "div";
}
export const usePoeninja = createGlobalState(() => {
@@ -36,47 +34,46 @@ export const usePoeninja = createGlobalState(() => {
const isLoading = shallowRef(false);
let PRICES_DB: PriceDatabase = [];
// const lastUpdateTime = 0;
// let downloadController: AbortController | undefined;
// let lastInterestTime = 0;
let lastUpdateTime = 0;
let downloadController: AbortController | undefined;
let lastInterestTime = 0;
async function load(force: boolean = false) {
// const league = leagues.selected.value;
// if (!league || !league.isPopular || league.realm !== "pc-ggg") return;
// if (
// !force &&
// (Date.now() - lastUpdateTime < UPDATE_INTERVAL_MS ||
// Date.now() - lastInterestTime > INTEREST_SPAN_MS)
// )
// return;
// if (downloadController) downloadController.abort();
// try {
// isLoading.value = true;
// downloadController = new AbortController();
// const response = await Host.proxy(
// `poe.ninja/api/data/DenseOverviews?league=${league.id}&language=en`,
// {
// signal: downloadController.signal,
// },
// );
// const jsonBlob = await response.text();
// PRICES_DB = splitJsonBlob(jsonBlob);
// const divine = findPriceByQuery({
// ns: "ITEM",
// name: "Divine Orb",
// variant: undefined,
// });
// if (divine && divine.chaos >= 30) {
// xchgRate.value = divine.chaos;
// }
// lastUpdateTime = Date.now();
// } finally {
// isLoading.value = false;
// }
const league = leagues.selected.value;
if (!league || !league.isPopular || league.realm !== "pc-ggg") return;
if (
!force &&
(Date.now() - lastUpdateTime < UPDATE_INTERVAL_MS ||
Date.now() - lastInterestTime > INTEREST_SPAN_MS)
)
return;
if (downloadController) downloadController.abort();
try {
isLoading.value = true;
downloadController = new AbortController();
const response = await Host.proxy(
`poe.ninja/api/data/DenseOverviews?league=${league.id}&language=en`,
{
signal: downloadController.signal,
},
);
const jsonBlob = await response.text();
PRICES_DB = splitJsonBlob(jsonBlob);
const divine = findPriceByQuery({
ns: "ITEM",
name: "Divine Orb",
});
if (divine && divine.exalted >= 30) {
xchgRate.value = divine.exalted;
}
lastUpdateTime = Date.now();
} finally {
isLoading.value = false;
}
}
function queuePricesFetch() {
// lastInterestTime = Date.now();
lastInterestTime = Date.now();
load();
}
@@ -96,8 +93,7 @@ export const usePoeninja = createGlobalState(() => {
// NOTE: order of keys is important
const searchString = JSON.stringify({
name: query.name,
variant: query.variant,
chaos: 0,
exalted: 0,
}).replace(":0}", ":");
for (const { ns, url, lines } of PRICES_DB) {
@@ -113,7 +109,7 @@ export const usePoeninja = createGlobalState(() => {
return {
...info,
url: `https://poe.ninja/${selectedLeagueToUrl()}/${url}/${denseInfoToDetailsId(info)}`,
url: `https://poe.ninja/poe2/economy/${selectedLeagueToUrl()}/${url}`,
};
}
return null;
@@ -168,74 +164,59 @@ export const usePoeninja = createGlobalState(() => {
};
});
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function denseInfoToDetailsId(info: NinjaDenseInfo): string {
return (info.variant ? `${info.name}, ${info.variant}` : info.name)
return info.name
.normalize("NFKD")
.replace(/[^a-zA-Z0-9:\- ]/g, "")
.toLowerCase()
.replace(/ /g, "-");
}
// function splitJsonBlob(jsonBlob: string): PriceDatabase {
// const NINJA_OVERVIEW = '{"type":"';
// const NAMESPACE_MAP: Array<{ ns: string; url: string; type: string }> = [
// { ns: "ITEM", url: "currency", type: "Currency" },
// { ns: "ITEM", url: "fragments", type: "Fragment" },
// { ns: "ITEM", url: "delirium-orbs", type: "DeliriumOrb" },
// { ns: "ITEM", url: "scarabs", type: "Scarab" },
// { ns: "ITEM", url: "artifacts", type: "Artifact" },
// { ns: "ITEM", url: "base-types", type: "BaseType" },
// { ns: "ITEM", url: "fossils", type: "Fossil" },
// { ns: "ITEM", url: "resonators", type: "Resonator" },
// { ns: "ITEM", url: "incubators", type: "Incubator" },
// { ns: "ITEM", url: "oils", type: "Oil" },
// { ns: "ITEM", url: "vials", type: "Vial" },
// { ns: "ITEM", url: "invitations", type: "Invitation" },
// { ns: "ITEM", url: "blighted-maps", type: "BlightedMap" },
// { ns: "ITEM", url: "blight-ravaged-maps", type: "BlightRavagedMap" },
// { ns: "ITEM", url: "essences", type: "Essence" },
// { ns: "ITEM", url: "maps", type: "Map" },
// { ns: "ITEM", url: "tattoos", type: "Tattoo" },
// { ns: "ITEM", url: "omens", type: "Omen" },
// { ns: "ITEM", url: "coffins", type: "Coffin" },
// { ns: "DIVINATION_CARD", url: "divination-cards", type: "DivinationCard" },
// { ns: "CAPTURED_BEAST", url: "beasts", type: "Beast" },
// { ns: "UNIQUE", url: "unique-jewels", type: "UniqueJewel" },
// { ns: "UNIQUE", url: "unique-flasks", type: "UniqueFlask" },
// { ns: "UNIQUE", url: "unique-weapons", type: "UniqueWeapon" },
// { ns: "UNIQUE", url: "unique-armours", type: "UniqueArmour" },
// { ns: "UNIQUE", url: "unique-accessories", type: "UniqueAccessory" },
// { ns: "UNIQUE", url: "unique-maps", type: "UniqueMap" },
// { ns: "UNIQUE", url: "unique-relics", type: "UniqueRelic" },
// { ns: "GEM", url: "skill-gems", type: "SkillGem" },
// ];
function splitJsonBlob(jsonBlob: string): PriceDatabase {
const NINJA_OVERVIEW = '{"type":"';
const NAMESPACE_MAP: Array<{ ns: string; url: string; type: string }> = [
{ ns: "ITEM", url: "currency", type: "Currency" },
{ ns: "ITEM", url: "fragments", type: "Fragments" },
{ ns: "ITEM", url: "abyssal-bones", type: "Abyss" },
{ ns: "ITEM", url: "uncut-gems", type: "UncutGems" },
{ ns: "ITEM", url: "lineage-support-gems", type: "LineageSupportGems" },
{ ns: "ITEM", url: "essences", type: "Essences" },
{ ns: "ITEM", url: "soul-cores", type: "Ultimatum" },
{ ns: "ITEM", url: "talismans", type: "Talismans" },
{ ns: "ITEM", url: "runes", type: "Runes" },
{ ns: "ITEM", url: "omens", type: "Ritual" },
{ ns: "ITEM", url: "expedition", type: "Expedition" },
{ ns: "ITEM", url: "distilled-emotions", type: "Delirium" },
{ ns: "ITEM", url: "breach-catalyst", type: "Breach" },
];
// const database: PriceDatabase = [];
// let startPos = jsonBlob.indexOf(NINJA_OVERVIEW);
// if (startPos === -1) return [];
const database: PriceDatabase = [];
let startPos = jsonBlob.indexOf(NINJA_OVERVIEW);
if (startPos === -1) return [];
// while (true) {
// const endPos = jsonBlob.indexOf(NINJA_OVERVIEW, startPos + 1);
while (true) {
const endPos = jsonBlob.indexOf(NINJA_OVERVIEW, startPos + 1);
// const type = jsonBlob.slice(
// startPos + NINJA_OVERVIEW.length,
// jsonBlob.indexOf('"', startPos + NINJA_OVERVIEW.length),
// );
// const lines = jsonBlob.slice(
// startPos,
// endPos === -1 ? jsonBlob.length : endPos,
// );
const type = jsonBlob.slice(
startPos + NINJA_OVERVIEW.length,
jsonBlob.indexOf('"', startPos + NINJA_OVERVIEW.length),
);
const lines = jsonBlob.slice(
startPos,
endPos === -1 ? jsonBlob.length : endPos,
);
// const isSupported = NAMESPACE_MAP.find((entry) => entry.type === type);
// if (isSupported) {
// database.push({ ns: isSupported.ns, url: isSupported.url, lines });
// }
const isSupported = NAMESPACE_MAP.find((entry) => entry.type === type);
if (isSupported) {
database.push({ ns: isSupported.ns, url: isSupported.url, lines });
}
// if (endPos === -1) break;
// startPos = endPos;
// }
// return database;
// }
if (endPos === -1) break;
startPos = endPos;
}
return database;
}
export function displayRounding(
value: number,
@@ -319,8 +319,8 @@ function selectItem(
const isAdded = addItem({
info: item,
discr: opts.altQuality,
chaos: price?.chaos,
price: price != null ? autoCurrency(price.chaos) : undefined,
chaos: price?.exalted,
price: price != null ? autoCurrency(price.exalted) : undefined,
});
if (isAdded && opts.withTimeout) {
showTimeout.value?.reset();
@@ -48,7 +48,7 @@ export default defineComponent({
variant: undefined,
});
if (price) {
totalChaos += price.chaos;
totalChaos += price.exalted;
} else {
totalChaos = undefined;
break;
@@ -66,8 +66,8 @@ export async function requestPoeprices(
throw new Error("poeprices.info gave the price in Exalted Orbs.");
}
const converted = autoCurrency([
data.min * xchgExalted.chaos,
data.max * xchgExalted.chaos,
data.min * xchgExalted.exalted,
data.max * xchgExalted.exalted,
]);
data.min = converted.min;
data.max = converted.max;
@@ -81,7 +81,7 @@ function findPriceByQueryId(queryId: string) {
const [name, variant] = encodedName.split(" // ");
const priceEntry = findPriceByQuery({ ns, name, variant });
if (priceEntry) {
return autoCurrency(priceEntry.chaos);
return autoCurrency(priceEntry.exalted);
}
}
@@ -48,11 +48,11 @@ export default defineComponent({
const price =
props.item.info.refName === "Divine Orb"
? {
min: n * one.chaos,
max: n * one.chaos,
min: n * one.exalted,
max: n * one.exalted,
currency: "chaos" as const,
}
: autoCurrency(n * one.chaos);
: autoCurrency(n * one.exalted);
return `${displayRounding(price.min)} ${price.currency}`;
}
@@ -144,12 +144,16 @@ export default defineComponent({
const price =
props.item.info.refName === "Divine Orb"
? { min: trend.chaos, max: trend.chaos, currency: "exalted" as const }
: autoCurrency(trend.chaos);
? {
min: trend.exalted,
max: trend.exalted,
currency: "exalted" as const,
}
: autoCurrency(trend.exalted);
return {
price,
change: deltaFromGraph(trend.graph),
change: trend.graph ? deltaFromGraph(trend.graph) : undefined,
url: trend.url,
};
});
+7 -2
View File
@@ -31,10 +31,15 @@
v-if="!currencyText"
>
<img
v-if="isValuable"
v-if="price?.currency === 'div'"
src="/images/divine.png"
class="max-w-full max-h-full"
/>
<img
v-else-if="price?.currency === 'chaos'"
src="/images/chaos.png"
class="max-w-full max-h-full"
/>
<img v-else src="/images/exa.png" class="max-w-full max-h-full" />
</div>
</div>
@@ -51,7 +56,7 @@ export default defineComponent({
type: Object as PropType<{
min: number;
max: number;
currency: "div" | "exalted";
currency: "chaos" | "div" | "exalted";
}>,
default: undefined,
},