feat: import Chinese-localized Buzz source snapshot
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
@@ -0,0 +1,339 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'app_colors.dart';
|
||||
import 'color_scheme.dart';
|
||||
import 'grid.dart';
|
||||
import 'text_theme.dart';
|
||||
|
||||
/// Border radius constants matching desktop shadcn "New York" style.
|
||||
/// Desktop uses --radius: 0.625rem (10px) as base:
|
||||
/// lg = 10px, md = 8px, sm = 6px
|
||||
class Radii {
|
||||
/// Small radius for compact UI elements.
|
||||
static const double xs = 4.0;
|
||||
static const double lg = 10.0;
|
||||
static const double md = 8.0;
|
||||
static const double sm = 6.0;
|
||||
static const double card = 12.0; // grouped settings cards
|
||||
static const double popover = 20.0;
|
||||
static const double dialog = 24.0; // desktop uses rounded-3xl for dialogs
|
||||
|
||||
/// Fully rounds pills, circles, and other capsule shapes.
|
||||
static const double full = 999.0;
|
||||
}
|
||||
|
||||
class AppTheme {
|
||||
static ThemeData light({
|
||||
ColorScheme? colorScheme,
|
||||
Gradient? topSectionGradient,
|
||||
}) {
|
||||
final scheme = colorScheme ?? lightColorScheme;
|
||||
final appColors = AppColors(
|
||||
success: const Color(0xFF40A02B), // Catppuccin Latte Green — universal
|
||||
warning: const Color(0xFFDF8E1D), // Latte Yellow
|
||||
accent: scheme.tertiary,
|
||||
topSectionGradient: topSectionGradient,
|
||||
);
|
||||
|
||||
return _buildTheme(
|
||||
scheme: scheme,
|
||||
appColors: appColors,
|
||||
brightness: Brightness.light,
|
||||
statusBarIconBrightness: Brightness.dark,
|
||||
statusBarBrightness: Brightness.light,
|
||||
);
|
||||
}
|
||||
|
||||
static ThemeData dark({
|
||||
ColorScheme? colorScheme,
|
||||
Gradient? topSectionGradient,
|
||||
}) {
|
||||
final scheme = colorScheme ?? darkColorScheme;
|
||||
final appColors = AppColors(
|
||||
success: const Color(
|
||||
0xFFA6DA95,
|
||||
), // Catppuccin Macchiato Green — universal
|
||||
warning: const Color(0xFFEED49F), // Macchiato Yellow
|
||||
accent: scheme.tertiary,
|
||||
topSectionGradient: topSectionGradient,
|
||||
);
|
||||
|
||||
return _buildTheme(
|
||||
scheme: scheme,
|
||||
appColors: appColors,
|
||||
brightness: Brightness.dark,
|
||||
statusBarIconBrightness: Brightness.light,
|
||||
statusBarBrightness: Brightness.dark,
|
||||
);
|
||||
}
|
||||
|
||||
static ThemeData _buildTheme({
|
||||
required ColorScheme scheme,
|
||||
required AppColors appColors,
|
||||
required Brightness brightness,
|
||||
required Brightness statusBarIconBrightness,
|
||||
required Brightness statusBarBrightness,
|
||||
}) {
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: scheme,
|
||||
splashFactory: NoSplash.splashFactory,
|
||||
scaffoldBackgroundColor: scheme.surface,
|
||||
extensions: [appColors],
|
||||
fontFamily: 'Inter',
|
||||
textTheme: textTheme,
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: scheme.onSurface,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
titleTextStyle: textTheme.titleMedium?.copyWith(
|
||||
color: scheme.onSurface,
|
||||
),
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarIconBrightness: statusBarIconBrightness,
|
||||
statusBarBrightness: statusBarBrightness,
|
||||
),
|
||||
),
|
||||
|
||||
// Bottom navigation: clean style, no indicator pill
|
||||
navigationBarTheme: NavigationBarThemeData(
|
||||
backgroundColor: scheme.surface,
|
||||
elevation: 0,
|
||||
indicatorColor: Colors.transparent,
|
||||
iconTheme: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return IconThemeData(color: scheme.primary, size: 24);
|
||||
}
|
||||
return IconThemeData(color: scheme.onSurfaceVariant, size: 24);
|
||||
}),
|
||||
labelTextStyle: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return textTheme.labelSmall?.copyWith(
|
||||
color: scheme.primary,
|
||||
fontWeight: FontWeight.w600,
|
||||
);
|
||||
}
|
||||
return textTheme.labelSmall?.copyWith(color: scheme.onSurfaceVariant);
|
||||
}),
|
||||
),
|
||||
|
||||
// Buttons: desktop uses rounded-md (8px), h-9 (36px), px-4 (16px)
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: scheme.primary,
|
||||
foregroundColor: scheme.onPrimary,
|
||||
elevation: 0,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
minimumSize: const Size(0, 36),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
),
|
||||
textStyle: textTheme.labelMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
filledButtonTheme: FilledButtonThemeData(
|
||||
style: FilledButton.styleFrom(
|
||||
elevation: 0,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
minimumSize: const Size(0, 36),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
),
|
||||
textStyle: textTheme.labelMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: scheme.surface,
|
||||
foregroundColor: scheme.onSurface,
|
||||
side: BorderSide(color: scheme.outline, width: 1),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
minimumSize: const Size(0, 36),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
),
|
||||
textStyle: textTheme.labelMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: scheme.onSurface,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
minimumSize: const Size(0, 36),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
),
|
||||
textStyle: textTheme.labelMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Cards: desktop uses rounded-lg (10px), flat, no elevation
|
||||
cardTheme: CardThemeData(
|
||||
color: scheme.surfaceContainerHighest,
|
||||
margin: EdgeInsets.zero,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.lg),
|
||||
),
|
||||
),
|
||||
|
||||
// Inputs: desktop uses outlined style, rounded-md (8px), h-9 (36px)
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: false,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
borderSide: BorderSide(color: scheme.outline),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
borderSide: BorderSide(color: scheme.outline),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
borderSide: BorderSide(color: scheme.primary),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
borderSide: BorderSide(color: scheme.error),
|
||||
),
|
||||
focusedErrorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
borderSide: BorderSide(color: scheme.error),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 10,
|
||||
),
|
||||
isDense: true,
|
||||
),
|
||||
|
||||
// Dialogs: desktop uses rounded-3xl (24px), custom overlay
|
||||
dialogTheme: DialogThemeData(
|
||||
backgroundColor: scheme.surface,
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.dialog),
|
||||
side: BorderSide(color: scheme.outline),
|
||||
),
|
||||
titleTextStyle: textTheme.titleLarge?.copyWith(
|
||||
color: scheme.onSurface,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
letterSpacing: -0.3,
|
||||
),
|
||||
contentTextStyle: textTheme.bodyMedium?.copyWith(
|
||||
color: scheme.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
|
||||
progressIndicatorTheme: ProgressIndicatorThemeData(
|
||||
strokeWidth: 2,
|
||||
color: scheme.primary,
|
||||
circularTrackColor: scheme.onSurfaceVariant.withValues(alpha: 0.2),
|
||||
),
|
||||
|
||||
listTileTheme: ListTileThemeData(
|
||||
titleTextStyle: textTheme.titleSmall?.copyWith(color: scheme.onSurface),
|
||||
subtitleTextStyle: textTheme.bodyMedium?.copyWith(
|
||||
color: scheme.secondary,
|
||||
),
|
||||
iconColor: scheme.secondary,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: Grid.twelve),
|
||||
minVerticalPadding: Grid.twelve,
|
||||
horizontalTitleGap: Grid.twelve,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
),
|
||||
),
|
||||
|
||||
// Chips: desktop uses rounded-sm (6px)
|
||||
chipTheme: ChipThemeData(
|
||||
labelStyle: textTheme.bodySmall?.copyWith(color: scheme.secondary),
|
||||
// M3 resolves the chip container via `color` (WidgetStateProperty);
|
||||
// `selectedColor` is the legacy M2 path and is ignored here. Selected
|
||||
// filter chips (Pulse/Search/Activity tabs) use the accent.
|
||||
color: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) return scheme.primary;
|
||||
return scheme.surfaceContainerHighest;
|
||||
}),
|
||||
checkmarkColor: scheme.onPrimary,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(Radii.sm),
|
||||
),
|
||||
side: BorderSide.none,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
labelPadding: EdgeInsets.zero,
|
||||
),
|
||||
|
||||
// Popups/menus share the elevated 20px mobile popover treatment.
|
||||
popupMenuTheme: PopupMenuThemeData(
|
||||
color: scheme.surface.withValues(alpha: 0.98),
|
||||
elevation: 8,
|
||||
shadowColor: scheme.shadow.withValues(alpha: 0.18),
|
||||
surfaceTintColor: Colors.transparent,
|
||||
textStyle: textTheme.labelLarge?.copyWith(color: scheme.onSurface),
|
||||
labelTextStyle: WidgetStatePropertyAll(
|
||||
textTheme.labelLarge?.copyWith(color: scheme.onSurface),
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.popover),
|
||||
side: BorderSide(
|
||||
color: Colors.black.withValues(alpha: 0.04),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Bottom sheet: match dialog radius
|
||||
bottomSheetTheme: BottomSheetThemeData(
|
||||
backgroundColor: scheme.surface,
|
||||
elevation: 0,
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.circular(Radii.dialog),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Tooltips: desktop uses rounded-md, primary bg
|
||||
tooltipTheme: TooltipThemeData(
|
||||
decoration: BoxDecoration(
|
||||
color: scheme.primary,
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
),
|
||||
textStyle: textTheme.bodySmall?.copyWith(
|
||||
color: scheme.onPrimary,
|
||||
fontSize: 12,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
|
||||
),
|
||||
|
||||
dividerTheme: DividerThemeData(
|
||||
color: scheme.outline,
|
||||
thickness: 1,
|
||||
space: 1,
|
||||
),
|
||||
|
||||
// Snackbar
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(Radii.md),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user