isl-vue3/src/stores/powerItems.ts

382 lines
12 KiB
TypeScript

import type { PowerItem } from '@/types/PowerItem'
import axios, { type AxiosRequestConfig } from 'axios'
import { defineStore } from 'pinia'
import { computed, ref, toRaw } from 'vue'
import axiosRetry from 'axios-retry'
import { apiBaseURL as apiBaseURLKey } from '@/types/ConfigSymbols'
import { inject } from 'vue'
import { getConfig } from '@/services/siteConfig'
import type { Config } from '@/types/Config'
const BLESSING = 1
const INTIMACY = 2
const FELLOW = 3
const noCacheConfig: AxiosRequestConfig = {
responseType: 'json',
headers: {
'Cache-Control': 'no-cache',
Pragma: 'no-cache',
Expires: '0'
}
}
export const usePowerItems = defineStore('powerItems', () => {
//#region privateVariables
const BLESSING_POWER_ITEM_STORAGE = 'BLESSING_POWER_ITEM_STORAGE'
const FELLOW_POWER_ITEM_STORAGE = 'FELLOW_POWER_ITEM_STORAGE'
const INTIMACY_POWER_ITEM_STORAGE = 'INTIMACY_POWER_ITEM_STORAGE'
let apiBaseURL = inject(apiBaseURLKey)!
if (apiBaseURL === undefined) {
getConfig().then((conf: Config | null) => {
if (conf !== null) {
apiBaseURL = conf.apiBaseURL
}
})
}
//#endregion
//#region state
const blessingPowerItems = ref(new Map<string, PowerItem>())
const fellowPowerItems = ref(new Map<string, PowerItem>())
const intimacyPowerItems = ref(new Map<string, PowerItem>())
//#endregion
axiosRetry(axios, {
retries: 3,
retryDelay: axiosRetry.exponentialDelay
})
//#region loaders
async function fetchBlessingItems() {
axios
.get(apiBaseURL + '/powerItems/byType/' + BLESSING + '/asMap', noCacheConfig)
.then((resp) => {
const plainMap = new Map<string, PowerItem>(
Object.entries(JSON.parse(localStorage.getItem(BLESSING_POWER_ITEM_STORAGE) || '{}'))
)
Object.keys(resp.data).map((key) => {
const cur = resp.data[key]
if (cur['owned'] === undefined) cur['owned'] = 0
cur['owned'] = plainMap.get(key) !== undefined ? plainMap.get(key)?.owned : 0
blessingPowerItems.value.set(key, resp.data[key])
})
})
.catch((err) => {
console.log(err)
})
}
async function fetchFellowItems() {
axios
.get(apiBaseURL + '/powerItems/byType/' + FELLOW + '/asMap', noCacheConfig)
.then((resp) => {
const plainMap = new Map<string, PowerItem>(
Object.entries(JSON.parse(localStorage.getItem(FELLOW_POWER_ITEM_STORAGE) || '{}'))
)
Object.keys(resp.data).map((key) => {
const cur = resp.data[key]
if (cur['owned'] === undefined) cur['owned'] = 0
cur['owned'] = plainMap.get(key) !== undefined ? plainMap.get(key)?.owned : 0
fellowPowerItems.value.set(key, resp.data[key])
})
})
.catch((err) => {
console.log(err)
})
}
async function fetchIntimacyItems() {
axios
.get(apiBaseURL + '/powerItems/byType/' + INTIMACY + '/asMap', noCacheConfig)
.then((resp) => {
const plainMap = new Map<string, PowerItem>(
Object.entries(JSON.parse(localStorage.getItem(INTIMACY_POWER_ITEM_STORAGE) || '{}'))
)
Object.keys(resp.data).map((key) => {
const cur = resp.data[key]
if (cur['owned'] === undefined) cur['owned'] = 0
cur['owned'] = plainMap.get(key) !== undefined ? plainMap.get(key)?.owned : 0
intimacyPowerItems.value.set(key, resp.data[key])
})
})
.catch((err) => {
console.log(err)
})
}
//#endregion
//#region setters
function updateOwned(key: string, newOwned: number) {
let cur = blessingPowerItems.value.get(key)
if (cur !== undefined) {
cur.owned = newOwned
blessingPowerItems.value.set(key, cur)
localStorage.setItem(
BLESSING_POWER_ITEM_STORAGE,
JSON.stringify(mapToObj(toRaw(blessingPowerItems.value)))
)
return
}
cur = fellowPowerItems.value.get(key)
if (cur !== undefined) {
cur.owned = newOwned
fellowPowerItems.value.set(key, cur)
localStorage.setItem(
FELLOW_POWER_ITEM_STORAGE,
JSON.stringify(mapToObj(toRaw(fellowPowerItems.value)))
)
}
cur = intimacyPowerItems.value.get(key)
if (cur !== undefined) {
cur.owned = newOwned
intimacyPowerItems.value.set(key, cur)
localStorage.setItem(
INTIMACY_POWER_ITEM_STORAGE,
JSON.stringify(mapToObj(toRaw(intimacyPowerItems.value)))
)
}
}
function addPowerItem(newItem: PowerItem): Promise<PowerItem | null> {
const resultPromise: Promise<PowerItem | null> = new Promise((resolve, reject) => {
axios
.post(apiBaseURL + '/powerItems/', newItem, noCacheConfig)
.then((resp) => {
resolve(resp.data)
})
.catch((rejected) => reject(rejected))
})
return resultPromise
}
//#endregion
//#region computed
const totalBlessingPower = computed(() =>
[...blessingPowerItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) => {
return currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0
},
0
)
)
const standardBlessingItems = computed(
() => new Map([...blessingPowerItems.value.entries()].filter((cur) => !cur[1].isEventItem))
)
const standardBlessingItemTotal = computed(() =>
[...standardBlessingItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0,
0
)
)
const specialBlessingItems = computed(
() => new Map([...blessingPowerItems.value.entries()].filter((cur) => cur[1].isEventItem))
)
const specialBlessingItemsMinTotal = computed(() =>
[...specialBlessingItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator + currentValue.minItemPower * currentValue.owned
: 0,
0
)
)
const specialBlessingItemsMaxTotal = computed(() =>
[...specialBlessingItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator + currentValue.maxItemPower * currentValue.owned
: 0,
0
)
)
const specialBlessingItemsAveTotal = computed(() =>
[...specialBlessingItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0,
0
)
)
const totalFellowPower = computed(() =>
[...fellowPowerItems.value.values()].reduce((accumulator: number, currentValue: PowerItem) => {
return currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0
}, 0)
)
const standardFellowItems = computed(
() => new Map([...fellowPowerItems.value.entries()].filter((cur) => !cur[1].isEventItem))
)
const standardFellowItemTotal = computed(() =>
[...standardFellowItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0,
0
)
)
const specialFellowItems = computed(
() => new Map([...fellowPowerItems.value.entries()].filter((cur) => cur[1].isEventItem))
)
const specialFellowItemsMinTotal = computed(() =>
[...specialFellowItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator + currentValue.minItemPower * currentValue.owned
: 0,
0
)
)
const specialFellowItemsMaxTotal = computed(() =>
[...specialFellowItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator + currentValue.maxItemPower * currentValue.owned
: 0,
0
)
)
const specialFellowItemsAveTotal = computed(() =>
[...specialFellowItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0,
0
)
)
const totalIntimacyPower = computed(() =>
[...intimacyPowerItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) => {
return currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0
},
0
)
)
const standardIntimacyItems = computed(
() => new Map([...intimacyPowerItems.value.entries()].filter((cur) => !cur[1].isEventItem))
)
const standardIntimacyItemTotal = computed(() =>
[...standardIntimacyItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0,
0
)
)
const specialIntimacyItems = computed(
() => new Map([...intimacyPowerItems.value.entries()].filter((cur) => cur[1].isEventItem))
)
const specialIntimacyItemsMinTotal = computed(() =>
[...specialIntimacyItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator + currentValue.minItemPower * currentValue.owned
: 0,
0
)
)
const specialIntimacyItemsMaxTotal = computed(() =>
[...specialIntimacyItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator + currentValue.maxItemPower * currentValue.owned
: 0,
0
)
)
const specialIntimacyItemsAveTotal = computed(() =>
[...specialIntimacyItems.value.values()].reduce(
(accumulator: number, currentValue: PowerItem) =>
currentValue !== undefined
? accumulator +
((currentValue.maxItemPower + currentValue.minItemPower) / 2) * currentValue.owned
: 0,
0
)
)
//#endregion
//#region helpers
function mapToObj(map: Map<string, PowerItem>) {
return Array.from(map).reduce((obj, [key, value]) => {
// Doing weird magic to work with maps is infuriating, and I haven't found a better solution for this.
// So ignore that error TypeScript, I (don't) know what I'm doing!
// @ts-ignore: noImplicitAny
obj[key] = value
return obj
}, {})
}
//#endregion
return {
blessingPowerItems,
fellowPowerItems,
intimacyPowerItems,
fetchBlessingItems,
fetchFellowItems,
fetchIntimacyItems,
updateOwned,
totalBlessingPower,
standardBlessingItems,
standardBlessingItemTotal,
specialBlessingItems,
specialBlessingItemsMinTotal,
specialBlessingItemsMaxTotal,
specialBlessingItemsAveTotal,
totalFellowPower,
standardFellowItems,
standardFellowItemTotal,
specialFellowItems,
specialFellowItemsMinTotal,
specialFellowItemsMaxTotal,
specialFellowItemsAveTotal,
totalIntimacyPower,
standardIntimacyItems,
standardIntimacyItemTotal,
specialIntimacyItems,
specialIntimacyItemsMinTotal,
specialIntimacyItemsMaxTotal,
specialIntimacyItemsAveTotal
}
})