Skip to content

[Fix] Improve toast notification behavior#488

Merged
samzong merged 1 commit into
mainfrom
fix/toast-notification-placement
May 6, 2026
Merged

[Fix] Improve toast notification behavior#488
samzong merged 1 commit into
mainfrom
fix/toast-notification-placement

Conversation

@samzong
Copy link
Copy Markdown
Collaborator

@samzong samzong commented May 6, 2026

Summary

Move renderer toast notifications away from the bottom action area, make them dismissible, and centralize toast behavior through a renderer facade.

Type of change

  • [Feat] new feature
  • [Fix] bug fix
  • [UI] UI or UX change
  • [Docs] documentation-only change
  • [Refactor] internal cleanup
  • [Build] CI, packaging, or tooling change
  • [Chore] maintenance

Why is this needed?

Toast notifications were appearing in the bottom-right corner, where they can overlap common save, exit, confirmation, and input actions. The dismiss control also needed to read as part of the toast instead of a floating window control.

What changed?

  • Moved app toasts to the top-right and limited visible toasts to three.
  • Added an inline dismiss button style for Sonner toasts.
  • Added @/lib/toast as the renderer toast facade with default success/info, longer warning, and finite error durations.
  • Updated renderer toast imports to use the centralized facade.

Architecture impact

  • Owning layer: renderer
  • Cross-layer impact: none
  • Invariants touched from docs/architecture-invariants.md: renderer remains presentation-only; no main/preload/core boundaries changed.
  • Why those invariants remain protected: the change only updates renderer toast configuration, imports, and a renderer test mock.

Linked issues

Closes #

Validation

  • pnpm lint
  • pnpm test
  • pnpm build
  • pnpm check:ui-contract
  • Manual smoke test
  • Not run

Commands, screenshots, or notes:

pnpm check
Manual screenshot review of toast close button placement.

Screenshots or recordings

Manual screenshot review confirmed the default floating close button looked wrong; this PR moves the close button inside the toast card while preserving existing color tokens: var(--bg-elevated), var(--border), var(--text-primary), var(--text-muted), and var(--bg-hover).

Release note

  • No user-facing change. Release note is NONE.
  • User-facing change. Release note is included below.
Toast notifications now appear in the top-right corner and include a clearer dismiss button.

Checklist

  • All commits are signed off (git commit -s)
  • The PR title uses at least one approved prefix: [Feat], [Fix], [UI], [Docs], [Refactor], [Build], or [Chore]
  • The summary explains both what changed and why
  • Validation reflects the commands actually run for this PR
  • Architecture impact is described and references any touched invariants
  • Cross-layer changes are explicitly justified
  • The release note block is accurate

Considered and deferred

  • packages/desktop/src/renderer/lib/toast.ts:14 [BOT-SCOPE]: Existing renderer controls use i18n for visible aria labels, but Sonner toast options are module-level constants; moving this into a translated component/builder is broader than this fix.
  • packages/desktop/src/renderer/lib/toast.ts:29 [BOT-NIT]: Object.assign preserves the Sonner API surface while overriding warning/error defaults; replacing it with a hand-written facade would recreate API drift risk.

Signed-off-by: samzong <[email protected]>

## Considered and deferred

- packages/desktop/src/renderer/lib/toast.ts:14 [BOT-SCOPE]: Existing renderer controls use i18n for visible aria labels, but Sonner toast options are module-level constants; moving this into a translated component/builder is broader than this fix.
- packages/desktop/src/renderer/lib/toast.ts:29 [BOT-NIT]: `Object.assign` preserves the Sonner API surface while overriding warning/error defaults; replacing it with a hand-written facade would recreate API drift risk.

Signed-off-by: samzong <[email protected]>
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors the application's toast notification system to improve user experience and UI consistency. By centralizing toast configuration through a new renderer facade, the changes ensure uniform behavior for success, warning, and error notifications while resolving layout conflicts with existing UI elements.

Highlights

  • Toast Notification Relocation: Moved toast notifications from the bottom-right to the top-right to prevent overlap with critical UI action areas.
  • Centralized Toast Facade: Introduced a new renderer toast facade at @/lib/toast to standardize toast behavior, durations, and styling across the application.
  • Improved UX: Added an inline dismiss button to toast notifications and limited the maximum number of visible toasts to three for a cleaner interface.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Hi @samzong,
Thanks for your pull request!
If the PR is ready, use the /auto-cc command to assign Reviewer to Review.
We will review it shortly.

Details

Instructions for interacting with me using comments are available here.
If you have questions or suggestions related to my behavior, please file an issue against the gh-ci-bot repository.

@samzong
Copy link
Copy Markdown
Collaborator Author

samzong commented May 6, 2026

/auto-cc

@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

closeButtonAriaLabel: 'Close notification',

P2 Badge Localize the close-button label

For non-English locales, this new toast dismiss control remains in English because the aria label is hardcoded in the renderer facade. .claude/rules/frontend.md requires new user-facing strings to use t(), and this label is announced to screen-reader users whenever a toast appears; build the toast options where useTranslation() is available or otherwise pass a translated label instead of a module-level literal.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request centralizes toast notification management by creating a dedicated utility in lib/toast.ts and introducing an AppToaster component to standardize styles and durations across the application. The review feedback identifies a violation of internationalization standards (Rule 43), specifically pointing out that user-facing strings like closeButtonAriaLabel should be translated using the t() function within a React component rather than being defined as module-level constants.

I am having trouble creating individual review comments. Click here to see my feedback.

packages/desktop/src/renderer/lib/toast.ts (14)

medium

The closeButtonAriaLabel is a user-facing string and should be internationalized using t() as per the repository style guide (rule 43). Since TOAST_OPTIONS is a module-level constant, you should move this label definition to the AppToaster component in App.tsx where the useTranslation hook is available.

References
  1. Rule 43: t() for all user-facing strings. (link)

packages/desktop/src/renderer/App.tsx (1-3)

medium

Import useTranslation to support internationalization of user-facing strings in the AppToaster component.

import { useState, useEffect, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { motion, AnimatePresence } from 'framer-motion';
import { Toaster, TOAST_DURATION_MS, TOAST_OPTIONS } from '@/lib/toast';
References
  1. Rule 43: t() for all user-facing strings. (link)

packages/desktop/src/renderer/App.tsx (23-34)

medium

Use the useTranslation hook to provide a translated aria-label for the toast close button, adhering to the internationalization requirements in the style guide.

function AppToaster({ themeMode }: { themeMode: Theme }) {
  const { t } = useTranslation();
  return (
    <Toaster
      theme={themeMode === 'auto' ? 'system' : themeMode}
      position="top-right"
      closeButton
      visibleToasts={3}
      duration={TOAST_DURATION_MS}
      toastOptions={TOAST_OPTIONS}
      closeButtonAriaLabel={t('common.close')}
    />
  );
}
References
  1. Rule 43: t() for all user-facing strings. (link)

@samzong samzong merged commit 088637b into main May 6, 2026
11 checks passed
@samzong samzong deleted the fix/toast-notification-placement branch May 6, 2026 17:25
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.

1 participant