mirror of
https://github.com/MadeBaruna/paimon-moe.git
synced 2024-11-23 07:17:43 +01:00
Merge pull request #16 from fadhluu/resinCalculator
Add desired resin input field
This commit is contained in:
commit
49dcb22697
7 changed files with 254 additions and 70 deletions
|
@ -205,12 +205,23 @@
|
||||||
"wasted": "Wasted EXP",
|
"wasted": "Wasted EXP",
|
||||||
"mora": "Mora Cost"
|
"mora": "Mora Cost"
|
||||||
},
|
},
|
||||||
|
"resinTable": {
|
||||||
|
"quantity": "Quantity",
|
||||||
|
"time": "Time To Wait"
|
||||||
|
},
|
||||||
"resin": {
|
"resin": {
|
||||||
"inputCurrentResin": "Input Current Resin...",
|
"currentResin": "Current Resin",
|
||||||
|
"desiredResin": "Desired Resin",
|
||||||
|
"or": "or",
|
||||||
|
"inputCurrentResin": "Input current resin...",
|
||||||
|
"inputDesireResin": "Input how many resin you want to wait...",
|
||||||
"timeFormat": "en",
|
"timeFormat": "en",
|
||||||
"calculate": "Calculate",
|
"calculate": "Calculate",
|
||||||
"currentTime": "Current Time",
|
"currentTime": "Current Time",
|
||||||
"fullTime": "Resin Will Be Replenished At"
|
"fullTime": "Will be replenished at",
|
||||||
|
"hours": "hours",
|
||||||
|
"minutes": "minutes",
|
||||||
|
"seconds": "seconds"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"items": {
|
"items": {
|
||||||
|
|
|
@ -205,12 +205,23 @@
|
||||||
"wasted": "Exp Terbuang",
|
"wasted": "Exp Terbuang",
|
||||||
"mora": "Jumlah Mora"
|
"mora": "Jumlah Mora"
|
||||||
},
|
},
|
||||||
|
"resinTable": {
|
||||||
|
"quantity": "Jumlah",
|
||||||
|
"time": "Waktu Menunggu"
|
||||||
|
},
|
||||||
"resin": {
|
"resin": {
|
||||||
"inputCurrentResin": "Masukkan Jumlah Resin Sekarang...",
|
"currentResin": "Resin Saat Ini",
|
||||||
|
"desiredResin": "Resin Yang Diinginkan",
|
||||||
|
"or": "atau",
|
||||||
|
"inputCurrentResin": "Masukkan jumlah resin sekarang...",
|
||||||
|
"inputDesireResin": "Masukkan jumlah resin yang diinginkan...",
|
||||||
"timeFormat": "id",
|
"timeFormat": "id",
|
||||||
"calculate": "Hitung",
|
"calculate": "Hitung",
|
||||||
"currentTime": "Waktu Sekarang",
|
"currentTime": "Waktu Sekarang",
|
||||||
"fullTime": "Resin Akan Penuh Pada"
|
"fullTime": "Akan terisi pada",
|
||||||
|
"hours": "jam",
|
||||||
|
"minutes": "menit",
|
||||||
|
"seconds": "detik"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"items": {
|
"items": {
|
||||||
|
|
|
@ -1,18 +1,36 @@
|
||||||
<script>
|
<script>
|
||||||
import { mdiClose } from '@mdi/js';
|
import { mdiClose } from '@mdi/js';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
import { t } from 'svelte-i18n';
|
import { t } from 'svelte-i18n';
|
||||||
import { fade } from 'svelte/transition';
|
import { fade } from 'svelte/transition';
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import rTime from 'dayjs/plugin/relativeTime';
|
||||||
|
import 'dayjs/locale/en';
|
||||||
|
import 'dayjs/locale/id';
|
||||||
|
|
||||||
|
dayjs.extend(rTime);
|
||||||
|
|
||||||
import Button from '../../components/Button.svelte';
|
import Button from '../../components/Button.svelte';
|
||||||
import Icon from '../../components/Icon.svelte';
|
import Icon from '../../components/Icon.svelte';
|
||||||
import Input from '../../components/Input.svelte';
|
import Input from '../../components/Input.svelte';
|
||||||
import { time } from '../../stores/time';
|
|
||||||
|
|
||||||
let changed = false;
|
let changed = true;
|
||||||
let currentResin = '';
|
let currentResin = '';
|
||||||
|
let desiredResin = '';
|
||||||
let maxResin = 160;
|
let maxResin = 160;
|
||||||
let millisecondsToWait;
|
let millisecondsToWait;
|
||||||
let fullTime = null;
|
let fullTime = null;
|
||||||
|
let relativeTime = null;
|
||||||
let missingResin = 160;
|
let missingResin = 160;
|
||||||
|
let resinTypeOutput = '';
|
||||||
|
let resinOutput = {
|
||||||
|
resin: 0,
|
||||||
|
condensed: {
|
||||||
|
resin: 0,
|
||||||
|
condensedResin: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let currentTime = dayjs();
|
||||||
|
|
||||||
let originalResin = {
|
let originalResin = {
|
||||||
id: 'original_resin',
|
id: 'original_resin',
|
||||||
|
@ -21,80 +39,163 @@
|
||||||
value: 8,
|
value: 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 8 menit per resin * 60 seconds * 1000 millisec
|
let condensedResin = {
|
||||||
let minutePerResin = originalResin.value * 60 * 1000;
|
id: 'condensed_resin',
|
||||||
|
image: '/images/condensed_resin.png',
|
||||||
let dateTimeOptions = {
|
label: 'Condensed Resin',
|
||||||
hour: 'numeric',
|
value: 40,
|
||||||
minute: 'numeric',
|
|
||||||
second: 'numeric',
|
|
||||||
weekday: 'long',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$: canCalculate = currentResin !== '' && currentResin >= 0 && currentResin < 160;
|
// 8 minute per resin * 60 seconds * 1000 millisec
|
||||||
|
let minutePerResin = originalResin.value * 60 * 1000;
|
||||||
|
|
||||||
|
$: isCurrentResin = currentResin >= 0 && currentResin < 160 && currentResin !== '';
|
||||||
|
$: isDesiredResin = desiredResin <= 160 && desiredResin >= 1 && desiredResin !== '';
|
||||||
|
$: canCalculate = isCurrentResin || isDesiredResin;
|
||||||
|
|
||||||
|
function calculateCondensedResin(nResin) {
|
||||||
|
if (condensedResin.value % nResin == 0) {
|
||||||
|
return {
|
||||||
|
resin: 0,
|
||||||
|
condensedResin: Math.floor(nResin / condensedResin.value),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
resin: nResin % condensedResin.value,
|
||||||
|
condensedResin: Math.floor(nResin / condensedResin.value),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function calculate() {
|
function calculate() {
|
||||||
missingResin = maxResin - currentResin;
|
missingResin = maxResin - currentResin;
|
||||||
millisecondsToWait = missingResin * minutePerResin;
|
resinOutput =
|
||||||
fullTime = new Date($time.getTime() + millisecondsToWait);
|
resinTypeOutput === 'maxResin'
|
||||||
|
? { resin: missingResin, condensed: calculateCondensedResin(missingResin) }
|
||||||
|
: { resin: desiredResin, condensed: calculateCondensedResin(desiredResin) };
|
||||||
|
millisecondsToWait = resinTypeOutput === 'maxResin' ? missingResin * minutePerResin : desiredResin * minutePerResin;
|
||||||
|
fullTime = dayjs(currentTime.valueOf() + millisecondsToWait);
|
||||||
|
changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange() {
|
function onChange(type) {
|
||||||
changed = true;
|
changed = true;
|
||||||
|
resinTypeOutput = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
currentTime = dayjs().add(0, 'minute');
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval);
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="bg-item rounded-xl p-4">
|
<div class="bg-item rounded-xl p-4">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-1 lg:grid-cols-1 xl:grid-cols-3 gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-1 lg:grid-cols-1 xl:grid-cols-3 gap-4">
|
||||||
<!-- input -->
|
<!-- input -->
|
||||||
<div class="md:col-span-1 xl:col-span-1">
|
<div class="md:col-span-1 xl:col-span-1 space-y-2">
|
||||||
|
<p class="text-center text-white">
|
||||||
|
{$t('calculator.resin.currentResin')}
|
||||||
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2"
|
on:change={() => onChange('maxResin')}
|
||||||
on:change={onChange}
|
|
||||||
type="number"
|
type="number"
|
||||||
min={0}
|
min={0}
|
||||||
max={160}
|
max={160}
|
||||||
bind:value={currentResin}
|
bind:value={currentResin}
|
||||||
placeholder={$t('calculator.resin.inputCurrentResin')}
|
placeholder={$t('calculator.resin.inputCurrentResin')}
|
||||||
/>
|
/>
|
||||||
<p class="text-white text-center mt-3 mb-2">
|
<p class="text-center text-white">{$t('calculator.resin.or')} {$t('calculator.resin.desiredResin')}</p>
|
||||||
{$t('calculator.resin.currentTime')}: {new Intl.DateTimeFormat(
|
<Input
|
||||||
$t('calculator.resin.timeFormat'),
|
on:change={() => onChange('desiredResin')}
|
||||||
dateTimeOptions,
|
type="number"
|
||||||
).format($time)}
|
min={1}
|
||||||
|
max={160}
|
||||||
|
bind:value={desiredResin}
|
||||||
|
placeholder={$t('calculator.resin.inputDesireResin')}
|
||||||
|
/>
|
||||||
|
<p class="text-white text-center">
|
||||||
|
{$t('calculator.resin.currentTime')}:
|
||||||
|
{#if $t('calculator.resin.timeFormat') === 'en'}
|
||||||
|
{currentTime.locale('en').format('dddd HH:mm:ss')}
|
||||||
|
{:else}
|
||||||
|
{currentTime.locale('id').format('dddd HH:mm:ss')}
|
||||||
|
{/if}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="md:col-span-2 xl:col-span-2">
|
<div class="md:col-span-1 xl:col-span-2">
|
||||||
<Button disabled={!canCalculate} className="block w-full md:w-auto" on:click={calculate}
|
<Button disabled={!canCalculate} className="block w-full md:w-auto" on:click={calculate}
|
||||||
>{$t('calculator.resin.calculate')}</Button
|
>{$t('calculator.resin.calculate')}</Button
|
||||||
>
|
>
|
||||||
{#if fullTime}
|
{#if !changed}
|
||||||
<div transition:fade={{ duration: 100 }} class="bg-background rounded-xl p-4 mt-2 block xl:inline-block">
|
<div transition:fade={{ duration: 100 }} class="bg-background rounded-xl p-4 mt-2 block xl:inline-block">
|
||||||
<tr>
|
<table class="w-full">
|
||||||
<td class="text-right border-b border-gray-700 py-1">
|
<tr>
|
||||||
<span class="text-white mr-2 whitespace-no-wrap"
|
<td class="text-right border-b border-gray-700 py-1">
|
||||||
>{missingResin}
|
<span class="text-white mr-2 whitespace-no-wrap"
|
||||||
<Icon size={0.5} path={mdiClose} /></span
|
>{resinOutput.resin}
|
||||||
>
|
<Icon size={0.5} path={mdiClose} /></span
|
||||||
</td>
|
>
|
||||||
<td class="border-b border-gray-700 py-1">
|
</td>
|
||||||
<span class="text-white">
|
<td class="border-b border-gray-700 py-1">
|
||||||
<span class="w-6 inline-block">
|
<span class="text-white">
|
||||||
<img class="h-6 inline-block mr-1" src={originalResin.image} alt={originalResin.label} />
|
<span class="w-6 inline-block">
|
||||||
|
<img class="h-6 inline-block mr-1" src={originalResin.image} alt={originalResin.label} />
|
||||||
|
</span>
|
||||||
|
{originalResin.label}
|
||||||
</span>
|
</span>
|
||||||
{originalResin.label}
|
</td>
|
||||||
</span>
|
</tr>
|
||||||
</td>
|
{#if resinOutput.condensed.condensedResin !== 0}
|
||||||
</tr>
|
<tr><td colspan="2" class="text-white text-center pt-2">{$t('calculator.resin.or')}</td></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td />
|
<td class="text-right border-b border-gray-700 py-1">
|
||||||
<td class="text-red-400 py-1">
|
<span class="text-white mr-2 whitespace-no-wrap"
|
||||||
{$t('calculator.resin.fullTime')}:
|
>{resinOutput.condensed.resin}
|
||||||
<span class="bg-red-400 rounded-lg mt-2 font-bold text-sm text-white p-1">
|
<Icon size={0.5} path={mdiClose} /></span
|
||||||
{new Intl.DateTimeFormat($t('calculator.resin.timeFormat'), dateTimeOptions).format(fullTime)}
|
>
|
||||||
</span></td
|
</td>
|
||||||
>
|
<td class="border-b border-gray-700 py-1">
|
||||||
</tr>
|
<span class="text-white">
|
||||||
|
<span class="w-6 inline-block">
|
||||||
|
<img class="h-6 inline-block mr-1" src={originalResin.image} alt={originalResin.label} />
|
||||||
|
</span>
|
||||||
|
{originalResin.label}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="text-right border-b border-gray-700 py-1">
|
||||||
|
<span class="text-white mr-2 whitespace-no-wrap"
|
||||||
|
>{resinOutput.condensed.condensedResin}
|
||||||
|
<Icon size={0.5} path={mdiClose} /></span
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
<td class="border-b border-gray-700 py-1">
|
||||||
|
<span class="text-white">
|
||||||
|
<span class="w-6 inline-block">
|
||||||
|
<img class="h-6 inline-block mr-1" src={condensedResin.image} alt={condensedResin.label} />
|
||||||
|
</span>
|
||||||
|
{condensedResin.label}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/if}
|
||||||
|
<tr>
|
||||||
|
<td class="text-red-400" colspan="2">
|
||||||
|
{$t('calculator.resin.fullTime')}:
|
||||||
|
{#if $t('calculator.resin.timeFormat') === 'en'}
|
||||||
|
{fullTime.locale('en').format('dddd HH:mm:ss')} ({fullTime.locale('en').fromNow()})
|
||||||
|
{:else}
|
||||||
|
{fullTime.locale('id').format('dddd HH:mm:ss')} ({fullTime.locale('id').fromNow()})
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
73
src/routes/calculator/_resinTable.svelte
Normal file
73
src/routes/calculator/_resinTable.svelte
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<script>
|
||||||
|
import { mdiArrowRight } from '@mdi/js';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import 'dayjs/locale/en';
|
||||||
|
import 'dayjs/locale/id';
|
||||||
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
|
import { t } from 'svelte-i18n';
|
||||||
|
import Icon from '../../components/Icon.svelte';
|
||||||
|
|
||||||
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
|
const step = [0, 15, 30, 45, 60, 75, 90, 105, 120, 145, 160];
|
||||||
|
const stepTime = [];
|
||||||
|
|
||||||
|
let originalResin = {
|
||||||
|
id: 'original_resin',
|
||||||
|
image: '/images/resin.png',
|
||||||
|
label: 'Original Resin',
|
||||||
|
value: 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
function counTimeRelative() {
|
||||||
|
step.map((s) => {
|
||||||
|
const time = originalResin.value * s * 60 * 1000;
|
||||||
|
stepTime.push(new Date().getTime() + time);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const rows = Array.from(Array(step.length - 1).keys());
|
||||||
|
|
||||||
|
counTimeRelative();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="block overflow-x-auto whitespace-no-wrap pb-1">
|
||||||
|
<div class="table w-full">
|
||||||
|
<div class="bg-item rounded-xl p-4 w-full">
|
||||||
|
<table class="w-full">
|
||||||
|
<tr>
|
||||||
|
<th class="px-2 font-display text-gray-400">{$t('calculator.resinTable.quantity')}</th>
|
||||||
|
<th class="px-2 font-display text-gray-400 align-bottom">{$t('calculator.resinTable.time')}</th>
|
||||||
|
</tr>
|
||||||
|
{#each rows as _, i}
|
||||||
|
<tr>
|
||||||
|
<td class="pl-2 text-white text-center"
|
||||||
|
>{step[0]}<Icon className="mb-1 text-gray-400" path={mdiArrowRight} size={0.7} />{step[i + 1]}
|
||||||
|
<img src={originalResin.image} alt={originalResin.label} class="h-6 w-6 inline" /></td
|
||||||
|
>
|
||||||
|
<td class="pr-2 text-white text-center">
|
||||||
|
{#if $t('calculator.resin.timeFormat') === 'en'}
|
||||||
|
{dayjs(new Date(stepTime[i + 1]))
|
||||||
|
.locale('en')
|
||||||
|
.fromNow()}
|
||||||
|
{:else}
|
||||||
|
{dayjs(new Date(stepTime[i + 1]))
|
||||||
|
.locale('id')
|
||||||
|
.fromNow()}
|
||||||
|
{/if}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{/each}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
@apply py-1;
|
||||||
|
@apply border-b;
|
||||||
|
@apply border-gray-700;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -8,16 +8,13 @@
|
||||||
import CharacterCalculator from './_character.svelte';
|
import CharacterCalculator from './_character.svelte';
|
||||||
import LevelUpTable from './_characterTable.svelte';
|
import LevelUpTable from './_characterTable.svelte';
|
||||||
import ResinCalculator from './_resin.svelte';
|
import ResinCalculator from './_resin.svelte';
|
||||||
|
import ResinTable from './_resinTable.svelte';
|
||||||
import Button from '../../components/Button.svelte';
|
import Button from '../../components/Button.svelte';
|
||||||
import Icon from '../../components/Icon.svelte';
|
import Icon from '../../components/Icon.svelte';
|
||||||
import HowToModal from '../../components/CalculatorHowToModal.svelte';
|
import HowToModal from '../../components/CalculatorHowToModal.svelte';
|
||||||
|
|
||||||
const { open: openModal } = getContext('simple-modal');
|
const { open: openModal } = getContext('simple-modal');
|
||||||
|
|
||||||
let weaponCalc;
|
|
||||||
let characterCalc;
|
|
||||||
let resinCalc;
|
|
||||||
|
|
||||||
function openHowTo() {
|
function openHowTo() {
|
||||||
openModal(
|
openModal(
|
||||||
HowToModal,
|
HowToModal,
|
||||||
|
@ -92,7 +89,7 @@
|
||||||
{$t('calculator.goto')}
|
{$t('calculator.goto')}
|
||||||
{$t('calculator.titleWeapon')}
|
{$t('calculator.titleWeapon')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="md:mb-0 md:ml-4 mb-4" on:click={() => findPos('resin')}>
|
<Button className="md:mt-0 md:mr-4 mt-4" on:click={() => findPos('resin')}>
|
||||||
<Icon size={0.8} path={mdiArrowDown} />
|
<Icon size={0.8} path={mdiArrowDown} />
|
||||||
{$t('calculator.goto')}
|
{$t('calculator.goto')}
|
||||||
{$t('calculator.titleResin')}
|
{$t('calculator.titleResin')}
|
||||||
|
@ -120,6 +117,8 @@
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<ResinCalculator />
|
<ResinCalculator />
|
||||||
<div class="mt-8" />
|
<div class="mt-8 space-y-4 grid md:grid-cols-2 md:gap-4 md:space-y-0">
|
||||||
<LevelUpTable />
|
<LevelUpTable />
|
||||||
|
<ResinTable />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { readable } from 'svelte/store';
|
|
||||||
|
|
||||||
export const time = readable(new Date(), function start(set) {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
set(new Date());
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
return function stop() {
|
|
||||||
clearInterval(interval);
|
|
||||||
};
|
|
||||||
});
|
|
BIN
static/images/condensed_resin.png
Normal file
BIN
static/images/condensed_resin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
Loading…
Reference in a new issue