feat: 移植 B50 成绩图,并把项目名从 purarine 改回 ichino
海报从 Empurple 的 Best50ImageRenderer/ImageBuilder 移植:按原始像素坐标 (1762x1850 画布、300x100 卡片、5 列、行距 120) 叠加在 base.png 上,底图里 已画好的面板/药丸标签/页脚不重复绘制;页面外壳走 Ichino 的 Material 3。 RatingCalculator 的达成率分档改成单张有序表,避免偏移与评级错位; RA 与评级由 test/rating_calculator_test.dart 的边界用例锁定。 GetUserRatingApi 只需要 userId(Cookie 可选),所以 Preview API 模式、未登录 游戏服务器时也能出图,只是没有 FC/AP/FS 标记。导出用 RepaintBoundary 抓 全尺寸 PNG:原生走 share_plus(不支持文件分享的平台回退为落盘并提示路径), web 走下载。 BEST35 与 BEST15 改为各自独立排版。原先沿用 Empurple 的跨列表全局序号, BEST35 没打满时 BEST15 会整体上移混进上半区。 path_provider 会经 path_provider_android 2.3.x 拖入 jni 插件,而 jni 把 windows/linux 也声明成 ffiPlugin,桌面构建因此去链接 jvm.lib 并失败, 故用 dependency_overrides 钉住 path_provider_android <2.3.0。
This commit is contained in:
1 parent
24ccd628d1
commit
79fa0d7a20
67 files changed
+1563
-62
No files matched your search
@@ -8,6 +8,7 @@ import '../models/user_data.dart';
|
||||
import '../models/user_preview.dart';
|
||||
import '../services/title_api_service.dart';
|
||||
import 'about_page.dart';
|
||||
import 'best50_page.dart';
|
||||
import 'high_risk_feature_page.dart';
|
||||
import 'settings_page.dart';
|
||||
import 'ticket_page.dart';
|
||||
@@ -42,6 +43,7 @@ class _HomePageState extends State<HomePage> {
|
||||
static const _tabTitles = [
|
||||
AppStrings.tabHome,
|
||||
AppStrings.tabTickets,
|
||||
AppStrings.tabBest50,
|
||||
AppStrings.tabRisk,
|
||||
AppStrings.tabSettings,
|
||||
AppStrings.tabAbout,
|
||||
@@ -218,6 +220,13 @@ class _HomePageState extends State<HomePage> {
|
||||
playerRating: _userData?.playerRating ?? _preview?.playerRating ?? 0,
|
||||
onLogoutRequested: _session.gameLogin != null ? _logoutSession : null,
|
||||
),
|
||||
Best50Page(
|
||||
userId: widget.userId,
|
||||
cookies: _session.cookies,
|
||||
userName: _userData?.userName ?? _preview?.userName ?? '',
|
||||
iconId: _userData?.iconId ?? _preview?.iconId ?? 0,
|
||||
playerRating: _userData?.playerRating ?? _preview?.playerRating ?? 0,
|
||||
),
|
||||
HighRiskFeaturePage(
|
||||
userId: widget.userId,
|
||||
cookies: _session.cookies,
|
||||
@@ -237,6 +246,7 @@ class _HomePageState extends State<HomePage> {
|
||||
destinations: const [
|
||||
NavigationDestination(icon: Icon(Icons.home_outlined), selectedIcon: Icon(Icons.home), label: AppStrings.tabHome),
|
||||
NavigationDestination(icon: Icon(Icons.confirmation_number_outlined), selectedIcon: Icon(Icons.confirmation_number), label: AppStrings.tabTickets),
|
||||
NavigationDestination(icon: Icon(Icons.bar_chart_outlined), selectedIcon: Icon(Icons.bar_chart), label: AppStrings.tabBest50),
|
||||
NavigationDestination(icon: Icon(Icons.warning_outlined), selectedIcon: Icon(Icons.inventory_2), label: AppStrings.tabRisk),
|
||||
NavigationDestination(icon: Icon(Icons.settings_outlined), selectedIcon: Icon(Icons.settings), label: AppStrings.tabSettings),
|
||||
NavigationDestination(icon: Icon(Icons.info_outlined), selectedIcon: Icon(Icons.info), label: AppStrings.tabAbout),
|
||||
@@ -272,7 +282,7 @@ class _HomePageState extends State<HomePage> {
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
FilledButton.icon(
|
||||
onPressed: () => setState(() => _currentTab = 3),
|
||||
onPressed: () => setState(() => _currentTab = 4),
|
||||
icon: const Icon(Icons.settings, size: 20),
|
||||
label: const Text(AppStrings.openSettings),
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user