mirror of https://github.com/hykilpikonna/AquaDX
[+] Display rating details
parent
e85533686e
commit
d9a332de44
|
@ -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
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -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] + "")
|
||||
}
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue