Skip to content

Toaster!#385

Merged
dewabisma merged 11 commits inton13/v3_designfrom
beast/toaster
Feb 16, 2026
Merged

Toaster!#385
dewabisma merged 11 commits inton13/v3_designfrom
beast/toaster

Conversation

@dewabisma
Copy link
Collaborator

Summary

Create toaster component and its' helpers. Also added extensions for easy usage.

Screenshots

Simulator Screenshot - iPhone 8 - 2026-02-16 at 11 27 47

@dewabisma dewabisma changed the base branch from main to n13/v3_design February 16, 2026 03:56
@dewabisma dewabisma requested a review from n13 February 16, 2026 05:07
@n13
Copy link
Collaborator

n13 commented Feb 16, 2026

Here's my review of PR #385: Toaster!


Overview

This PR introduces a new toaster notification system to replace the existing snackbar pattern in v2 screens. It adds a Toaster widget, helper functions, BuildContext extensions, and migrates several screens from snackbar_helper to the new toaster. The architecture is solid overall -- nice clean layered approach with widget, helper, and extensions.


Issues

1. DRY Violation: toaster_helper.dart duplicates snackbar_helper.dart

The showToaster function is nearly identical to showTopSnackBar -- same flash package, same FlashBar configuration with all the same transparent colors, FlashPosition.top, Clip.none, etc. The only difference is the content widget. Consider extracting the shared FlashBar scaffolding into a common function that accepts a Widget content parameter, and having both helpers call it.

2. Incomplete Migration

A few spots were missed:

  • wallet_ready_screen.dart line 94 still calls showCopySnackbar and still imports snackbar_helper.dart:
      if (mounted) showCopySnackbar(context, title: 'Error', message: 'Error saving wallet: $e');
  • settings_screen.dart still imports and uses snackbar_helper.dart / showTopSnackBar.
  • clipboard_extensions.dart still retains the old ClipboardExtensions on Clipboard class with copyTextWithSnackbar and its snackbar_helper.dart import. If the v2 screens are fully migrated, this old extension (and the import) could be cleaned up in this PR or flagged as tech debt.

3. Inconsistent Extension Coverage

toaster_extensions.dart wraps showSuccessToaster, showWarningToaster, and showErrorToaster -- but not showCopyToaster or the base showToaster. Meanwhile, copyTextWithToaster lives in a separate extension (ClipboardWithToasterExtensions) in a different file. This makes the API surface fragmented. Consider either:

  • Adding showCopyToaster to ToasterExtensions, or
  • Having copyTextWithToaster delegate through the extension rather than importing toaster_helper.dart directly.

4. Toaster Widget -- Using Icon as a Parameter Type

class Toaster extends StatelessWidget {
  final String message;
  final Icon? icon;

Accepting Icon? and then destructuring it (icon?.icon, icon?.color) is a bit unusual. Cleaner alternatives:

  • Accept IconData? and Color? as separate params, or
  • Accept Widget? icon and render it directly (more flexible, allows custom widgets).

5. Questionable Default Icon

    final Widget displayIcon = Icon(
      icon?.icon ?? Icons.copy,
      color: icon?.color ?? Colors.white,

Defaulting to Icons.copy when no icon is provided means every toaster without an explicit icon shows a copy icon. An Icons.info_outline or no icon at all would be a safer default.

6. Leftover Comment

      // width: 343, // Width will be handled by the flash package's constraints

This commented-out code should be removed.

7. persistent: true -- Intentional?

    duration: duration,
    persistent: true,

In the flash package, persistent: true means the flash bar won't dismiss on background tap. Users typically expect to dismiss toasters by tapping. Was this intentional?

8. Misleading Parameter Name

  FlashBehavior style = FlashBehavior.floating,

The parameter style maps to behavior in FlashBar. Renaming to behavior would be more self-documenting and consistent with the library's API.

9. Redundant Default

        mainAxisAlignment: MainAxisAlignment.start,

MainAxisAlignment.start is the default for Row -- can be removed.


Nits (Non-blocking)

  • Unrelated changes in this PR: The glass_container.dart asset rename (glass_button_40_bg.png -> glass_40.png) and formatting-only changes in app.dart, transaction_service.dart, and activity_section.dart are noise. Ideally these would be in a separate cleanup PR.
  • Border radius: 14.22 is a very specific number. If this came from a Figma spec, that's fine -- just making sure it's intentional and not a rounding artifact.

Summary

The toaster component itself looks good -- clean widget, nice use of the theme system for colors, and the migration of call sites is heading in the right direction. The main concerns are:

  1. DRY: Extract the shared FlashBar scaffolding between toaster_helper and snackbar_helper
  2. Completeness: Missed a couple of migration spots in v2 screens
  3. API consistency: The extension coverage is uneven across the helper functions
  4. Icon parameter pattern: Should be Widget? or IconData? + Color?

Happy to help fix any of these if you'd like!

@n13
Copy link
Collaborator

n13 commented Feb 16, 2026

Ok
Recommendations:

Delete snackbar_helper. We can just use the new one everywhere.

Make icon non-optional - user must intentionally set icon - we can make a special factor constructor for copy, since we use that everywhere. ... actually we already have showCopyToaster

Ignore my whitespace complaints, it seems to be wrong in the v3 branch

@n13
Copy link
Collaborator

n13 commented Feb 16, 2026


PR #385 Re-Review: Toaster!

Great work on the updates -- the major issues from the first review have been addressed. Here's where things stand now.

Issues Resolved

  1. DRY violation -- eliminated. snackbar_helper.dart and top_snackbar_content.dart are both deleted. There's now a single toaster system, no more duplication.

  2. Incomplete migration -- completed. Every call site across both features/ and v2/ screens has been migrated. snackbar_extensions.dart is deleted. The old ClipboardExtensions on Clipboard static method is gone.

  3. Extension coverage -- consistent. toaster_extensions.dart now exposes all five variants: showSuccessToaster, showWarningToaster, showErrorToaster, showCopyToaster, and showInfoToaster.

  4. Default Icons.copy icon -- fixed. icon is now required, so every call site must be explicit about its icon.

  5. Leftover commented-out code -- removed. The // width: 343 line is gone.

  6. persistent: true -- fixed. Changed to persistent: false, so toasters are now dismissible by tap.

  7. Misleading style parameter -- fixed. Renamed to behavior to match the FlashBar API.

  8. Redundant mainAxisAlignment: MainAxisAlignment.start -- removed.


Remaining Items

1. Missing await in clipboard_extensions.dart

extension ClipboardWithToasterExtensions on BuildContext {
  Future<void> copyTextWithToaster(String text, {String message = 'Address copied to clipboard'}) async {
    await Clipboard.setData(ClipboardData(text: text));

    showCopyToaster(message: message);
  }
}

showCopyToaster returns Future<void> but isn't awaited. The method itself is async and returns Future<void>, so callers might expect it completes after the toaster is shown. This is either a small bug or should be intentionally documented. Adding await or making the method non-async and returning void would be more consistent.

2. Icon parameter pattern (minor)

The Toaster widget still accepts Icon and destructures it to create a new Icon:

final Widget displayIcon = Icon(icon.icon, color: icon.color, size: context.isTablet ? 20 : 16);

This silently discards any other properties set on the passed Icon (e.g. semanticLabel, textDirection). Using IconData + Color? as separate params would be more explicit about what's actually used. Not a blocker -- just slightly unusual.

3. crossAxisAlignment: CrossAxisAlignment.center is the default for Row -- can be removed for conciseness, but very minor.


Overall Verdict

This is looking really good now. The migration is thorough, the old snackbar system is fully removed, and the new toaster API is clean and consistent. The only actionable item is the missing await in clipboard_extensions.dart -- the rest are minor nits. Happy to approve once that's addressed!

@n13
Copy link
Collaborator

n13 commented Feb 16, 2026

  1. and 2. should be fixed

dewabisma and others added 2 commits February 16, 2026 16:25
* feat: create new auth wrapper

* fix: code formatting

* feat: remove old auth wrapper, rename new auth wrapper to lock screen

* feat: revert name back to auth wrapper, add button to trigger authentication

* feat: use the unfilled button style
Copy link
Collaborator

@n13 n13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@dewabisma dewabisma merged commit ff3d24e into n13/v3_design Feb 16, 2026
@dewabisma dewabisma deleted the beast/toaster branch February 16, 2026 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants