-
-
Notifications
You must be signed in to change notification settings - Fork 310
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor
PosterButton
and libraries, good UICollectionView
s, prop…
…er orientation handling, and more (#905)
- Loading branch information
Showing
285 changed files
with
6,643 additions
and
5,793 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
PreferencesView/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"pins" : [ | ||
{ | ||
"identity" : "swizzleswift", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/MarioIannotta/SwizzleSwift", | ||
"state" : { | ||
"branch" : "master", | ||
"revision" : "e2d31c646182bf94a496b173c6ee5ad191230e9a" | ||
} | ||
} | ||
], | ||
"version" : 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// swift-tools-version: 5.9 | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "PreferencesView", | ||
platforms: [ | ||
.iOS(.v15), | ||
.tvOS(.v15), | ||
], | ||
products: [ | ||
.library( | ||
name: "PreferencesView", | ||
targets: ["PreferencesView"] | ||
), | ||
], | ||
dependencies: [ | ||
.package(url: "https://github.com/MarioIannotta/SwizzleSwift", branch: "master"), | ||
], | ||
targets: [ | ||
.target( | ||
name: "PreferencesView", | ||
dependencies: [.product(name: "SwizzleSwift", package: "SwizzleSwift")] | ||
), | ||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# PreferencesView |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
PreferencesView/Sources/PreferencesView/KeyCommandsBuilder.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// | ||
// 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 Foundation | ||
|
||
@resultBuilder | ||
public enum KeyCommandsBuilder { | ||
|
||
public static func buildBlock(_ components: [KeyCommandAction]...) -> [KeyCommandAction] { | ||
components.flatMap { $0 } | ||
} | ||
|
||
public static func buildExpression(_ expression: KeyCommandAction) -> [KeyCommandAction] { | ||
[expression] | ||
} | ||
|
||
public static func buildOptional(_ component: [KeyCommandAction]?) -> [KeyCommandAction] { | ||
component ?? [] | ||
} | ||
|
||
public static func buildEither(first component: [KeyCommandAction]) -> [KeyCommandAction] { | ||
component | ||
} | ||
|
||
public static func buildEither(second component: [KeyCommandAction]) -> [KeyCommandAction] { | ||
component | ||
} | ||
|
||
public static func buildArray(_ components: [[KeyCommandAction]]) -> [KeyCommandAction] { | ||
components.flatMap { $0 } | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
PreferencesView/Sources/PreferencesView/PreferenceKeys.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// | ||
// 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 | ||
|
||
#if os(iOS) | ||
struct KeyCommandsPreferenceKey: PreferenceKey { | ||
|
||
static var defaultValue: [KeyCommandAction] = [] | ||
|
||
static func reduce(value: inout [KeyCommandAction], nextValue: () -> [KeyCommandAction]) { | ||
value.append(contentsOf: nextValue()) | ||
} | ||
} | ||
|
||
struct PreferredScreenEdgesDeferringSystemGesturesPreferenceKey: PreferenceKey { | ||
|
||
static var defaultValue: UIRectEdge = [.left, .right] | ||
|
||
static func reduce(value: inout UIRectEdge, nextValue: () -> UIRectEdge) {} | ||
} | ||
|
||
struct PrefersHomeIndicatorAutoHiddenPreferenceKey: PreferenceKey { | ||
|
||
static var defaultValue: Bool = false | ||
|
||
static func reduce(value: inout Bool, nextValue: () -> Bool) { | ||
value = nextValue() || value | ||
} | ||
} | ||
|
||
struct SupportedOrientationsPreferenceKey: PreferenceKey { | ||
|
||
static var defaultValue: UIInterfaceOrientationMask = .allButUpsideDown | ||
|
||
static func reduce(value: inout UIInterfaceOrientationMask, nextValue: () -> UIInterfaceOrientationMask) {} | ||
} | ||
#endif |
26 changes: 26 additions & 0 deletions
26
PreferencesView/Sources/PreferencesView/PreferencesView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// | ||
// 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 | ||
import SwizzleSwift | ||
|
||
public struct PreferencesView<Content: View>: UIViewControllerRepresentable { | ||
|
||
private var content: () -> Content | ||
|
||
public init(@ViewBuilder content: @escaping () -> Content) { | ||
_ = UIViewController.swizzlePreferences | ||
self.content = content | ||
} | ||
|
||
public func makeUIViewController(context: Context) -> UIPreferencesHostingController { | ||
UIPreferencesHostingController(content: content) | ||
} | ||
|
||
public func updateUIViewController(_ uiViewController: UIPreferencesHostingController, context: Context) {} | ||
} |
113 changes: 113 additions & 0 deletions
113
PreferencesView/Sources/PreferencesView/UIPreferencesHostingController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// | ||
// 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 | ||
|
||
public class UIPreferencesHostingController: UIHostingController<AnyView> { | ||
|
||
init<Content: View>(@ViewBuilder content: @escaping () -> Content) { | ||
let box = Box() | ||
let rootView = AnyView( | ||
content() | ||
#if os(iOS) | ||
.onPreferenceChange(KeyCommandsPreferenceKey.self) { | ||
box.value?._keyCommandActions = $0 | ||
} | ||
.onPreferenceChange(PrefersHomeIndicatorAutoHiddenPreferenceKey.self) { | ||
box.value?._prefersHomeIndicatorAutoHidden = $0 | ||
} | ||
.onPreferenceChange(PreferredScreenEdgesDeferringSystemGesturesPreferenceKey.self) { | ||
box.value?._preferredScreenEdgesDeferringSystemGestures = $0 | ||
} | ||
.onPreferenceChange(SupportedOrientationsPreferenceKey.self) { | ||
box.value?._orientations = $0 | ||
} | ||
#endif | ||
) | ||
|
||
super.init(rootView: rootView) | ||
|
||
box.value = self | ||
} | ||
|
||
@available(*, unavailable) | ||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
#if os(iOS) | ||
|
||
// MARK: Key Commands | ||
|
||
private var _keyCommandActions: [KeyCommandAction] = [] { | ||
willSet { | ||
_keyCommands = newValue.map { action in | ||
let keyCommand = UIKeyCommand( | ||
title: action.title, | ||
action: #selector(keyCommandHit), | ||
input: String(action.input), | ||
modifierFlags: action.modifierFlags | ||
) | ||
|
||
keyCommand.subtitle = action.subtitle | ||
keyCommand.wantsPriorityOverSystemBehavior = true | ||
|
||
return keyCommand | ||
} | ||
} | ||
} | ||
|
||
private var _keyCommands: [UIKeyCommand] = [] | ||
|
||
override public var keyCommands: [UIKeyCommand]? { | ||
_keyCommands | ||
} | ||
|
||
@objc | ||
private func keyCommandHit(keyCommand: UIKeyCommand) { | ||
guard let action = _keyCommandActions | ||
.first(where: { $0.input == keyCommand.input && $0.modifierFlags == keyCommand.modifierFlags }) else { return } | ||
action.action() | ||
} | ||
|
||
// MARK: Orientation | ||
|
||
var _orientations: UIInterfaceOrientationMask = .all { | ||
didSet { | ||
if #available(iOS 16, *) { | ||
setNeedsUpdateOfSupportedInterfaceOrientations() | ||
} | ||
} | ||
} | ||
|
||
override public var supportedInterfaceOrientations: UIInterfaceOrientationMask { | ||
_orientations | ||
} | ||
|
||
// MARK: Defer Edges | ||
|
||
private var _preferredScreenEdgesDeferringSystemGestures: UIRectEdge = [.left, .right] { | ||
didSet { setNeedsUpdateOfScreenEdgesDeferringSystemGestures() } | ||
} | ||
|
||
override public var preferredScreenEdgesDeferringSystemGestures: UIRectEdge { | ||
_preferredScreenEdgesDeferringSystemGestures | ||
} | ||
|
||
// MARK: Home Indicator Auto Hidden | ||
|
||
private var _prefersHomeIndicatorAutoHidden = false { | ||
didSet { setNeedsUpdateOfHomeIndicatorAutoHidden() } | ||
} | ||
|
||
override public var prefersHomeIndicatorAutoHidden: Bool { | ||
_prefersHomeIndicatorAutoHidden | ||
} | ||
|
||
#endif | ||
} |
Oops, something went wrong.