- 清理大量废弃的 barrel 导出文件,移除冗余的中间导出层 - 修复所有相对路径导入错误,统一调整为扁平化模块引用 - 更新多平台 pubspec 版本号与依赖库版本 - 补充后端功能问题管理后台与脚本工具 - 调整部分页面的快捷方式文案适配新功能 - 更新部分翻译覆盖率与API文档
237 lines
8.2 KiB
Dart
237 lines
8.2 KiB
Dart
/// ============================================================
|
|
/// 闲言APP — 了解我们页面(主入口)
|
|
/// 创建时间: 2026-05-29
|
|
/// 更新时间: 2026-06-01
|
|
/// 作用: 展示开发者信息、团队信息、贡献者、官网链接、联系方式、QQ群
|
|
/// 上次更新: 团队信息卡片重新设计+多语言支持;开发者名称中文显示;QQ群非中文显示Telegram
|
|
/// ============================================================
|
|
|
|
import 'dart:ui';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
|
|
import '../../../core/theme/app_theme.dart';
|
|
import '../../../core/theme/app_spacing.dart';
|
|
import '../../../core/theme/app_typography.dart';
|
|
import '../../../core/theme/app_radius.dart';
|
|
import '../../../core/constants/app_constants.dart';
|
|
import '../../../shared/widgets/adaptive/adaptive_back_button.dart';
|
|
import '../../../l10n/translations.dart';
|
|
import 'learn_us_sections.dart';
|
|
|
|
class LearnUsPage extends ConsumerWidget {
|
|
const LearnUsPage({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final ext = AppTheme.ext(context);
|
|
final t = ref.watch(translationsProvider);
|
|
|
|
return CupertinoPageScaffold(
|
|
backgroundColor: ext.bgPrimary,
|
|
navigationBar: CupertinoNavigationBar(
|
|
leading: const AdaptiveBackButton(),
|
|
middle: Text(
|
|
t.about.learnUs,
|
|
style: AppTypography.title3.copyWith(
|
|
color: ext.textPrimary,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
backgroundColor: ext.bgElevated.withValues(alpha: 0.85),
|
|
border: null,
|
|
),
|
|
child: SafeArea(
|
|
child: SingleChildScrollView(
|
|
physics: const BouncingScrollPhysics(),
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppSpacing.md,
|
|
vertical: AppSpacing.sm,
|
|
),
|
|
child: Column(
|
|
children: [
|
|
LearnUsGlassHeader(ext: ext, t: t),
|
|
const SizedBox(height: AppSpacing.md),
|
|
OfficialSiteSection(ext: ext, t: t),
|
|
const SizedBox(height: AppSpacing.md),
|
|
DeveloperSection(ext: ext, t: t),
|
|
const SizedBox(height: AppSpacing.md),
|
|
TeamSection(ext: ext, t: t),
|
|
const SizedBox(height: AppSpacing.md),
|
|
QQGroupSection(ext: ext, t: t),
|
|
const SizedBox(height: AppSpacing.md),
|
|
ContributorsSection(ext: ext, t: t),
|
|
const SizedBox(height: AppSpacing.xl),
|
|
LearnUsFooter(ext: ext, t: t),
|
|
const SizedBox(height: AppSpacing.xxl),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
// ============================================================
|
|
// 液态玻璃头部
|
|
// ============================================================
|
|
|
|
class LearnUsGlassHeader extends StatelessWidget {
|
|
const LearnUsGlassHeader({super.key, required this.ext, required this.t});
|
|
|
|
final AppThemeExtension ext;
|
|
final T t;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return ClipRRect(
|
|
borderRadius: AppRadius.lgBorder,
|
|
child: BackdropFilter(
|
|
filter: ImageFilter.blur(
|
|
sigmaX: 20 * ext.glassBlurMultiplier,
|
|
sigmaY: 20 * ext.glassBlurMultiplier,
|
|
),
|
|
child: Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.all(AppSpacing.lg),
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
colors: [
|
|
ext.accent.withValues(alpha: 0.85),
|
|
ext.accent,
|
|
ext.accentLight.withValues(alpha: 0.65),
|
|
],
|
|
begin: Alignment.topLeft,
|
|
end: Alignment.bottomRight,
|
|
),
|
|
borderRadius: AppRadius.lgBorder,
|
|
border: Border.all(
|
|
color: CupertinoColors.white.withValues(alpha: 0.3),
|
|
width: 0.5,
|
|
),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: ext.accent.withValues(alpha: 0.18),
|
|
blurRadius: 16,
|
|
offset: const Offset(0, 4),
|
|
),
|
|
],
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(3),
|
|
decoration: BoxDecoration(
|
|
borderRadius: AppRadius.mdBorder,
|
|
border: Border.all(
|
|
color: CupertinoColors.white.withValues(alpha: 0.35),
|
|
width: 2,
|
|
),
|
|
),
|
|
child: ClipRRect(
|
|
borderRadius: AppRadius.smBorder,
|
|
child: Image.asset(
|
|
'assets/templates/resized/icon_80x80.png',
|
|
width: 52,
|
|
height: 52,
|
|
fit: BoxFit.cover,
|
|
errorBuilder: (ctx, err, st) => Container(
|
|
width: 52,
|
|
height: 52,
|
|
decoration: BoxDecoration(
|
|
color: CupertinoColors.white.withValues(alpha: 0.15),
|
|
borderRadius: AppRadius.smBorder,
|
|
),
|
|
child: const Center(
|
|
child: Text('💬', style: TextStyle(fontSize: 24)),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: AppSpacing.lg),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
AppConstants.appName,
|
|
style: AppTypography.title2.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
color: CupertinoColors.white,
|
|
),
|
|
),
|
|
const SizedBox(height: AppSpacing.xs),
|
|
Text(
|
|
t.about.learnUsSlogan,
|
|
style: AppTypography.subhead.copyWith(
|
|
color: CupertinoColors.white.withValues(alpha: 0.85),
|
|
),
|
|
),
|
|
const SizedBox(height: AppSpacing.sm),
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppSpacing.sm,
|
|
vertical: AppSpacing.xs,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: CupertinoColors.white.withValues(alpha: 0.18),
|
|
borderRadius: AppRadius.pillBorder,
|
|
),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(
|
|
CupertinoIcons.tag,
|
|
size: 12,
|
|
color: CupertinoColors.white.withValues(alpha: 0.9),
|
|
),
|
|
const SizedBox(width: AppSpacing.xs),
|
|
Text(
|
|
'Version ${AppVersion.version}',
|
|
style: AppTypography.caption2.copyWith(
|
|
color: CupertinoColors.white.withValues(
|
|
alpha: 0.95,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class LearnUsFooter extends StatelessWidget {
|
|
const LearnUsFooter({super.key, required this.ext, required this.t});
|
|
|
|
final AppThemeExtension ext;
|
|
final T t;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Container(width: 40, height: 1, color: ext.textHint),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
|
child: Text(
|
|
t.about.bottomEnd,
|
|
style: AppTypography.caption1.copyWith(color: ext.textHint),
|
|
),
|
|
),
|
|
Container(width: 40, height: 1, color: ext.textHint),
|
|
],
|
|
);
|
|
}
|
|
}
|