Skip to content

Commit 33bcffa

Browse files
author
Programistich
committed
Cancellation install or update app in hub
1 parent 81094cd commit 33bcffa

6 files changed

Lines changed: 136 additions & 31 deletions

File tree

Flipper/Packages/Core/Sources/Applications/Applications.swift

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class Applications: ObservableObject {
1212
public typealias Application = Catalog.Application
1313

1414
private var categories: [Category] = []
15+
private var taskStorage: [Application.ID: Task<Void, Never>] = [:]
1516

1617
public enum InstalledStatus {
1718
case loading
@@ -117,30 +118,40 @@ public class Applications: ObservableObject {
117118
}
118119

119120
public func install(_ application: Application) async {
120-
do {
121-
statuses[application.id] = .installing(0)
122-
try await _install(application) { progress in
123-
Task {
124-
statuses[application.id] = .installing(progress)
121+
taskStorage[application.id]?.cancel()
122+
123+
taskStorage[application.id] = Task {
124+
do {
125+
statuses[application.id] = .installing(0)
126+
try await _install(application) { progress in
127+
Task {
128+
statuses[application.id] = .installing(progress)
129+
}
125130
}
131+
statuses[application.id] = .installed
132+
} catch {
133+
logger.error("install app: \(error)")
126134
}
127-
statuses[application.id] = .installed
128-
} catch {
129-
logger.error("install app: \(error)")
135+
taskStorage[application.id] = nil
130136
}
131137
}
132138

133139
public func update(_ application: Application) async {
134-
do {
135-
statuses[application.id] = .updating(0)
136-
try await _install(application) { progress in
137-
Task {
138-
statuses[application.id] = .updating(progress)
140+
taskStorage[application.id]?.cancel()
141+
142+
taskStorage[application.id] = Task {
143+
do {
144+
statuses[application.id] = .updating(0)
145+
try await _install(application) { progress in
146+
Task {
147+
statuses[application.id] = .updating(progress)
148+
}
139149
}
150+
statuses[application.id] = .installed
151+
} catch {
152+
logger.error("update app: \(error)")
140153
}
141-
statuses[application.id] = .installed
142-
} catch {
143-
logger.error("update app: \(error)")
154+
taskStorage[application.id] = nil
144155
}
145156
}
146157

@@ -163,6 +174,26 @@ public class Applications: ObservableObject {
163174
}
164175
}
165176

177+
public func cancel(_ id: Application.ID) async {
178+
guard
179+
let status = statuses[id],
180+
let task = taskStorage[id]
181+
else { return }
182+
183+
guard status.hasCancelOpportunity else { return }
184+
task.cancel()
185+
186+
switch status {
187+
case .updating:
188+
statuses[id] = .outdated
189+
case .installing:
190+
installed.removeAll { $0.id == id }
191+
statuses[id] = .notInstalled
192+
default:
193+
return
194+
}
195+
}
196+
166197
public enum OpenAppStatus {
167198
case success
168199
case busy
@@ -402,6 +433,14 @@ public class Applications: ObservableObject {
402433
case .checking: return 8
403434
}
404435
}
436+
437+
public var hasCancelOpportunity: Bool {
438+
switch self {
439+
case .installing: return true
440+
case .updating: return true
441+
default: return false
442+
}
443+
}
405444
}
406445

407446
public var hasOpenAppSupport: Bool {

Flipper/Packages/UI/Sources/Hub/Apps/AppView/AppView+Buttons.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@ extension AppView {
2525

2626
var body: some View {
2727
HStack(alignment: .center, spacing: 12) {
28-
if canDelete {
28+
if status.hasCancelOpportunity {
29+
CancelProgressAppButton {
30+
cancel()
31+
}
32+
.frame(width: 46, height: 46)
33+
} else if canDelete {
2934
DeleteAppButton {
3035
confirmDelete = true
3136
}
@@ -122,6 +127,12 @@ extension AppView {
122127
}
123128
}
124129

130+
func cancel() {
131+
Task {
132+
await model.cancel(application.id)
133+
}
134+
}
135+
125136
func openApp() {
126137
Task {
127138
await model.openApp(by: application.id) { result in

Flipper/Packages/UI/Sources/Hub/Apps/Components/AppRow.swift

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,24 @@ struct AppRow: View {
3333
.disabled(!isBuildReady)
3434

3535
if isInstalled {
36-
DeleteAppButton {
37-
showConfirmDelete = true
38-
}
39-
.frame(width: 34, height: 34)
40-
.alert(isPresented: $showConfirmDelete) {
41-
ConfirmDeleteAppAlert(
42-
isPresented: $showConfirmDelete,
43-
application: application,
44-
category: model.category(for: application)
45-
) {
46-
delete()
36+
if status.hasCancelOpportunity {
37+
CancelProgressAppButton {
38+
cancel()
39+
}
40+
.frame(width: 34, height: 34)
41+
} else {
42+
DeleteAppButton {
43+
showConfirmDelete = true
44+
}
45+
.frame(width: 34, height: 34)
46+
.alert(isPresented: $showConfirmDelete) {
47+
ConfirmDeleteAppAlert(
48+
isPresented: $showConfirmDelete,
49+
application: application,
50+
category: model.category(for: application)
51+
) {
52+
delete()
53+
}
4754
}
4855
}
4956
}
@@ -69,6 +76,12 @@ struct AppRow: View {
6976
}
7077
}
7178

79+
func cancel() {
80+
Task {
81+
await model.cancel(application.id)
82+
}
83+
}
84+
7285
struct AppRowActionButton: View {
7386
@EnvironmentObject var model: Applications
7487
@EnvironmentObject var device: Device

Flipper/Packages/UI/Sources/Hub/Apps/Components/Buttons.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,16 @@ struct UpdateAllAppButton: View {
5252
}
5353
}
5454

55-
struct DeleteAppButton: View {
56-
var action: () -> Void
55+
private struct ActionAppButton: View {
56+
let image: String
57+
let action: () -> Void
5758

5859
var body: some View {
5960
Button {
6061
action()
6162
} label: {
6263
GeometryReader { proxy in
63-
Image("AppDelete")
64+
Image(image)
6465
.resizable()
6566
.frame(
6667
width: proxy.size.width,
@@ -70,6 +71,22 @@ struct DeleteAppButton: View {
7071
}
7172
}
7273

74+
struct DeleteAppButton: View {
75+
var action: () -> Void
76+
77+
var body: some View {
78+
ActionAppButton(image: "AppDelete", action: action)
79+
}
80+
}
81+
82+
struct CancelProgressAppButton: View {
83+
var action: () -> Void
84+
85+
var body: some View {
86+
ActionAppButton(image: "AppCancel", action: action)
87+
}
88+
}
89+
7390
struct InstallAppButton: View {
7491
var action: () -> Void
7592

Lines changed: 4 additions & 0 deletions
Loading
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "AppCancel.svg",
5+
"idiom" : "universal",
6+
"scale" : "1x"
7+
},
8+
{
9+
"idiom" : "universal",
10+
"scale" : "2x"
11+
},
12+
{
13+
"idiom" : "universal",
14+
"scale" : "3x"
15+
}
16+
],
17+
"info" : {
18+
"author" : "xcode",
19+
"version" : 1
20+
}
21+
}

0 commit comments

Comments
 (0)