mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 13:33:42 +00:00
UI improvements
This commit is contained in:
parent
72d735e962
commit
c94687f54e
@ -2,28 +2,26 @@ import Foundation
|
|||||||
|
|
||||||
extension Int {
|
extension Int {
|
||||||
func formattedAsAbbreviation() -> String {
|
func formattedAsAbbreviation() -> String {
|
||||||
typealias Abbrevation = (threshold: Double, divisor: Double, suffix: String)
|
let num = fabs(Double(self))
|
||||||
let abbreviations: [Abbrevation] = [
|
|
||||||
(0, 1, ""), (1000.0, 1000.0, "K"),
|
|
||||||
(999_999.0, 1_000_000.0, "M"), (999_999_999.0, 1_000_000_000.0, "B")
|
|
||||||
]
|
|
||||||
|
|
||||||
let startValue = Double(abs(self))
|
guard num >= 1000.0 else {
|
||||||
|
|
||||||
guard let nextAbbreviationIndex = abbreviations.firstIndex(where: { startValue < $0.threshold }) else {
|
|
||||||
return String(self)
|
return String(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
let abbreviation = abbreviations[abbreviations.index(before: nextAbbreviationIndex)]
|
let exp = Int(log10(num) / 3.0)
|
||||||
|
let units = ["K", "M", "B", "T", "X"]
|
||||||
|
let unit = units[exp - 1]
|
||||||
|
|
||||||
let formatter = NumberFormatter()
|
let formatter = NumberFormatter()
|
||||||
|
|
||||||
formatter.positiveSuffix = abbreviation.suffix
|
formatter.positiveSuffix = unit
|
||||||
formatter.negativeSuffix = abbreviation.suffix
|
formatter.negativeSuffix = unit
|
||||||
formatter.allowsFloats = true
|
formatter.allowsFloats = true
|
||||||
formatter.minimumIntegerDigits = 1
|
formatter.minimumIntegerDigits = 1
|
||||||
formatter.minimumFractionDigits = 0
|
formatter.minimumFractionDigits = 0
|
||||||
formatter.maximumFractionDigits = 1
|
formatter.maximumFractionDigits = 1
|
||||||
|
|
||||||
return formatter.string(from: NSNumber(value: Double(self) / abbreviation.divisor))!
|
let roundedNum = round(10 * num / pow(1000.0, Double(exp))) / 10
|
||||||
|
return formatter.string(from: NSNumber(value: roundedNum))!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ struct FavoriteItem: Codable, Equatable, Identifiable, Defaults.Serializable {
|
|||||||
return "Popular"
|
return "Popular"
|
||||||
case let .trending(country, category):
|
case let .trending(country, category):
|
||||||
let trendingCountry = Country(rawValue: country)!
|
let trendingCountry = Country(rawValue: country)!
|
||||||
let trendingCategory = category.isNil ? nil : TrendingCategory(rawValue: category!)!
|
let trendingCategory = category.isNil ? nil : TrendingCategory(rawValue: category!)
|
||||||
return "\(trendingCountry.flag) \(trendingCountry.id) \(trendingCategory?.name ?? "Trending")"
|
return "\(trendingCountry.flag) \(trendingCountry.id) \(trendingCategory?.name ?? "Trending")"
|
||||||
case let .channel(_, name):
|
case let .channel(_, name):
|
||||||
return name
|
return name
|
||||||
|
@ -85,11 +85,19 @@ struct Video: Identifiable, Equatable, Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var likesCount: String? {
|
var likesCount: String? {
|
||||||
likes?.formattedAsAbbreviation()
|
guard likes != -1 else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return likes?.formattedAsAbbreviation()
|
||||||
}
|
}
|
||||||
|
|
||||||
var dislikesCount: String? {
|
var dislikesCount: String? {
|
||||||
dislikes?.formattedAsAbbreviation()
|
guard dislikes != -1 else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return dislikes?.formattedAsAbbreviation()
|
||||||
}
|
}
|
||||||
|
|
||||||
func thumbnailURL(quality: Thumbnail.Quality) -> URL? {
|
func thumbnailURL(quality: Thumbnail.Quality) -> URL? {
|
||||||
|
@ -2,32 +2,16 @@ import Defaults
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
extension Defaults.Keys {
|
extension Defaults.Keys {
|
||||||
static let invidiousInstanceID = "default-invidious-instance"
|
|
||||||
static let pipedInstanceID = "default-piped-instance"
|
|
||||||
static let privateAccountID = "default-private-invidious-account"
|
|
||||||
|
|
||||||
static let instances = Key<[Instance]>("instances", default: [
|
static let instances = Key<[Instance]>("instances", default: [
|
||||||
.init(
|
.init(
|
||||||
app: .piped,
|
app: .piped,
|
||||||
id: pipedInstanceID,
|
id: "default-piped-instance",
|
||||||
name: "Public",
|
name: "Kavin",
|
||||||
apiURL: "https://pipedapi.kavin.rocks",
|
apiURL: "https://pipedapi.kavin.rocks",
|
||||||
frontendURL: "https://piped.kavin.rocks"
|
frontendURL: "https://piped.kavin.rocks"
|
||||||
),
|
|
||||||
.init(app: .invidious,
|
|
||||||
id: invidiousInstanceID,
|
|
||||||
name: "Private",
|
|
||||||
apiURL: "https://invidious.home.arekf.net")
|
|
||||||
])
|
|
||||||
static let accounts = Key<[Account]>("accounts", default: [
|
|
||||||
.init(
|
|
||||||
id: privateAccountID,
|
|
||||||
instanceID: invidiousInstanceID,
|
|
||||||
name: "arekf",
|
|
||||||
url: "https://invidious.home.arekf.net",
|
|
||||||
sid: "ki55SJbaQmm0bOxUWctGAQLYPQRgk-CXDPw5Dp4oBmI="
|
|
||||||
)
|
)
|
||||||
])
|
])
|
||||||
|
static let accounts = Key<[Account]>("accounts", default: [])
|
||||||
static let lastAccountID = Key<Account.ID?>("lastAccountID")
|
static let lastAccountID = Key<Account.ID?>("lastAccountID")
|
||||||
static let lastInstanceID = Key<Instance.ID?>("lastInstanceID")
|
static let lastInstanceID = Key<Instance.ID?>("lastInstanceID")
|
||||||
static let lastUsedPlaylistID = Key<Playlist.ID?>("lastPlaylistID")
|
static let lastUsedPlaylistID = Key<Playlist.ID?>("lastPlaylistID")
|
||||||
@ -36,9 +20,8 @@ extension Defaults.Keys {
|
|||||||
static let sponsorBlockCategories = Key<Set<String>>("sponsorBlockCategories", default: Set(SponsorBlockAPI.categories))
|
static let sponsorBlockCategories = Key<Set<String>>("sponsorBlockCategories", default: Set(SponsorBlockAPI.categories))
|
||||||
|
|
||||||
static let favorites = Key<[FavoriteItem]>("favorites", default: [
|
static let favorites = Key<[FavoriteItem]>("favorites", default: [
|
||||||
.init(section: .trending("US", nil)),
|
.init(section: .trending("US", "default")),
|
||||||
.init(section: .searchQuery("World Discoveries", "", "", "")),
|
.init(section: .channel("UC-lHJZR3Gqxm24_Vd_AJ5Yw", "PewDiePie")),
|
||||||
.init(section: .searchQuery("Full Body Workout", "", "", "")),
|
|
||||||
.init(section: .searchQuery("Apple Pie Recipes", "", "", ""))
|
.init(section: .searchQuery("Apple Pie Recipes", "", "", ""))
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ struct FavoriteItemView: View {
|
|||||||
private var isVisible: Bool {
|
private var isVisible: Bool {
|
||||||
switch item.section {
|
switch item.section {
|
||||||
case .subscriptions:
|
case .subscriptions:
|
||||||
return accounts.app.supportsSubscriptions
|
return accounts.app.supportsSubscriptions && accounts.signedIn
|
||||||
case .popular:
|
case .popular:
|
||||||
return accounts.app.supportsPopular
|
return accounts.app.supportsPopular
|
||||||
default:
|
default:
|
||||||
@ -93,7 +93,7 @@ struct FavoriteItemView: View {
|
|||||||
|
|
||||||
case let .trending(country, category):
|
case let .trending(country, category):
|
||||||
let trendingCountry = Country(rawValue: country)!
|
let trendingCountry = Country(rawValue: country)!
|
||||||
let trendingCategory = category.isNil ? nil : TrendingCategory(rawValue: category!)!
|
let trendingCategory = category.isNil ? nil : TrendingCategory(rawValue: category!)
|
||||||
|
|
||||||
return accounts.api.trending(country: trendingCountry, category: trendingCategory)
|
return accounts.api.trending(country: trendingCountry, category: trendingCategory)
|
||||||
|
|
||||||
|
@ -33,19 +33,28 @@ struct VerticalCells: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var adaptiveItem: [GridItem] {
|
var adaptiveItem: [GridItem] {
|
||||||
[GridItem(.adaptive(minimum: adaptiveGridItemMinimumSize))]
|
[GridItem(.adaptive(minimum: adaptiveGridItemMinimumSize, maximum: adaptiveGridItemMaximumSize))]
|
||||||
}
|
}
|
||||||
|
|
||||||
var adaptiveGridItemMinimumSize: Double {
|
var adaptiveGridItemMinimumSize: Double {
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
return verticalSizeClass == .regular ? 320 : 800
|
return verticalSizeClass == .regular ? 320 : 800
|
||||||
#elseif os(tvOS)
|
#elseif os(tvOS)
|
||||||
return 500
|
return 600
|
||||||
#else
|
#else
|
||||||
return 320
|
return 320
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var adaptiveGridItemMaximumSize: Double {
|
||||||
|
#if os(tvOS)
|
||||||
|
return 600
|
||||||
|
#else
|
||||||
|
return .infinity
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var scrollViewShowsIndicators: Bool {
|
var scrollViewShowsIndicators: Bool {
|
||||||
#if !os(tvOS)
|
#if !os(tvOS)
|
||||||
true
|
true
|
||||||
@ -57,7 +66,7 @@ struct VerticalCells: View {
|
|||||||
|
|
||||||
struct VeticalCells_Previews: PreviewProvider {
|
struct VeticalCells_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
VerticalCells(items: ContentItem.array(of: Video.allFixtures))
|
VerticalCells(items: ContentItem.array(of: Array(repeating: Video.fixture, count: 30)))
|
||||||
.injectFixtureEnvironmentObjects()
|
.injectFixtureEnvironmentObjects()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,8 @@ final class IntFormatTests: XCTestCase {
|
|||||||
1101: "1,1K",
|
1101: "1,1K",
|
||||||
12345: "12,3K",
|
12345: "12,3K",
|
||||||
123_456: "123,5K",
|
123_456: "123,5K",
|
||||||
123_626_789: "123,6M"
|
123_626_789: "123,6M",
|
||||||
|
1_331_211_123: "1,3B"
|
||||||
]
|
]
|
||||||
|
|
||||||
samples.forEach { value, formatted in
|
samples.forEach { value, formatted in
|
||||||
|
@ -182,6 +182,7 @@
|
|||||||
3765917C27237D21009F956E /* PINCache in Frameworks */ = {isa = PBXBuildFile; productRef = 3765917B27237D21009F956E /* PINCache */; };
|
3765917C27237D21009F956E /* PINCache in Frameworks */ = {isa = PBXBuildFile; productRef = 3765917B27237D21009F956E /* PINCache */; };
|
||||||
3765917E27237D2A009F956E /* PINCache in Frameworks */ = {isa = PBXBuildFile; productRef = 3765917D27237D2A009F956E /* PINCache */; };
|
3765917E27237D2A009F956E /* PINCache in Frameworks */ = {isa = PBXBuildFile; productRef = 3765917D27237D2A009F956E /* PINCache */; };
|
||||||
37666BAA27023AF000F869E5 /* AccountSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37666BA927023AF000F869E5 /* AccountSelectionView.swift */; };
|
37666BAA27023AF000F869E5 /* AccountSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37666BA927023AF000F869E5 /* AccountSelectionView.swift */; };
|
||||||
|
3766AFD2273DA97D00686348 /* Int+FormatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BA796D26DC412E002A0235 /* Int+FormatTests.swift */; };
|
||||||
376A33E02720CAD6000C1D6B /* VideosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376A33DF2720CAD6000C1D6B /* VideosApp.swift */; };
|
376A33E02720CAD6000C1D6B /* VideosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376A33DF2720CAD6000C1D6B /* VideosApp.swift */; };
|
||||||
376A33E12720CAD6000C1D6B /* VideosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376A33DF2720CAD6000C1D6B /* VideosApp.swift */; };
|
376A33E12720CAD6000C1D6B /* VideosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376A33DF2720CAD6000C1D6B /* VideosApp.swift */; };
|
||||||
376A33E22720CAD6000C1D6B /* VideosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376A33DF2720CAD6000C1D6B /* VideosApp.swift */; };
|
376A33E22720CAD6000C1D6B /* VideosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376A33DF2720CAD6000C1D6B /* VideosApp.swift */; };
|
||||||
@ -2044,6 +2045,7 @@
|
|||||||
3774123327387CB000423605 /* Defaults.swift in Sources */,
|
3774123327387CB000423605 /* Defaults.swift in Sources */,
|
||||||
3774123527387CC700423605 /* PipedAPI.swift in Sources */,
|
3774123527387CC700423605 /* PipedAPI.swift in Sources */,
|
||||||
3774124E27387D2300423605 /* Playlist.swift in Sources */,
|
3774124E27387D2300423605 /* Playlist.swift in Sources */,
|
||||||
|
3766AFD2273DA97D00686348 /* Int+FormatTests.swift in Sources */,
|
||||||
3774124F27387D2300423605 /* SubscriptionsModel.swift in Sources */,
|
3774124F27387D2300423605 /* SubscriptionsModel.swift in Sources */,
|
||||||
3774126127387D2D00423605 /* AccountsModel.swift in Sources */,
|
3774126127387D2D00423605 /* AccountsModel.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user