Skip to content

Commit b8950ac

Browse files
committed
Attempting to fix compile error
1 parent 9324d3d commit b8950ac

1 file changed

Lines changed: 145 additions & 113 deletions

File tree

StikJIT/Views/ProfileView.swift

Lines changed: 145 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -131,123 +131,23 @@ struct ProfileView: View {
131131
@State private var confirmRemove = false
132132
@State private var removeTargetName: String = ""
133133
@State private var removeTargetUUID: String = ""
134-
135-
134+
135+
// Computed strings to reduce body complexity
136+
private var removeProfileText: String {
137+
String(format: "Remove profile for %@ (UUID: %@)?\nApps associated with this profile may become unavailable.".localized, removeTargetName, removeTargetUUID)
138+
}
139+
136140
var body: some View {
137141
NavigationStack {
138142
List {
139-
if working && entries.isEmpty {
140-
Section {
141-
HStack {
142-
Spacer()
143-
ProgressView("Loading...")
144-
Spacer()
145-
}
146-
}
147-
} else if entries.isEmpty && notMatchedProfiles.isEmpty {
148-
Section {
149-
Text("No profiles found.")
150-
.foregroundStyle(.secondary)
151-
}
152-
}
153-
154-
ForEach(entries) { entry in
155-
Section {
156-
// Header/Status Row
157-
VStack(alignment: .leading, spacing: 4) {
158-
if let match = entry.bestMatchingProfile {
159-
HStack {
160-
Image(systemName: "clock")
161-
Text(String(format: "Expires: %@"), match.profile.formattedDate)
162-
}
163-
.foregroundStyle(match.profile.dateColor)
164-
.font(.subheadline)
165-
} else {
166-
HStack {
167-
Image(systemName: "exclamationmark.triangle")
168-
Text("No matching profile")
169-
}
170-
.font(.subheadline)
171-
.foregroundColor(.refreshRed)
172-
}
173-
174-
Text(entry.id)
175-
.font(.caption.monospaced())
176-
.foregroundStyle(.secondary)
177-
.textSelection(.enabled)
178-
}
179-
180-
// Profiles
181-
if let recent = entry.mostRecentProfile {
182-
profileRow(match: recent, isMostRecent: true)
183-
}
184-
185-
if let best = entry.bestMatchingProfile, best.profile.uuid != entry.mostRecentProfile?.profile.uuid {
186-
profileRow(match: best, isMostRecent: false)
187-
}
188-
189-
if entry.profileMatches.count > 1 {
190-
let showMore = expandedApps.contains(entry.id)
191-
let extraProfiles = entry.profileMatches.dropFirst(recentAndBestCount(for: entry))
192-
193-
if !extraProfiles.isEmpty {
194-
if showMore {
195-
ForEach(extraProfiles, id: \.profile.uuid) { match in
196-
profileRow(match: match, isMostRecent: false)
197-
}
198-
}
199-
200-
Button {
201-
withAnimation {
202-
if showMore { expandedApps.remove(entry.id) }
203-
else { expandedApps.insert(entry.id) }
204-
}
205-
} label: {
206-
Label(showMore ? String(format: "Hide older profiles".localized) : String(format: "Show %d older profiles".localized, extraProfiles.count),
207-
systemImage: showMore ? "chevron.up" : "chevron.down")
208-
.font(.caption)
209-
.foregroundStyle(.blue)
210-
}
211-
}
212-
}
213-
} header: {
214-
Text(entry.name)
215-
}
216-
}
217-
218-
if !notMatchedProfiles.isEmpty {
219-
Section("Other Profiles") {
220-
ForEach(notMatchedProfiles) { entry in
221-
VStack(alignment: .leading) {
222-
Text(entry.id)
223-
.font(.caption.monospaced())
224-
.foregroundStyle(.primary)
225-
}
226-
227-
ForEach(entry.profileMatches, id: \.profile.uuid) { match in
228-
profileRow(match: match, isMostRecent: false)
229-
}
230-
}
231-
}
232-
}
143+
loadingOrEmptySection
144+
appEntriesSection
145+
otherProfilesSection
233146
}
234147
.listStyle(.insetGrouped)
235148
.navigationTitle("App Expiry")
236149
.toolbar {
237-
ToolbarItemGroup(placement: .navigationBarTrailing) {
238-
Button {
239-
isImporterPresented = true
240-
} label: {
241-
Label("Add", systemImage: "plus")
242-
}
243-
244-
Button {
245-
Task { await loadData(force: true) }
246-
} label: {
247-
Label("Reload", systemImage: "arrow.clockwise")
248-
}
249-
250-
}
150+
toolbarContent
251151
}
252152
.onAppear { Task { await loadData() } }
253153
.fileImporter(
@@ -271,7 +171,7 @@ struct ProfileView: View {
271171
}
272172
}
273173
}
274-
.alert(alertTitle, isPresented: $alert) {
174+
.alert(alertTitle, isPresented: $alert) {
275175
Button("OK", role: .cancel) { }
276176
} message: {
277177
Text(alertMsg)
@@ -282,10 +182,142 @@ struct ProfileView: View {
282182
}
283183
Button("Cancel", role: .cancel) { }
284184
} message: {
285-
Text(String(format: "Remove profile for %@ (UUID: %@)?\nApps associated with this profile may become unavailable.".localized, removeTargetName, removeTargetUUID))
185+
Text(removeProfileText)
286186
}
287187
}
288-
188+
189+
@ViewBuilder
190+
private var loadingOrEmptySection: some View {
191+
if working && entries.isEmpty {
192+
Section {
193+
HStack {
194+
Spacer()
195+
ProgressView("Loading...")
196+
Spacer()
197+
}
198+
}
199+
} else if entries.isEmpty && notMatchedProfiles.isEmpty {
200+
Section {
201+
Text("No profiles found.")
202+
.foregroundStyle(.secondary)
203+
}
204+
}
205+
}
206+
207+
@ViewBuilder
208+
private var appEntriesSection: some View {
209+
ForEach(entries) { entry in
210+
Section {
211+
entryStatusRow(entry: entry)
212+
profilesList(for: entry)
213+
} header: {
214+
Text(entry.name)
215+
}
216+
}
217+
}
218+
219+
@ViewBuilder
220+
private var otherProfilesSection: some View {
221+
if !notMatchedProfiles.isEmpty {
222+
Section("Other Profiles") {
223+
ForEach(notMatchedProfiles) { entry in
224+
VStack(alignment: .leading) {
225+
Text(entry.id)
226+
.font(.caption.monospaced())
227+
.foregroundStyle(.primary)
228+
}
229+
230+
ForEach(entry.profileMatches, id: \.profile.uuid) { match in
231+
profileRow(match: match, isMostRecent: false)
232+
}
233+
}
234+
}
235+
}
236+
}
237+
238+
@ToolbarContentBuilder
239+
private var toolbarContent: some ToolbarContent {
240+
ToolbarItemGroup(placement: .navigationBarTrailing) {
241+
Button {
242+
isImporterPresented = true
243+
} label: {
244+
Label("Add", systemImage: "plus")
245+
}
246+
247+
Button {
248+
Task { await loadData(force: true) }
249+
} label: {
250+
Label("Reload", systemImage: "arrow.clockwise")
251+
}
252+
}
253+
}
254+
255+
@ViewBuilder
256+
private func entryStatusRow(entry: AppProfileStatus) -> some View {
257+
VStack(alignment: .leading, spacing: 4) {
258+
if let match = entry.bestMatchingProfile {
259+
HStack {
260+
Image(systemName: "clock")
261+
Text(String(format: "Expires: %@", match.profile.formattedDate))
262+
}
263+
.foregroundStyle(match.profile.dateColor)
264+
.font(.subheadline)
265+
} else {
266+
HStack {
267+
Image(systemName: "exclamationmark.triangle")
268+
Text("No matching profile")
269+
}
270+
.font(.subheadline)
271+
.foregroundColor(.refreshRed)
272+
}
273+
274+
Text(entry.id)
275+
.font(.caption.monospaced())
276+
.foregroundStyle(.secondary)
277+
.textSelection(.enabled)
278+
}
279+
}
280+
281+
@ViewBuilder
282+
private func profilesList(for entry: AppProfileStatus) -> some View {
283+
if let recent = entry.mostRecentProfile {
284+
profileRow(match: recent, isMostRecent: true)
285+
}
286+
287+
if let best = entry.bestMatchingProfile, best.profile.uuid != entry.mostRecentProfile?.profile.uuid {
288+
profileRow(match: best, isMostRecent: false)
289+
}
290+
291+
if entry.profileMatches.count > 1 {
292+
let showMore = expandedApps.contains(entry.id)
293+
let extraProfiles = entry.profileMatches.dropFirst(recentAndBestCount(for: entry))
294+
295+
if !extraProfiles.isEmpty {
296+
if showMore {
297+
ForEach(extraProfiles, id: \.profile.uuid) { match in
298+
profileRow(match: match, isMostRecent: false)
299+
}
300+
}
301+
302+
showMoreButton(showMore: showMore, extraCount: extraProfiles.count, entryId: entry.id)
303+
}
304+
}
305+
}
306+
307+
private func showMoreButton(showMore: Bool, extraCount: Int, entryId: String) -> some View {
308+
Button {
309+
withAnimation {
310+
if showMore { expandedApps.remove(entryId) }
311+
else { expandedApps.insert(entryId) }
312+
}
313+
} label: {
314+
Label(showMore ? "Hide older profiles".localized : String(format: "Show %d older profiles".localized, extraCount),
315+
systemImage: showMore ? "chevron.up" : "chevron.down")
316+
.font(.caption)
317+
.foregroundStyle(.blue)
318+
}
319+
}
320+
289321
private func profileActionButton(icon: String, color: Color, action: @escaping () -> Void) -> some View {
290322
Button(action: action) {
291323
Image(systemName: icon)

0 commit comments

Comments
 (0)