mirror of
https://github.com/MewoLab/AquaDX.git
synced 2026-09-30 18:58:04 +03:00
feat: improved announcement management, custom qr access code handler, fixes
This commit is contained in:
@@ -7,4 +7,10 @@ VITE_TURNSTILE_SITE_KEY=0x4AAAAAAASGA2KQEIelo9P9
|
||||
VITE_DISCORD_INVITE=https://discord.gg/FNgveqFF7s
|
||||
VITE_TELEGRAM_INVITE=https://t.me/+zBL4RZdyfvUzZGU1
|
||||
VITE_QQ_INVITE=https://qm.qq.com/q/dpYmGoVHnG
|
||||
VITE_GITHUB_REPOSITORY=https://github.com/MewoLab/AquaDX
|
||||
VITE_GITHUB_REPOSITORY=https://github.com/MewoLab/AquaDX
|
||||
|
||||
# example:
|
||||
# https://aquadx.net/#accesskey=....
|
||||
VITE_ACCESSCODE_QKEY=accesskey
|
||||
|
||||
VITE_DEFAULT_GAME=mai2
|
||||
+3
-1
@@ -35,4 +35,6 @@ dist-ssr
|
||||
public/chu3
|
||||
|
||||
# local env file
|
||||
*.local
|
||||
*.local
|
||||
|
||||
.env
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
import Settings from "./pages/User/Settings.svelte";
|
||||
import MaiPhoto from "./pages/MaiPhoto.svelte";
|
||||
import { pfp, tooltip } from "./libs/ui"
|
||||
import { ANNOUNCEMENT } from "./libs/config";
|
||||
import { ANNOUNCEMENT } from "./libs/announcement";
|
||||
import { DEFAULT_GAME } from "./libs/config"
|
||||
import { t } from "./libs/i18n";
|
||||
import Transfer from "./pages/Transfer/Transfer.svelte";
|
||||
import { link } from "d3";
|
||||
@@ -34,7 +35,7 @@
|
||||
let me: AquaNetUser
|
||||
let playedMai = false
|
||||
|
||||
let recentGame: string = "mai2";
|
||||
let recentGame: string = DEFAULT_GAME;
|
||||
|
||||
if (USER.isLoggedIn())
|
||||
{
|
||||
@@ -60,9 +61,9 @@
|
||||
<span>AquaNet</span>
|
||||
</a>
|
||||
{/if}
|
||||
{#if ANNOUNCEMENT}
|
||||
{#if $ANNOUNCEMENT}
|
||||
<div class="announcement">
|
||||
<strong>{t('navigation.notice')}</strong>: {ANNOUNCEMENT}
|
||||
<strong>{t('navigation.notice')}</strong>: {$ANNOUNCEMENT}
|
||||
</div>
|
||||
{/if}
|
||||
<a href="/home">{t('navigation.home').toLowerCase()}</a>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// card handler. for dealing user QR scan.
|
||||
// this will assumes that the link of the generated QR code in [access code]
|
||||
// page has been altered by modder to link to custom
|
||||
|
||||
import { ACCESSCODE_QKEY } from "./config";
|
||||
|
||||
const query = new URLSearchParams(location.hash.slice(1));
|
||||
const lsKey = "acurl"
|
||||
|
||||
export const url_has = (): boolean => query.has(ACCESSCODE_QKEY);
|
||||
export const get = (): string => localStorage.getItem(lsKey) || "";
|
||||
export const has = (): boolean => !!localStorage.getItem(lsKey);
|
||||
export const clear = (): void => localStorage.removeItem(lsKey);
|
||||
|
||||
export function check() {
|
||||
if (!url_has()) return
|
||||
|
||||
console.log("Found access code in URL. Saving.")
|
||||
localStorage.setItem(lsKey, query.get(ACCESSCODE_QKEY) || "")
|
||||
}
|
||||
|
||||
export function preview() {
|
||||
const card = get()
|
||||
const masked =
|
||||
card.slice(0, 4) +
|
||||
"x".repeat(card.length - 4);
|
||||
|
||||
return masked.match(/.{1,4}/g)?.join(" ");
|
||||
}
|
||||
|
||||
export function previewR() {
|
||||
const card = get()
|
||||
|
||||
return card.match(/.{1,4}/g)?.join(" ");
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { writable } from "svelte/store"
|
||||
|
||||
export const ANNOUNCEMENT = writable('')
|
||||
|
||||
// This task must not bother the existing one. Keep it async in the background instead
|
||||
void (async () => {
|
||||
let r = await fetch("/announcement.txt")
|
||||
if (!r.ok) return;
|
||||
|
||||
ANNOUNCEMENT.set(await r.text())
|
||||
})()
|
||||
@@ -17,7 +17,8 @@ export const FADE_OUT = { duration: 200 }
|
||||
export const FADE_IN = { delay: 400 }
|
||||
export const DEFAULT_PFP = '/assets/imgs/no_profile.png'
|
||||
|
||||
export const ANNOUNCEMENT = '' // If set, will add an announcement to the top bar. Keep it short.
|
||||
// Key name for access key scanned from QR code
|
||||
export const ACCESSCODE_QKEY = import.meta.env.VITE_ACCESSCODE_QKEY || "accesskey"
|
||||
|
||||
// Documentation for Userbox mode can be found in `docs/aquabox-url-mode.md`
|
||||
// Please note that if this is set, it must be manually unset by users in Chuni Settings -> Update Userbox -> Switch to URL mode -> (empty value) -> Enter key
|
||||
@@ -25,6 +26,8 @@ export const USERBOX_DEFAULT_URL = ""
|
||||
|
||||
export const HAS_USERBOX_ASSETS = true
|
||||
|
||||
export const DEFAULT_GAME = import.meta.env.VITE_DEFAULT_GAME || "mai2"
|
||||
|
||||
// Meow meow meow
|
||||
|
||||
// Matching servers
|
||||
@@ -45,4 +48,4 @@ export const CHU3_MATCHINGS: ChusanMatchingOption[] = [
|
||||
reflector: "http://reflector.naominet.live:18080/",
|
||||
coop: ["RinNET", "MysteriaNET"],
|
||||
},
|
||||
]
|
||||
]
|
||||
@@ -60,6 +60,7 @@ export const EN_REF_Welcome = {
|
||||
'welcome.verified': 'Your email has been verified! You can now log in now.',
|
||||
'welcome.verification-failed': 'Verification failed: ${message}. Please try again.',
|
||||
'welcome.password-reset-done': 'Your password has been updated! Please log back in.',
|
||||
'welcome.login_link': 'Login / register to link your card.'
|
||||
}
|
||||
|
||||
export const EN_REF_LEADERBOARD = {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { t } from "../libs/i18n";
|
||||
import ImportDataAction from "./Home/ImportDataAction.svelte";
|
||||
import DashboardTabs from "../components/DashboardTabs.svelte";
|
||||
import * as acUrl from "../libs/acUrl";
|
||||
|
||||
USER.ensureLoggedIn();
|
||||
|
||||
@@ -13,6 +14,10 @@
|
||||
let error = "";
|
||||
|
||||
USER.me().then((m) => me = m).catch(e => error = e.message)
|
||||
|
||||
if (acUrl.has()) {
|
||||
location.href = "/cards"
|
||||
}
|
||||
</script>
|
||||
|
||||
<main class="content">
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
import StatusOverlays from "../../components/StatusOverlays.svelte"
|
||||
import { t } from "../../libs/i18n"
|
||||
import DashboardTabs from "../../components/DashboardTabs.svelte";
|
||||
import * as acUrl from "../../libs/acUrl"
|
||||
import { ACCESSCODE_QKEY } from "../../libs/config";
|
||||
|
||||
// State
|
||||
let state: 'ready' | 'linking-AC' | 'linking-SN' | 'loading' = "loading"
|
||||
@@ -27,7 +29,10 @@
|
||||
// Always put the ghost card at the top
|
||||
m.cards.sort((a, b) => a.isGhost ? -1 : 1)
|
||||
state = "ready"
|
||||
|
||||
linkQR()
|
||||
}).catch(e => error = e.message)
|
||||
acUrl.check()
|
||||
updateMe()
|
||||
|
||||
// Data conflict overlay
|
||||
@@ -273,6 +278,16 @@
|
||||
};
|
||||
inputACChange();
|
||||
}
|
||||
|
||||
function linkQR() {
|
||||
if (!acUrl.has()) return;
|
||||
|
||||
inputAC = acUrl.get()
|
||||
if (inputAC.length !== 20) return inputAC = "";
|
||||
|
||||
inputACChange()
|
||||
acUrl.clear()
|
||||
}
|
||||
</script>
|
||||
|
||||
<main class="content">
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
import UserCard from "../components/UserCard.svelte";
|
||||
import Tooltip from "../components/Tooltip.svelte";
|
||||
import Cap from "./Ranking/Cap.svelte";
|
||||
import { DEFAULT_GAME } from "../libs/config";
|
||||
|
||||
export let game: GameName = 'mai2';
|
||||
export let game: GameName = DEFAULT_GAME;
|
||||
|
||||
title(`Ranking`);
|
||||
|
||||
|
||||
@@ -6,6 +6,14 @@
|
||||
import { USER } from "../libs/sdk";
|
||||
import { t } from "../libs/i18n"
|
||||
|
||||
import * as acUrl from "../libs/acUrl"
|
||||
const hasAc = acUrl.has()
|
||||
let previewAc = ""
|
||||
|
||||
if (hasAc) {
|
||||
previewAc = acUrl.preview() || ""
|
||||
}
|
||||
|
||||
let params = new URLSearchParams(window.location.search)
|
||||
|
||||
let state = "home"
|
||||
@@ -178,6 +186,13 @@
|
||||
<main id="home" class="no-margin">
|
||||
<div>
|
||||
<h1 id="title">AquaNet</h1>
|
||||
<div id="welcome">
|
||||
{#if hasAc}
|
||||
<span>{t('welcome.login_link')}:</span><br>
|
||||
<small>{previewAc}</small>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if state === "home"}
|
||||
<div class="btn-group" transition:slide>
|
||||
<button on:click={() => state = 'login'}>{t('welcome.btn-login')}</button>
|
||||
@@ -329,6 +344,9 @@
|
||||
margin-bottom: 32px
|
||||
opacity: 0.9
|
||||
|
||||
#welcome
|
||||
margin-bottom: 32px
|
||||
|
||||
.btn-group
|
||||
display: flex
|
||||
gap: 8px
|
||||
|
||||
Reference in New Issue
Block a user