mirror of
https://github.com/MewoLab/AquaDX.git
synced 2026-02-13 12:07:27 +08:00
[+] optOutOfLeaderboard
This commit is contained in:
@@ -26,6 +26,8 @@ export interface AquaNetUser {
|
|||||||
ghostCard: Card
|
ghostCard: Card
|
||||||
cards: Card[]
|
cards: Card[]
|
||||||
computedName: string,
|
computedName: string,
|
||||||
|
password: string,
|
||||||
|
optOutOfLeaderboard: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CardSummaryGame {
|
export interface CardSummaryGame {
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ export const EN_REF_SETTINGS = {
|
|||||||
'settings.fields.waccaAlwaysVip.desc': 'Set VIP expiration date to 2077-01-01',
|
'settings.fields.waccaAlwaysVip.desc': 'Set VIP expiration date to 2077-01-01',
|
||||||
'settings.fields.rounding.name': 'Score Rounding',
|
'settings.fields.rounding.name': 'Score Rounding',
|
||||||
'settings.fields.rounding.desc': 'Round the score to one decimal place',
|
'settings.fields.rounding.desc': 'Round the score to one decimal place',
|
||||||
|
'settings.fields.optOutOfLeaderboard.name': 'Opt Out of Leaderboard',
|
||||||
|
'settings.fields.optOutOfLeaderboard.desc': 'You will still be able to see yourself on the leaderboard after logging in',
|
||||||
'settings.mai2.name': 'Player Name',
|
'settings.mai2.name': 'Player Name',
|
||||||
'settings.profile.picture': 'Profile Picture',
|
'settings.profile.picture': 'Profile Picture',
|
||||||
'settings.profile.upload-new': 'Upload New',
|
'settings.profile.upload-new': 'Upload New',
|
||||||
|
|||||||
@@ -148,6 +148,8 @@ const zhSettings: typeof EN_REF_SETTINGS = {
|
|||||||
'settings.fields.waccaAlwaysVip.desc': '将 VIP 到期时间设置为 2077-01-01',
|
'settings.fields.waccaAlwaysVip.desc': '将 VIP 到期时间设置为 2077-01-01',
|
||||||
'settings.fields.rounding.name': '分数舍入',
|
'settings.fields.rounding.name': '分数舍入',
|
||||||
'settings.fields.rounding.desc': '把分数四舍五入到一位小数',
|
'settings.fields.rounding.desc': '把分数四舍五入到一位小数',
|
||||||
|
'settings.fields.optOutOfLeaderboard.name': '不参与排行榜',
|
||||||
|
'settings.fields.optOutOfLeaderboard.desc': '登录之后还是可以在排行榜上看到自己',
|
||||||
'settings.mai2.name': '玩家名字',
|
'settings.mai2.name': '玩家名字',
|
||||||
'settings.profile.picture': '头像',
|
'settings.profile.picture': '头像',
|
||||||
'settings.profile.upload-new': '上传',
|
'settings.profile.upload-new': '上传',
|
||||||
|
|||||||
@@ -28,12 +28,11 @@
|
|||||||
[ 'password', t('settings.profile.password') ],
|
[ 'password', t('settings.profile.password') ],
|
||||||
[ 'profileLocation', t('settings.profile.location') ],
|
[ 'profileLocation', t('settings.profile.location') ],
|
||||||
[ 'profileBio', t('settings.profile.bio') ],
|
[ 'profileBio', t('settings.profile.bio') ],
|
||||||
]
|
] as const
|
||||||
|
|
||||||
// Fetch user data
|
// Fetch user data
|
||||||
const getMe = () => USER.me().then((m) => {
|
const getMe = () => USER.me().then((m) => {
|
||||||
me = m
|
me = m
|
||||||
values = profileFields.map(([field]) => me[field as keyof AquaNetUser])
|
|
||||||
|
|
||||||
CARD.userGames(m.username).then(games => {
|
CARD.userGames(m.username).then(games => {
|
||||||
if (games.chu3 && !tabs.includes('chu3')) {
|
if (games.chu3 && !tabs.includes('chu3')) {
|
||||||
@@ -49,7 +48,6 @@
|
|||||||
}).catch(e => error = e.message)
|
}).catch(e => error = e.message)
|
||||||
getMe()
|
getMe()
|
||||||
|
|
||||||
let values = Array(profileFields.length).fill('')
|
|
||||||
let changed: string[] = []
|
let changed: string[] = []
|
||||||
let pfpField: HTMLInputElement
|
let pfpField: HTMLInputElement
|
||||||
|
|
||||||
@@ -92,7 +90,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if tab === 0}
|
{#if tab === 0 && me}
|
||||||
<!-- Tab 0: Profile settings -->
|
<!-- Tab 0: Profile settings -->
|
||||||
<div out:fade={FADE_OUT} in:fade={FADE_IN} class="fields">
|
<div out:fade={FADE_OUT} in:fade={FADE_IN} class="fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
@@ -118,10 +116,10 @@
|
|||||||
<label for={field}>{name}</label>
|
<label for={field}>{name}</label>
|
||||||
<div>
|
<div>
|
||||||
<input id={field} type="text" use:passwordAction={field === 'password'}
|
<input id={field} type="text" use:passwordAction={field === 'password'}
|
||||||
bind:value={values[i]} on:input={() => changed = [...changed, field]}
|
bind:value={me[field]} on:input={() => changed = [...changed, field]}
|
||||||
placeholder={field === 'password' ? t('settings.profile.unchanged') : t('settings.profile.unset')}/>
|
placeholder={field === 'password' ? t('settings.profile.unchanged') : t('settings.profile.unset')}/>
|
||||||
{#if changed.includes(field) && values[i]}
|
{#if changed.includes(field) && me[field]}
|
||||||
<button transition:slide={{axis: 'x'}} on:click={() => submit(field, values[i])}>
|
<button transition:slide={{axis: 'x'}} on:click={() => submit(field, me[field])}>
|
||||||
{#if submitting === field}
|
{#if submitting === field}
|
||||||
<Icon icon="line-md:loading-twotone-loop" />
|
<Icon icon="line-md:loading-twotone-loop" />
|
||||||
{:else}
|
{:else}
|
||||||
@@ -132,6 +130,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
|
<div class="field m-t">
|
||||||
|
<div class="bool">
|
||||||
|
<input id="optOutOfLeaderboard" type="checkbox" bind:checked={me.optOutOfLeaderboard}
|
||||||
|
on:change={() => submit('optOutOfLeaderboard', me.optOutOfLeaderboard.toString())}/>
|
||||||
|
<label for="optOutOfLeaderboard">
|
||||||
|
<span class="name">{ts(`settings.fields.optOutOfLeaderboard.name`)}</span>
|
||||||
|
<span class="desc">{ts(`settings.fields.optOutOfLeaderboard.desc`)}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else if tabs[tab] === 'chu3'}
|
{:else if tabs[tab] === 'chu3'}
|
||||||
<!-- Userbox settings -->
|
<!-- Userbox settings -->
|
||||||
@@ -155,6 +163,18 @@
|
|||||||
flex-direction: column
|
flex-direction: column
|
||||||
gap: 12px
|
gap: 12px
|
||||||
|
|
||||||
|
.bool
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
gap: 1rem
|
||||||
|
|
||||||
|
label
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
|
||||||
|
.desc
|
||||||
|
opacity: 0.6
|
||||||
|
|
||||||
.field
|
.field
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import icu.samnyan.aqua.sega.allnet.KeychipSession
|
|||||||
import icu.samnyan.aqua.sega.general.dao.CardRepository
|
import icu.samnyan.aqua.sega.general.dao.CardRepository
|
||||||
import icu.samnyan.aqua.sega.general.model.Card
|
import icu.samnyan.aqua.sega.general.model.Card
|
||||||
import jakarta.persistence.*
|
import jakarta.persistence.*
|
||||||
|
import lombok.Builder
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder
|
import org.springframework.security.crypto.password.PasswordEncoder
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
@@ -52,6 +53,7 @@ class AquaNetUser(
|
|||||||
var profileLocation: String? = "",
|
var profileLocation: String? = "",
|
||||||
var profileBio: String? = "",
|
var profileBio: String? = "",
|
||||||
var profilePicture: String? = "",
|
var profilePicture: String? = "",
|
||||||
|
var optOutOfLeaderboard: Boolean = false,
|
||||||
|
|
||||||
// Email confirmation
|
// Email confirmation
|
||||||
var emailConfirmed: Boolean = false,
|
var emailConfirmed: Boolean = false,
|
||||||
@@ -194,4 +196,6 @@ class AquaUserServices(
|
|||||||
// Check if profile bio is valid
|
// Check if profile bio is valid
|
||||||
if (length > 255) 400 - "Profile bio too long (max 255 letters)"
|
if (length > 255) 400 - "Profile bio too long (max 255 letters)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun checkOptOutOfLeaderboard(optOutOfLeaderboard: Str) = optOutOfLeaderboard.toBoolean()
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ abstract class GameApiController<T : IUserData>(name: String, userDataClass: KCl
|
|||||||
// TODO: pagination
|
// TODO: pagination
|
||||||
// Shadow-ban: Do not show banned cards in the ranking except for the user who owns the card
|
// Shadow-ban: Do not show banned cards in the ranking except for the user who owns the card
|
||||||
val players = userDataRepo.findAll().sortedByDescending { it.playerRating }
|
val players = userDataRepo.findAll().sortedByDescending { it.playerRating }
|
||||||
.filter { it.card?.rankingBanned != true || it.card?.aquaUser?.let { it == reqUser } ?: false }
|
.filter { (it.card?.rankingBanned != true && it.card?.aquaUser?.optOutOfLeaderboard != true) || it.card?.aquaUser?.let { it == reqUser } ?: false }
|
||||||
return players.filter { it.card != null }.mapIndexed { i, user ->
|
return players.filter { it.card != null }.mapIndexed { i, user ->
|
||||||
val card = user.card!!
|
val card = user.card!!
|
||||||
val plays = playlogRepo.findByUserCardExtId(card.extId)
|
val plays = playlogRepo.findByUserCardExtId(card.extId)
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE `aquadx`.`aqua_net_user`
|
||||||
|
ADD COLUMN `opt_out_of_leaderboard` bit NOT NULL DEFAULT b'0';
|
||||||
Reference in New Issue
Block a user