claude nmsl

This commit is contained in:
Cookiues committed 2026-05-29 16:36:24 +08:00
1 parent cd6491cdc5
commit 2ad6781049
10 files changed
+119 -35

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
/// Breakpoints: phone < 600, tablet 600–900, desktop > 900
const double _breakpointTablet = 600;
const double _breakpointDesktop = 900;
/// Returns a responsive max width for content containers.
/// - Phone: 500
/// - Tablet: 700
/// - Desktop: 900
double responsiveMaxWidth(BuildContext context) {
final width = MediaQuery.of(context).size.width;
if (width >= _breakpointDesktop) return 900;
if (width >= _breakpointTablet) return 700;
return 500;
}
/// Whether the screen is tablet-sized or wider.
bool isTablet(BuildContext context) =>
MediaQuery.of(context).size.width >= _breakpointTablet;
/// Whether the screen is desktop-sized or wider.
bool isDesktop(BuildContext context) =>
MediaQuery.of(context).size.width >= _breakpointDesktop;
/// Build columns for tablet/desktop — on phone, each item is full-width;
/// on tablet+ they are laid out in [columns] columns.
List<Widget> responsiveGrid({
required BuildContext context,
required List<Widget> children,
int columns = 2,
double spacing = 12,
}) {
final tablet = isTablet(context);
if (!tablet) return children;
final rows = <Widget>[];
final padded = <Widget>[];
for (int i = 0; i < children.length; i++) {
padded.add(children[i]);
if ((i + 1) % columns == 0 || i == children.length - 1) {
final cols = <Widget>[];
for (int j = 0; j < padded.length; j++) {
cols.add(Expanded(child: padded[j]));
}
// pad incomplete last row with empty expanded widgets
while (cols.length < columns) {
cols.add(const Expanded(child: SizedBox.shrink()));
}
rows.add(Padding(
padding: EdgeInsets.only(bottom: rows.isEmpty ? 0 : spacing),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (int j = 0; j < cols.length; j++) ...[
if (j > 0) SizedBox(width: spacing),
cols[j],
],
],
),
));
padded.clear();
}
}
return rows;
}
+14
View File
@@ -11,6 +11,7 @@ class AppStrings {
static const appTitle = 'Project Ichino';
static const loginSubtitle = '扫描或输入二维码进行登录';
static const qrCodeToken = 'QR Code 令牌';
static const qrHint = '粘贴二维码解析内容...';
static const qrParsedResult = '解析结果(截取后 64 位)';
static const uploadQR = '上传二维码';
static const login = '登录';
@@ -123,18 +124,31 @@ class AppStrings {
static const machineSettings = '机器信息';
static const save = '保存';
static const labelTitleServerUrl = 'Title Server URL';
static const hintTitleServerUrl = 'https://maimai-gm.wahlap.com:42081/Maimai2Servlet/';
static const labelAesKey = 'AES Key';
static const hintAesKey = 'your aes key string';
static const labelAesIv = 'AES IV';
static const hintAesIv = 'your aes iv string';
static const labelClientId = 'Client ID';
static const hintClientId = 'A63E01C2805';
static const labelRegionId = 'Region ID';
static const hintRegionId = '1';
static const labelPlaceId = 'Place ID';
static const hintPlaceId = '1403';
static const labelObfuscateParam = 'Obfuscate Param';
static const hintObfuscateParam = 'LatuAa81';
static const labelApiVersion = 'API Version (Mai-Encoding)';
static const hintApiVersion = '1.53';
static const labelRegionName = 'Region 名称';
static const hintRegionName = '北京';
static const labelPlaceName = 'Place 名称';
static const hintPlaceName = 'Place name';
static const labelKeychipId = 'Keychip ID';
static const hintKeychipId = 'ID';
static const labelAimeUrl = 'Aime URL';
static const hintAimeUrl = 'http://ai.sys-allnet.cn/wc_aime/api/get_data';
static const labelAimeSalt = 'Aime Salt';
static const hintAimeSalt = 'API Key 派生用 Salt';
static String fieldRequired(String label) => '$label 不能为空';
// Config Export/Import
+2 -2
View File
@@ -33,7 +33,7 @@ class TitleServerConfig {
this.aimeUrl = '',
this.aimeSalt = '',
String? openGameID,
}) : openGameID = openGameID ?? '';
}) : openGameID = openGameID ?? 'MAID';
List<int> get aesKeyBytes => utf8.encode(aesKey);
List<int> get aesIvBytes => utf8.encode(aesIv);
@@ -70,7 +70,7 @@ class TitleServerConfig {
keychipId: json['keychipId'] as String? ?? '',
aimeUrl: json['aimeUrl'] as String? ?? '',
aimeSalt: json['aimeSalt'] as String? ?? '',
openGameID: json['openGameID'] as String? ?? '',
openGameID: json['openGameID'] as String? ?? 'MAID',
);
}
}