Merge pull request #16 from fadhluu/resinCalculator

Add desired resin input field
pull/1/head
Made Baruna 2021-03-21 22:51:16 +08:00 committed by GitHub
commit 49dcb22697
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 254 additions and 70 deletions

View File

@ -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": {

View File

@ -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": {

View File

@ -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>

View 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>

View File

@ -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>

View File

@ -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);
};
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB