diff --git a/AquaNet/src/libs/generalTypes.ts b/AquaNet/src/libs/generalTypes.ts
index 5c6535d4..072a18b7 100644
--- a/AquaNet/src/libs/generalTypes.ts
+++ b/AquaNet/src/libs/generalTypes.ts
@@ -26,6 +26,8 @@ export interface AquaNetUser {
ghostCard: Card
cards: Card[]
computedName: string,
+ password: string,
+ optOutOfLeaderboard: boolean,
}
export interface CardSummaryGame {
diff --git a/AquaNet/src/libs/i18n/en_ref.ts b/AquaNet/src/libs/i18n/en_ref.ts
index bfa6aaee..87539149 100644
--- a/AquaNet/src/libs/i18n/en_ref.ts
+++ b/AquaNet/src/libs/i18n/en_ref.ts
@@ -139,6 +139,8 @@ export const EN_REF_SETTINGS = {
'settings.fields.waccaAlwaysVip.desc': 'Set VIP expiration date to 2077-01-01',
'settings.fields.rounding.name': 'Score Rounding',
'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.profile.picture': 'Profile Picture',
'settings.profile.upload-new': 'Upload New',
diff --git a/AquaNet/src/libs/i18n/zh.ts b/AquaNet/src/libs/i18n/zh.ts
index 0659e249..eb64f6b7 100644
--- a/AquaNet/src/libs/i18n/zh.ts
+++ b/AquaNet/src/libs/i18n/zh.ts
@@ -148,6 +148,8 @@ const zhSettings: typeof EN_REF_SETTINGS = {
'settings.fields.waccaAlwaysVip.desc': '将 VIP 到期时间设置为 2077-01-01',
'settings.fields.rounding.name': '分数舍入',
'settings.fields.rounding.desc': '把分数四舍五入到一位小数',
+ 'settings.fields.optOutOfLeaderboard.name': '不参与排行榜',
+ 'settings.fields.optOutOfLeaderboard.desc': '登录之后还是可以在排行榜上看到自己',
'settings.mai2.name': '玩家名字',
'settings.profile.picture': '头像',
'settings.profile.upload-new': '上传',
diff --git a/AquaNet/src/pages/User/Settings.svelte b/AquaNet/src/pages/User/Settings.svelte
index 0951196f..28800b53 100644
--- a/AquaNet/src/pages/User/Settings.svelte
+++ b/AquaNet/src/pages/User/Settings.svelte
@@ -28,12 +28,11 @@
[ 'password', t('settings.profile.password') ],
[ 'profileLocation', t('settings.profile.location') ],
[ 'profileBio', t('settings.profile.bio') ],
- ]
+ ] as const
// Fetch user data
const getMe = () => USER.me().then((m) => {
me = m
- values = profileFields.map(([field]) => me[field as keyof AquaNetUser])
CARD.userGames(m.username).then(games => {
if (games.chu3 && !tabs.includes('chu3')) {
@@ -49,7 +48,6 @@
}).catch(e => error = e.message)
getMe()
- let values = Array(profileFields.length).fill('')
let changed: string[] = []
let pfpField: HTMLInputElement
@@ -92,7 +90,7 @@
- {#if tab === 0}
+ {#if tab === 0 && me}
{/each}
+
+
+ submit('optOutOfLeaderboard', me.optOutOfLeaderboard.toString())}/>
+
+
+
{:else if tabs[tab] === 'chu3'}
@@ -155,6 +163,18 @@
flex-direction: column
gap: 12px
+ .bool
+ display: flex
+ align-items: center
+ gap: 1rem
+
+ label
+ display: flex
+ flex-direction: column
+
+ .desc
+ opacity: 0.6
+
.field
display: flex
flex-direction: column
diff --git a/src/main/java/icu/samnyan/aqua/net/db/AquaNetUser.kt b/src/main/java/icu/samnyan/aqua/net/db/AquaNetUser.kt
index bd9e4fe4..01319fdd 100644
--- a/src/main/java/icu/samnyan/aqua/net/db/AquaNetUser.kt
+++ b/src/main/java/icu/samnyan/aqua/net/db/AquaNetUser.kt
@@ -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.model.Card
import jakarta.persistence.*
+import lombok.Builder
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.stereotype.Service
@@ -52,6 +53,7 @@ class AquaNetUser(
var profileLocation: String? = "",
var profileBio: String? = "",
var profilePicture: String? = "",
+ var optOutOfLeaderboard: Boolean = false,
// Email confirmation
var emailConfirmed: Boolean = false,
@@ -194,4 +196,6 @@ class AquaUserServices(
// Check if profile bio is valid
if (length > 255) 400 - "Profile bio too long (max 255 letters)"
}
-}
\ No newline at end of file
+
+ fun checkOptOutOfLeaderboard(optOutOfLeaderboard: Str) = optOutOfLeaderboard.toBoolean()
+}
diff --git a/src/main/java/icu/samnyan/aqua/net/games/GameApiController.kt b/src/main/java/icu/samnyan/aqua/net/games/GameApiController.kt
index a5a42339..a325c9ae 100644
--- a/src/main/java/icu/samnyan/aqua/net/games/GameApiController.kt
+++ b/src/main/java/icu/samnyan/aqua/net/games/GameApiController.kt
@@ -50,7 +50,7 @@ abstract class GameApiController(name: String, userDataClass: KCl
// TODO: pagination
// 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 }
- .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 ->
val card = user.card!!
val plays = playlogRepo.findByUserCardExtId(card.extId)
diff --git a/src/main/resources/db/migration/mariadb/V263__opt_out_of_leaderboard.sql b/src/main/resources/db/migration/mariadb/V263__opt_out_of_leaderboard.sql
new file mode 100644
index 00000000..96c4606e
--- /dev/null
+++ b/src/main/resources/db/migration/mariadb/V263__opt_out_of_leaderboard.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `aquadx`.`aqua_net_user`
+ ADD COLUMN `opt_out_of_leaderboard` bit NOT NULL DEFAULT b'0';