Fix iOS 15 Poster Buttons (#1172)
This commit is contained in:
parent
e4fd98c244
commit
d85ffb4156
|
@ -90,11 +90,13 @@ extension String {
|
|||
.replacingOccurrences(of: ".swift", with: "")
|
||||
}
|
||||
|
||||
// TODO: fix if count > 62
|
||||
static func random(count: Int) -> String {
|
||||
let characters = Self.alphanumeric.randomSample(count: count)
|
||||
return String(characters)
|
||||
}
|
||||
|
||||
// TODO: fix if upper bound > 62
|
||||
static func random(count range: Range<Int>) -> String {
|
||||
let characters = Self.alphanumeric.randomSample(count: Int.random(in: range))
|
||||
return String(characters)
|
||||
|
@ -114,6 +116,20 @@ extension String {
|
|||
|
||||
return s
|
||||
}
|
||||
|
||||
// TODO: remove after iOS 15 support removed
|
||||
|
||||
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
|
||||
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
|
||||
let boundingBox = self.boundingRect(
|
||||
with: constraintRect,
|
||||
options: .usesLineFragmentOrigin,
|
||||
attributes: [.font: font],
|
||||
context: nil
|
||||
)
|
||||
|
||||
return ceil(boundingBox.height)
|
||||
}
|
||||
}
|
||||
|
||||
extension CharacterSet {
|
||||
|
|
|
@ -31,8 +31,16 @@ extension Backport where Content: View {
|
|||
content
|
||||
.lineLimit(limit, reservesSpace: reservesSpace)
|
||||
} else {
|
||||
// This may still not be enough and will probably have to
|
||||
// use String.height in a frame as caller site
|
||||
//
|
||||
// The `.font` modifier must come after this modifier in
|
||||
// order for the layout and content fonts to match
|
||||
ZStack(alignment: .top) {
|
||||
Text(String(repeating: " \n", count: limit))
|
||||
if reservesSpace {
|
||||
Text("A" + String(repeating: "A\nA", count: limit - 1))
|
||||
.hidden()
|
||||
}
|
||||
|
||||
content
|
||||
.lineLimit(limit)
|
||||
|
|
|
@ -37,7 +37,5 @@ struct EnvironmentModifier<Wrapped: View, Value>: ViewModifier {
|
|||
|
||||
func body(content: Content) -> some View {
|
||||
wrapped(environmentValue)
|
||||
|
||||
// wrapped(content)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,24 +42,27 @@ final class UserSession {
|
|||
extension Container {
|
||||
var currentUserSession: Factory<UserSession?> {
|
||||
self {
|
||||
if let lastUserID = Defaults[.lastSignedInUserID],
|
||||
let user = try? SwiftfinStore.dataStack.fetchOne(
|
||||
From<UserModel>().where(\.$id == lastUserID)
|
||||
)
|
||||
{
|
||||
guard let server = user.server,
|
||||
let _ = SwiftfinStore.dataStack.fetchExisting(server)
|
||||
else {
|
||||
fatalError("No associated server for last user")
|
||||
}
|
||||
guard let lastUserID = Defaults[.lastSignedInUserID] else { return nil }
|
||||
|
||||
return .init(
|
||||
server: server.state,
|
||||
user: user.state
|
||||
)
|
||||
guard let user = try? SwiftfinStore.dataStack.fetchOne(
|
||||
From<UserModel>().where(\.$id == lastUserID)
|
||||
) else {
|
||||
// had last user ID but no saved user
|
||||
Defaults[.lastSignedInUserID] = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
guard let server = user.server,
|
||||
let _ = SwiftfinStore.dataStack.fetchExisting(server)
|
||||
else {
|
||||
fatalError("No associated server for last user")
|
||||
}
|
||||
|
||||
return .init(
|
||||
server: server.state,
|
||||
user: user.state
|
||||
)
|
||||
}.cached
|
||||
}
|
||||
}
|
||||
|
|
|
@ -824,6 +824,7 @@
|
|||
E1DABAFA2A270E62008AC34A /* OverviewCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1DABAF92A270E62008AC34A /* OverviewCard.swift */; };
|
||||
E1DABAFC2A270EE7008AC34A /* MediaSourcesCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1DABAFB2A270EE7008AC34A /* MediaSourcesCard.swift */; };
|
||||
E1DABAFE2A27B982008AC34A /* RatingsCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1DABAFD2A27B982008AC34A /* RatingsCard.swift */; };
|
||||
E1DC7ACA2C63337C00AEE368 /* iOS15View.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1DC7AC92C63337C00AEE368 /* iOS15View.swift */; };
|
||||
E1DC9814296DC06200982F06 /* PulseLogHandler in Frameworks */ = {isa = PBXBuildFile; productRef = E1DC9813296DC06200982F06 /* PulseLogHandler */; };
|
||||
E1DC981A296DD1CD00982F06 /* CinematicBackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1DC9818296DD1CD00982F06 /* CinematicBackgroundView.swift */; };
|
||||
E1DC983D296DEB9B00982F06 /* UnwatchedIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1DC983C296DEB9B00982F06 /* UnwatchedIndicator.swift */; };
|
||||
|
@ -1485,6 +1486,7 @@
|
|||
E1DABAF92A270E62008AC34A /* OverviewCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverviewCard.swift; sourceTree = "<group>"; };
|
||||
E1DABAFB2A270EE7008AC34A /* MediaSourcesCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSourcesCard.swift; sourceTree = "<group>"; };
|
||||
E1DABAFD2A27B982008AC34A /* RatingsCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingsCard.swift; sourceTree = "<group>"; };
|
||||
E1DC7AC92C63337C00AEE368 /* iOS15View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOS15View.swift; sourceTree = "<group>"; };
|
||||
E1DC9818296DD1CD00982F06 /* CinematicBackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CinematicBackgroundView.swift; sourceTree = "<group>"; };
|
||||
E1DC983C296DEB9B00982F06 /* UnwatchedIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnwatchedIndicator.swift; sourceTree = "<group>"; };
|
||||
E1DC9840296DEBD800982F06 /* WatchedIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchedIndicator.swift; sourceTree = "<group>"; };
|
||||
|
@ -2100,6 +2102,7 @@
|
|||
E1DE2B492B97ECB900F6715F /* ErrorView.swift */,
|
||||
E1921B7528E63306003A5238 /* GestureView.swift */,
|
||||
E178B0752BE435D70023651B /* HourMinutePicker.swift */,
|
||||
E1DC7AC92C63337C00AEE368 /* iOS15View.swift */,
|
||||
E1FE69A928C29CC20021BC93 /* LandscapePosterProgressBar.swift */,
|
||||
4E16FD4E2C0183B500110147 /* LetterPickerBar */,
|
||||
E1A8FDEB2C0574A800D0A51C /* ListRow.swift */,
|
||||
|
@ -4571,6 +4574,7 @@
|
|||
E1BDF2F329524C3B00CC0294 /* ChaptersActionButton.swift in Sources */,
|
||||
E173DA5026D048D600CC4EB7 /* ServerDetailView.swift in Sources */,
|
||||
E1BE1CF02BDB6C97008176A9 /* UserProfileSettingsView.swift in Sources */,
|
||||
E1DC7ACA2C63337C00AEE368 /* iOS15View.swift in Sources */,
|
||||
E1CFE28028FA606800B7D34C /* ChapterTrack.swift in Sources */,
|
||||
E1401CA22938122C00E8B599 /* AppIcons.swift in Sources */,
|
||||
E1BDF2FB2952502300CC0294 /* SubtitleActionButton.swift in Sources */,
|
||||
|
|
|
@ -66,7 +66,7 @@ struct SwiftfinApp: App {
|
|||
// Swiftfin
|
||||
|
||||
// don't keep last user id
|
||||
if Defaults[.signOutOnClose] {
|
||||
if Defaults[.signOutOnClose] || Container.shared.currentUserSession() == nil {
|
||||
Defaults[.lastSignedInUserID] = nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,16 +140,36 @@ extension PosterButton {
|
|||
let item: Item
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
if item.showTitle {
|
||||
TitleContentView(item: item)
|
||||
iOS15View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
if item.showTitle {
|
||||
TitleContentView(item: item)
|
||||
.backport
|
||||
.lineLimit(1, reservesSpace: true)
|
||||
.iOS15 { v in
|
||||
v.font(.footnote.weight(.regular))
|
||||
}
|
||||
}
|
||||
|
||||
SubtitleContentView(item: item)
|
||||
.backport
|
||||
.lineLimit(1, reservesSpace: true)
|
||||
.iOS15 { v in
|
||||
v.font(.caption.weight(.medium))
|
||||
}
|
||||
}
|
||||
} content: {
|
||||
VStack(alignment: .leading) {
|
||||
if item.showTitle {
|
||||
TitleContentView(item: item)
|
||||
.backport
|
||||
.lineLimit(1, reservesSpace: true)
|
||||
}
|
||||
|
||||
SubtitleContentView(item: item)
|
||||
.backport
|
||||
.lineLimit(1, reservesSpace: true)
|
||||
}
|
||||
|
||||
SubtitleContentView(item: item)
|
||||
.backport
|
||||
.lineLimit(1, reservesSpace: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// Swiftfin is subject to the terms of the Mozilla Public
|
||||
// License, v2.0. If a copy of the MPL was not distributed with this
|
||||
// file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) 2024 Jellyfin & Jellyfin Contributors
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// TODO: remove when iOS 15 support removed
|
||||
struct iOS15View<iOS15Content: View, Content: View>: View {
|
||||
|
||||
let iOS15: () -> iOS15Content
|
||||
let content: () -> Content
|
||||
|
||||
var body: some View {
|
||||
if #available(iOS 16, *) {
|
||||
content()
|
||||
} else {
|
||||
iOS15()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,17 @@ import SwiftUI
|
|||
|
||||
extension View {
|
||||
|
||||
// TODO: remove after removing support for iOS 15
|
||||
|
||||
@ViewBuilder
|
||||
func iOS15<Content: View>(@ViewBuilder _ content: (Self) -> Content) -> some View {
|
||||
if #available(iOS 16, *) {
|
||||
self
|
||||
} else {
|
||||
content(self)
|
||||
}
|
||||
}
|
||||
|
||||
func detectOrientation(_ orientation: Binding<UIDeviceOrientation>) -> some View {
|
||||
modifier(DetectOrientation(orientation: orientation))
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ extension ChannelLibraryView {
|
|||
.foregroundColor(.primary)
|
||||
.backport
|
||||
.lineLimit(1, reservesSpace: true)
|
||||
.font(.footnote.weight(.regular))
|
||||
}
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
|
|
|
@ -49,6 +49,7 @@ extension SeriesEpisodeSelector {
|
|||
.multilineTextAlignment(.leading)
|
||||
.backport
|
||||
.lineLimit(3, reservesSpace: true)
|
||||
.font(.caption.weight(.light))
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
|
@ -61,6 +62,14 @@ extension SeriesEpisodeSelector {
|
|||
headerView
|
||||
|
||||
contentView
|
||||
.iOS15 { v in
|
||||
v.frame(
|
||||
height: "A\nA\nA".height(
|
||||
withConstrainedWidth: 10,
|
||||
font: Font.caption.uiFont
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
L10n.seeMore.text
|
||||
.font(.caption.weight(.light))
|
||||
|
|
|
@ -43,7 +43,6 @@ struct SeriesEpisodeSelector: View {
|
|||
)
|
||||
.labelStyle(.episodeSelector)
|
||||
}
|
||||
.fixedSize()
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
|
|
Loading…
Reference in New Issue