Skip to content

feat(group): add delete action to group overflow menu - #120

Merged
hawkff merged 1 commit into
mainfrom
feat/026-group-menu-delete
Jul 4, 2026
Merged

hawkff merged 1 commit into
mainfrom
feat/026-group-menu-delete

Conversation

@hawkff

@hawkff hawkff commented Jul 4, 2026 •

Copy link
Copy Markdown
Owner

Adds a Remove entry to the group card options (three-dot) menu.

  • Confirmation dialog before removal, using the existing prompt string
  • Reuses the existing GroupManager.deleteGroup path (resets selection, notifies listeners, reconfigures the subscription updater)
  • Entry is hidden for the default group and for groups currently updating, matching the existing swipe-guard rules
  • No new strings; existing translations cover all locales

Verified locally: spotlessKotlinCheck and compileOssDebugKotlin green; CodeRabbit CLI review clean.

Greptile Summary

Adds a "Delete" entry to the group card's three-dot overflow menu, giving users a menu-based alternative to swipe-to-delete. The feature is correctly guarded (hidden for the default ungrouped group and for groups currently updating, mirroring the existing ItemTouchHelper.getSwipeDirs guard) and shows a confirmation dialog before calling the already-established GroupManager.deleteGroup path.

  • GroupFragment.kt: New R.id.action_delete_group branch in onMenuItemClick shows a MaterialAlertDialogBuilder confirmation before dispatching GroupManager.deleteGroup on the default dispatcher; guard condition at popup build-time matches the swipe guard exactly.
  • group_action_menu.xml: New action_delete_group item appended, referencing the existing @string/delete resource; the file is missing a trailing newline.

Confidence Score: 4/5

Safe to merge; the change is a small, well-scoped addition that reuses existing guard logic and the established delete pathway.

The implementation faithfully mirrors the swipe-to-delete behavior: same guard conditions, same GroupManager.deleteGroup call, same dispatcher dispatch. The only issue found is a missing trailing newline in the XML file.

No files require special attention; the missing newline in group_action_menu.xml is cosmetic only.

Important Files Changed

Filename Overview
app/src/main/java/io/nekohasekai/sagernet/ui/GroupFragment.kt Adds action_delete_group handler with a confirmation dialog and correctly mirrors the existing swipe-to-delete guard (ungrouped
app/src/main/res/menu/group_action_menu.xml New action_delete_group menu item added at the end of the list using the existing @string/delete resource; file is missing a trailing newline.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    actor User
    participant GroupHolder
    participant PopupMenu
    participant Dialog as MaterialAlertDialog
    participant GroupManager
    participant Database as SagerDatabase

    User->>GroupHolder: tap three-dot button
    GroupHolder->>GroupHolder: "check ungrouped || id in GroupUpdater.updating"
    alt guard passes
        GroupHolder->>PopupMenu: inflate group_action_menu.xml
        GroupHolder->>PopupMenu: removeItem(action_delete_group) [if blocked]
        GroupHolder->>PopupMenu: show()
        User->>PopupMenu: select Delete
        PopupMenu->>Dialog: show confirmation (delete_group_prompt)
        User->>Dialog: confirm (Yes)
        Dialog->>GroupManager: deleteGroup(proxyGroup.id) [on default dispatcher]
        GroupManager->>Database: deleteById(groupId)
        GroupManager->>Database: deleteByGroup(groupId) [profiles]
        GroupManager->>GroupManager: notify listeners (groupRemoved)
        GroupManager->>GroupManager: SubscriptionUpdater.reconfigureUpdater()
    else guard fails (ungrouped or updating)
        GroupHolder->>PopupMenu: action_delete_group removed from menu
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    actor User
    participant GroupHolder
    participant PopupMenu
    participant Dialog as MaterialAlertDialog
    participant GroupManager
    participant Database as SagerDatabase

    User->>GroupHolder: tap three-dot button
    GroupHolder->>GroupHolder: "check ungrouped || id in GroupUpdater.updating"
    alt guard passes
        GroupHolder->>PopupMenu: inflate group_action_menu.xml
        GroupHolder->>PopupMenu: removeItem(action_delete_group) [if blocked]
        GroupHolder->>PopupMenu: show()
        User->>PopupMenu: select Delete
        PopupMenu->>Dialog: show confirmation (delete_group_prompt)
        User->>Dialog: confirm (Yes)
        Dialog->>GroupManager: deleteGroup(proxyGroup.id) [on default dispatcher]
        GroupManager->>Database: deleteById(groupId)
        GroupManager->>Database: deleteByGroup(groupId) [profiles]
        GroupManager->>GroupManager: notify listeners (groupRemoved)
        GroupManager->>GroupManager: SubscriptionUpdater.reconfigureUpdater()
    else guard fails (ungrouped or updating)
        GroupHolder->>PopupMenu: action_delete_group removed from menu
    end
Loading

Reviews (1): Last reviewed commit: "feat(group): add delete action to group ..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Adds a Remove entry to the group card options menu with a confirmation
dialog, reusing the existing group deletion path. Hidden for the default
group and for groups currently updating, matching the swipe-guard rules.
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1f6a4df1-7f43-4f7a-8772-28e8e2449529

📥 Commits

Reviewing files that changed from the base of the PR and between e2ffd10 and ff17a61.

📒 Files selected for processing (2)
  • app/src/main/java/io/nekohasekai/sagernet/ui/GroupFragment.kt
  • app/src/main/res/menu/group_action_menu.xml

Comment @coderabbitai help to get the list of available commands.

<item
android:id="@+id/action_delete_group"
android:title="@string/delete" />
</menu> No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Missing newline at end of file

The file is missing a trailing newline (the diff shows \ No newline at end of file). Most editors and POSIX tools expect files to end with a newline, and the rest of the menu XML files in this project include one. This can cause spurious diff noise in future changes.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@hawkff

hawkff commented Jul 4, 2026

Copy link
Copy Markdown
Owner Author

Re: trailing newline — the missing EOF newline is pre-existing in this file on main (the diff only surfaces it because the change touches the last lines). Leaving it as-is to avoid a review/CI cycle for a one-byte change; happy to fold it into the next change that touches this file.

@hawkff
hawkff merged commit 371cfef into main Jul 4, 2026
8 checks passed
@hawkff
hawkff deleted the feat/026-group-menu-delete branch July 4, 2026 00:27
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