diff --git a/UI/NoorUI/Components/AppStoreDownloadButton.swift b/UI/NoorUI/Components/AppStoreDownloadButton.swift
index fd5c22de..f873c932 100644
--- a/UI/NoorUI/Components/AppStoreDownloadButton.swift
+++ b/UI/NoorUI/Components/AppStoreDownloadButton.swift
@@ -21,7 +21,7 @@ struct AppStoreDownloadButton: View {
     let action: AsyncAction
 
     var body: some View {
-        Button(asyncAction: action) {
+        AsyncButton(action: action) {
             Group {
                 switch type {
                 case .pending:
diff --git a/UI/NoorUI/Components/List/NoorListItem.swift b/UI/NoorUI/Components/List/NoorListItem.swift
index 824e3bc6..ca295c62 100644
--- a/UI/NoorUI/Components/List/NoorListItem.swift
+++ b/UI/NoorUI/Components/List/NoorListItem.swift
@@ -96,9 +96,9 @@ public struct NoorListItem: View {
             if let accessory, accessory.actionable {
                 // Use Tap gesture since tapping accessory button will also trigger the whole cell selection.
                 content
-                    .onTapGesture(asyncAction: action)
+                    .onAsyncTapGesture(asyncAction: action)
             } else {
-                Button(asyncAction: action) {
+                AsyncButton(action: action) {
                     content
                 }
             }
diff --git a/UI/NoorUI/Features/AdvancedAudioOptions/AdvancedAudioOptionsView.swift b/UI/NoorUI/Features/AdvancedAudioOptions/AdvancedAudioOptionsView.swift
index 8b920081..4cb3641a 100644
--- a/UI/NoorUI/Features/AdvancedAudioOptions/AdvancedAudioOptionsView.swift
+++ b/UI/NoorUI/Features/AdvancedAudioOptions/AdvancedAudioOptionsView.swift
@@ -67,7 +67,7 @@ private struct LastVerseButton: View {
     let action: AsyncAction
 
     var body: some View {
-        Button(asyncAction: action) {
+        AsyncButton(action: action) {
             Text(label)
                 .foregroundColor(.white)
                 .padding(.vertical, 5)
diff --git a/UI/NoorUI/Features/AyahMenu/AyahMenuView.swift b/UI/NoorUI/Features/AyahMenu/AyahMenuView.swift
index 8901c4a8..eadf374a 100644
--- a/UI/NoorUI/Features/AyahMenu/AyahMenuView.swift
+++ b/UI/NoorUI/Features/AyahMenu/AyahMenuView.swift
@@ -225,10 +225,7 @@ private struct Row<Symbol: View>: View {
     @ScaledMetric var verticalPadding = 12
 
     var body: some View {
-        Button {
-            await action()
-        }
-        label: {
+        AsyncButton(action: action) {
             HStack {
                 ZStack {
                     IconCircles()
@@ -314,8 +311,8 @@ private struct NoteCircles: View {
     var body: some View {
         HStack {
             ForEach(Note.Color.sortedColors, id: \.self) { color in
-                Button(
-                    asyncAction: { await tapped(color) },
+                AsyncButton(
+                    action: { await tapped(color) },
                     label: { NoteCircle(color: color.color, selected: color == selectedColor) }
                 )
                 .shadow(color: Color.tertiarySystemGroupedBackground, radius: 1)
diff --git a/UI/UIx/SwiftUI/Miscellaneous/AsyncAction.swift b/UI/UIx/SwiftUI/Miscellaneous/AsyncAction.swift
index a42d9bae..4135d736 100644
--- a/UI/UIx/SwiftUI/Miscellaneous/AsyncAction.swift
+++ b/UI/UIx/SwiftUI/Miscellaneous/AsyncAction.swift
@@ -12,22 +12,63 @@ public typealias AsyncAction = @MainActor @Sendable () async -> Void
 public typealias ItemAction<Item> = @MainActor @Sendable (Item) -> Void
 public typealias AsyncItemAction<Item> = @MainActor @Sendable (Item) async -> Void
 
-extension Button {
-    public init(asyncAction: @escaping AsyncAction, @ViewBuilder label: () -> Label) {
-        self.init(action: {
-            Task {
-                await asyncAction()
+public struct AsyncButton<Label: View>: View {
+    // MARK: Lifecycle
+
+    public init(action: @escaping AsyncAction, label: () -> Label) {
+        self.action = action
+        self.label = label()
+    }
+
+    // MARK: Public
+
+    public var body: some View {
+        Button {
+            // Cancel the previous task
+            currentTask?.cancel()
+
+            // Start a new task
+            currentTask = Task {
+                await action()
             }
-        }, label: label)
+        } label: {
+            label
+        }
     }
+
+    // MARK: Private
+
+    private let action: AsyncAction
+    private let label: Label
+
+    @State private var currentTask: Task<Void, Never>? = nil
 }
 
 extension View {
-    public func onTapGesture(count: Int = 1, asyncAction action: @escaping AsyncAction) -> some View {
-        onTapGesture(count: count, perform: {
-            Task {
+    public func onAsyncTapGesture(count: Int = 1, asyncAction action: @escaping AsyncAction) -> some View {
+        modifier(AsyncTapGestureModifier(count: count, action: action))
+    }
+}
+
+private struct AsyncTapGestureModifier: ViewModifier {
+    // MARK: Internal
+
+    let count: Int
+    let action: AsyncAction
+
+    func body(content: Content) -> some View {
+        content.onTapGesture(count: count, perform: {
+            // Cancel the previous task
+            currentTask?.cancel()
+
+            // Start a new task
+            currentTask = Task {
                 await action()
             }
         })
     }
+
+    // MARK: Private
+
+    @State private var currentTask: Task<Void, Never>? = nil
 }