@@ -4,10 +4,15 @@ import Foundation
44
55public struct AppDetailView : View {
66 let app : AltApp
7+
8+ // Manager that controls download/sign flow (your existing class)
79 @StateObject private var downloadManager = DownloadSignManager ( )
10+
11+ // Read certificate selection from the shared CertificatesManager
12+ @ObservedObject private var certificatesManager = CertificatesManager . shared
13+
814 @Environment ( \. dismiss) private var dismiss
915
10- // NEW: alert state for missing certificate
1116 @State private var showCertError = false
1217
1318 private var latestVersion : AppVersion ? {
@@ -33,7 +38,7 @@ public struct AppDetailView: View {
3338 ScrollView {
3439 VStack ( alignment: . leading, spacing: 16 ) {
3540
36- // App Header
41+ // App Header (icon + meta)
3742 HStack ( alignment: . top, spacing: 16 ) {
3843 ZStack {
3944 RoundedRectangle ( cornerRadius: 12 )
@@ -152,7 +157,7 @@ public struct AppDetailView: View {
152157 }
153158 }
154159
155- // Screenshots (from general app)
160+ // Screenshots
156161 if let screenshots = app. screenshotURLs, !screenshots. isEmpty {
157162 ScrollView ( . horizontal, showsIndicators: false ) {
158163 HStack ( spacing: 12 ) {
@@ -189,21 +194,21 @@ public struct AppDetailView: View {
189194 }
190195 }
191196
192- Spacer ( minLength: 80 ) // Space for the progress bar
197+ Spacer ( minLength: 80 ) // space for progress bar
193198 }
194199 . frame ( maxWidth: . infinity, alignment: . leading)
195200 . padding ( )
196201 }
197-
198- // Floating Download Button
202+
203+ // Floating Install button
199204 if !downloadManager. isProcessing {
200205 VStack {
201206 Spacer ( )
202207 HStack {
203208 Spacer ( )
204209 Button ( action: {
205- // CHECK: show error immediately if no cert selected
206- if downloadManager . selectedCertificate == nil {
210+ // Immediate certificate check from CertificatesManager
211+ if certificatesManager . selectedCertificate == nil {
207212 showCertError = true
208213 return
209214 }
@@ -221,25 +226,27 @@ public struct AppDetailView: View {
221226 . cornerRadius ( 25 )
222227 . shadow ( radius: 5 )
223228 }
229+ . disabled ( certificatesManager. selectedCertificate == nil )
230+ . opacity ( certificatesManager. selectedCertificate == nil ? 0.6 : 1.0 )
224231 . padding ( . trailing, 20 )
225232 . padding ( . bottom, 20 )
226233 }
227234 }
228235 }
229-
230- // Progress Bar (fixed at bottom, not part of scroll )
236+
237+ // Progress Bar (fixed at bottom)
231238 if downloadManager. isProcessing {
232239 VStack ( spacing: 0 ) {
233240 Rectangle ( )
234241 . fill ( Color . gray. opacity ( 0.1 ) )
235242 . frame ( height: 1 )
236-
243+
237244 VStack ( spacing: 8 ) {
238245 HStack {
239246 ProgressView ( value: downloadManager. progress, total: 1.0 )
240247 . progressViewStyle ( LinearProgressViewStyle ( tint: downloadManager. showSuccess ? . green : . blue) )
241248 . scaleEffect ( x: 1 , y: 1.5 , anchor: . center)
242-
249+
243250 if downloadManager. showSuccess {
244251 Image ( systemName: " checkmark.circle.fill " )
245252 . foregroundColor ( . green)
@@ -251,16 +258,16 @@ public struct AppDetailView: View {
251258 . frame ( width: 40 )
252259 }
253260 }
254-
261+
255262 HStack {
256263 Text ( downloadManager. status)
257264 . font ( . caption)
258265 . foregroundColor ( downloadManager. showSuccess ? . green : . secondary)
259266 . lineLimit ( 1 )
260267 . truncationMode ( . middle)
261-
268+
262269 Spacer ( )
263-
270+
264271 if !downloadManager. showSuccess {
265272 Button ( " Cancel " ) {
266273 downloadManager. cancel ( )
@@ -288,8 +295,7 @@ public struct AppDetailView: View {
288295 . foregroundColor ( . red)
289296 } else if app. downloadURL != nil {
290297 Button ( action: {
291- // Also check here if you want consistent behaviour
292- if downloadManager. selectedCertificate == nil {
298+ if certificatesManager. selectedCertificate == nil {
293299 showCertError = true
294300 return
295301 }
@@ -300,10 +306,11 @@ public struct AppDetailView: View {
300306 Text ( " Download " )
301307 }
302308 }
309+ . disabled ( certificatesManager. selectedCertificate == nil )
310+ . opacity ( certificatesManager. selectedCertificate == nil ? 0.6 : 1.0 )
303311 }
304312 }
305313 }
306- // ALERT: shown immediately when no certificate selected
307314 . alert ( " Please select a certificate first! " , isPresented: $showCertError) {
308315 Button ( " OK " , role: . cancel) { }
309316 }
0 commit comments