[+] Display rating details

pull/23/head
Azalea 2024-03-15 01:10:15 -04:00
parent e85533686e
commit d9a332de44
8 changed files with 96 additions and 3 deletions

View File

@ -176,6 +176,14 @@ input.error
@media (max-width: $w-mobile)
margin: 100px 0 0
.fw-block
margin-left: -32px
margin-right: -32px
padding: 12px 32px
background-color: $ov-darker
// Inner shadow
box-shadow: inset 0 10px 10px -2px $c-shadow, inset 0 -10px 10px -2px $c-shadow
> h2.outer-title, > .outer-title-options
margin-top: -5rem
margin-bottom: 1rem

View File

@ -0,0 +1,64 @@
<!-- Svelte 4.2.11 -->
<script lang="ts">
import { slide } from "svelte/transition";
import { t } from "../libs/i18n";
import type { GenericGameSummary } from "../libs/generalTypes";
export let g: GenericGameSummary
const detail = Object.entries(g.detailedRanks).toSorted((a, b) => +b[0] - +a[0])
</script>
<div class="rank-detail-container fw-block" transition:slide>
<div>
<h2>{t("UserHome.RankDetail.Title")}</h2>
<table>
<!-- rankDetails: { Level : { Rank : Count } } -->
<!-- Rows are levels, columns are ranks -->
<!-- Headers -->
<tr>
<th>{t("UserHome.RankDetail.Level")}</th>
{#each Object.values(g.ranks) as rankMap}<th>{rankMap.name}</th>{/each}
</tr>
<!-- Data -->
{#each detail as [level, rankMap]}
<tr>
<td>{level}</td>
{#each Object.values(rankMap) as count}<td>{count}</td>{/each}
</tr>
{/each}
</table>
</div>
</div>
<style lang="sass">
@import "../vars"
.rank-detail-container
> div
margin: 1em auto
max-width: 500px
table
width: 100%
border-collapse: collapse
table-layout: fixed
th:not(:first-child)
background: $grad-special
-webkit-background-clip: text
-webkit-text-fill-color: transparent
background-clip: text
color: $c-main
padding: 0.5em
th, td
padding: 0.5em
text-align: center
&:first-child
color: $c-main
</style>

View File

@ -86,6 +86,7 @@ export interface GenericGameSummary {
rating: number
ratingHighest: number
ranks: RankCount[]
detailedRanks: { [key: number]: { [key: string]: number } }
maxCombo: number
fullCombo: number
allPerfect: number

View File

@ -18,6 +18,10 @@ if (navigator.language.startsWith('zh')) {
}
export function t(key: keyof LocalizedMessages, variables?: { [index: string]: any }) {
if (!msgs[lang][key]) {
console.warn(`Missing translation for ${key}`)
return key
}
if (variables) {
return msgs[lang][key].replace(/\${(.*?)}/g, (_: string, v: string | number) => variables[v] + "")
}

View File

@ -20,6 +20,9 @@ export const EN_REF_USER = {
'UserHome.UnknownSong': "(unknown song)",
'UserHome.Settings': 'Settings',
'UserHome.NoValidGame': "The user hasn't played any game yet.",
'UserHome.ShowRanksDetails': "Click to show details",
'UserHome.RankDetail.Title': 'Achievement Details',
'UserHome.RankDetail.Level': "Level",
}
export const EN_REF_Welcome = {

View File

@ -22,6 +22,9 @@ const zhUser: typeof EN_REF_USER = {
'UserHome.UnknownSong': "(未知曲目)",
'UserHome.Settings': '设置',
'UserHome.NoValidGame': "用户还没有玩过游戏",
'UserHome.ShowRanksDetails': "点击显示评分详细",
'UserHome.RankDetail.Title': '评分详细',
'UserHome.RankDetail.Level': "等级",
}
const zhWelcome: typeof EN_REF_Welcome = {

View File

@ -17,6 +17,7 @@
import StatusOverlays from "../components/StatusOverlays.svelte";
import Icon from "@iconify/svelte";
import { GAME_TITLE, t } from "../libs/i18n";
import RankDetails from "../components/RankDetails.svelte";
const TREND_DAYS = 60
@ -40,6 +41,8 @@
validGames: [ string, string ][]
} | null
let showDetailRank = false
USER.isLoggedIn() && USER.me().then(u => me = u)
@ -131,7 +134,9 @@
</div>
</div>
<div class="info-bottom">
<div class="info-bottom clickable" use:tooltip={t("UserHome.ShowRanksDetails")}
on:click={() => showDetailRank = !showDetailRank} role="button" tabindex="0"
on:keydown={e => e.key === "Enter" && (showDetailRank = !showDetailRank)}>
{#each d.user.ranks as r}
<div>
<span>{r.name}</span>
@ -170,6 +175,8 @@
</div>
</div>
{#if showDetailRank}<RankDetails g={d.user}/>{/if}
<div>
<h2>{t('UserHome.PlayActivity')}</h2>
<div class="activity-info">
@ -308,6 +315,9 @@ $gap: 20px
letter-spacing: 0.1em
color: $c-main
.info-bottom
width: max-content
.info-top > div > span:last-child
font-size: 1.5rem

View File

@ -8,8 +8,8 @@ $c-shadow: rgba(0, 0, 0, 0.1)
$ov-light: rgba(white, 0.04)
$ov-lighter: rgba(white, 0.08)
$ov-dark: rgba(black, 0.04)
$ov-darker: rgba(black, 0.08)
$ov-dark: rgba(black, 0.1)
$ov-darker: rgba(black, 0.18)
$nav-height: 4rem
$w-mobile: 560px