Files
SideStore/AltWidget/Countdown.swift
Riley Testut b7caaeb788 [AltWidget] Fixes incorrect days until expiration
Previously, we used Date() to calculate the number of days until apps expired. This meant all calculations were based on when the widget extension was run — not when it was actually displayed. As a result, this made it seem like the widget never updated since all timeline entries were calculated from the same date.

Now, we instead calculate remaining days from AppEntry.date. This means the widget’s remaining days are relative to the current timeline entry’s date, matching what is displayed in AltStore.
2021-10-04 17:51:14 -07:00

81 lines
2.5 KiB
Swift

//
// Countdown.swift
// AltWidgetExtension
//
// Created by Riley Testut on 7/6/20.
// Copyright © 2020 Riley Testut. All rights reserved.
//
import SwiftUI
import WidgetKit
struct Countdown: View
{
var startDate: Date?
var endDate: Date?
var currentDate: Date = Date()
@Environment(\.font) private var font
private var numberOfDays: Int {
guard let date = self.endDate else { return 0 }
let numberOfDays = date.numberOfCalendarDays(since: self.currentDate)
return numberOfDays
}
private var fractionComplete: CGFloat {
guard let startDate = self.startDate, let endDate = self.endDate else { return 1.0 }
let totalNumberOfDays = endDate.numberOfCalendarDays(since: startDate)
let fractionComplete = CGFloat(self.numberOfDays) / CGFloat(totalNumberOfDays)
return fractionComplete
}
@ViewBuilder
private func overlay(progress: CGFloat) -> some View
{
let strokeStyle = StrokeStyle(lineWidth: 4.0, lineCap: .round, lineJoin: .round)
if self.numberOfDays > 9 || self.numberOfDays < 0 {
Capsule(style: .continuous)
.trim(from: 0.0, to: progress)
.stroke(style: strokeStyle)
}
else {
Circle()
.trim(from: 0.0, to: progress)
.rotation(Angle(degrees: -90), anchor: .center)
.stroke(style: strokeStyle)
}
}
var body: some View {
Text("\(numberOfDays)")
.font((font ?? .title).monospacedDigit())
.bold()
.opacity(endDate != nil ? 1 : 0)
.padding(.horizontal, 12)
.padding(.vertical, 6)
.overlay(
ZStack {
overlay(progress: 1.0)
.opacity(0.3)
overlay(progress: fractionComplete)
}
)
}
}
struct Countdown_Previews: PreviewProvider {
static var previews: some View {
let startDate = Calendar.current.date(byAdding: .day, value: -2, to: Date()) ?? Date()
Group {
Countdown(startDate: startDate, endDate: Calendar.current.date(byAdding: .day, value: 7, to: startDate))
Countdown(startDate: startDate, endDate: Calendar.current.date(byAdding: .day, value: 365, to: startDate))
}
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}