Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Ruddarr/Models/Queue/QueueItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,17 @@ struct QueueItem: Codable, Identifiable, Equatable {

var progressLabel: String {
guard sizeleft > 0 else { return 100.formatted(.percent) }
return ((size - sizeleft) / size).formatted(.percent.precision(.fractionLength(1)))
return progressFraction.formatted(.percent.precision(.fractionLength(1)))
}

var progressFraction: Float {
guard size > 0 else { return sizeleft <= 0 ? 1 : 0 }
return min(max((size - sizeleft) / size, 0), 1)
}

var hasDownloadProgress: Bool {
trackedDownloadState == .downloading ||
status == "downloading"
}

var remainingLabel: String? {
Expand Down
55 changes: 48 additions & 7 deletions Ruddarr/Views/Calendar/CalendarMedia.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import SwiftUI
struct CalendarMovie: View {
var date: Date
var movie: Movie
var downloadProgress: Float?

@EnvironmentObject var settings: AppSettings

Expand All @@ -17,10 +18,7 @@ struct CalendarMovie: View {

Spacer()

statusIcon
.font(.subheadline)
.imageScale(.small)
.foregroundStyle(.secondary)
status
}

if let type = movie.releaseType(for: date) {
Expand Down Expand Up @@ -51,6 +49,18 @@ struct CalendarMovie: View {
!movie.monitored && !movie.isDownloaded
}

@ViewBuilder
var status: some View {
if let downloadProgress {
CalendarDownloadProgress(progress: downloadProgress)
} else {
statusIcon
.font(.subheadline)
.imageScale(.small)
.foregroundStyle(.secondary)
}
}

@ViewBuilder
var statusIcon: some View {
if movie.isDownloaded {
Expand All @@ -67,6 +77,7 @@ struct CalendarMovie: View {

struct CalendarEpisode: View {
var episode: Episode
var downloadProgress: Float?

@EnvironmentObject var settings: AppSettings

Expand Down Expand Up @@ -97,9 +108,7 @@ struct CalendarEpisode: View {

Spacer()

statusIcon
.foregroundStyle(.secondary)
.imageScale(.small)
status
}
.foregroundStyle(.secondary)
.font(.subheadline)
Expand Down Expand Up @@ -154,6 +163,17 @@ struct CalendarEpisode: View {
}
}

@ViewBuilder
var status: some View {
if let downloadProgress {
CalendarDownloadProgress(progress: downloadProgress)
} else {
statusIcon
.foregroundStyle(.secondary)
.imageScale(.small)
}
}

@ViewBuilder
var statusIcon: some View {
if episode.isDownloaded {
Expand All @@ -172,6 +192,27 @@ struct CalendarEpisode: View {
}
}

private struct CalendarDownloadProgress: View {
var progress: Float

@EnvironmentObject var settings: AppSettings

var body: some View {
ZStack {
Circle()
.stroke(.secondary.opacity(0.28), lineWidth: 2)

Circle()
.trim(from: 0, to: CGFloat(progress))
.stroke(settings.theme.tint, style: StrokeStyle(lineWidth: 2, lineCap: .round))
.rotationEffect(.degrees(-90))
}
.frame(width: 18, height: 18)
.accessibilityLabel("Downloading")
.accessibilityValue(progress.formatted(.percent.precision(.fractionLength(0))))
}
}

enum CalendarMediaType: CaseIterable {
case all
case movies
Expand Down
56 changes: 54 additions & 2 deletions Ruddarr/Views/CalendarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import SwiftUI

struct CalendarView: View {
@State var calendar = MediaCalendar()
@State var queue = Queue.shared

@State private var scrollView: ScrollViewProxy?
@State private var initializationError: API.Error?
Expand Down Expand Up @@ -80,6 +81,8 @@ struct CalendarView: View {
todayButton
}
.onAppear {
queue.instances = settings.instances

if Set(calendar.instances.map(\.id)) != Set(settings.instances.map(\.id)) {
calendar.reset()
calendar.instances = settings.instances
Expand All @@ -94,6 +97,10 @@ struct CalendarView: View {
.task {
await load()
}
.task {
queue.instances = settings.instances
await queue.fetchTasks()
}
.alert(
isPresented: $alertPresented,
error: calendar.error
Expand Down Expand Up @@ -241,13 +248,20 @@ struct CalendarView: View {
VStack(spacing: 8) {
if displayMovies, let movies = filteredMovies[timestamp] {
ForEach(movies) { movie in
CalendarMovie(date: date, movie: movie)
CalendarMovie(
date: date,
movie: movie,
downloadProgress: downloadProgress(for: movie)
)
}
}

if displaySeries, let episodes = filteredEpisodes[timestamp] {
ForEach(episodes) { episode in
CalendarEpisode(episode: episode)
CalendarEpisode(
episode: episode,
downloadProgress: downloadProgress(for: episode)
)
}
}

Expand Down Expand Up @@ -371,6 +385,44 @@ struct CalendarView: View {
}
}

extension CalendarView {
var activeQueueItems: [QueueItem] {
queue.items
.flatMap { $0.value }
.filter(\.hasDownloadProgress)
}

func activeDownload(for movie: Movie) -> QueueItem? {
activeQueueItems.first {
$0.instanceId == movie.instanceId &&
$0.movieId == movie.id
}
}

func downloadProgress(for movie: Movie) -> Float? {
activeDownload(for: movie)?.progressFraction
}

func activeDownload(for episode: Episode) -> QueueItem? {
activeQueueItems.first {
guard $0.instanceId == episode.instanceId else {
return false
}

if let episodeId = $0.episodeId {
return episodeId == episode.id
}

return $0.seriesId == episode.seriesId &&
$0.seasonNumber == episode.seasonNumber
}
}

func downloadProgress(for episode: Episode) -> Float? {
activeDownload(for: episode)?.progressFraction
}
}

// swiftlint:disable file_length
#Preview {
dependencies.router.selectedTab = .calendar
Expand Down