diff --git a/Sources/TVAnarchy/OfflineCacheView.swift b/Sources/TVAnarchy/OfflineCacheView.swift index fb19aa2..49a0099 100644 --- a/Sources/TVAnarchy/OfflineCacheView.swift +++ b/Sources/TVAnarchy/OfflineCacheView.swift @@ -104,23 +104,18 @@ struct OfflineCacheView: View { } } - if !pinnedItems.isEmpty { - Section { - ForEach(pinnedItems) { item in - row(for: item) - } - } header: { - sectionHeader("Starred (kept from cull) · \(pinnedItems.count)") - } - } - - ForEach(nonPinnedGrouped, id: \.show) { group in + // Items stay in their own show group regardless of star + // state — starring just toggles the star on the row (and + // protection from cull), it doesn't relocate the file. + ForEach(groupedFiltered, id: \.show) { group in Section { ForEach(group.items) { item in row(for: item) } } header: { - sectionHeader("\(group.show) · \(group.items.count)") + let starred = group.items.filter(isPinned).count + sectionHeader("\(group.show) · \(group.items.count)" + + (starred > 0 ? " · ★\(starred)" : "")) } } } @@ -187,14 +182,6 @@ struct OfflineCacheView: View { .sorted { $0.modifiedAt > $1.modifiedAt } } - private var nonPinnedGrouped: [(show: String, items: [OfflineCachedFile])] { - let pinSet = Set(localPolicy.pinned.map { $0.lowercased() }) - let non = filteredItems.filter { !pinSet.contains($0.name.lowercased()) } - let dict = Dictionary(grouping: non, by: \.showDir) - return dict.keys.sorted { $0.localizedCaseInsensitiveCompare($1) == .orderedAscending } - .map { k in (k, dict[k]!.sorted { $0.modifiedAt > $1.modifiedAt }) } - } - private var canPlayAll: Bool { !filteredItems.isEmpty } private var localDevice: DeviceConfig? { @@ -279,17 +266,10 @@ struct OfflineCacheView: View { private func row(for item: OfflineCachedFile) -> some View { HStack(spacing: 10) { - if isPinned(item) { - Image(systemName: "star.fill") - .font(.caption) - .foregroundStyle(.yellow) - .frame(width: 20) - } else { - Image(systemName: "play.rectangle.on.rectangle.fill") - .font(.body) - .foregroundStyle(.tint) - .frame(width: 20) - } + Image(systemName: "play.rectangle.on.rectangle.fill") + .font(.body) + .foregroundStyle(.tint) + .frame(width: 20) VStack(alignment: .leading, spacing: 1) { Text(item.name)