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

Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
2026-08-13 18:34:25 +08:00
parent 61c3fa1df9
commit 9dfa06ffee
3785 changed files with 1085458 additions and 2 deletions
@@ -0,0 +1,41 @@
part of '../pairing_page.dart';
class _OnboardingBackground extends StatelessWidget {
final Widget child;
const _OnboardingBackground({required this.child});
@override
Widget build(BuildContext context) {
return DecoratedBox(
key: const Key('pairing-onboarding-background'),
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [_onboardingChartreuse, _onboardingShellBottom],
),
),
child: CustomPaint(painter: const _DotGridPainter(), child: child),
);
}
}
class _DotGridPainter extends CustomPainter {
const _DotGridPainter();
@override
void paint(Canvas canvas, Size size) {
final dotPaint = Paint()..color = _onboardingInk.withValues(alpha: 0.08);
const spacing = 24.0;
for (var x = 0.0; x <= size.width; x += spacing) {
for (var y = 0.0; y <= size.height; y += spacing) {
canvas.drawCircle(Offset(x, y), 1, dotPaint);
}
}
}
@override
bool shouldRepaint(_DotGridPainter oldDelegate) => false;
}
@@ -0,0 +1,261 @@
part of '../pairing_page.dart';
class _PairingWelcomeView extends StatelessWidget {
final TextEditingController codeController;
final bool isBusy;
final bool pairingCodeExpanded;
final String? errorMessage;
final VoidCallback onScan;
final VoidCallback onTogglePairingCode;
final VoidCallback onConnect;
const _PairingWelcomeView({
required this.codeController,
required this.isBusy,
required this.pairingCodeExpanded,
required this.errorMessage,
required this.onScan,
required this.onTogglePairingCode,
required this.onConnect,
});
@override
Widget build(BuildContext context) {
final reducedMotion = MediaQuery.disableAnimationsOf(context);
final revealDuration = reducedMotion
? Duration.zero
: const Duration(milliseconds: 220);
return LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(
Grid.gutter,
Grid.sm,
Grid.gutter,
Grid.sm,
),
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: constraints.maxHeight - (Grid.sm * 2),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 136,
height: 136,
alignment: Alignment.center,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Color(0x4DFFFFFF),
),
child: const TappableFlappingBee(
width: 76,
color: _onboardingInk,
),
),
const SizedBox(height: Grid.sm),
Text(
context.l10n.pairingWelcome,
textAlign: TextAlign.center,
style: context.textTheme.headlineSmall?.copyWith(
color: _onboardingInk,
fontWeight: FontWeight.w600,
letterSpacing: -0.4,
),
),
const SizedBox(height: Grid.xxs),
Text(
context.l10n.pairingDescription,
textAlign: TextAlign.center,
style: context.textTheme.bodyMedium?.copyWith(
color: _onboardingMutedInk,
),
),
const SizedBox(height: Grid.md),
ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 440),
child: SizedBox(
width: double.infinity,
child: Column(
children: [
FilledButton(
style: _onboardingButtonStyle,
onPressed: isBusy ? null : onScan,
child: isBusy && !pairingCodeExpanded
? SizedBox(
width: 20,
height: 20,
child: BuzzLoadingIndicator(
size: 20,
color: _onboardingCtaLabel,
semanticLabel: context.l10n.openingScanner,
),
)
: Text(context.l10n.scanQrCode),
),
const SizedBox(height: Grid.xxs),
TextButton(
style: _onboardingSecondaryButtonStyle,
onPressed: isBusy ? null : onTogglePairingCode,
child: Text(
pairingCodeExpanded
? context.l10n.hidePairingCode
: context.l10n.usePairingCode,
),
),
AnimatedSwitcher(
duration: revealDuration,
switchInCurve: Curves.easeOutCubic,
switchOutCurve: Curves.easeInCubic,
transitionBuilder: (child, animation) {
return SizeTransition(
sizeFactor: animation,
axisAlignment: -1,
child: FadeTransition(
opacity: animation,
child: child,
),
);
},
child: pairingCodeExpanded
? Column(
key: const ValueKey('pairing-code-fields'),
children: [
const SizedBox(height: Grid.twelve),
TextField(
controller: codeController,
style: context.textTheme.bodyMedium
?.copyWith(color: _onboardingInk),
cursorColor: _onboardingInk,
decoration: InputDecoration(
filled: true,
fillColor: Colors.white.withValues(
alpha: 0.7,
),
hintText:
context.l10n.pairingCodeHint,
hintStyle: context.textTheme.bodyMedium
?.copyWith(
color: _onboardingMutedInk,
),
prefixIcon: const Icon(
LucideIcons.link,
color: _onboardingInk,
),
enabledBorder: _inputBorder,
disabledBorder: _inputBorder,
focusedBorder: _inputBorder.copyWith(
borderSide: const BorderSide(
color: _onboardingInk,
),
),
isDense: true,
),
autocorrect: false,
enableSuggestions: false,
enabled: !isBusy,
contextMenuBuilder:
(context, editableTextState) {
return AdaptiveTextSelectionToolbar.editableText(
editableTextState:
editableTextState,
);
},
),
const SizedBox(height: Grid.twelve),
SizedBox(
width: double.infinity,
child: FilledButton(
style: _onboardingButtonStyle,
onPressed: isBusy ? null : onConnect,
child: isBusy
? SizedBox(
width: 20,
height: 20,
child: BuzzLoadingIndicator(
size: 20,
color: _onboardingCtaLabel,
semanticLabel: context.l10n.connecting,
),
)
: Text(context.l10n.connect),
),
),
],
)
: const SizedBox(
key: ValueKey('pairing-code-fields-hidden'),
),
),
if (errorMessage != null) ...[
const SizedBox(height: Grid.twelve),
Container(
padding: const EdgeInsets.all(Grid.twelve),
decoration: BoxDecoration(
color: context.colors.errorContainer,
borderRadius: BorderRadius.circular(Radii.md),
),
child: Row(
children: [
Icon(
LucideIcons.triangleAlert,
size: 16,
color: context.colors.onErrorContainer,
),
const SizedBox(width: Grid.xxs),
Expanded(
child: Text(
errorMessage!,
style: context.textTheme.bodySmall
?.copyWith(
color:
context.colors.onErrorContainer,
),
),
),
],
),
),
],
],
),
),
),
],
),
),
);
},
);
}
}
final _inputBorder = OutlineInputBorder(
borderRadius: BorderRadius.circular(Radii.md),
borderSide: BorderSide(color: _onboardingInk.withValues(alpha: 0.18)),
);
final _onboardingButtonStyle = FilledButton.styleFrom(
minimumSize: const Size(0, 48),
padding: const EdgeInsets.symmetric(
horizontal: Grid.lg,
vertical: Grid.twelve,
),
backgroundColor: _onboardingInk,
foregroundColor: _onboardingCtaLabel,
disabledBackgroundColor: _onboardingInk.withValues(alpha: 0.38),
disabledForegroundColor: _onboardingCtaLabel.withValues(alpha: 0.7),
shape: const StadiumBorder(),
);
final _onboardingSecondaryButtonStyle = TextButton.styleFrom(
minimumSize: const Size(0, 44),
padding: const EdgeInsets.symmetric(horizontal: Grid.md, vertical: Grid.xxs),
backgroundColor: _onboardingInk.withValues(alpha: 0.1),
foregroundColor: _onboardingInk,
disabledBackgroundColor: _onboardingInk.withValues(alpha: 0.05),
disabledForegroundColor: _onboardingInk.withValues(alpha: 0.45),
shape: const StadiumBorder(),
);