diff --git a/src/app/coins-rules/coins-rules-screen.tsx b/src/app/coins-rules/coins-rules-screen.tsx
index 1cf60b13..f6708312 100644
--- a/src/app/coins-rules/coins-rules-screen.tsx
+++ b/src/app/coins-rules/coins-rules-screen.tsx
@@ -13,6 +13,10 @@ import { BackButton } from "@/app/_components";
import { MobileShell } from "@/app/_components/core";
import { ROUTES } from "@/router/routes";
+import {
+ FREE_PRIVATE_MESSAGE_LABEL,
+ FREE_STANDARD_CHAT_LABEL,
+} from "./coins-rules.constants";
import styles from "./coins-rules-screen.module.css";
interface CoinRuleItem {
@@ -26,13 +30,13 @@ const COIN_RULES: readonly CoinRuleItem[] = [
{
title: "Standard Chat",
cost: "2 coins / message",
- free: "50 free messages weekly",
+ free: FREE_STANDARD_CHAT_LABEL,
icon: MessageCircle,
},
{
title: "Private Chat",
cost: "10 coins / message",
- free: "1 free message daily",
+ free: FREE_PRIVATE_MESSAGE_LABEL,
icon: Sparkles,
},
{
@@ -92,8 +96,8 @@ export function CoinsRulesScreen() {
Free Allowance
- Standard chat includes 50 free messages weekly. Private chat
- includes 1 free message daily.
+ Standard chat includes {FREE_STANDARD_CHAT_LABEL}. Private chat
+ includes {FREE_PRIVATE_MESSAGE_LABEL}.
diff --git a/src/app/coins-rules/coins-rules.constants.ts b/src/app/coins-rules/coins-rules.constants.ts
new file mode 100644
index 00000000..e05e1e60
--- /dev/null
+++ b/src/app/coins-rules/coins-rules.constants.ts
@@ -0,0 +1,5 @@
+export const FREE_STANDARD_CHAT_DAILY_COUNT = 30;
+export const FREE_PRIVATE_MESSAGE_DAILY_COUNT = 2;
+
+export const FREE_STANDARD_CHAT_LABEL = `${FREE_STANDARD_CHAT_DAILY_COUNT} free messages daily`;
+export const FREE_PRIVATE_MESSAGE_LABEL = `${FREE_PRIVATE_MESSAGE_DAILY_COUNT} free private messages daily`;
diff --git a/src/app/sidebar/components/sidebar-wallet-card.module.css b/src/app/sidebar/components/sidebar-wallet-card.module.css
index c1da3d74..6e1f3342 100644
--- a/src/app/sidebar/components/sidebar-wallet-card.module.css
+++ b/src/app/sidebar/components/sidebar-wallet-card.module.css
@@ -106,6 +106,53 @@
align-items: stretch;
}
+.freeAllowance {
+ display: flex;
+ grid-column: 1 / -1;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--spacing-md, 12px);
+ margin-top: clamp(2px, 0.741vw, 4px);
+ padding: clamp(10px, 2.222vw, 12px) clamp(12px, 2.963vw, 16px);
+ border: 1px solid rgba(246, 87, 160, 0.12);
+ border-radius: var(--responsive-card-radius-sm, 18px);
+ background: rgba(255, 255, 255, 0.72);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.78);
+}
+
+.freeAllowanceTitle {
+ margin: 0;
+ color: #6d5d64;
+ font-size: var(--responsive-caption, 13px);
+ font-weight: 820;
+ line-height: 1.2;
+ white-space: nowrap;
+}
+
+.freeAllowanceItems {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-end;
+ gap: clamp(8px, 1.852vw, 10px);
+}
+
+.freeAllowanceItem {
+ display: inline-flex;
+ align-items: baseline;
+ gap: 3px;
+ color: #51464b;
+ font-size: var(--responsive-caption, 13px);
+ font-weight: 720;
+ line-height: 1.2;
+ white-space: nowrap;
+}
+
+.freeAllowanceItem strong {
+ color: #f657a0;
+ font-size: var(--responsive-body, 16px);
+ font-weight: 900;
+}
+
.activateButton,
.topUpButton {
display: inline-flex;
@@ -186,4 +233,13 @@
.rulesButton {
font-size: var(--responsive-body, 14px);
}
+
+ .freeAllowance {
+ align-items: flex-start;
+ flex-direction: column;
+ }
+
+ .freeAllowanceItems {
+ justify-content: flex-start;
+ }
}
diff --git a/src/app/sidebar/components/sidebar-wallet-card.tsx b/src/app/sidebar/components/sidebar-wallet-card.tsx
index 0c69bb9c..550b35a3 100644
--- a/src/app/sidebar/components/sidebar-wallet-card.tsx
+++ b/src/app/sidebar/components/sidebar-wallet-card.tsx
@@ -2,6 +2,11 @@
import { FaCoins } from "react-icons/fa6";
+import {
+ FREE_PRIVATE_MESSAGE_DAILY_COUNT,
+ FREE_STANDARD_CHAT_DAILY_COUNT,
+} from "@/app/coins-rules/coins-rules.constants";
+
import styles from "./sidebar-wallet-card.module.css";
export interface SidebarWalletCardProps {
@@ -58,6 +63,20 @@ export function SidebarWalletCard({
Top Up
+
+
+
Free Allowance
+
+
+ {FREE_STANDARD_CHAT_DAILY_COUNT}
+ chats / day
+
+
+ {FREE_PRIVATE_MESSAGE_DAILY_COUNT}
+ private / day
+
+
+
);
}
diff --git a/src/app/splash/splash-screen.tsx b/src/app/splash/splash-screen.tsx
index 35fe78e4..5c50debd 100644
--- a/src/app/splash/splash-screen.tsx
+++ b/src/app/splash/splash-screen.tsx
@@ -4,7 +4,6 @@ import { useEffect } from "react";
import { MobileShell } from "@/app/_components/core";
import { useAppNavigator } from "@/router/use-app-navigator";
-import { useAuthState } from "@/stores/auth/auth-context";
import { pwaUtil } from "@/utils";
import {
@@ -15,8 +14,6 @@ import {
} from "./components";
import styles from "./components/splash-screen.module.css";
-const AUTO_OPEN_CHAT_DELAY_MS = 1800;
-
// 尽量早地缓存 beforeinstallprompt,避免用户停留 splash 时浏览器事件已触发并丢失。
if (typeof window !== "undefined") {
pwaUtil.prepareInstallPrompt();
@@ -24,7 +21,6 @@ if (typeof window !== "undefined") {
export function SplashScreen() {
const navigator = useAppNavigator();
- const state = useAuthState();
const handleStartChat = () => {
navigator.openChat({ replace: true });
@@ -34,14 +30,6 @@ export function SplashScreen() {
pwaUtil.prepareInstallPrompt();
}, []);
- useEffect(() => {
- const timer = window.setTimeout(() => {
- navigator.openChat({ replace: true });
- }, AUTO_OPEN_CHAT_DELAY_MS);
-
- return () => window.clearTimeout(timer);
- }, [navigator]);
-
return (