Merge pull request #4 from exzork/refactor-substat

ui/ux improvement
This commit is contained in:
Muhammad Eko Prasetyo 2022-05-16 08:22:35 +07:00 committed by GitHub
commit 579a5eea90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 159 additions and 40 deletions

View File

@ -21,6 +21,7 @@
"i18next-browser-languagedetector": "^6.1.4", "i18next-browser-languagedetector": "^6.1.4",
"i18next-http-backend": "^1.4.0", "i18next-http-backend": "^1.4.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mathjs": "^10.5.3",
"postcss": "^8.4.12", "postcss": "^8.4.12",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",

View File

@ -1,7 +1,7 @@
import {ChangeEvent, useEffect, useState} from "react"; import {ChangeEvent, useEffect, useState} from "react";
import ReliquaryDataProvider, {IReliquaryAffix, IReliquaryMain} from "../providers/ReliquaryDataProvider"; import ReliquaryDataProvider, {IReliquaryAffix, IReliquaryMain} from "../providers/ReliquaryDataProvider";
import {Autocomplete, Chip, createFilterOptions, TextField} from "@mui/material"; import {Autocomplete, Chip, createFilterOptions, TextField} from "@mui/material";
import {permutations} from "mathjs";
//@ts-ignore //@ts-ignore
import _ from "lodash"; import _ from "lodash";
import {useTranslation} from "react-i18next"; import {useTranslation} from "react-i18next";
@ -11,15 +11,23 @@ interface IArtifact {
name: string; name: string;
} }
interface IPropTypeValues {
[key: string]: number[]; //number is the values
}
interface ISelectedPropTypeValues{
[key: string]: number[]; //number is the ids
}
export default function Artifacts() { export default function Artifacts() {
const [reliquaryMains, setReliquaryMains] = useState<IReliquaryMain[]>([]); const [reliquaryMains, setReliquaryMains] = useState<IReliquaryMain[]>([]);
const [reliquaryAffixes, setReliquaryAffixes] = useState<IReliquaryAffix[]>([]); const [reliquaryAffixes, setReliquaryAffixes] = useState<IReliquaryAffix[]>([]);
const [uid, setUid] = useState(0); const [uid, setUid] = useState(0);
const [selectedArtifact, setSelectedArtifact] = useState(0); const [selectedArtifact, setSelectedArtifact] = useState(0);
const [selectedMainStat, setSelectedMainStat] = useState(0); const [selectedMainStat, setSelectedMainStat] = useState(0);
const [selectedAffixes, setSelectedAffixes] = useState<number[]>([]);
const [selectedAffixesAmount, setSelectedAffixesAmount] = useState<Record<number, number>>({});
const [artifactEnhancements, setArtifactEnhancements] = useState(0); const [artifactEnhancements, setArtifactEnhancements] = useState(0);
const [affixesValues, setAffixesValues] = useState<IPropTypeValues>({});
const [selectedAffixesValues, setSelectedAffixesValues] = useState<ISelectedPropTypeValues>({});
const {t} = useTranslation("artifact"); const {t} = useTranslation("artifact");
@ -54,9 +62,14 @@ export default function Artifacts() {
}); });
}, []); }, []);
useEffect(() => {
const av: IPropTypeValues = getPropTypeValues(reliquaryAffixes);
setAffixesValues(av);
}, [reliquaryAffixes]);
useEffect(() => { useEffect(() => {
handleGeneratedArtifact() handleGeneratedArtifact()
}, [uid, selectedArtifact, selectedMainStat, selectedAffixes, selectedAffixesAmount, artifactEnhancements]); }, [uid, selectedArtifact, selectedMainStat, selectedAffixesValues , artifactEnhancements]);
const handleArtifactChange = (event: any, value: any) => { const handleArtifactChange = (event: any, value: any) => {
if (value !== null) { if (value !== null) {
@ -70,40 +83,88 @@ export default function Artifacts() {
} }
}; };
const handleAffixSelected = (event: ChangeEvent<HTMLInputElement>, amount = false, affixId=0) => { const getAffixIdByPropTypeAndPropValue = (propType: string, propValue: number) => {
let newSelectedAffixes = [...selectedAffixes]; return reliquaryAffixes.filter((x) => x.PropType === propType && x.PropValue === propValue)[0].Id;
let newSelectedAffixesAmount = {...selectedAffixesAmount};
if (amount) {
newSelectedAffixesAmount[affixId]=Number(event.target.value);
} else {
if (newSelectedAffixes.indexOf(Number(event.currentTarget.value)) === -1) {
newSelectedAffixes.push(Number(event.currentTarget.value));
newSelectedAffixesAmount[Number(event.currentTarget.value)] = 1;
} else {
newSelectedAffixes.splice(newSelectedAffixes.indexOf(Number(event.currentTarget.value)), 1);
newSelectedAffixesAmount[Number(event.currentTarget.value)] = 0;
}
}
setSelectedAffixes(newSelectedAffixes);
setSelectedAffixesAmount(newSelectedAffixesAmount);
}; };
const getPercent = (affix:IReliquaryAffix)=>{ const getListOfIdsByPropTypeAndRequestValue = (affixName: string, requestValue: number)=>{
if (affix.PropType.indexOf("PERCENT") !== -1 || affix.PropType.indexOf("CRITICAL") !== -1 || affix.PropType.indexOf("EFFICIENCY") !== -1 || affix.PropType.indexOf("HURT") !== -1 || affix.PropType.indexOf("RATIO") !== -1 || affix.PropType.indexOf("ADD") !== -1) { const possibleValues = affixesValues[affixName];
return parseFloat(String(affix.PropValue*100)).toPrecision(3) + "%";
let ids:number[] = [];
let closestValue = 0;
let less:number[] = [];
possibleValues.forEach((value) => {
if (value <= requestValue) {
less.push(value);
} }
return parseInt(String(affix.PropValue)); });
less.sort();
less.reverse();
for (let i of less) {
while ((closestValue+i) <= requestValue) {
closestValue += i;
const id = getAffixIdByPropTypeAndPropValue(affixName, i);
if (id !== undefined) {
ids.push(id);
}
}
if(closestValue === requestValue) break;
}
return {ids, closestValue};
}
const handleAffixChange = (event: ChangeEvent<HTMLInputElement>, affixName:string) => {
let affixesSelected = {...selectedAffixesValues};
const affixValues = parseInt(event.target.value);
if (affixValues > 0) {
if (affixesSelected[affixName] === undefined) affixesSelected[affixName] = [];
if (affixName.indexOf("PERCENT") !== -1 || affixName.indexOf("CRITICAL") !== -1 || affixName.indexOf("EFFICIENCY") !== -1 || affixName.indexOf("HURT") !== -1 || affixName.indexOf("RATIO") !== -1 || affixName.indexOf("ADD") !== -1){
const {ids} = getListOfIdsByPropTypeAndRequestValue(affixName, affixValues/100);
affixesSelected[affixName] = ids;
} else {
const {ids} = getListOfIdsByPropTypeAndRequestValue(affixName, affixValues);
affixesSelected[affixName] = ids;
}
} else {
delete affixesSelected[affixName];
}
setSelectedAffixesValues(affixesSelected);
};
const handleGetAffixClosestValue = (event: ChangeEvent<HTMLInputElement>, affixName:string) => {
const affixValues = parseInt(event.target.value);
if (affixValues === 0) return;
const {closestValue} =getListOfIdsByPropTypeAndRequestValue(affixName, affixValues);
event.target.value = parseFloat(closestValue.toFixed(3)).toString();
}
const getPropTypeValues = (affixes:IReliquaryAffix[])=>{
let propTypeValues:IPropTypeValues = {};
affixes.forEach(affix=>{
if (propTypeValues[affix.PropType] === undefined) {
propTypeValues[affix.PropType] = [];
}
propTypeValues[affix.PropType].push(affix.PropValue);
});
return propTypeValues;
}; };
const handleGeneratedArtifact = () => { const handleGeneratedArtifact = () => {
let selectedAffixesCombine: (string | number)[] = []; let selectedAffixesCombine: (string | number)[] = [];
if (selectedAffixes.length > 0) { if (Object.keys(selectedAffixesValues).length > 0) {
selectedAffixesCombine = selectedAffixes.map(x => { Object.keys(selectedAffixesValues).forEach(affixName => {
if (selectedAffixesAmount[x] > 1) { const affixValues = selectedAffixesValues[affixName];
return x + "," + selectedAffixesAmount[x]; const distinctValues = Array.from(new Set(affixValues));
} distinctValues.forEach(value => {
return x; const countAffixes = affixValues.filter(x => x === value).length;
}); if (countAffixes > 1) selectedAffixesCombine.push(value+","+countAffixes);
else selectedAffixesCombine.push(value);
})
})
} }
const generated = "/giveart @"+uid+" "+selectedArtifact+" "+selectedMainStat+" "+selectedAffixesCombine.join(" ")+" "+Number(artifactEnhancements+1); const generated = "/giveart @"+uid+" "+selectedArtifact+" "+selectedMainStat+" "+selectedAffixesCombine.join(" ")+" "+Number(artifactEnhancements+1);
setGeneratedArtifact(generated); setGeneratedArtifact(generated);
@ -169,15 +230,27 @@ export default function Artifacts() {
className="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2"> className="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
{t('sub_stats')} {t('sub_stats')}
</label> </label>
<div className="mt-1 sm:mt-0 sm:col-span-2 h-48 overflow-auto"> <div className="mt-1 sm:mt-0 sm:col-span-2 h-48 overflow-auto grid gap-x-10 gap-y-2 grid-cols-2">
{reliquaryAffixes.map((affix, index) => { {Object.keys(affixesValues).map((key, index) => {
return ( return (
<div key={index} className="flex"> <div key={index} className="flex items-center mt-1">
<input type="checkbox" className="mr-4 ml-4 focus:ring-indigo-500 h-4 w-4 mt-1 text-indigo-600 border-gray-300 rounded" value={affix.Id} id={"select-"+affix.Id} onChange={(e)=>handleAffixSelected(e,false,0)}/> <div className="ml-3 flex-grow ">
<label className="flex-grow" htmlFor={"select-"+affix.Id}>{t(affix.PropType) +" - "+getPercent(affix)}</label> <div className="text-sm leading-5 text-gray-900">
<input type="number" defaultValue="1" min="1" className="flex-none block shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md" onChange={(e)=>handleAffixSelected(e,true, affix.Id)}/> {t(key)}
</div> </div>
); </div>
<div className="ml-auto flex-none">
<input type="number"
step={0.01}
className="block shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md"
id={key}
defaultValue={0}
onChange={(e)=>handleAffixChange(e,key)}
onBlur={(e)=>handleGetAffixClosestValue(e,key)}
/>
</div>
</div>
)
})} })}
</div> </div>
</div> </div>

View File

@ -1018,7 +1018,7 @@
core-js-pure "^3.20.2" core-js-pure "^3.20.2"
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.17.9" version "7.17.9"
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz"
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
@ -3253,6 +3253,11 @@ commondir@^1.0.1:
resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz" resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz"
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
complex.js@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.1.1.tgz#0675dac8e464ec431fb2ab7d30f41d889fb25c31"
integrity sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==
compressible@~2.0.16: compressible@~2.0.16:
version "2.0.18" version "2.0.18"
resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz"
@ -3622,7 +3627,7 @@ debug@^3.1.1, debug@^3.2.7:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
decimal.js@^10.2.1: decimal.js@^10.2.1, decimal.js@^10.3.1:
version "10.3.1" version "10.3.1"
resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz" resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz"
integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
@ -3999,6 +4004,11 @@ escape-html@~1.0.3:
resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz"
integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
escape-latex@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1"
integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==
escape-string-regexp@^1.0.5: escape-string-regexp@^1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
@ -5334,6 +5344,11 @@ jake@^10.8.5:
filelist "^1.0.1" filelist "^1.0.1"
minimatch "^3.0.4" minimatch "^3.0.4"
javascript-natural-sort@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59"
integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=
jest-changed-files@^27.5.1: jest-changed-files@^27.5.1:
version "27.5.1" version "27.5.1"
resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz" resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz"
@ -6118,6 +6133,21 @@ makeerror@1.0.12:
dependencies: dependencies:
tmpl "1.0.5" tmpl "1.0.5"
mathjs@^10.5.3:
version "10.5.3"
resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-10.5.3.tgz#79e0dd9cf370adce80699cc40ed18c1c0cb6599e"
integrity sha512-RtF+F7SdRIf2E2+btyGDhuB6wmPjOH9KeNglfclaaaI6eK7ZNfsQS6IRAKvGyNsr8sFc6Pyb3JBLqEhYBuknVQ==
dependencies:
"@babel/runtime" "^7.17.9"
complex.js "^2.1.1"
decimal.js "^10.3.1"
escape-latex "^1.2.0"
fraction.js "^4.2.0"
javascript-natural-sort "^0.7.1"
seedrandom "^3.0.5"
tiny-emitter "^2.1.0"
typed-function "^2.1.0"
mdn-data@2.0.14: mdn-data@2.0.14:
version "2.0.14" version "2.0.14"
resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz"
@ -7856,6 +7886,11 @@ schema-utils@^4.0.0:
ajv-formats "^2.1.1" ajv-formats "^2.1.1"
ajv-keywords "^5.0.0" ajv-keywords "^5.0.0"
seedrandom@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
select-hose@^2.0.0: select-hose@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz"
@ -8456,6 +8491,11 @@ thunky@^1.0.2:
resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz"
integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
tiny-emitter@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
tmpl@1.0.5: tmpl@1.0.5:
version "1.0.5" version "1.0.5"
resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz"
@ -8580,6 +8620,11 @@ type-is@~1.6.18:
media-typer "0.3.0" media-typer "0.3.0"
mime-types "~2.1.24" mime-types "~2.1.24"
typed-function@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.1.0.tgz#ded6f8a442ba8749ff3fe75bc41419c8d46ccc3f"
integrity sha512-bctQIOqx2iVbWGDGPWwIm18QScpu2XRmkC19D8rQGFsjKSgteq/o1hTZvIG/wuDq8fanpBDrLkLq+aEN/6y5XQ==
typedarray-to-buffer@^3.1.5: typedarray-to-buffer@^3.1.5:
version "3.1.5" version "3.1.5"
resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz"