mirror of
https://github.com/block/buzz.git
synced 2026-10-27 04:30:52 +00:00
Attach hidden connection action to labelled wordmark
Keep the developer entry without a keyboard path by product decision. Co-authored-by: Terp <5856f6900e8e0a4e0ea1f4f8d2ee33e4753d2119bc122f94ecafc660b46c0511@buzz.block.builderlab.xyz> Signed-off-by: kenny lopez <klopez4212@gmail.com>
This commit is contained in:
@@ -323,38 +323,42 @@ class _PairingWelcomeView extends HookWidget {
|
|||||||
setupContent == null &&
|
setupContent == null &&
|
||||||
!signInPending &&
|
!signInPending &&
|
||||||
!isBusy;
|
!isBusy;
|
||||||
final welcome = Semantics(
|
final welcome = Padding(
|
||||||
customSemanticsActions: canRevealOptions
|
padding: const EdgeInsets.symmetric(
|
||||||
? {
|
horizontal: Grid.gutter,
|
||||||
const CustomSemanticsAction(label: 'More connection options'):
|
vertical: Grid.sm,
|
||||||
revealOptions,
|
),
|
||||||
}
|
child: CustomScrollView(
|
||||||
: null,
|
// Stay fixed when the welcome content fits; allow only real overflow
|
||||||
child: Padding(
|
// (such as the pairing form above the keyboard), with no rubber banding.
|
||||||
padding: const EdgeInsets.symmetric(
|
physics: const ClampingScrollPhysics(),
|
||||||
horizontal: Grid.gutter,
|
slivers: [
|
||||||
vertical: Grid.sm,
|
SliverFillRemaining(
|
||||||
),
|
hasScrollBody: false,
|
||||||
child: CustomScrollView(
|
child: Column(
|
||||||
// Stay fixed when the welcome content fits; allow only real overflow
|
children: [
|
||||||
// (such as the pairing form above the keyboard), with no rubber banding.
|
Expanded(
|
||||||
physics: const ClampingScrollPhysics(),
|
child: _TwoFingerDoubleTapSurface(
|
||||||
slivers: [
|
onDoubleTap: canRevealOptions ? revealOptions : null,
|
||||||
SliverFillRemaining(
|
child: Center(
|
||||||
hasScrollBody: false,
|
child: Column(
|
||||||
child: Column(
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
ConstrainedBox(
|
||||||
child: _TwoFingerDoubleTapSurface(
|
constraints: const BoxConstraints(maxWidth: 320),
|
||||||
onDoubleTap: canRevealOptions ? revealOptions : null,
|
child: AspectRatio(
|
||||||
child: Center(
|
aspectRatio: 777 / 326,
|
||||||
child: Column(
|
child: Semantics(
|
||||||
mainAxisSize: MainAxisSize.min,
|
// Hidden developer entry intentionally has no
|
||||||
children: [
|
// keyboard shortcut. Keep its assistive action
|
||||||
ConstrainedBox(
|
// on the existing labelled wordmark node.
|
||||||
constraints: const BoxConstraints(maxWidth: 320),
|
customSemanticsActions: canRevealOptions
|
||||||
child: AspectRatio(
|
? {
|
||||||
aspectRatio: 777 / 326,
|
const CustomSemanticsAction(
|
||||||
|
label: 'More connection options',
|
||||||
|
): revealOptions,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
child: OnboardingWordmark(
|
child: OnboardingWordmark(
|
||||||
key: const Key('pairing-buzz-wordmark'),
|
key: const Key('pairing-buzz-wordmark'),
|
||||||
color: context._onboardingIsDark
|
color: context._onboardingIsDark
|
||||||
@@ -363,73 +367,71 @@ class _PairingWelcomeView extends HookWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: Grid.xxs),
|
),
|
||||||
Text(
|
const SizedBox(height: Grid.xxs),
|
||||||
'Your people, your agents, your projects —\nall in one place.',
|
Text(
|
||||||
textAlign: TextAlign.center,
|
'Your people, your agents, your projects —\nall in one place.',
|
||||||
style: context.textTheme.bodyLarge?.copyWith(
|
textAlign: TextAlign.center,
|
||||||
color: context._onboardingInk,
|
style: context.textTheme.bodyLarge?.copyWith(
|
||||||
),
|
color: context._onboardingInk,
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: Grid.md),
|
),
|
||||||
ConstrainedBox(
|
const SizedBox(height: Grid.md),
|
||||||
constraints: const BoxConstraints(maxWidth: 440),
|
ConstrainedBox(
|
||||||
child: SizedBox(
|
constraints: const BoxConstraints(maxWidth: 440),
|
||||||
width: double.infinity,
|
child: SizedBox(
|
||||||
child: setupContent != null
|
width: double.infinity,
|
||||||
? setupContent!
|
child: setupContent != null
|
||||||
: !connectionLanding
|
? setupContent!
|
||||||
? actions(2)
|
: !connectionLanding
|
||||||
: ClipRect(
|
? actions(2)
|
||||||
child: Stack(
|
: ClipRect(
|
||||||
alignment: Alignment.bottomCenter,
|
child: Stack(
|
||||||
children: [
|
alignment: Alignment.bottomCenter,
|
||||||
for (var page = 1; page < 5; page++)
|
children: [
|
||||||
ExcludeFocus(
|
for (var page = 1; page < 5; page++)
|
||||||
|
ExcludeFocus(
|
||||||
|
excluding: page != selectedPage,
|
||||||
|
child: ExcludeSemantics(
|
||||||
excluding: page != selectedPage,
|
excluding: page != selectedPage,
|
||||||
child: ExcludeSemantics(
|
child: IgnorePointer(
|
||||||
excluding: page != selectedPage,
|
ignoring: page != selectedPage,
|
||||||
child: IgnorePointer(
|
child: AnimatedSlide(
|
||||||
ignoring: page != selectedPage,
|
key: ValueKey('welcome-panel-$page'),
|
||||||
child: AnimatedSlide(
|
offset: Offset(
|
||||||
key: ValueKey(
|
page == selectedPage
|
||||||
'welcome-panel-$page',
|
? 0
|
||||||
),
|
: page == 1
|
||||||
offset: Offset(
|
? -1
|
||||||
page == selectedPage
|
: 1,
|
||||||
? 0
|
0,
|
||||||
: page == 1
|
),
|
||||||
? -1
|
duration: revealDuration,
|
||||||
: 1,
|
curve: page == selectedPage
|
||||||
0,
|
? Curves.easeOutQuad
|
||||||
),
|
: Curves.easeOutCubic.flipped,
|
||||||
duration: revealDuration,
|
child: SizedBox(
|
||||||
curve: page == selectedPage
|
width: double.infinity,
|
||||||
? Curves.easeOutQuad
|
child: actions(page),
|
||||||
: Curves.easeOutCubic.flipped,
|
|
||||||
child: SizedBox(
|
|
||||||
width: double.infinity,
|
|
||||||
child: actions(page),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return PopScope(
|
return PopScope(
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:buzz/shared/hosted/hosted_community_creation.dart';
|
import 'package:buzz/shared/hosted/hosted_community_creation.dart';
|
||||||
import 'package:buzz/shared/hosted/hosted_environment.dart';
|
import 'package:buzz/shared/hosted/hosted_environment.dart';
|
||||||
import 'package:buzz/features/onboarding/hosted_connect_page.dart';
|
import 'package:buzz/features/onboarding/hosted_connect_page.dart';
|
||||||
@@ -10,6 +12,7 @@ import 'package:buzz/shared/hosted/builderlab_account.dart';
|
|||||||
import 'package:buzz/shared/hosted/hosted_community_connection.dart';
|
import 'package:buzz/shared/hosted/hosted_community_connection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter/semantics.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
@@ -46,7 +49,7 @@ void main() {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
await revealOptions(tester);
|
await revealOptionsWithSemantics(tester);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
tester.view.physicalSize = const Size(420, 900);
|
tester.view.physicalSize = const Size(420, 900);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
@@ -322,3 +325,31 @@ Future<void> revealOptions(WidgetTester tester) async {
|
|||||||
await tester.pump(const Duration(milliseconds: 50));
|
await tester.pump(const Duration(milliseconds: 50));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> revealOptionsWithSemantics(WidgetTester tester) async {
|
||||||
|
final handle = tester.ensureSemantics();
|
||||||
|
try {
|
||||||
|
await tester.pump();
|
||||||
|
final wordmark = tester.getSemantics(find.bySemanticsLabel('Buzz'));
|
||||||
|
final data = wordmark.getSemanticsData();
|
||||||
|
final actionIds = data.customSemanticsActionIds!;
|
||||||
|
expect(actionIds, hasLength(1));
|
||||||
|
expect(
|
||||||
|
CustomSemanticsAction.getAction(actionIds.single)!.label,
|
||||||
|
'More connection options',
|
||||||
|
);
|
||||||
|
// The action belongs to the wordmark, never an unlabelled page-sized stop.
|
||||||
|
expect(data.label, 'Buzz');
|
||||||
|
expect(wordmark.rect.height, lessThan(200));
|
||||||
|
wordmark.owner!.performAction(
|
||||||
|
wordmark.id,
|
||||||
|
ui.SemanticsAction.customAction,
|
||||||
|
actionIds.single,
|
||||||
|
);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('Enter a community link').hitTestable(), findsOneWidget);
|
||||||
|
expect(find.text('Use a pairing code').hitTestable(), findsOneWidget);
|
||||||
|
} finally {
|
||||||
|
handle.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user