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,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(),
|
||||
);
|
||||
Reference in New Issue
Block a user