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)
|
@media (max-width: $w-mobile)
|
||||||
margin: 100px 0 0
|
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
|
> h2.outer-title, > .outer-title-options
|
||||||
margin-top: -5rem
|
margin-top: -5rem
|
||||||
margin-bottom: 1rem
|
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
|
rating: number
|
||||||
ratingHighest: number
|
ratingHighest: number
|
||||||
ranks: RankCount[]
|
ranks: RankCount[]
|
||||||
|
detailedRanks: { [key: number]: { [key: string]: number } }
|
||||||
maxCombo: number
|
maxCombo: number
|
||||||
fullCombo: number
|
fullCombo: number
|
||||||
allPerfect: number
|
allPerfect: number
|
||||||
|
|
|
@ -18,6 +18,10 @@ if (navigator.language.startsWith('zh')) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function t(key: keyof LocalizedMessages, variables?: { [index: string]: any }) {
|
export function t(key: keyof LocalizedMessages, variables?: { [index: string]: any }) {
|
||||||
|
if (!msgs[lang][key]) {
|
||||||
|
console.warn(`Missing translation for ${key}`)
|
||||||
|
return key
|
||||||
|
}
|
||||||
if (variables) {
|
if (variables) {
|
||||||
return msgs[lang][key].replace(/\${(.*?)}/g, (_: string, v: string | number) => variables[v] + "")
|
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.UnknownSong': "(unknown song)",
|
||||||
'UserHome.Settings': 'Settings',
|
'UserHome.Settings': 'Settings',
|
||||||
'UserHome.NoValidGame': "The user hasn't played any game yet.",
|
'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 = {
|
export const EN_REF_Welcome = {
|
||||||
|
|
|
@ -22,6 +22,9 @@ const zhUser: typeof EN_REF_USER = {
|
||||||
'UserHome.UnknownSong': "(未知曲目)",
|
'UserHome.UnknownSong': "(未知曲目)",
|
||||||
'UserHome.Settings': '设置',
|
'UserHome.Settings': '设置',
|
||||||
'UserHome.NoValidGame': "用户还没有玩过游戏",
|
'UserHome.NoValidGame': "用户还没有玩过游戏",
|
||||||
|
'UserHome.ShowRanksDetails': "点击显示评分详细",
|
||||||
|
'UserHome.RankDetail.Title': '评分详细',
|
||||||
|
'UserHome.RankDetail.Level': "等级",
|
||||||
}
|
}
|
||||||
|
|
||||||
const zhWelcome: typeof EN_REF_Welcome = {
|
const zhWelcome: typeof EN_REF_Welcome = {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
import StatusOverlays from "../components/StatusOverlays.svelte";
|
import StatusOverlays from "../components/StatusOverlays.svelte";
|
||||||
import Icon from "@iconify/svelte";
|
import Icon from "@iconify/svelte";
|
||||||
import { GAME_TITLE, t } from "../libs/i18n";
|
import { GAME_TITLE, t } from "../libs/i18n";
|
||||||
|
import RankDetails from "../components/RankDetails.svelte";
|
||||||
|
|
||||||
const TREND_DAYS = 60
|
const TREND_DAYS = 60
|
||||||
|
|
||||||
|
@ -40,6 +41,8 @@
|
||||||
validGames: [ string, string ][]
|
validGames: [ string, string ][]
|
||||||
} | null
|
} | null
|
||||||
|
|
||||||
|
let showDetailRank = false
|
||||||
|
|
||||||
USER.isLoggedIn() && USER.me().then(u => me = u)
|
USER.isLoggedIn() && USER.me().then(u => me = u)
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,7 +134,9 @@
|
||||||
</div>
|
</div>
|
||||||
</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}
|
{#each d.user.ranks as r}
|
||||||
<div>
|
<div>
|
||||||
<span>{r.name}</span>
|
<span>{r.name}</span>
|
||||||
|
@ -170,6 +175,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{#if showDetailRank}<RankDetails g={d.user}/>{/if}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2>{t('UserHome.PlayActivity')}</h2>
|
<h2>{t('UserHome.PlayActivity')}</h2>
|
||||||
<div class="activity-info">
|
<div class="activity-info">
|
||||||
|
@ -308,6 +315,9 @@ $gap: 20px
|
||||||
letter-spacing: 0.1em
|
letter-spacing: 0.1em
|
||||||
color: $c-main
|
color: $c-main
|
||||||
|
|
||||||
|
.info-bottom
|
||||||
|
width: max-content
|
||||||
|
|
||||||
.info-top > div > span:last-child
|
.info-top > div > span:last-child
|
||||||
font-size: 1.5rem
|
font-size: 1.5rem
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,8 @@ $c-shadow: rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
$ov-light: rgba(white, 0.04)
|
$ov-light: rgba(white, 0.04)
|
||||||
$ov-lighter: rgba(white, 0.08)
|
$ov-lighter: rgba(white, 0.08)
|
||||||
$ov-dark: rgba(black, 0.04)
|
$ov-dark: rgba(black, 0.1)
|
||||||
$ov-darker: rgba(black, 0.08)
|
$ov-darker: rgba(black, 0.18)
|
||||||
|
|
||||||
$nav-height: 4rem
|
$nav-height: 4rem
|
||||||
$w-mobile: 560px
|
$w-mobile: 560px
|
||||||
|
|
Loading…
Reference in New Issue