mirror of
https://github.com/block/buzz.git
synced 2026-11-06 17:31:19 +00:00
Tapping the headphones button in a channel header used to start a Huddle straight away, which turned on the microphone and posted "Huddle started" to the channel. The button is easy to hit by accident. Now, when no Huddle is running there, the button asks "Start a Huddle?" first, with Cancel and Start Huddle. - `showConfirmation` in `shared/widgets/confirmation_dialog.dart` adds a non-destructive mode to the shared confirm helper. `showDestructiveConfirmation` now calls it with `destructive: true`, so existing callers behave the same. On iOS the native UIKit alert reads a new `destructive` argument and uses `.default` style instead of `.destructive` when it's false. On other platforms the confirm button keeps the default `FilledButton` style instead of the error color. - `_huddleNavigationAction` asks before calling `start`. That covers both the Material header button and the iOS native navigation action. Opening or joining a Huddle that's already running stays one tap, and so do the explicit "Start new" buttons inside the Huddle sheets. Companion to block/buzz-app#2687, which adds the same confirmation on desktop. buzz-app#2660 also moves the desktop button away from the members button, but there's no equivalent move on mobile: the headphones is the only action in the header. ### Screenshots Rendered by a scratch widget test from the real `ChannelDetailPage` (Android/Material path, Inter loaded) at 390×844. The scratch test has been removed. On iOS, the same confirmation shows as a native UIKit alert, which isn't captured here because this machine has no iOS Simulator. Before: tapping the headphones goes straight into a call. <img src="https://github.com/user-attachments/assets/adced280-2abd-44ad-a079-1c83749892a0" width="300" alt="Before"> After, light and dark, cropped to the new dialog: | Light | Dark | | --- | --- | |  |  | ### Validation - The existing journey "community transition cancels and awaits an in-flight Huddle start" now taps the button and checks that the dialog appears, that Cancel closes it without publishing anything, and that tapping again and choosing Start Huddle starts the call. With the confirm removed, this test fails. - `channel_member_profile_actions_test` checks that destructive confirmations still send `destructive: true` to the iOS bridge. - Full `flutter test`: 4,508 passed. `flutter analyze` and `dart format` are clean. - Not yet checked: the iOS native alert on a device or simulator, and a human trying it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Diem Nguyen <diem@squareup.com> Co-authored-by: Fizz <6be7be23ec5bba868f3e1db5ec86013d76bd1a293dce5b435a192158fec13641@buzz.block.builderlab.xyz> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
69 lines
2.1 KiB
Dart
69 lines
2.1 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
import '../theme/theme.dart';
|
|
import 'modal_presentation.dart';
|
|
|
|
/// Confirms a destructive action using a UIKit alert on iOS.
|
|
/// Returns true only when the person explicitly chooses the destructive action.
|
|
Future<bool> showDestructiveConfirmation({
|
|
required BuildContext context,
|
|
required String title,
|
|
required String message,
|
|
required String confirmLabel,
|
|
}) => showConfirmation(
|
|
context: context,
|
|
title: title,
|
|
message: message,
|
|
confirmLabel: confirmLabel,
|
|
destructive: true,
|
|
);
|
|
|
|
/// Confirms an action using a UIKit alert on iOS.
|
|
/// Returns true only when the person explicitly chooses the confirm action.
|
|
Future<bool> showConfirmation({
|
|
required BuildContext context,
|
|
required String title,
|
|
required String message,
|
|
required String confirmLabel,
|
|
bool destructive = false,
|
|
}) async {
|
|
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.iOS) {
|
|
return await const MethodChannel(
|
|
'buzz/confirmation_dialog',
|
|
).invokeMethod<bool>('present', {
|
|
'title': title,
|
|
'message': message,
|
|
'confirmLabel': confirmLabel,
|
|
'cancelLabel': 'Cancel',
|
|
'destructive': destructive,
|
|
'dark': context.theme.brightness == Brightness.dark,
|
|
}) ==
|
|
true;
|
|
}
|
|
return await showBuzzDialog<bool>(
|
|
context: context,
|
|
builder: (dialogContext) => AlertDialog.adaptive(
|
|
title: Text(title),
|
|
content: Text(message),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(dialogContext).pop(false),
|
|
child: const Text('Cancel'),
|
|
),
|
|
FilledButton(
|
|
onPressed: () => Navigator.of(dialogContext).pop(true),
|
|
style: destructive
|
|
? FilledButton.styleFrom(
|
|
backgroundColor: context.colors.error,
|
|
)
|
|
: null,
|
|
child: Text(confirmLabel),
|
|
),
|
|
],
|
|
),
|
|
) ==
|
|
true;
|
|
}
|