5
5
6
6
import SwiftUI
7
7
8
-
9
8
struct IPFSStatusView : View {
10
9
@EnvironmentObject private var ipfsState : IPFSState
10
+ @State private var showingGCAlert = false
11
11
12
12
static let formatter = {
13
13
let byteCountFormatter = ByteCountFormatter ( )
@@ -45,7 +45,21 @@ struct IPFSStatusView: View {
45
45
ProgressView ( )
46
46
. progressViewStyle ( . circular)
47
47
. controlSize ( . small)
48
- } else {
48
+ }
49
+ else {
50
+ Button {
51
+ showingGCAlert = true
52
+ } label: {
53
+ Image ( systemName: " arrow.3.trianglepath " )
54
+ . resizable ( )
55
+ . aspectRatio ( contentMode: . fit)
56
+ . frame ( height: 15 )
57
+ . foregroundStyle ( Color . secondary)
58
+ }
59
+ . buttonStyle ( . plain)
60
+ . help ( " Run IPFS garbage collection. " )
61
+ . disabled ( !ipfsState. online)
62
+
49
63
if !ipfsState. isShowingStatusWindow {
50
64
Button {
51
65
IPFSStatusWindowManager . shared. activate ( )
@@ -66,14 +80,18 @@ struct IPFSStatusView: View {
66
80
Task . detached ( priority: . userInitiated) {
67
81
if newValue {
68
82
try ? await IPFSDaemon . shared. launch ( )
69
- } else {
83
+ }
84
+ else {
70
85
try ? await IPFSDaemon . shared. shutdown ( )
71
86
}
72
87
await IPFSState . shared. updateStatus ( )
73
88
await MainActor . run {
74
89
self . isDaemonOnline = newValue
75
90
}
76
- UserDefaults . standard. setValue ( newValue, forKey: IPFSState . lastUserLaunchState)
91
+ UserDefaults . standard. setValue (
92
+ newValue,
93
+ forKey: IPFSState . lastUserLaunchState
94
+ )
77
95
}
78
96
}
79
97
}
@@ -83,14 +101,32 @@ struct IPFSStatusView: View {
83
101
. padding ( . vertical, 12 )
84
102
. frame ( height: 44 )
85
103
}
86
- . padding ( 0 )
104
+ . background ( . regularMaterial)
105
+ . alert ( isPresented: $showingGCAlert) {
106
+ Alert (
107
+ title: Text ( " Are you sure you want to manually run garbage collection? " ) ,
108
+ message: Text ( " This will free up disk space by removing unused data. " ) ,
109
+ primaryButton: . destructive( Text ( " Run GC " ) ) {
110
+ Task {
111
+ do {
112
+ try await IPFSDaemon . shared. gc ( )
113
+ }
114
+ catch {
115
+ debugPrint ( " failed to run gc: \( error) " )
116
+ }
117
+ }
118
+ } ,
119
+ secondaryButton: . cancel( )
120
+ )
121
+ }
87
122
. frame ( width: 280 )
88
123
. background ( . regularMaterial)
89
124
. task {
90
125
Task . detached ( priority: . background) {
91
126
do {
92
127
try await self . ipfsState. calculateRepoSize ( )
93
- } catch {
128
+ }
129
+ catch {
94
130
debugPrint ( " failed to calculate repo size: \( error) " )
95
131
}
96
132
}
@@ -103,9 +139,15 @@ struct IPFSStatusView: View {
103
139
HStack {
104
140
Text ( " Local Gateway " )
105
141
Spacer ( minLength: 1 )
106
- Link ( self . ipfsState. getGateway ( ) , destination: URL ( string: self . ipfsState. getGateway ( ) + " /ipns/k51qzi5uqu5dibstm2yxidly22jx94embd7j3xjstfk65ulictn2ajnjvpiac7 " ) !)
107
- . focusable ( false )
108
- . disabled ( !self . ipfsState. online)
142
+ Link (
143
+ self . ipfsState. getGateway ( ) ,
144
+ destination: URL (
145
+ string: self . ipfsState. getGateway ( )
146
+ + " /ipns/k51qzi5uqu5dibstm2yxidly22jx94embd7j3xjstfk65ulictn2ajnjvpiac7 "
147
+ ) !
148
+ )
149
+ . focusable ( false )
150
+ . disabled ( !self . ipfsState. online)
109
151
}
110
152
HStack {
111
153
Text ( " Repo Size " )
@@ -114,7 +156,8 @@ struct IPFSStatusView: View {
114
156
ProgressView ( )
115
157
. progressViewStyle ( . circular)
116
158
. controlSize ( . mini)
117
- } else {
159
+ }
160
+ else {
118
161
if let repoSize = ipfsState. repoSize {
119
162
Text ( Self . formatter. string ( fromByteCount: repoSize) )
120
163
}
0 commit comments