Skip to content

Commit

Permalink
feat: support display character cultivate data from skland
Browse files Browse the repository at this point in the history
  • Loading branch information
Tsuk1ko committed Jul 5, 2024
1 parent 91109f5 commit 8ed072f
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 26 deletions.
12 changes: 10 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,9 @@ a {
filter: none !important;
}
.of-hidden {
overflow: hidden;
}
.no-wrap {
white-space: nowrap;
}
Expand Down Expand Up @@ -551,13 +554,14 @@ a {
flex-wrap: nowrap;
vertical-align: middle;
margin: 2px 4px 2px 0;
&-left {
& > .mdui-btn {
margin: 0 !important;
}
&-left {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
&-right {
margin: 0 !important;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: rgba(0, 0, 0, 0.13) 1px solid;
Expand Down Expand Up @@ -607,6 +611,10 @@ a {
border: none !important;
}
.mdui-m-l-auto {
margin-left: auto !important;
}
.mdui-m-l-05 {
margin-left: 4px !important;
}
Expand Down
52 changes: 43 additions & 9 deletions src/components/material/PresetSettingDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@
<template v-if="sp">
<div class="mdui-card-header mdui-p-b-0">
<Avatar class="mdui-card-header-avatar mdui-color-grey-400" :name="selectedPresetName" />
<div class="mdui-card-header-title">{{ $t(`character.${selectedPresetName}`) }}</div>
<div class="mdui-card-header-title flex-nowrap">
<span class="mdui-text-truncate">{{ $t(`character.${selectedPresetName}`) }}</span>
<small v-if="curSklandCultivate" class="mdui-text-color-theme-secondary mdui-m-l-1">{{
getCultivateCharLevelText(selectedPresetName)
}}</small>
</div>
</div>
<div class="mdui-card-content preset-list mdui-p-x-3">
<!-- 精英化选框 -->
Expand All @@ -24,9 +29,14 @@
</div>
<!-- 普通技能选框 -->
<div class="skill-normal cb-with-num-select" v-if="sp.skills.normal.length >= 2">
<mdui-checkbox v-model="pSetting.skills.normal[0]" class="mdui-p-r-2">{{
$t('common.skill')
}}</mdui-checkbox>
<mdui-checkbox v-model="pSetting.skills.normal[0]" class="mdui-p-r-2">
<span>{{ $t('common.skill') }}</span>
<span
v-if="curSklandCultivate.mainSkillLevel"
class="mdui-text-color-theme-secondary mdui-m-l-1"
>({{ curSklandCultivate.mainSkillLevel }})</span
>
</mdui-checkbox>
<div class="num-select inline-block">
<mdui-select-num
v-model="pSetting.skills.normal[1]"
Expand Down Expand Up @@ -57,10 +67,16 @@
v-model="pSetting.skills.elite[i][0]"
class="skill-elite-cb mdui-p-r-2"
:custom-slot="true"
><div class="mdui-text-truncate">{{
$t(`skill.${skill.name}`)
}}</div></mdui-checkbox
>
<div class="mdui-valign flex-nowrap no-wrap of-hidden">
<span class="mdui-text-truncate">{{ $t(`skill.${skill.name}`) }}</span>
<span
v-if="curSklandCultivate.skills"
class="mdui-text-color-theme-secondary mdui-m-l-1"
>({{ curSklandCultivate.skills[skill.name] }})</span
>
</div>
</mdui-checkbox>
<DataImg
class="skill-icon mdui-shadow-4"
type="skill"
Expand Down Expand Up @@ -110,8 +126,16 @@
val =>
!$root.isReleasedUniequip(id) && !val && $nextTick($refs.dialog.handleUpdate)
"
>{{ $t(`uniequip.${id}`) }}</mdui-checkbox
>
<div class="mdui-valign flex-nowrap no-wrap of-hidden">
<span class="mdui-text-truncate">{{ $t(`uniequip.${id}`) }}</span>
<span
v-if="curSklandCultivate.equips"
class="mdui-text-color-theme-secondary mdui-m-l-1"
>({{ curSklandCultivate.equips[id] }})</span
>
</div>
</mdui-checkbox>
<div class="uniequip-icon no-pe mdui-shadow-4">
<DataImg
class="uniequip-icon-img"
Expand Down Expand Up @@ -188,9 +212,10 @@
<script>
import { defineComponent, markRaw } from 'vue';
import { mapState } from 'pinia';
import { mapState, mapActions } from 'pinia';
import { debounce } from 'lodash';
import { useDataStore } from '@/store/data';
import { useSklandStore } from '@/store/skland';
import DataImg from '@/components/DataImg.vue';
const offsetUniequipIcons = new Set([
Expand Down Expand Up @@ -233,6 +258,10 @@ export default defineComponent({
}),
computed: {
...mapState(useDataStore, ['characterTable', 'uniequip']),
...mapState(useSklandStore, {
sklandCredValid: 'credValid',
sklandCultivateCharacters: 'cultivateCharacters',
}),
selectedPresetName() {
return this.parent().selectedPresetName;
},
Expand All @@ -245,6 +274,9 @@ export default defineComponent({
presetUniequip() {
return this.parent().presetUniequip;
},
curSklandCultivate() {
return this.sklandCultivateCharacters[this.selectedPresetName] || {};
},
},
created() {
this.updateOverflowDebounce = markRaw(debounce(this.updateOverflow, 300));
Expand All @@ -253,9 +285,11 @@ export default defineComponent({
this.unbindEvents();
},
methods: {
...mapActions(useSklandStore, ['updateSklandCultivateIfExpired', 'getCultivateCharLevelText']),
open() {
this.overflow = 'hidden';
this.$refs.dialog.open();
if (this.$root.supportSkland) this.updateSklandCultivateIfExpired();
},
updateOverflow() {
const dialogRect = this.$refs.dialog.$el.getBoundingClientRect();
Expand Down
4 changes: 4 additions & 0 deletions src/data/changelog.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
[
{
"time": "2024-07-05",
"changes": ["【精英材料计算】预设支持显示当前干员练度(森空岛)"]
},
{
"time": "2024-06-28",
"changes": [
Expand Down
3 changes: 3 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ new Vue({
// 分级模组和黑键同期实装
return this.isReleasedChar('4046_ebnhlz');
},
supportSkland() {
return this.serverCN;
},
},
methods: {
...mapActions(useHotUpdateStore, ['initData']),
Expand Down
6 changes: 4 additions & 2 deletions src/store/materialValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ export const useMaterialValueStore = defineStore('materialValue', () => {

let fetchFailed = 0;

// TODO 等一图流恢复
const loadData = async (force = false) => {
if (force) {
fetchData();
// fetchData();
return;
}

Expand All @@ -32,10 +33,11 @@ export const useMaterialValueStore = defineStore('materialValue', () => {
}

if (!dataReady.value || dataExpired.value) {
fetchData();
// fetchData();
}
};

// eslint-disable-next-line no-unused-vars
const fetchData = async () => {
if (fetchFailed >= MAX_FETCH_TRY) return;
try {
Expand Down
81 changes: 79 additions & 2 deletions src/store/skland.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
import _ from 'lodash';
import { useNamespacedLocalStorage } from '@/utils/NamespacedLocalStorage';
import { fetchSkland } from '@/utils/skland';
import { defineStore } from 'pinia';
import { computed, watch } from 'vue';
import { computed, watch, shallowRef } from 'vue';

const cnNumTextMap = ['零', '一', '二'];

const idStandardization = id => id.replace(/\[([0-9]+?)\]/g, '_$1');

const handleCharactersCultivateData = list => {
let amiya;
const otherAmiya = [];
const mapHandleKeys = ['skills', 'equips'];
const newList = list.filter(char => {
char.id = char.id.replace(/^char_/, '');
mapHandleKeys.forEach(key => {
if (!char[key]) {
char[key] = {};
return;
}
char[key] = _.fromPairs(char[key].map(({ id, level }) => [idStandardization(id), level]));
});
if (char.id === '002_amiya') amiya = char;
else if (/_amiya\d+$/.test(char.id)) {
otherAmiya.push(char);
return false;
}
return true;
});
if (amiya && otherAmiya.length) {
otherAmiya.forEach(char => {
mapHandleKeys.forEach(key => {
Object.assign(amiya[key], char[key]);
});
});
}
return _.keyBy(newList, 'id');
};

export const useSklandStore = defineStore('skland', () => {
const storage = useNamespacedLocalStorage('skland', {
Expand All @@ -12,12 +47,16 @@ export const useSklandStore = defineStore('skland', () => {
});
const { cred, token, uid } = storage;

let cultivateLastFetch = 0;
const cultivateCharacters = shallowRef({});

const credValid = computed(() => cred.value.length === 32);

watch(cred, () => {
if (!credValid.value) return;
token.value = '';
uid.value = '';
cultivateCharacters.value = {};
});

const refreshToken = async () => {
Expand All @@ -34,13 +73,15 @@ export const useSklandStore = defineStore('skland', () => {

const fetchSklandCultivate = async () => {
if (!credValid.value) return;
cultivateLastFetch = Date.now();
await refreshToken();
await fetchSklandBinding();
const data = await fetchSkland(
`/api/v1/game/cultivate/player?uid=${uid.value}`,
cred.value,
token.value,
);
cultivateCharacters.value = handleCharactersCultivateData(data.characters);
return data.items;
};

Expand All @@ -54,5 +95,41 @@ export const useSklandStore = defineStore('skland', () => {
uid.value = newUid;
};

return { cred, credValid, fetchSklandCultivate };
const updateSklandCultivateIfExpired = async () => {
if (Date.now() - cultivateLastFetch < 1800e3 && cultivateCharacters.value) return;
await fetchSklandCultivate();
};

const getCultivateCharLevelText = id => {
const char = cultivateCharacters.value[id];
if (!char) return '';
return char.evolvePhase
? `精${cnNumTextMap[char.evolvePhase]}${char.level}级`
: `${char.level}级`;
};

const getPresetItemCultivateText = id => {
const char = cultivateCharacters.value[id];
if (!char) return '';
const skillValues = Object.values(char.skills);
const equipValues = Object.values(char.equips);
const parts = [
getCultivateCharLevelText(id),
`技${char.mainSkillLevel}`,
_.sum(skillValues) ? `专${skillValues.join('')}` : null,
_.sum(equipValues) ? `模${equipValues.join('')}` : null,
`潜${char.potentialRank + 1}`,
];
return parts.filter(_.identity).join('/');
};

return {
cred,
credValid,
cultivateCharacters,
fetchSklandCultivate,
updateSklandCultivateIfExpired,
getCultivateCharLevelText,
getPresetItemCultivateText,
};
});
24 changes: 18 additions & 6 deletions src/views/Material/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,10 @@ export default defineComponent({
},
}),
...mapState(usePenguinDataStore, ['penguinData', 'curPenguinDataServer']),
...mapState(useSklandStore, { sklandCredValid: 'credValid' }),
...mapState(useSklandStore, {
sklandCredValid: 'credValid',
sklandCultivateCharacters: 'cultivateCharacters',
}),
syncCode: {
get() {
return this.setting[`syncCodeV${SYNC_CODE_VER}`];
Expand Down Expand Up @@ -624,10 +627,11 @@ export default defineComponent({
}
return 0;
});
return _.map(result, o => ({ name: o.name, text: this.$t(`character.${o.name}`) })).slice(
0,
10,
);
return _.map(result.slice(0, 10), o => ({
name: o.name,
text: this.$t(`character.${o.name}`),
cultivateText: this.$root.supportSkland ? this.getPresetItemCultivateText(o.name) : null,
}));
},
presetUniequip() {
return this.sp?.uniequip.filter(
Expand Down Expand Up @@ -956,7 +960,11 @@ export default defineComponent({
...mapActions(useDataStore, ['getStageTable']),
...mapActions(usePenguinDataStore, ['loadPenguinData', 'fetchPenguinData']),
...mapActions(useMaterialValueStore, ['loadMaterialValueData', 'calcStageEfficiency']),
...mapActions(useSklandStore, ['fetchSklandCultivate']),
...mapActions(useSklandStore, [
'fetchSklandCultivate',
'updateSklandCultivateIfExpired',
'getPresetItemCultivateText',
]),
isPlannerUnavailableItem(id) {
return (
this.materialTable[id]?.type === MaterialTypeEnum.MOD_TOKEN ||
Expand Down Expand Up @@ -1787,6 +1795,10 @@ export default defineComponent({
this.$snackbar(this.$t('common.copied'));
}
},
async updateSklandCultivateIfSupport() {
if (!this.$root.supportSkland) return;
await this.updateSklandCultivateIfExpired();
},
},
created() {
this.throttleAutoSyncUpload = _.throttle(() => this.cloudSaveData(true), 5000, {
Expand Down
3 changes: 3 additions & 0 deletions src/views/Material/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ $highlight-colors-dark: #eee, #e6ee9c, #90caf9, #b39ddb, #fff59d;
.preset-list > div:not(:first-child) {
margin-top: 8px;
}
.preset-cultivate-text {
opacity: 0.65;
}
.elite-cb-list {
display: flex;
.mdui-checkbox {
Expand Down
Loading

0 comments on commit 8ed072f

Please sign in to comment.