mirror of
https://github.com/MadeBaruna/paimon-moe.git
synced 2024-11-22 23:10:58 +01:00
Add guaranteed icon on wish counter page
This commit is contained in:
parent
affe44be7c
commit
f6e884a177
7 changed files with 195 additions and 20 deletions
|
@ -28,6 +28,7 @@
|
|||
|
||||
<style>
|
||||
.tooltip {
|
||||
@apply text-background rounded-xl bg-gray-400 border border-gray-800 p-2 absolute text-sm;
|
||||
@apply p-2 absolute rounded-xl bg-gray-400 border border-gray-800;
|
||||
@apply text-sm text-background z-10;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -314,6 +314,17 @@ export const banners = {
|
|||
// featured: ['zhongli', 'ganyu'],
|
||||
// featuredRare: ['xingqiu', 'beidou', 'yanfei'],
|
||||
// },
|
||||
{
|
||||
name: 'Everbloom Violet',
|
||||
image: 1,
|
||||
shortName: 'Yae',
|
||||
start: '2022-02-16 06:00:00',
|
||||
end: '2022-03-08 17:59:59',
|
||||
color: '#ffd1f9',
|
||||
featured: ['yae_miko'],
|
||||
featuredRare: ['thoma', 'diona', 'fischl'],
|
||||
timezoneDependent: true,
|
||||
},
|
||||
],
|
||||
weapons: [
|
||||
{
|
||||
|
@ -581,5 +592,16 @@ export const banners = {
|
|||
featured: ['amos_bow', 'vortex_vanquisher'],
|
||||
featuredRare: ['lithic_blade', 'favonius_sword', 'dragons_bane', 'favonius_codex', 'sacrificial_bow'],
|
||||
},
|
||||
{
|
||||
name: 'Epitome Invocation',
|
||||
image: 25,
|
||||
start: '2022-02-16 06:00:00',
|
||||
end: '2022-03-08 17:59:59',
|
||||
shortName: 'Verity',
|
||||
color: '#b042f5',
|
||||
featured: ['kaguras_verity', 'primordial_jade_cutter'],
|
||||
featuredRare: ['wavebreakers_fin', 'sacrificial_sword', 'rainslasher', 'eye_of_perception', 'the_stringless'],
|
||||
timezoneDependent: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -448,6 +448,10 @@
|
|||
"won": "Won 50:50",
|
||||
"lost": "Lost 50:50",
|
||||
"guaranteed": "Guaranteed"
|
||||
},
|
||||
"backupReminder": {
|
||||
"title": "All data are saved on your browser!",
|
||||
"desc": "So if by any chance the browser cache got deleted, your wish history will be gone! You can enable Google Drive sync on setting to backup your data, or download the data manually there."
|
||||
}
|
||||
},
|
||||
"calculator": {
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
let errorProcessingPull = null;
|
||||
|
||||
const bannerType = bannerTypes[id];
|
||||
const withRateIcon = bannerType === 'characters' || bannerType === 'weapons';
|
||||
let bannerChart;
|
||||
let pieChart;
|
||||
|
||||
|
@ -208,16 +209,20 @@
|
|||
};
|
||||
|
||||
if (item.rarity === 5) {
|
||||
newPull.guaranteed = rateUp;
|
||||
rateUp = !currentBanner.featured.includes(newPull.id);
|
||||
newPull.loseRateOff = rateUp;
|
||||
if (withRateIcon) {
|
||||
newPull.guaranteed = rateUp;
|
||||
rateUp = !currentBanner.featured.includes(newPull.id);
|
||||
newPull.loseRateOff = rateUp;
|
||||
}
|
||||
|
||||
selectedBanners[currentBannerIndex].legendary.push(newPull);
|
||||
allLegendary.push(newPull);
|
||||
} else if (item.rarity === 4) {
|
||||
newPull.guaranteed = rateUpRare;
|
||||
rateUpRare = !currentBanner.featuredRare.includes(newPull.id);
|
||||
newPull.loseRateOff = rateUpRare;
|
||||
if (withRateIcon) {
|
||||
newPull.guaranteed = rateUpRare;
|
||||
rateUpRare = !currentBanner.featuredRare.includes(newPull.id);
|
||||
newPull.loseRateOff = rateUpRare;
|
||||
}
|
||||
|
||||
allRare.push(newPull);
|
||||
if (pull.type === 'character') {
|
||||
|
@ -612,7 +617,7 @@
|
|||
<Icon marginBottom={2} size={0.7} path={mdiStar} />
|
||||
</Tooltip>
|
||||
{/if}
|
||||
{:else if pull.rarity > 3}
|
||||
{:else if pull.guaranteed === true && withRateIcon}
|
||||
<Tooltip title={$t('wish.rateon.guaranteed')}>
|
||||
<Icon marginBottom={2} size={0.7} path={mdiStarOutline} className="opacity-50" />
|
||||
</Tooltip>
|
||||
|
|
12
src/routes/wish/_backupReminder.svelte
Normal file
12
src/routes/wish/_backupReminder.svelte
Normal file
|
@ -0,0 +1,12 @@
|
|||
<script>
|
||||
import { t } from 'svelte-i18n';
|
||||
import Button from '../../components/Button.svelte';
|
||||
|
||||
export let close;
|
||||
</script>
|
||||
|
||||
<p class="text-white font-bold text-lg mb-2">{$t('wish.backupReminder.title')}</p>
|
||||
<p class="text-gray-200 mb-4">{$t('wish.backupReminder.desc')}</p>
|
||||
<div class="flex justify-end">
|
||||
<Button on:click={close}>{$t('wish.import.close')}</Button>
|
||||
</div>
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { slide } from 'svelte/transition';
|
||||
import { mdiPencil, mdiStar, mdiChevronDown, mdiTableOfContents } from '@mdi/js';
|
||||
import { mdiPencil, mdiStar, mdiChevronDown, mdiTableOfContents, mdiArrowUpCircle } from '@mdi/js';
|
||||
import debounce from 'lodash/debounce';
|
||||
|
||||
const { open: openModal, close: closeModal } = getContext('simple-modal');
|
||||
|
@ -18,6 +18,7 @@
|
|||
import dayjs from 'dayjs';
|
||||
import { weaponList } from '../../data/weaponList';
|
||||
import { getAccountPrefix } from '../../stores/account';
|
||||
import Tooltip from '../../components/Tooltip.svelte';
|
||||
|
||||
let numberFormat = Intl.NumberFormat();
|
||||
|
||||
|
@ -41,6 +42,11 @@
|
|||
let showRarity = [true, true, false];
|
||||
let sortedPull = [];
|
||||
|
||||
let guaranteed = {
|
||||
legendary: false,
|
||||
rare: false,
|
||||
};
|
||||
|
||||
$: path = `wish-counter-${id}`;
|
||||
$: if ($fromRemote) {
|
||||
readLocalData();
|
||||
|
@ -199,6 +205,11 @@
|
|||
legendary = counterData.legendary;
|
||||
rare = counterData.rare;
|
||||
pulls = counterData.pulls || [];
|
||||
|
||||
if (counterData.guaranteed) {
|
||||
guaranteed.legendary = counterData.guaranteed.legendary;
|
||||
guaranteed.rare = counterData.guaranteed.rare;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,7 +289,6 @@
|
|||
rare = 0;
|
||||
saveData();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="bg-item rounded-xl p-4 inline-flex flex-col w-full" style="height: min-content;">
|
||||
|
@ -310,7 +320,9 @@
|
|||
</span>
|
||||
{#if isEdit}
|
||||
<Input type="number" min={1} bind:value={totalEdit} />
|
||||
{:else}<span class="font-black text-3xl text-white ml-4">{total}</span>{/if}
|
||||
{:else}
|
||||
<span class="font-black text-3xl text-white ml-4">{total}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
class={`${
|
||||
|
@ -326,14 +338,20 @@
|
|||
</div>
|
||||
{/if}
|
||||
<span class="text-gray-200 whitespace-no-wrap flex-1">
|
||||
5
|
||||
<Icon path={mdiStar} size={0.75} className="mb-1" />
|
||||
{$t('wish.pity')}
|
||||
5★ {$t('wish.pity')}
|
||||
<br /><span class="text-gray-600">{$t('wish.guarantee', { values: { pity: legendaryPity } })}</span>
|
||||
</span>
|
||||
{#if isEdit}
|
||||
<Input type="number" min={1} bind:value={legendaryEdit} />
|
||||
{:else}<span class="font-black text-3xl text-legendary-from ml-4">{legendary}</span>{/if}
|
||||
{:else}
|
||||
{#if guaranteed.legendary}
|
||||
<span class="rate-tooltip" style="margin-bottom: 2px; margin-left: 2px;">
|
||||
<Icon size={1} path={mdiArrowUpCircle} className="text-legendary-from" />
|
||||
<span class="tooltip-content legendary">{$t('wish.detail.guaranteed')}</span>
|
||||
</span>
|
||||
{/if}
|
||||
<span class="font-black text-3xl text-legendary-from ml-4">{legendary}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
class={`${
|
||||
|
@ -349,14 +367,20 @@
|
|||
</div>
|
||||
{/if}
|
||||
<span class="text-gray-200 whitespace-no-wrap flex-1">
|
||||
4
|
||||
<Icon path={mdiStar} size={0.75} className="mb-1" />
|
||||
{$t('wish.pity')}
|
||||
4★ {$t('wish.pity')}
|
||||
<br /><span class="text-gray-600">{$t('wish.guarantee', { values: { pity: 10 } })}</span>
|
||||
</span>
|
||||
{#if isEdit}
|
||||
<Input type="number" min={1} bind:value={rareEdit} />
|
||||
{:else}<span class="font-black text-3xl text-rare-from ml-4">{rare}</span>{/if}
|
||||
{:else}
|
||||
{#if guaranteed.rare}
|
||||
<span class="rate-tooltip" style="margin-bottom: 2px; margin-left: 2px;">
|
||||
<Icon size={1} path={mdiArrowUpCircle} className="text-rare-from" />
|
||||
<span class="tooltip-content rare">{$t('wish.detail.guaranteed')}</span>
|
||||
</span>
|
||||
{/if}
|
||||
<span class="font-black text-3xl text-rare-from ml-4">{rare}</span>
|
||||
{/if}
|
||||
</div>
|
||||
{#if isEdit}
|
||||
<Button on:click={saveEdit} className="mt-4">Save</Button>
|
||||
|
@ -491,4 +515,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
.rate-tooltip {
|
||||
@apply relative;
|
||||
|
||||
.tooltip-content {
|
||||
top: 30px;
|
||||
right: 0px;
|
||||
width: 250px;
|
||||
@apply absolute;
|
||||
@apply hidden;
|
||||
@apply text-background;
|
||||
@apply rounded-xl;
|
||||
@apply p-2;
|
||||
@apply text-sm z-20;
|
||||
@apply border-background border-2;
|
||||
|
||||
&.legendary {
|
||||
@apply bg-legendary-from;
|
||||
}
|
||||
&.rare {
|
||||
@apply bg-rare-from;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover .tooltip-content {
|
||||
@apply block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
import Input from '../../components/Input.svelte';
|
||||
import Select from '../../components/Select.svelte';
|
||||
import Icon from '../../components/Icon.svelte';
|
||||
import { server } from '../../stores/server';
|
||||
import { getTimeOffset, server } from '../../stores/server';
|
||||
import ImportFaqModal from './_importFaq.svelte';
|
||||
import BackupReminderModal from './_backupReminder.svelte';
|
||||
import Textarea from '../../components/Textarea.svelte';
|
||||
import { getAccountPrefix } from '../../stores/account';
|
||||
import { getLocalSaveJson, readSave, updateSave } from '../../stores/saveManager';
|
||||
|
@ -32,6 +33,8 @@
|
|||
import { submitWishTally } from '../../functions/wishTally';
|
||||
import Ad from '../../components/Ad.svelte';
|
||||
import Checkbox from '../../components/Checkbox.svelte';
|
||||
import { driveSignedIn } from '../../stores/dataSync';
|
||||
import { banners } from '../../data/banners';
|
||||
|
||||
const numberFormat = Intl.NumberFormat();
|
||||
let fetchController;
|
||||
|
@ -107,6 +110,8 @@
|
|||
|
||||
let error = '';
|
||||
|
||||
let bannerList = [];
|
||||
|
||||
let wishes = {};
|
||||
|
||||
async function downloadBackup() {
|
||||
|
@ -370,6 +375,8 @@
|
|||
manualInput: false,
|
||||
});
|
||||
|
||||
if ($driveSignedIn === false) openBackupReminder();
|
||||
|
||||
pushToast($t('wish.import.success'));
|
||||
goto('/wish');
|
||||
}
|
||||
|
@ -394,6 +401,9 @@
|
|||
|
||||
const combined = [...localWishes, ...importedWishes];
|
||||
|
||||
let latestLegendary = null;
|
||||
let latestRare = null;
|
||||
|
||||
let rare = 0;
|
||||
let legendary = 0;
|
||||
for (let i = 0; i < combined.length; i++) {
|
||||
|
@ -408,10 +418,12 @@
|
|||
}
|
||||
|
||||
if (rarity === 5) {
|
||||
latestLegendary = combined[i];
|
||||
combined[i].pity = legendary;
|
||||
legendary = 0;
|
||||
// rare = 0;
|
||||
} else if (rarity === 4) {
|
||||
latestRare = combined[i];
|
||||
combined[i].pity = rare;
|
||||
rare = 0;
|
||||
} else {
|
||||
|
@ -419,11 +431,37 @@
|
|||
}
|
||||
}
|
||||
|
||||
let rateUpLegendary = false;
|
||||
let rateUpRare = false;
|
||||
if (type.id === 'character-event' || type.id === 'weapon-event') {
|
||||
processBannerList(type.id);
|
||||
|
||||
if (latestLegendary !== null) {
|
||||
const itemBanner = getBannerByTime(latestLegendary.time);
|
||||
console.log(latestLegendary.time, itemBanner);
|
||||
if (itemBanner && itemBanner.featured) {
|
||||
rateUpLegendary = !itemBanner.featured.includes(latestLegendary.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (latestRare !== null) {
|
||||
const itemBanner = getBannerByTime(latestRare.time);
|
||||
console.log(latestRare.time, itemBanner);
|
||||
if (itemBanner && itemBanner.featured) {
|
||||
rateUpRare = !itemBanner.featuredRare.includes(latestRare.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const data = {
|
||||
total: combined.length,
|
||||
legendary,
|
||||
rare,
|
||||
pulls: combined,
|
||||
guaranteed: {
|
||||
legendary: rateUpLegendary,
|
||||
rare: rateUpRare,
|
||||
},
|
||||
};
|
||||
|
||||
await updateSave(`${prefix}${path}`, data);
|
||||
|
@ -600,6 +638,19 @@
|
|||
);
|
||||
}
|
||||
|
||||
function openBackupReminder() {
|
||||
openModal(
|
||||
BackupReminderModal,
|
||||
{
|
||||
close: closeModal,
|
||||
},
|
||||
{
|
||||
closeButton: false,
|
||||
styleWindow: { background: '#25294A', width: '500px' },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
function detectPlatform() {
|
||||
const userAgent = navigator.userAgent || navigator.vendor;
|
||||
if (/android/i.test(userAgent)) {
|
||||
|
@ -628,6 +679,35 @@
|
|||
}, 2000);
|
||||
}
|
||||
|
||||
function processBannerList(bannerType) {
|
||||
const type = bannerType === 'character-event' ? 'characters' : 'weapons';
|
||||
|
||||
bannerList = banners[type].map((e) => {
|
||||
// banner data based on Asia time
|
||||
const diff = e.timezoneDependent === true ? 8 - getTimeOffset() : 0;
|
||||
|
||||
const id = `${e.name} ${e.image}`;
|
||||
const start = dayjs(e.start, 'YYYY-MM-DD HH:mm:ss').subtract(diff, 'hour');
|
||||
const end = dayjs(e.end, 'YYYY-MM-DD HH:mm:ss');
|
||||
|
||||
return {
|
||||
...e,
|
||||
id,
|
||||
start: start.unix(),
|
||||
end: end.unix(),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getBannerByTime(time) {
|
||||
const unixTime = dayjs(time).unix();
|
||||
for (let i = bannerList.length - 1; i >= 0; i--) {
|
||||
if (unixTime >= bannerList[i].start && unixTime < bannerList[i].end) {
|
||||
return bannerList[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue