Add fishing spot timer
|
@ -8,20 +8,24 @@
|
||||||
let px = 'px-4';
|
let px = 'px-4';
|
||||||
let py = 'py-2';
|
let py = 'py-2';
|
||||||
let textColor = 'white';
|
let textColor = 'white';
|
||||||
let borderColor = 'white';
|
let borderColorHover = 'white';
|
||||||
|
let borderColorFocus = 'white';
|
||||||
|
|
||||||
$: switch (color) {
|
$: switch (color) {
|
||||||
case 'blue':
|
case 'blue':
|
||||||
textColor = 'text-white';
|
textColor = 'text-white';
|
||||||
borderColor = 'border-primary';
|
borderColorHover = 'hover:border-primary';
|
||||||
|
borderColorFocus = 'focus:border-primary';
|
||||||
break;
|
break;
|
||||||
case 'red':
|
case 'red':
|
||||||
textColor = 'text-red-400';
|
textColor = 'text-red-400';
|
||||||
borderColor = 'border-red-400';
|
borderColorHover = 'hover:border-red-400';
|
||||||
|
borderColorFocus = 'focus:border-red-400';
|
||||||
break;
|
break;
|
||||||
case 'green':
|
case 'green':
|
||||||
textColor = 'text-green-400';
|
textColor = 'text-green-400';
|
||||||
borderColor = 'border-green-400';
|
borderColorHover = 'hover:border-green-400';
|
||||||
|
borderColorFocus = 'focus:border-green-400';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +46,7 @@
|
||||||
class="{textColor} border-2 border-white border-opacity-25 {rounded
|
class="{textColor} border-2 border-white border-opacity-25 {rounded
|
||||||
? 'rounded-xl'
|
? 'rounded-xl'
|
||||||
: 'rounded-none'} {px} {py} transition duration-100
|
: 'rounded-none'} {px} {py} transition duration-100
|
||||||
hover:{borderColor} focus:outline-none focus:{borderColor} disabled:opacity-50 disabled:border-gray-600 {className}"
|
{borderColorHover} {borderColorFocus} focus:outline-none disabled:opacity-50 disabled:border-gray-600 {className}"
|
||||||
on:click
|
on:click
|
||||||
>
|
>
|
||||||
<slot />
|
<slot />
|
||||||
|
|
|
@ -196,7 +196,6 @@
|
||||||
const data = await getData();
|
const data = await getData();
|
||||||
remoteSave = data;
|
remoteSave = data;
|
||||||
|
|
||||||
console.log(JSON.stringify(remoteSave));
|
|
||||||
const remoteSize = new Blob([JSON.stringify(remoteSave)]).size / 1000;
|
const remoteSize = new Blob([JSON.stringify(remoteSave)]).size / 1000;
|
||||||
|
|
||||||
const localSave = await getLocalSaveJson();
|
const localSave = await getLocalSaveJson();
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
{
|
{
|
||||||
"cider_lake": {
|
"17668": {
|
||||||
"name": "Cider Lake",
|
"name": "Windrise",
|
||||||
"fish": [
|
"fish": [
|
||||||
|
"medaka",
|
||||||
"aizen_medaka",
|
"aizen_medaka",
|
||||||
"crystalfish",
|
|
||||||
"venomspine_fish",
|
"venomspine_fish",
|
||||||
"rusty_koi",
|
|
||||||
"tea-colored_shirakodai"
|
"tea-colored_shirakodai"
|
||||||
],
|
],
|
||||||
"location": "mondstadt"
|
"location": "mondstadt"
|
||||||
},
|
},
|
||||||
"stormbearer_mountains": {
|
"17669": {
|
||||||
"name": "Stormbearer Mountains",
|
"name": "Stormbearer Mountains",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
|
@ -23,7 +22,17 @@
|
||||||
],
|
],
|
||||||
"location": "mondstadt"
|
"location": "mondstadt"
|
||||||
},
|
},
|
||||||
"stormterrors_lair": {
|
"17670": {
|
||||||
|
"name": "Stormterror's Lair",
|
||||||
|
"fish": [
|
||||||
|
"medaka",
|
||||||
|
"aizen_medaka",
|
||||||
|
"dawncatcher",
|
||||||
|
"tea-colored_shirakodai"
|
||||||
|
],
|
||||||
|
"location": "mondstadt"
|
||||||
|
},
|
||||||
|
"17671": {
|
||||||
"name": "Stormterror's Lair",
|
"name": "Stormterror's Lair",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
|
@ -33,17 +42,31 @@
|
||||||
],
|
],
|
||||||
"location": "mondstadt"
|
"location": "mondstadt"
|
||||||
},
|
},
|
||||||
"windrise": {
|
"17672": {
|
||||||
"name": "Windrise",
|
"name": "Cider Lake",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
"aizen_medaka",
|
"aizen_medaka",
|
||||||
"venomspine_fish",
|
"venomspine_fish",
|
||||||
|
"akai_maou",
|
||||||
|
"tea-colored_shirakodai",
|
||||||
|
"pufferfish",
|
||||||
|
"bitter_pufferfish"
|
||||||
|
],
|
||||||
|
"location": "mondstadt"
|
||||||
|
},
|
||||||
|
"17673": {
|
||||||
|
"name": "Cider Lake",
|
||||||
|
"fish": [
|
||||||
|
"aizen_medaka",
|
||||||
|
"crystalfish",
|
||||||
|
"venomspine_fish",
|
||||||
|
"rusty_koi",
|
||||||
"tea-colored_shirakodai"
|
"tea-colored_shirakodai"
|
||||||
],
|
],
|
||||||
"location": "mondstadt"
|
"location": "mondstadt"
|
||||||
},
|
},
|
||||||
"near_dawn_winery": {
|
"17674": {
|
||||||
"name": "Near Dawn Winery",
|
"name": "Near Dawn Winery",
|
||||||
"fish": [
|
"fish": [
|
||||||
"aizen_medaka",
|
"aizen_medaka",
|
||||||
|
@ -56,7 +79,7 @@
|
||||||
],
|
],
|
||||||
"location": "mondstadt"
|
"location": "mondstadt"
|
||||||
},
|
},
|
||||||
"dragonspine": {
|
"17676": {
|
||||||
"name": "Dragonspine",
|
"name": "Dragonspine",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
|
@ -66,7 +89,7 @@
|
||||||
],
|
],
|
||||||
"location": "mondstadt"
|
"location": "mondstadt"
|
||||||
},
|
},
|
||||||
"qingce_village": {
|
"17675": {
|
||||||
"name": "Qingce Village",
|
"name": "Qingce Village",
|
||||||
"fish": [
|
"fish": [
|
||||||
"sweet-flower_medaka",
|
"sweet-flower_medaka",
|
||||||
|
@ -78,7 +101,7 @@
|
||||||
],
|
],
|
||||||
"location": "liyue"
|
"location": "liyue"
|
||||||
},
|
},
|
||||||
"dihua_marsh": {
|
"17677": {
|
||||||
"name": "Dihua Marsh",
|
"name": "Dihua Marsh",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
|
@ -88,31 +111,16 @@
|
||||||
],
|
],
|
||||||
"location": "liyue"
|
"location": "liyue"
|
||||||
},
|
},
|
||||||
"beside_wangshu_inn": {
|
"17678": {
|
||||||
"name": "Beside Wangshu Inn",
|
"name": "Bishui Plain",
|
||||||
"fish": [
|
"fish": [
|
||||||
"sweet-flower_medaka",
|
"medaka",
|
||||||
"betta",
|
"betta",
|
||||||
"akai_maou",
|
|
||||||
"golden_koi",
|
|
||||||
"rusty_koi",
|
|
||||||
"brown_shirakodai"
|
"brown_shirakodai"
|
||||||
],
|
],
|
||||||
"location": "liyue"
|
"location": "liyue"
|
||||||
},
|
},
|
||||||
"beside_guili_plains": {
|
"17679": {
|
||||||
"name": "Beside Guili Plains",
|
|
||||||
"fish": [
|
|
||||||
"sweet-flower_medaka",
|
|
||||||
"betta",
|
|
||||||
"akai_maou",
|
|
||||||
"golden_koi",
|
|
||||||
"rusty_koi",
|
|
||||||
"brown_shirakodai"
|
|
||||||
],
|
|
||||||
"location": "liyue"
|
|
||||||
},
|
|
||||||
"bishui_plain": {
|
|
||||||
"name": "Bishui Plain",
|
"name": "Bishui Plain",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
|
@ -122,7 +130,18 @@
|
||||||
],
|
],
|
||||||
"location": "liyue"
|
"location": "liyue"
|
||||||
},
|
},
|
||||||
"mt._hulao": {
|
"17680": {
|
||||||
|
"name": "Mt. Aocang",
|
||||||
|
"fish": [
|
||||||
|
"medaka",
|
||||||
|
"sweet-flower_medaka",
|
||||||
|
"dawncatcher",
|
||||||
|
"crystalfish",
|
||||||
|
"abiding_angelfish"
|
||||||
|
],
|
||||||
|
"location": "liyue"
|
||||||
|
},
|
||||||
|
"17681": {
|
||||||
"name": "Mt. Hulao",
|
"name": "Mt. Hulao",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
|
@ -134,7 +153,28 @@
|
||||||
],
|
],
|
||||||
"location": "liyue"
|
"location": "liyue"
|
||||||
},
|
},
|
||||||
"luhua_pool": {
|
"17682": {
|
||||||
|
"name": "Beside Wangshu Inn",
|
||||||
|
"fish": [
|
||||||
|
"sweet-flower_medaka",
|
||||||
|
"betta",
|
||||||
|
"akai_maou",
|
||||||
|
"golden_koi",
|
||||||
|
"rusty_koi",
|
||||||
|
"brown_shirakodai"
|
||||||
|
],
|
||||||
|
"location": "liyue"
|
||||||
|
},
|
||||||
|
"17683": {
|
||||||
|
"name": "Tianqiu Valley",
|
||||||
|
"fish": [
|
||||||
|
"medaka",
|
||||||
|
"crystalfish",
|
||||||
|
"betta"
|
||||||
|
],
|
||||||
|
"location": "liyue"
|
||||||
|
},
|
||||||
|
"17684": {
|
||||||
"name": "Luhua Pool",
|
"name": "Luhua Pool",
|
||||||
"fish": [
|
"fish": [
|
||||||
"sweet-flower_medaka",
|
"sweet-flower_medaka",
|
||||||
|
@ -146,16 +186,19 @@
|
||||||
],
|
],
|
||||||
"location": "liyue"
|
"location": "liyue"
|
||||||
},
|
},
|
||||||
"tianqiu_valley": {
|
"17685": {
|
||||||
"name": "Tianqiu Valley",
|
"name": "Beside Guili Plains",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"sweet-flower_medaka",
|
||||||
"crystalfish",
|
"betta",
|
||||||
"betta"
|
"akai_maou",
|
||||||
|
"golden_koi",
|
||||||
|
"rusty_koi",
|
||||||
|
"brown_shirakodai"
|
||||||
],
|
],
|
||||||
"location": "liyue"
|
"location": "liyue"
|
||||||
},
|
},
|
||||||
"liyue_harbor": {
|
"17686": {
|
||||||
"name": "Liyue Harbor",
|
"name": "Liyue Harbor",
|
||||||
"fish": [
|
"fish": [
|
||||||
"sweet-flower_medaka",
|
"sweet-flower_medaka",
|
||||||
|
@ -166,48 +209,7 @@
|
||||||
],
|
],
|
||||||
"location": "liyue"
|
"location": "liyue"
|
||||||
},
|
},
|
||||||
"mt._aocang": {
|
"17687": {
|
||||||
"name": "Mt. Aocang",
|
|
||||||
"fish": [
|
|
||||||
"medaka",
|
|
||||||
"sweet-flower_medaka",
|
|
||||||
"dawncatcher",
|
|
||||||
"crystalfish",
|
|
||||||
"abiding_angelfish"
|
|
||||||
],
|
|
||||||
"location": "liyue"
|
|
||||||
},
|
|
||||||
"ritou": {
|
|
||||||
"name": "Ritou",
|
|
||||||
"fish": [
|
|
||||||
"glaze_medaka",
|
|
||||||
"lunged_stickleback",
|
|
||||||
"akai_maou",
|
|
||||||
"pufferfish",
|
|
||||||
"bitter_pufferfish"
|
|
||||||
],
|
|
||||||
"location": "inazuma"
|
|
||||||
},
|
|
||||||
"near_amakane_island": {
|
|
||||||
"name": "Near Amakane Island",
|
|
||||||
"fish": [
|
|
||||||
"glaze_medaka",
|
|
||||||
"lunged_stickleback",
|
|
||||||
"purple_shirakodai"
|
|
||||||
],
|
|
||||||
"location": "inazuma"
|
|
||||||
},
|
|
||||||
"nazuchi_beach": {
|
|
||||||
"name": "Nazuchi Beach",
|
|
||||||
"fish": [
|
|
||||||
"medaka",
|
|
||||||
"lunged_stickleback",
|
|
||||||
"purple_shirakodai",
|
|
||||||
"bitter_pufferfish"
|
|
||||||
],
|
|
||||||
"location": "inazuma"
|
|
||||||
},
|
|
||||||
"sangonomiya_shrine": {
|
|
||||||
"name": "Sangonomiya Shrine",
|
"name": "Sangonomiya Shrine",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
|
@ -219,7 +221,7 @@
|
||||||
],
|
],
|
||||||
"location": "inazuma"
|
"location": "inazuma"
|
||||||
},
|
},
|
||||||
"suigetsu_pool": {
|
"17688": {
|
||||||
"name": "Suigetsu Pool",
|
"name": "Suigetsu Pool",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"medaka",
|
||||||
|
@ -231,7 +233,35 @@
|
||||||
],
|
],
|
||||||
"location": "inazuma"
|
"location": "inazuma"
|
||||||
},
|
},
|
||||||
"koseki_village": {
|
"17689": {
|
||||||
|
"name": "Nazuchi Beach",
|
||||||
|
"fish": [
|
||||||
|
"medaka",
|
||||||
|
"lunged_stickleback",
|
||||||
|
"purple_shirakodai",
|
||||||
|
"bitter_pufferfish"
|
||||||
|
],
|
||||||
|
"location": "inazuma"
|
||||||
|
},
|
||||||
|
"17690": {
|
||||||
|
"name": "Tatarasuna",
|
||||||
|
"fish": [
|
||||||
|
"raimei_angelfish"
|
||||||
|
],
|
||||||
|
"location": "inazuma"
|
||||||
|
},
|
||||||
|
"17691": {
|
||||||
|
"name": "Near Koseki Village",
|
||||||
|
"fish": [
|
||||||
|
"medaka",
|
||||||
|
"dawncatcher",
|
||||||
|
"crystalfish",
|
||||||
|
"purple_shirakodai",
|
||||||
|
"pufferfish"
|
||||||
|
],
|
||||||
|
"location": "inazuma"
|
||||||
|
},
|
||||||
|
"17694": {
|
||||||
"name": "Koseki Village",
|
"name": "Koseki Village",
|
||||||
"fish": [
|
"fish": [
|
||||||
"glaze_medaka",
|
"glaze_medaka",
|
||||||
|
@ -243,21 +273,33 @@
|
||||||
],
|
],
|
||||||
"location": "inazuma"
|
"location": "inazuma"
|
||||||
},
|
},
|
||||||
"near_koseki_village": {
|
"17692": {
|
||||||
"name": "Near Koseki Village",
|
"name": "Ritou",
|
||||||
"fish": [
|
"fish": [
|
||||||
"medaka",
|
"glaze_medaka",
|
||||||
"dawncatcher",
|
"lunged_stickleback",
|
||||||
"crystalfish",
|
"akai_maou",
|
||||||
"purple_shirakodai",
|
"pufferfish",
|
||||||
"pufferfish"
|
"bitter_pufferfish"
|
||||||
],
|
],
|
||||||
"location": "inazuma"
|
"location": "inazuma"
|
||||||
},
|
},
|
||||||
"tatarasuna": {
|
"17693": {
|
||||||
"name": "Tatarasuna",
|
"name": "Near Amakane Island",
|
||||||
"fish": [
|
"fish": [
|
||||||
"raimei_angelfish"
|
"glaze_medaka",
|
||||||
|
"lunged_stickleback",
|
||||||
|
"purple_shirakodai"
|
||||||
|
],
|
||||||
|
"location": "inazuma"
|
||||||
|
},
|
||||||
|
"18686": {
|
||||||
|
"name": "Chirai Shrine",
|
||||||
|
"fish": [
|
||||||
|
"medaka",
|
||||||
|
"glaze_medaka",
|
||||||
|
"dawncatcher",
|
||||||
|
"crystalfish"
|
||||||
],
|
],
|
||||||
"location": "inazuma"
|
"location": "inazuma"
|
||||||
}
|
}
|
||||||
|
|
|
@ -761,8 +761,14 @@
|
||||||
},
|
},
|
||||||
"fishing": {
|
"fishing": {
|
||||||
"title": "Fishing Book",
|
"title": "Fishing Book",
|
||||||
|
"subtitle": "Mark the fishing spot as empty when you already fish out all the fish to start the respawn timer",
|
||||||
"mondstadt": "Mondstadt",
|
"mondstadt": "Mondstadt",
|
||||||
"liyue": "Liyue",
|
"liyue": "Liyue",
|
||||||
"inazuma": "Inazuma"
|
"inazuma": "Inazuma",
|
||||||
|
"setEmpty": "Set as empty",
|
||||||
|
"emptyTime": "Time when the spot is empty:",
|
||||||
|
"clear": "Clear",
|
||||||
|
"save": "Save",
|
||||||
|
"cancel": "Cancel"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,6 +9,9 @@
|
||||||
<h1 class="font-display px-4 md:px-8 font-black text-5xl text-white">{$t('settings.changelog')}</h1>
|
<h1 class="font-display px-4 md:px-8 font-black text-5xl text-white">{$t('settings.changelog')}</h1>
|
||||||
<pre
|
<pre
|
||||||
class="text-white px-4 md:px-8">
|
class="text-white px-4 md:px-8">
|
||||||
|
2021/10/15
|
||||||
|
- Add fishing spot timer
|
||||||
|
|
||||||
2021/10/13
|
2021/10/13
|
||||||
- Update weapons
|
- Update weapons
|
||||||
- Update achievements
|
- Update achievements
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<script>
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
|
||||||
|
import { t } from 'svelte-i18n';
|
||||||
|
|
||||||
|
import Button from '../../components/Button.svelte';
|
||||||
|
import Input from '../../components/Input.svelte';
|
||||||
|
|
||||||
|
export let time;
|
||||||
|
export let close;
|
||||||
|
export let clear;
|
||||||
|
export let edit;
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
const updatedTime = dayjs(time);
|
||||||
|
edit(updatedTime);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p class="text-white mb-4">{$t('fishing.emptyTime')}</p>
|
||||||
|
<Input type="datetime-local" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}" bind:value={time} />
|
||||||
|
<div class="flex space-x-2 mt-4">
|
||||||
|
<Button on:click={clear} color="red">{$t('fishing.clear')}</Button>
|
||||||
|
<div class="flex-1" />
|
||||||
|
<Button on:click={save} color="green">{$t('fishing.save')}</Button>
|
||||||
|
<Button on:click={close}>{$t('fishing.cancel')}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -18,22 +18,137 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { locale, t } from 'svelte-i18n';
|
import { locale, t } from 'svelte-i18n';
|
||||||
import { onMount } from 'svelte';
|
import { getContext, onMount } from 'svelte';
|
||||||
|
import { mdiCheck, mdiPencil } from '@mdi/js';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import duration from 'dayjs/plugin/duration';
|
||||||
|
dayjs.extend(duration);
|
||||||
|
|
||||||
|
import Button from '../../components/Button.svelte';
|
||||||
|
import Icon from '../../components/Icon.svelte';
|
||||||
|
import { readSave, updateSave } from '../../stores/saveManager';
|
||||||
|
import { getAccountPrefix } from '../../stores/account';
|
||||||
|
import EditModal from './_editModal.svelte';
|
||||||
|
|
||||||
|
const { open: openModal, close: closeModal } = getContext('simple-modal');
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
export let spots;
|
export let spots;
|
||||||
|
|
||||||
let fishList = data;
|
let fishList = data;
|
||||||
|
let timer = {};
|
||||||
|
let now = dayjs();
|
||||||
|
|
||||||
|
async function setAsEmpty(id) {
|
||||||
|
timer[id] = {
|
||||||
|
time: dayjs(),
|
||||||
|
text: '3d',
|
||||||
|
};
|
||||||
|
|
||||||
|
await save();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setEditing(id) {
|
||||||
|
openModal(
|
||||||
|
EditModal,
|
||||||
|
{
|
||||||
|
time: timer[id].time.format('YYYY-MM-DDTHH:mm'),
|
||||||
|
close: closeModal,
|
||||||
|
edit: (time) => edit(id, time),
|
||||||
|
clear: () => clear(id),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
closeButton: false,
|
||||||
|
styleWindow: { background: '#25294A', width: '500px' },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function clear(id) {
|
||||||
|
delete timer[id];
|
||||||
|
closeModal();
|
||||||
|
await save();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function edit(id, time) {
|
||||||
|
timer[id] = {
|
||||||
|
time,
|
||||||
|
text: '...',
|
||||||
|
};
|
||||||
|
closeModal();
|
||||||
|
await save();
|
||||||
|
}
|
||||||
|
|
||||||
async function changeLocale(locale) {
|
async function changeLocale(locale) {
|
||||||
const _data = await import(`../../data/fishing/${locale}.json`);
|
const _data = await import(`../../data/fishing/${locale}.json`);
|
||||||
fishList = _data.default;
|
fishList = _data.default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDuration(time) {
|
||||||
|
const diff = time.add(3, 'days').diff(now);
|
||||||
|
const duration = dayjs.duration(diff);
|
||||||
|
let format = 'D[d] HH:mm:ss';
|
||||||
|
if (duration.days() === 0) {
|
||||||
|
format = 'HH:mm:ss';
|
||||||
|
}
|
||||||
|
|
||||||
|
return duration.format(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function load() {
|
||||||
|
const prefix = getAccountPrefix();
|
||||||
|
const data = await readSave(`${prefix}fishing`);
|
||||||
|
const timerData = {};
|
||||||
|
if (data !== null) {
|
||||||
|
for (const [id, item] of Object.entries(data)) {
|
||||||
|
timerData[id] = {
|
||||||
|
...item,
|
||||||
|
text: '...',
|
||||||
|
time: dayjs(item.time),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = timerData;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function save() {
|
||||||
|
const prefix = getAccountPrefix();
|
||||||
|
const formattedTimer = {};
|
||||||
|
for (const [id, item] of Object.entries(timer)) {
|
||||||
|
formattedTimer[id] = {
|
||||||
|
...item,
|
||||||
|
time: item.time.toISOString(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
await updateSave(`${prefix}fishing`, formattedTimer);
|
||||||
|
}
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
await load();
|
||||||
|
|
||||||
locale.subscribe((val) => {
|
locale.subscribe((val) => {
|
||||||
changeLocale(val);
|
changeLocale(val);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
now = dayjs();
|
||||||
|
for (const [id, item] of Object.entries(timer)) {
|
||||||
|
if (item.time.add(3, 'days').isBefore(now)) {
|
||||||
|
delete timer[id];
|
||||||
|
save();
|
||||||
|
} else {
|
||||||
|
item.text = getDuration(item.time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = timer;
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval);
|
||||||
|
};
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -44,12 +159,15 @@
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
<div class="lg:ml-64 pt-20 lg:pt-8 max-w-screen-xl">
|
<div class="lg:ml-64 pt-20 lg:pt-8 max-w-screen-xl">
|
||||||
<h1 class="font-display px-4 md:px-8 font-black text-5xl text-white">{$t('fishing.title')}</h1>
|
<h1 class="font-display px-4 md:px-8 font-black text-5xl text-white">{$t('fishing.title')}</h1>
|
||||||
|
<p class="text-gray-400 px-4 md:px-8 font-medium pb-4" style="margin-top: -1rem;">
|
||||||
|
※ {$t('fishing.subtitle')}
|
||||||
|
</p>
|
||||||
{#each Object.entries(spots) as [id, location]}
|
{#each Object.entries(spots) as [id, location]}
|
||||||
<h3 class="font-display px-4 md:px-8 font-black text-2xl text-white mt-4 mb-2">{$t(`fishing.${id}`)}</h3>
|
<h3 class="font-display px-4 md:px-8 font-black text-2xl text-white mt-4 mb-2">{$t(`fishing.${id}`)}</h3>
|
||||||
<div class="px-4 md:px-8 w-full">
|
<div class="px-4 md:px-8 w-full">
|
||||||
{#each location as spot}
|
{#each location as spot}
|
||||||
<div class="flex flex-col items-center md:items-start md:flex-row w-full bg-item rounded-xl p-4 mb-2">
|
<div class="flex flex-col items-center md:items-start md:flex-row w-full bg-item rounded-xl p-4 mb-2">
|
||||||
<div class="mr-4">
|
<div class="mr-4 flex flex-col">
|
||||||
<img
|
<img
|
||||||
class="w-48 h-48 rounded-md"
|
class="w-48 h-48 rounded-md"
|
||||||
style="min-width: 192px;"
|
style="min-width: 192px;"
|
||||||
|
@ -57,6 +175,21 @@
|
||||||
alt={spot.name}
|
alt={spot.name}
|
||||||
title={spot.name}
|
title={spot.name}
|
||||||
/>
|
/>
|
||||||
|
{#if timer[spot.id]}
|
||||||
|
<div class="flex mt-2 items-center">
|
||||||
|
<p class="text-white text-center mr-1 flex-1">
|
||||||
|
{timer[spot.id].text}
|
||||||
|
</p>
|
||||||
|
<Button on:click={() => setEditing(spot.id)} size="sm">
|
||||||
|
<Icon path={mdiPencil} color="white" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<Button on:click={() => setAsEmpty(spot.id)} size="sm" className="mt-2 flex-1">
|
||||||
|
{$t('fishing.setEmpty')}
|
||||||
|
<Icon path={mdiCheck} color="white" />
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap pt-6 md:pt-0 justify-center md:justify-start"
|
class="flex flex-wrap pt-6 md:pt-0 justify-center md:justify-start"
|
||||||
|
|
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 73 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 234 KiB |
Before Width: | Height: | Size: 230 KiB |
Before Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 144 KiB |
Before Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 206 KiB |
Before Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 216 KiB |
Before Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 167 KiB |
Before Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 182 KiB |
Before Width: | Height: | Size: 143 KiB |
Before Width: | Height: | Size: 157 KiB |
Before Width: | Height: | Size: 193 KiB |
Before Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 130 KiB |