Compare commits

...

46 Commits

Author SHA1 Message Date
Arkadiusz Fal
987f6dcac8 Bump build number to 169 2023-11-04 11:34:45 +01:00
Arkadiusz Fal
1113a94d67 Update CHANGELOG 2023-11-04 11:34:25 +01:00
Arkadiusz Fal
8c6fc7d561 Update dependencies 2023-11-04 11:33:01 +01:00
Arkadiusz Fal
fb84927fc8 Bump build number to 168 2023-10-24 09:17:22 +02:00
Arkadiusz Fal
c452e66999 Update CHANGELOG 2023-10-24 09:17:22 +02:00
Arkadiusz Fal
7ab91e08f4 Update dependencies 2023-10-24 09:16:37 +02:00
Arkadiusz Fal
bdd18dba4e Merge pull request #543 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2023-10-24 09:15:59 +02:00
maboroshin
026654d3a2 Translated using Weblate (Japanese)
Currently translated at 100.0% (533 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ja/
2023-10-22 19:40:21 +02:00
mere
e9729bc9b3 Translated using Weblate (Romanian)
Currently translated at 100.0% (533 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ro/
2023-10-22 19:40:21 +02:00
Arkadiusz Fal
a04159969e Use AF for Piped token request 2023-10-22 19:39:34 +02:00
Arkadiusz Fal
3624d186bc Bump build number to 167 2023-10-16 15:53:58 +02:00
Arkadiusz Fal
31ea4860cf Bump version number to 1.5.1 2023-10-16 15:53:41 +02:00
Arkadiusz Fal
5a074d7607 Bump build number to 166 2023-10-15 14:10:05 +02:00
Arkadiusz Fal
9d8b20148b Update CHANGELOG 2023-10-15 14:09:37 +02:00
Arkadiusz Fal
0ffb9d0606 Fix date parsing for piped videos 2023-10-15 14:08:38 +02:00
Arkadiusz Fal
8258d8d5b4 Bring back iOS 14 and macOS 11 2023-10-15 14:08:08 +02:00
Arkadiusz Fal
94915b0496 Revert "Drop iOS 14 and macOS 11 support"
This reverts commit dcef7f47ff.
2023-10-15 13:35:23 +02:00
Arkadiusz Fal
053b4a22b8 Fix style 2023-10-15 13:33:46 +02:00
Arkadiusz Fal
e6a9f39477 Bump build number to 165 2023-10-15 00:46:59 +02:00
Arkadiusz Fal
ff4f80b7ef Update CHANGELOG 2023-10-15 00:46:59 +02:00
Arkadiusz Fal
7e1218ce13 Update packages 2023-10-15 00:46:59 +02:00
Arkadiusz Fal
4c707271c3 Add setting to disable chapters and related, add info section in
player settings
2023-10-15 00:46:59 +02:00
Arkadiusz Fal
04e56638ce Fix possible crash 2023-10-15 00:46:59 +02:00
Arkadiusz Fal
674269c4c1 Fix issue with tvOS screensaver 2023-10-15 00:46:58 +02:00
Arkadiusz Fal
2b4627c3d6 Fix lint 2023-10-15 00:46:58 +02:00
Arkadiusz Fal
4260c6d6b5 Merge pull request #539 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2023-10-15 00:46:13 +02:00
maboroshin
4057021cb9 Translated using Weblate (Japanese)
Currently translated at 99.4% (530 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ja/
2023-10-10 15:04:11 +00:00
gallegonovato
151a99c2a3 Translated using Weblate (Spanish)
Currently translated at 84.2% (449 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/es/
2023-10-08 12:03:32 +00:00
Radical
bd606a4cf8 Translated using Weblate (Norwegian Bokmål)
Currently translated at 59.6% (318 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/nb_NO/
2023-10-08 12:03:31 +00:00
Ophiushi
4dbf2551d9 Translated using Weblate (French)
Currently translated at 100.0% (533 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/fr/
2023-09-28 19:02:38 +02:00
Arkadiusz Fal
8fefbccc83 Bump build number to 164 2023-09-26 18:19:49 +02:00
Arkadiusz Fal
65bc1e4efe Update CHANGELOG 2023-09-26 18:19:27 +02:00
Arkadiusz Fal
9a257ec897 Fix quality profile form 2023-09-26 18:19:09 +02:00
Arkadiusz Fal
dd0a966a9f Bump build number to 163 2023-09-26 17:57:19 +02:00
Arkadiusz Fal
cec0327293 Update CHANGELOG 2023-09-26 17:47:18 +02:00
Arkadiusz Fal
5b2c94758b Set window min width on macOS 2023-09-26 17:47:00 +02:00
Arkadiusz Fal
2dd1d2ac56 Fix possible crash 2023-09-26 17:44:01 +02:00
Arkadiusz Fal
3be7a5a69f Fix issue with creating quality profile 2023-09-26 17:44:01 +02:00
Arkadiusz Fal
3e6ea2633e Remove unnecessary frameworks 2023-09-26 17:44:01 +02:00
Arkadiusz Fal
2ef692edb8 Migrate to SwiftUIIntrospect 2023-09-26 17:44:01 +02:00
Arkadiusz Fal
3edfa5dfe7 Set focus on search textfield on macOS
Fix #268
2023-09-26 17:44:01 +02:00
Arkadiusz Fal
8976ef04f6 Localization fix 2023-09-26 17:44:00 +02:00
Arkadiusz Fal
cf81aedb60 Merge pull request #538 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2023-09-26 17:43:48 +02:00
joaooliva
78a225cde4 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (533 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/pt_BR/
2023-09-26 17:43:26 +02:00
Arkadiusz Fal
efdbbbc1f4 Translated using Weblate (Polish)
Currently translated at 100.0% (533 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/pl/
2023-09-26 17:43:26 +02:00
Anonymous
f82056a358 Translated using Weblate (English)
Currently translated at 100.0% (533 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/en/
2023-09-26 17:43:26 +02:00
69 changed files with 1173 additions and 260 deletions

View File

@@ -0,0 +1,15 @@
import SwiftUI
extension Backport where Content: View {
@ViewBuilder func badge(_ count: Text?) -> some View {
#if os(tvOS)
content
#else
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
content.badge(count)
} else {
content
}
#endif
}
}

View File

@@ -0,0 +1,15 @@
import Foundation
import SwiftUI
extension Backport where Content: View {
@ViewBuilder func listRowSeparator(_ visible: Bool) -> some View {
if #available(iOS 15, macOS 13, *) {
content
#if !os(tvOS)
.listRowSeparator(visible ? .visible : .hidden)
#endif
} else {
content
}
}
}

View File

@@ -0,0 +1,11 @@
import SwiftUI
extension Backport where Content: View {
@ViewBuilder func refreshable(action: @Sendable @escaping () async -> Void) -> some View {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
content.refreshable(action: action)
} else {
content
}
}
}

View File

@@ -0,0 +1,11 @@
import SwiftUI
extension Backport where Content: View {
@ViewBuilder func tint(_ color: Color?) -> some View {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
content.tint(color)
} else {
content.foregroundColor(color)
}
}
}

View File

@@ -0,0 +1,97 @@
/*
Copyright © 2020 Apple Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import SwiftUI
#if os(iOS)
public struct VisualEffectBlur<Content: View>: View {
/// Defaults to .systemMaterial
var blurStyle: UIBlurEffect.Style
/// Defaults to nil
var vibrancyStyle: UIVibrancyEffectStyle?
var content: Content
public init(blurStyle: UIBlurEffect.Style = .systemMaterial, vibrancyStyle: UIVibrancyEffectStyle? = nil, @ViewBuilder content: () -> Content) {
self.blurStyle = blurStyle
self.vibrancyStyle = vibrancyStyle
self.content = content()
}
public var body: some View {
Representable(blurStyle: blurStyle, vibrancyStyle: vibrancyStyle, content: ZStack { content })
.accessibility(hidden: Content.self == EmptyView.self)
}
}
// MARK: - Representable
extension VisualEffectBlur {
struct Representable<Content: View>: UIViewRepresentable {
var blurStyle: UIBlurEffect.Style
var vibrancyStyle: UIVibrancyEffectStyle?
var content: Content
func makeUIView(context: Context) -> UIVisualEffectView {
context.coordinator.blurView
}
func updateUIView(_: UIVisualEffectView, context: Context) {
context.coordinator.update(content: content, blurStyle: blurStyle, vibrancyStyle: vibrancyStyle)
}
func makeCoordinator() -> Coordinator {
Coordinator(content: content)
}
}
}
// MARK: - Coordinator
extension VisualEffectBlur.Representable {
class Coordinator {
let blurView = UIVisualEffectView()
let vibrancyView = UIVisualEffectView()
let hostingController: UIHostingController<Content>
init(content: Content) {
hostingController = UIHostingController(rootView: content)
hostingController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
hostingController.view.backgroundColor = nil
blurView.contentView.addSubview(vibrancyView)
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
vibrancyView.contentView.addSubview(hostingController.view)
vibrancyView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
func update(content: Content, blurStyle: UIBlurEffect.Style, vibrancyStyle: UIVibrancyEffectStyle?) {
hostingController.rootView = content
let blurEffect = UIBlurEffect(style: blurStyle)
blurView.effect = blurEffect
if let vibrancyStyle {
vibrancyView.effect = UIVibrancyEffect(blurEffect: blurEffect, style: vibrancyStyle)
} else {
vibrancyView.effect = nil
}
hostingController.view.setNeedsDisplay()
}
}
}
extension VisualEffectBlur where Content == EmptyView {
init(blurStyle: UIBlurEffect.Style = .systemMaterial) {
self.init(blurStyle: blurStyle, vibrancyStyle: nil) {
EmptyView()
}
}
}
#endif

View File

@@ -0,0 +1,83 @@
/*
Copyright © 2020 Apple Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import SwiftUI
#if os(macOS)
public struct VisualEffectBlur: View {
private var material: NSVisualEffectView.Material
private var blendingMode: NSVisualEffectView.BlendingMode
private var state: NSVisualEffectView.State
public init(
material: NSVisualEffectView.Material = .headerView,
blendingMode: NSVisualEffectView.BlendingMode = .withinWindow,
state: NSVisualEffectView.State = .followsWindowActiveState
) {
self.material = material
self.blendingMode = blendingMode
self.state = state
}
public var body: some View {
Representable(
material: material,
blendingMode: blendingMode,
state: state
).accessibility(hidden: true)
}
}
// MARK: - Representable
extension VisualEffectBlur {
struct Representable: NSViewRepresentable {
var material: NSVisualEffectView.Material
var blendingMode: NSVisualEffectView.BlendingMode
var state: NSVisualEffectView.State
func makeNSView(context: Context) -> NSVisualEffectView {
context.coordinator.visualEffectView
}
func updateNSView(_: NSVisualEffectView, context: Context) {
context.coordinator.update(material: material)
context.coordinator.update(blendingMode: blendingMode)
context.coordinator.update(state: state)
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
}
class Coordinator {
let visualEffectView = NSVisualEffectView()
init() {
visualEffectView.blendingMode = .withinWindow
}
func update(material: NSVisualEffectView.Material) {
visualEffectView.material = material
}
func update(blendingMode: NSVisualEffectView.BlendingMode) {
visualEffectView.blendingMode = blendingMode
}
func update(state: NSVisualEffectView.State) {
visualEffectView.state = state
}
}
}
#endif

View File

@@ -1,18 +1,7 @@
## Build 162
* Added support for "Podcasts" and "Releases" channel tabs (Invidious)
## Build 169
* Fixed issue with MPV subtitles not working
* Updated dependencies
## Previous builds
* Added button in Location settings to add current used public location to "Custom Locations"
* Updated mpv and dependencies (using mpvkit library, mpv 0.36.0, ffmpeg 6.0)
* Increased controls timeline/scrubber gesture area for easier handling
* Fixed handling playlist links
* Fixed issue where Piped videos would use audio for other language version
* Fixed issue with handling opening URLs on macOS
* Fixed issue with "Keep channels with unwatched videos on top of subscriptions list" setting not honored in sidebar
* Fixed performance issues with accounts with large amount of subscribed channels
* Fixed regression with opening videos links
* Fixed issue with deselecting formats in Quality profiles
* Fixed compatibility with iOS 17, macOS 14 and tvOS 17
* Dropped support for iOS 14 and macOS 11
* Fixed reported crashes
* Other minor fixes and improvements
* Fixed issue where Piped login token would not refresh
* Other minor changes and improvements

View File

@@ -8,16 +8,16 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.827.0)
aws-sdk-core (3.183.0)
aws-partitions (1.840.0)
aws-sdk-core (3.185.1)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.71.0)
aws-sdk-core (~> 3, >= 3.177.0)
aws-sdk-kms (1.72.0)
aws-sdk-core (~> 3, >= 3.184.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.135.0)
aws-sdk-s3 (1.136.0)
aws-sdk-core (~> 3, >= 3.181.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.6)
@@ -36,7 +36,7 @@ GEM
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.103.0)
excon (0.104.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -107,7 +107,7 @@ GEM
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.49.0)
google-apis-androidpublisher_v3 (0.51.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.1)
addressable (~> 2.5, >= 2.5.1)
@@ -192,7 +192,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (2.4.2)
unicode-display_width (2.5.0)
webrick (1.8.1)
word_wrap (1.0.0)
xcodeproj (1.23.0)

View File

@@ -1,3 +1,4 @@
import Alamofire
import AVFoundation
import Foundation
import Siesta
@@ -148,28 +149,43 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
return
}
login.request(
.post,
json: ["username": username, "password": password]
)
.onSuccess { response in
let token = response.json.dictionaryValue["token"]?.string ?? ""
if let error = response.json.dictionaryValue["error"]?.string {
NavigationModel.shared.presentAlert(
title: "Account Error",
message: error
)
} else if !token.isEmpty {
AccountsModel.setToken(self.account, token)
self.objectWillChange.send()
} else {
NavigationModel.shared.presentAlert(
title: "Account Error",
message: "Could not update your token."
)
AF.request(
login.url,
method: .post,
parameters: ["username": username, "password": password],
encoding: JSONEncoding.default
).responseDecodable(of: JSON.self) { [weak self] response in
guard let self else {
return
}
self.configure()
switch response.result {
case let .success(value):
let json = JSON(value)
let token = json.dictionaryValue["token"]?.string ?? ""
if let error = json.dictionaryValue["error"]?.string {
NavigationModel.shared.presentAlert(
title: "Account Error",
message: error
)
} else if !token.isEmpty {
AccountsModel.setToken(self.account, token)
self.objectWillChange.send()
} else {
NavigationModel.shared.presentAlert(
title: "Account Error",
message: "Could not update your token."
)
}
self.configure()
case let .failure(error):
NavigationModel.shared.presentAlert(
title: "Account Error",
message: error.localizedDescription
)
}
}
}
@@ -496,7 +512,17 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
let uploaded = details["uploaded"]?.double
var published = (uploaded.isNil || uploaded == -1) ? nil : (uploaded! / 1000).formattedAsRelativeTime()
if published.isNil {
var publishedAt: Date?
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withInternetDateTime]
if published.isNil,
let date = details["uploadDate"]?.string,
let formattedDate = dateFormatter.date(from: date)
{
publishedAt = formattedDate
} else {
published = (details["uploadedDate"] ?? details["uploadDate"])?.string ?? ""
}
@@ -526,6 +552,7 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
thumbnails: thumbnails,
live: live,
short: details["isShort"]?.bool ?? (length <= Video.shortLength),
publishedAt: publishedAt,
likes: details["likes"]?.int,
dislikes: details["dislikes"]?.int,
streams: extractStreams(from: content),

View File

@@ -666,6 +666,10 @@ final class AVPlayerBackend: PlayerBackend {
} else {
ScreenSaverManager.shared.enable()
}
#else
DispatchQueue.main.async {
UIApplication.shared.isIdleTimerDisabled = self.model.presentingPlayer && self.isPlaying
}
#endif
self.timeObserverThrottle.execute {

View File

@@ -18,6 +18,12 @@ final class SearchModel: ObservableObject {
@Published var focused = false
#if os(iOS)
var textField: UITextField!
#elseif os(macOS)
var textField: NSTextField!
#endif
var accounts: AccountsModel { .shared }
private var resource: Resource!

View File

@@ -290,8 +290,8 @@ struct Video: Identifiable, Equatable, Hashable {
}
var localStreamIsFile: Bool {
guard let localStream else { return false }
return localStream.localURL.isFileURL
guard let url = localStream?.localURL else { return false }
return url.isFileURL
}
var localStreamIsRemoteURL: Bool {

View File

@@ -40,7 +40,7 @@ struct ChannelVideosView: View {
}
var body: some View {
VStack {
let content = VStack {
#if os(tvOS)
VStack {
HStack(spacing: 24) {
@@ -181,12 +181,19 @@ struct ChannelVideosView: View {
.navigationTitle(navigationTitle)
#endif
#if os(tvOS)
.background(Color.background(scheme: colorScheme))
#endif
#if !os(iOS)
.focusScope(focusNamespace)
#endif
return Group {
if #available(macOS 12.0, *) {
content
#if os(tvOS)
.background(Color.background(scheme: colorScheme))
#endif
#if !os(iOS)
.focusScope(focusNamespace)
#endif
} else {
content
}
}
}
var verticalCellsEdgesIgnoringSafeArea: Edge.Set {

View File

@@ -63,9 +63,16 @@ struct Constants {
static func seekIcon(_ type: String, _ interval: TimeInterval) -> String {
let interval = Int(interval)
let allVersions = [5, 10, 15, 30, 45, 60, 75, 90]
let allVersions = [10, 15, 30, 45, 60, 75, 90]
let iOS15 = [5]
let iconName = "go\(type).\(interval)"
if #available(iOS 15, macOS 12, *) {
if iOS15.contains(interval) {
return iconName
}
}
if allVersions.contains(interval) {
return iconName
}

View File

@@ -263,6 +263,8 @@ extension Defaults.Keys {
static let hideShorts = Key<Bool>("hideShorts", default: false)
static let hideWatched = Key<Bool>("hideWatched", default: false)
static let showInspector = Key<ShowInspectorSetting>("showInspector", default: .onlyLocal)
static let showChapters = Key<Bool>("showChapters", default: true)
static let showRelated = Key<Bool>("showRelated", default: true)
static let widgetsSettings = Key<[WidgetSettings]>("widgetsSettings", default: [])
}

View File

@@ -34,7 +34,8 @@ struct DocumentsView: View {
}
.navigationTitle(directoryLabel)
.padding(.horizontal)
.navigationBarTitleDisplayMode(.inline)
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
.backport
.refreshable {
DispatchQueue.main.async {
self.refresh()

View File

@@ -15,10 +15,14 @@ struct AccountViewButton: View {
} label: {
HStack(spacing: 6) {
if !accountPickerDisplaysUsername || !(model.current?.isPublic ?? true) {
if let name = model.current?.app?.rawValue.capitalized {
Image(name)
.resizable()
.frame(width: accountImageSize, height: accountImageSize)
if #available(iOS 15, macOS 12, *) {
if let name = model.current?.app?.rawValue.capitalized {
Image(name)
.resizable()
.frame(width: accountImageSize, height: accountImageSize)
} else {
Image(systemName: "globe")
}
} else {
Image(systemName: "globe")
}

View File

@@ -1,7 +1,7 @@
import Defaults
import SwiftUI
#if os(iOS)
import Introspect
import SwiftUIIntrospect
#endif
struct AppSidebarNavigation: View {
@@ -15,7 +15,7 @@ struct AppSidebarNavigation: View {
var body: some View {
#if os(iOS)
content.introspectViewController { viewController in
content.introspect(.viewController, on: .iOS(.v15, .v16, .v17)) { viewController in
// workaround for an empty supplementary view on launch
// the supplementary view is determined by the default selection inside the
// primary view, but the primary view is not loaded so its selection is not read

View File

@@ -38,6 +38,7 @@ struct AppSidebarPlaylists: View {
if accounts.app.userPlaylistsEndpointIncludesVideos, !playlist.videos.isEmpty {
label
.backport
.badge(Text("\(playlist.videos.count)"))
} else {
label

View File

@@ -33,6 +33,7 @@ struct AppSidebarSubscriptions: View {
Spacer()
}
.lineLimit(1)
.backport
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil)
}
.contextMenu {

View File

@@ -95,6 +95,7 @@ struct AppTabNavigation: View {
.accessibility(label: Text("Subscriptions"))
}
.tag(TabSelection.subscriptions)
.backport
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedText : nil)
}

View File

@@ -167,6 +167,9 @@ struct ContentView: View {
#if os(iOS)
.statusBarHidden(player.playingFullScreen)
#endif
#if os(macOS)
.frame(minWidth: 1200)
#endif
}
@ViewBuilder var videoPlayer: some View {

View File

@@ -35,7 +35,9 @@ struct Sidebar: View {
}
}
.onChange(of: navigation.sidebarSectionChanged) { _ in
scrollScrollViewToItem(scrollView: scrollView, for: navigation.tabSelection)
if let tabSelection = navigation.tabSelection {
scrollScrollViewToItem(scrollView: scrollView, for: tabSelection)
}
}
.listStyle(.sidebar)
}
@@ -79,6 +81,7 @@ struct Sidebar: View {
Label("Subscriptions", systemImage: "star.circle")
.accessibility(label: Text("Subscriptions"))
}
.backport
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedText : nil)
.contextMenu {
playUnwatchedButton

View File

@@ -47,7 +47,7 @@ final class AppleAVPlayerViewController: UIViewController {
infoViewControllers.append(infoViewController([.chapters], title: "Chapters"))
infoViewControllers.append(infoViewController([.comments], title: "Comments"))
let queueSections = [NowPlayingView.ViewSection.playingNext]
var queueSections = [NowPlayingView.ViewSection.playingNext]
infoViewControllers.append(contentsOf: [
infoViewController([.related], title: "Related"),

View File

@@ -7,8 +7,19 @@ struct ControlBackgroundModifier: ViewModifier {
func body(content: Content) -> some View {
if enabled {
content
if #available(iOS 15, macOS 12, *) {
content
.background(.thinMaterial)
} else {
content
#if os(macOS)
.background(VisualEffectBlur(material: .hudWindow))
#elseif os(iOS)
.background(VisualEffectBlur(blurStyle: .systemThinMaterial).edgesIgnoringSafeArea(edgesIgnoringSafeArea))
#else
.background(.thinMaterial)
#endif
}
} else {
content
}

View File

@@ -255,6 +255,8 @@ struct PlayerControls: View {
{
ThumbnailView(url: url)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.opacity)
.animation(.default)
} else if player.videoForDisplay == nil {
Color.black
}

View File

@@ -18,9 +18,8 @@ struct RelatedView: View {
Color.clear.padding(.bottom, 50)
.listRowBackground(Color.clear)
#if os(iOS)
.listRowSeparator(.hidden)
#endif
.backport
.listRowSeparator(false)
}
}
}

View File

@@ -219,17 +219,25 @@ struct CommentView: View {
}
private var commentText: some View {
Text(comment.text)
#if !os(tvOS)
.textSelection(.enabled)
#endif
#if os(macOS)
.font(.system(size: 14))
#elseif os(iOS)
.font(.system(size: 15))
#endif
.lineSpacing(3)
.fixedSize(horizontal: false, vertical: true)
Group {
let text = Text(comment.text)
#if os(macOS)
.font(.system(size: 14))
#elseif os(iOS)
.font(.system(size: 15))
#endif
.lineSpacing(3)
.fixedSize(horizontal: false, vertical: true)
if #available(iOS 15.0, macOS 12.0, *) {
text
#if !os(tvOS)
.textSelection(.enabled)
#endif
} else {
text
}
}
}
private func openChannelAction() {

View File

@@ -32,8 +32,13 @@ struct CommentsView: View {
struct CommentsView_Previews: PreviewProvider {
static var previews: some View {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
CommentsView()
.previewInterfaceOrientation(.landscapeRight)
.injectFixtureEnvironmentObjects()
}
CommentsView()
.previewInterfaceOrientation(.landscapeRight)
.injectFixtureEnvironmentObjects()
}
}

View File

@@ -79,10 +79,15 @@ struct InspectorView: View {
Text(detail.localized())
.foregroundColor(.secondary)
Spacer()
Text(value).lineLimit(1)
#if !os(tvOS)
let value = Text(value).lineLimit(1)
if #available(iOS 15.0, macOS 12.0, *) {
value
#if !os(tvOS)
.textSelection(.enabled)
#endif
#endif
} else {
value
}
}
.font(.caption)
}

View File

@@ -30,9 +30,8 @@ struct PlayerQueueView: View {
#endif
Color.clear.padding(.bottom, 50)
.listRowBackground(Color.clear)
#if os(iOS)
.listRowSeparator(.hidden)
#endif
.backport
.listRowSeparator(false)
}
.environment(\.inNavigationView, false)
}

View File

@@ -59,15 +59,23 @@ struct VideoDescription: View {
@ViewBuilder var textDescription: some View {
#if !os(iOS)
Text(description)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : Self.collapsedLines)
#if !os(tvOS)
.textSelection(.enabled)
#endif
.multilineTextAlignment(.leading)
.font(.system(size: 14))
.lineSpacing(3)
Group {
if #available(macOS 12, *) {
Text(description)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : Self.collapsedLines)
#if !os(tvOS)
.textSelection(.enabled)
#endif
} else {
Text(description)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : Self.collapsedLines)
}
}
.multilineTextAlignment(.leading)
.font(.system(size: 14))
.lineSpacing(3)
#endif
}

View File

@@ -184,6 +184,8 @@ struct VideoDetails: View {
@Default(.enableReturnYouTubeDislike) private var enableReturnYouTubeDislike
@Default(.playerSidebar) private var playerSidebar
@Default(.showInspector) private var showInspector
@Default(.showChapters) private var showChapters
@Default(.showRelated) private var showRelated
#if !os(tvOS)
@Default(.showScrollToTopInComments) private var showScrollToTopInComments
#endif
@@ -309,29 +311,29 @@ struct VideoDetails: View {
.padding(.horizontal)
}
if player.videoBeingOpened.isNil,
!video.isLocal,
!video.chapters.isEmpty
{
Section(header: chaptersHeader) {
ChaptersView()
if player.videoBeingOpened.isNil {
if showChapters,
!video.isLocal,
!video.chapters.isEmpty
{
Section(header: chaptersHeader) {
ChaptersView()
}
}
}
if player.videoBeingOpened.isNil,
video.isLocal || showInspector == .always
{
InspectorView(video: player.videoForDisplay)
.padding(.horizontal)
}
if showInspector == .always || video.isLocal {
InspectorView(video: player.videoForDisplay)
.padding(.horizontal)
}
if player.videoBeingOpened.isNil,
!sidebarQueue,
!(player.videoForDisplay?.related.isEmpty ?? true)
{
RelatedView()
.padding(.horizontal)
.padding(.top, 20)
if showRelated,
!sidebarQueue,
!(player.videoForDisplay?.related.isEmpty ?? true)
{
RelatedView()
.padding(.horizontal)
.padding(.top, 20)
}
}
}
}

View File

@@ -294,6 +294,9 @@ struct VideoPlayerView: View {
}
})
#endif
.background(Color.black)
if !detailsHiddenInFullScreen {
VideoDetails(
video: player.videoForDisplay,

View File

@@ -91,6 +91,13 @@ struct PlaylistsView: View {
loadResource()
}
#if os(iOS)
.refreshControl { refreshControl in
model.load(force: true) {
model.reloadPlaylists.toggle()
refreshControl.endRefreshing()
}
}
.backport
.refreshable {
DispatchQueue.main.async {
model.load(force: true) { model.reloadPlaylists.toggle() }

View File

@@ -1,24 +1,28 @@
import Introspect
import Repeat
import SwiftUI
import SwiftUIIntrospect
@available(iOS 15.0, macOS 12, *)
struct FocusableSearchTextField: View {
@ObservedObject private var state = SearchModel.shared
#if os(iOS)
@State private var textField: UITextField?
#elseif os(macOS)
@State private var textField: NSTextField?
#endif
var body: some View {
SearchTextField()
#if os(iOS)
.introspectTextField { field in
textField = field
#if os(macOS)
.introspect(.textField, on: .macOS(.v12, .v13, .v14)) { textField in
state.textField = textField
}
.onAppear {
DispatchQueue.main.async {
state.textField?.becomeFirstResponder()
}
}
#elseif os(iOS)
.introspect(.textField, on: .iOS(.v15, .v16, .v17)) { textField in
state.textField = textField
}
.onChange(of: state.focused) { newValue in
if newValue, let textField, !textField.isFirstResponder {
if newValue, let textField = state.textField, !textField.isFirstResponder {
textField.becomeFirstResponder()
textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)
}

View File

@@ -95,7 +95,11 @@ struct SearchView: View {
filtersMenu
}
FocusableSearchTextField()
if #available(macOS 12, *) {
FocusableSearchTextField()
} else {
SearchTextField()
}
}
#endif
}
@@ -175,7 +179,11 @@ struct SearchView: View {
searchMenu
}
ToolbarItem(placement: .principal) {
FocusableSearchTextField()
if #available(iOS 15, *) {
FocusableSearchTextField()
} else {
SearchTextField()
}
}
}
.navigationBarTitleDisplayMode(.inline)

View File

@@ -11,7 +11,7 @@ struct AddPublicInstanceButton: View {
_ = InstancesModel.shared.add(app: app, name: "", url: account.urlString)
regenerateID()
} label: {
Label("Add \(account.urlString)", systemImage: "plus")
Label(String(format: "Add %@", account.urlString), systemImage: "plus")
}
.id(id)
}

View File

@@ -30,6 +30,8 @@ struct PlayerSettings: View {
@Default(.enableReturnYouTubeDislike) private var enableReturnYouTubeDislike
@Default(.showInspector) private var showInspector
@Default(.showChapters) private var showChapters
@Default(.showRelated) private var showRelated
@ObservedObject private var accounts = AccountsModel.shared
@@ -73,8 +75,19 @@ struct PlayerSettings: View {
}
#if !os(tvOS)
Section(header: SettingsHeader(text: "Inspector".localized())) {
inspectorVisibilityPicker
Section(header: SettingsHeader(text: "Info".localized())) {
expandVideoDescriptionToggle
showChaptersToggle
showRelatedToggle
#if os(macOS)
HStack {
Text("Inspector")
inspectorVisibilityPicker
}
.padding(.leading, 20)
#else
inspectorVisibilityPicker
#endif
}
#endif
@@ -96,9 +109,6 @@ struct PlayerSettings: View {
showScrollToTopInCommentsToggle
#endif
#if !os(tvOS)
expandVideoDescriptionToggle
#endif
returnYouTubeDislikeToggle
}
}
@@ -240,15 +250,25 @@ struct PlayerSettings: View {
}
#endif
private var inspectorVisibilityPicker: some View {
Picker("Visibility", selection: $showInspector) {
Text("Always").tag(ShowInspectorSetting.always)
Text("Only for local files and URLs").tag(ShowInspectorSetting.onlyLocal)
#if !os(tvOS)
private var inspectorVisibilityPicker: some View {
Picker("Inspector", selection: $showInspector) {
Text("Always").tag(ShowInspectorSetting.always)
Text("Only for local files and URLs").tag(ShowInspectorSetting.onlyLocal)
}
#if os(macOS)
.labelsHidden()
#endif
}
#if os(macOS)
.labelsHidden()
#endif
}
private var showChaptersToggle: some View {
Toggle("Chapters", isOn: $showChapters)
}
private var showRelatedToggle: some View {
Toggle("Related", isOn: $showRelated)
}
#endif
}
struct PlayerSettings_Previews: PreviewProvider {

View File

@@ -201,7 +201,7 @@ struct QualityProfileForm: View {
@ViewBuilder var formatsPicker: some View {
#if os(macOS)
ForEach(QualityProfile.Format.allCases, id: \.self) { format in
let list = ForEach(QualityProfile.Format.allCases, id: \.self) { format in
MultiselectRow(
title: format.description,
selected: isFormatSelected(format),
@@ -210,8 +210,16 @@ struct QualityProfileForm: View {
toggleFormat(format, value: value)
}
}
.listStyle(.inset(alternatesRowBackgrounds: true))
Group {
if #available(macOS 12.0, *) {
list
.listStyle(.inset(alternatesRowBackgrounds: true))
} else {
list
.listStyle(.inset)
}
}
Spacer()
#else
ForEach(QualityProfile.Format.allCases, id: \.self) { format in
@@ -227,7 +235,7 @@ struct QualityProfileForm: View {
}
func isFormatSelected(_ format: QualityProfile.Format) -> Bool {
(initialized ? formats : qualityProfile.formats).contains(format)
(initialized || qualityProfile.isNil ? formats : qualityProfile.formats).contains(format)
}
func toggleFormat(_ format: QualityProfile.Format, value: Bool) {

View File

@@ -175,14 +175,24 @@ struct QualitySettings: View {
}
}
#if os(macOS)
List {
if #available(macOS 12.0, *) {
#if os(macOS)
List {
list
}
.listStyle(.inset(alternatesRowBackgrounds: true))
#else
list
}
.listStyle(.inset(alternatesRowBackgrounds: true))
#else
list
#endif
#endif
} else {
#if os(macOS)
List {
list
}
#else
list
#endif
}
}
}

View File

@@ -266,7 +266,7 @@ struct SettingsView: View {
case .browsing:
return 800
case .player:
return 480
return 500
case .controls:
return 920
case .quality:

View File

@@ -50,8 +50,15 @@ struct SponsorBlockSettings: View {
}
}
list
.listStyle(.inset(alternatesRowBackgrounds: true))
Group {
if #available(macOS 12.0, *) {
list
.listStyle(.inset(alternatesRowBackgrounds: true))
} else {
list
.listStyle(.inset)
}
}
Spacer()
#else
ForEach(SponsorBlockAPI.categories, id: \.self) { category in

View File

@@ -34,9 +34,8 @@ struct ChannelsView: View {
Text(channel.name)
.lineLimit(1)
}
#if !os(tvOS)
.backport
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil)
#endif
Group {
#if os(tvOS)
@@ -74,9 +73,8 @@ struct ChannelsView: View {
Color.clear.padding(.bottom, 50)
.listRowBackground(Color.clear)
#if os(iOS)
.listRowSeparator(.hidden)
#endif
.backport
.listRowSeparator(false)
}
}
#if !os(tvOS)
@@ -91,8 +89,14 @@ struct ChannelsView: View {
subscriptions.load(force: true)
}
#if os(iOS)
.refreshControl { refreshControl in
subscriptions.load(force: true) {
refreshControl.endRefreshing()
}
}
.backport
.refreshable {
subscriptions.load(force: true)
await subscriptions.load(force: true)
}
#endif
#if !os(tvOS)

View File

@@ -22,8 +22,14 @@ struct FeedView: View {
feed.loadResources()
}
#if os(iOS)
.refreshControl { refreshControl in
feed.loadResources(force: true) {
refreshControl.endRefreshing()
}
}
.backport
.refreshable {
feed.loadResources(force: true)
await feed.loadResources(force: true)
}
#endif
#if !os(tvOS)

View File

@@ -16,7 +16,11 @@ struct TrendingCountry: View {
VStack {
#if !os(tvOS)
HStack {
TextField("Country", text: $query, prompt: Text(Self.prompt))
if #available(iOS 15.0, macOS 12.0, *) {
TextField("Country", text: $query, prompt: Text(Self.prompt))
} else {
TextField(Self.prompt, text: $query)
}
Button("Done") { selectCountryAndDismiss() }
.keyboardShortcut(.defaultAction)
@@ -53,8 +57,12 @@ struct TrendingCountry: View {
return Group {
#if os(macOS)
list
.listStyle(.inset(alternatesRowBackgrounds: true))
if #available(macOS 12.0, *) {
list
.listStyle(.inset(alternatesRowBackgrounds: true))
} else {
list
}
#else
list
#endif

View File

@@ -95,7 +95,12 @@ struct TrendingView: View {
.navigationTitle("Trending")
#endif
#if os(iOS)
.refreshControl { refreshControl in
resource.load().onCompletion { _ in
refreshControl.endRefreshing()
}
}
.backport
.refreshable {
DispatchQueue.main.async {
resource.load()

View File

@@ -48,19 +48,23 @@ struct ThumbnailView: View {
}
@ViewBuilder var asyncImageIfAvailable: some View {
CachedAsyncImage(url: url, urlCache: BaseCacheModel.imageCache, transaction: Transaction(animation: .default)) { phase in
switch phase {
case let .success(image):
image
.resizable()
case .failure:
placeholder.onAppear {
guard let url else { return }
thumbnails.insertUnloadable(url)
if #available(iOS 15, macOS 12, *) {
CachedAsyncImage(url: url, urlCache: BaseCacheModel.imageCache) { phase in
switch phase {
case let .success(image):
image
.resizable()
case .failure:
placeholder.onAppear {
guard let url else { return }
thumbnails.insertUnloadable(url)
}
default:
placeholder
}
default:
placeholder
}
} else {
webImage
}
}

View File

@@ -8,7 +8,7 @@ struct OpenSettingsButton: View {
#endif
var body: some View {
Button {
let button = Button {
presentationMode.wrappedValue.dismiss()
#if os(macOS)
@@ -20,7 +20,13 @@ struct OpenSettingsButton: View {
Label("Open Settings", systemImage: "gearshape.2")
}
.buttonStyle(.plain)
.buttonStyle(.borderedProminent)
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
button
.buttonStyle(.borderedProminent)
} else {
button
}
}
}

View File

@@ -47,6 +47,14 @@ struct PopularView: View {
}
}
.navigationBarTitleDisplayMode(.inline)
.refreshControl { refreshControl in
resource?.load().onCompletion { _ in
refreshControl.endRefreshing()
}
.onFailure { self.error = $0 }
.onSuccess { _ in self.error = nil }
}
.backport
.refreshable {
DispatchQueue.main.async {
resource?.load()
@@ -54,7 +62,7 @@ struct PopularView: View {
.onSuccess { _ in self.error = nil }
}
}
.navigationBarTitleDisplayMode(.inline)
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
#endif
#if os(macOS)
.toolbar {

View File

@@ -281,7 +281,11 @@ struct VideoContextMenuView: View {
let label = Label("Remove…", systemImage: "trash.fill")
.foregroundColor(Color("AppRedColor"))
Button(role: .destructive, action: action) { label }
if #available(iOS 15, macOS 12, *) {
Button(role: .destructive, action: action) { label }
} else {
Button(action: action) { label }
}
}
#endif

View File

@@ -595,3 +595,6 @@
"Play Now in AVPlayer" = "Play Now in AVPlayer";
"Show channel avatars in videos lists" = "Show channel avatars in videos lists";
"Show channel avatars in channels lists" = "Show channel avatars in channels lists";
"Podcasts" = "Podcasts";
"Releases" = "Releases";
"Add %@" = "Add %@";

View File

@@ -116,7 +116,7 @@
"Decrease rate" = "Tasa de disminución";
"Decreased opacity" = "Opacidad disminuida";
"High" = "Alto";
"%lld videos" = "%lld videos";
"%lld videos" = "%lld vídeos";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Recordatorios explícitos para marquen \"me gusta\", se suscriban o interactúen con ellos en cualquier plataforma de pago o gratuita (por ejemplo, haciendo clic en un vídeo).";
"Formats will be selected in order as listed.\nHLS is an adaptive format (resolution setting does not apply)." = "Los formatos se seleccionarán en orden como se indica.\nHLS es un formato adaptable (no aplica la configuración de resolución).";
"Fullscreen size" = "Tamaño de pantalla completa";
@@ -331,7 +331,7 @@
"Replies" = "Respuestas";
"Reset" = "Reiniciar";
"Save history of searches, channels and playlists" = "Guardar historial de búsquedas, canales y listas de reproducción";
"Search" = "Buscar;
"Search" = "Buscar";
"Seek gesture sensitivity" = "Buscar sensibilidad en los gestos";
"Select location closest to you:" = "Seleccione la ubicación más cercana:";
@@ -502,3 +502,17 @@
"Playback history is empty" = "El historial de reproducción está vacío";
"Copy%@link" = "Copiar%@enlace";
"Share%@link" = "Compartir%@enlace";
"Open expanded" = "Abrir maximizada";
"Single tap gesture" = "Gesto con un solo toque";
"Right click channel thumbnail to open context menu with more actions" = "Haz clic con el botón derecho en la miniatura del canal para abrir el menú contextual con más acciones";
"Short videos: visible" = "Vídeos cortos: visibles";
"Tap and hold channel thumbnail to open context menu with more actions" = "Mantén pulsada la miniatura del canal para abrir el menú contextual con más acciones";
"Maximum width expanded" = "Ancho máximo ampliado";
"Short videos: hidden" = "Vídeos cortos: ocultos";
"Clear all" = "Borrar todo";
"Always show controls buttons" = "Mostrar siempre los botones de control";
"Mark channel feed as unwatched" = "Marcar el canal como no visto";
"Play all unwatched" = "Reproducir todo lo no visto";
"Mark channel feed as watched" = "Marcar el canal como visto";
"Double tap gesture" = "Doble toque";
"Player Bar" = "Barra del reproductor";

View File

@@ -597,3 +597,6 @@
"Play Now in MPV" = "Lire maintenant dans MPV";
"Show channel avatars in videos lists" = "Afficher les avatars des chaînes dans les listes de vidéos";
"Show channel avatars in channels lists" = "Afficher les avatars des chaînes dans les listes de chaînes";
"Podcasts" = "Podcasts";
"Releases" = "Sorties";
"Add %@" = "Ajouter %@";

View File

@@ -567,7 +567,7 @@
"Opened File" = "開いたファイル";
"File Extension" = "ファイル拡張子";
"Opening file..." = "ファイルを読み込み中...";
"Your Accounts" = "使用するアカウント";
"Your Accounts" = "アカウントを使用";
"Public account" = "公開アカウント";
"Browse without account" = "アカウントなしで閲覧";
"Rotate when entering fullscreen on landscape video" = "横長動画を全画面にしたら回転するか";
@@ -597,3 +597,6 @@
"Landscape right" = "右を下に横長";
"Show channel avatars in channels lists" = "チャンネル一覧にチャンネルのアイコンを表示";
"Show channel avatars in videos lists" = "動画一覧にチャンネルのアイコンを表示";
"Podcasts" = "ポッドキャスト";
"Releases" = "リリース";
"Add %@" = "追加 %@";

View File

@@ -271,7 +271,7 @@
"Popular" = "Populært";
"Connection failed" = "Kunne ikke koble til";
"Add Location" = "Legg til sted";
"Always use AVPlayer for live videos" = "AVPlayer for direkte-videoer";
"Always use AVPlayer for live videos" = "Alltid bruk AVPlayer for direktesendinger";
"Apply to all" = "Bruk for alle";
"Automatic" = "Automatisk";
"Autoplaying Next" = "Spiller neste også";

View File

@@ -598,3 +598,6 @@
"Show video context menu options to force selected backend" = "Pokaż opcje menu kontekstowego wideo, aby wymusić wybrany silnik";
"Show channel avatars in videos lists" = "Pokaż awatary kanałów na listach wideo";
"Show channel avatars in channels lists" = "Pokaż awatary kanałów na listach kanałów";
"Podcasts" = "Podkasty";
"Releases" = "Wydania";
"Add %@" = "Dodaj %@";

View File

@@ -597,3 +597,6 @@
"Play Now in MPV" = "Tocar Agora em MPV";
"Show channel avatars in videos lists" = "Mostrar avatares de canais em listas de vídeos";
"Show channel avatars in channels lists" = "Mostrar avatares de canais em listas de canais";
"Podcasts" = "Podcasts";
"Releases" = "Lançamentos";
"Add %@" = "Adicionar %@";

View File

@@ -254,7 +254,7 @@
"Play Now" = "Redă acum";
"Play All" = "Reda toate";
"Play Next" = "Redă Următorul";
"Playlists" = "Playlist";
"Playlists" = "Playlist-uri";
"Profiles" = "Profiluri";
"Preferred Formats" = "Formate preferate";
"Quality" = "Calitate";
@@ -597,3 +597,6 @@
"Show video context menu options to force selected backend" = "Afișați opțiunile din meniul contextual video pentru a forța backend-ul selectat";
"Show channel avatars in videos lists" = "Afișați avatarele canalului în listele de videoclipuri";
"Show channel avatars in channels lists" = "Afișați avatarele canalelor în listele de canale";
"Podcasts" = "Podcast-uri";
"Releases" = "Lansări";
"Add %@" = "Adaugă %@";

View File

@@ -0,0 +1,15 @@
//
// UIResponder+Extensions.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 21/09/2021.
//
import Foundation
import UIKit
extension UIResponder {
var parentViewController: UIViewController? {
next as? UIViewController ?? next?.parentViewController
}
}

View File

@@ -0,0 +1,70 @@
//
// UIView+Extensions.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 19/09/2021.
//
import Foundation
import UIKit
extension UIView {
/// Returs frame in screen coordinates.
var globalFrame: CGRect {
if let window {
return convert(bounds, to: window.screen.coordinateSpace)
} else {
return .zero
}
}
/// Returns with all the instances of the given view type in the view hierarchy.
func viewsInHierarchy<ViewType: UIView>() -> [ViewType]? {
var views: [ViewType] = []
viewsInHierarchy(views: &views)
return views.isEmpty ? nil : views
}
private func viewsInHierarchy<ViewType: UIView>(views: inout [ViewType]) {
subviews.forEach { eachSubView in
if let matchingView = eachSubView as? ViewType {
views.append(matchingView)
}
eachSubView.viewsInHierarchy(views: &views)
}
}
/// Search ancestral view hierarcy for the given view type.
func searchViewAnchestorsFor<ViewType: UIView>(
_ onViewFound: (ViewType) -> Void
) {
if let matchingView = superview as? ViewType {
onViewFound(matchingView)
} else {
superview?.searchViewAnchestorsFor(onViewFound)
}
}
/// Search ancestral view hierarcy for the given view type.
func searchViewAnchestorsFor<ViewType: UIView>() -> ViewType? {
if let matchingView = superview as? ViewType {
return matchingView
} else {
return superview?.searchViewAnchestorsFor()
}
}
func printViewHierarchyInformation(_ level: Int = 0) {
printViewInformation(level)
subviews.forEach { $0.printViewHierarchyInformation(level + 1) }
}
func printViewInformation(_ level: Int) {
let leadingWhitespace = String(repeating: " ", count: level)
let className = "\(Self.self)"
let superclassName = "\(superclass!)"
let frame = "\(self.frame)"
let id = (accessibilityIdentifier == nil) ? "" : " `\(accessibilityIdentifier!)`"
print("\(leadingWhitespace)\(className): \(superclassName)\(id) \(frame)")
}
}

View File

@@ -0,0 +1,56 @@
//
// RefreshControl.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 18/09/2021.
//
import Combine
import Foundation
import SwiftUI
import UIKit
final class RefreshControl: ObservableObject {
static var navigationBarTitleDisplayMode: NavigationBarItem.TitleDisplayMode {
if #available(iOS 15.0, *) {
return .automatic
}
return .inline
}
let onValueChanged: (_ refreshControl: UIRefreshControl) -> Void
init(onValueChanged: @escaping ((UIRefreshControl) -> Void)) {
self.onValueChanged = onValueChanged
}
/// Adds a `UIRefreshControl` to the `UIScrollView` provided.
func add(to scrollView: UIScrollView) {
scrollView.refreshControl = UIRefreshControl().withTarget(
self,
action: #selector(onValueChangedAction),
for: .valueChanged
)
.testable(as: "RefreshControl")
}
@objc private func onValueChangedAction(sender: UIRefreshControl) {
onValueChanged(sender)
}
}
extension UIRefreshControl {
/// Convinience method to assign target action inline.
func withTarget(_ target: Any?, action: Selector, for controlEvents: UIControl.Event) -> UIRefreshControl {
addTarget(target, action: action, for: controlEvents)
return self
}
/// Convinience method to match refresh control for UI testing.
func testable(as id: String) -> UIRefreshControl {
isAccessibilityElement = true
accessibilityIdentifier = id
return self
}
}

View File

@@ -0,0 +1,46 @@
//
// RefreshControlModifier.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 18/09/2021.
//
import Foundation
import SwiftUI
struct RefreshControlModifier: ViewModifier {
@State private var geometryReaderFrame: CGRect = .zero
let refreshControl: RefreshControl
init(onValueChanged: @escaping (UIRefreshControl) -> Void) {
refreshControl = RefreshControl(onValueChanged: onValueChanged)
}
func body(content: Content) -> some View {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
return content
} else {
return content
.background(
GeometryReader { geometry in
ScrollViewMatcher(
onResolve: { scrollView in
refreshControl.add(to: scrollView)
},
geometryReaderFrame: $geometryReaderFrame
)
.preference(key: FramePreferenceKey.self, value: geometry.frame(in: .global))
.onPreferenceChange(FramePreferenceKey.self) { frame in
self.geometryReaderFrame = frame
}
}
)
}
}
}
extension View {
func refreshControl(onValueChanged: @escaping (_ refreshControl: UIRefreshControl) -> Void) -> some View {
modifier(RefreshControlModifier(onValueChanged: onValueChanged))
}
}

View File

@@ -0,0 +1,18 @@
//
// FramePreferenceKey.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 21/09/2021.
//
import Foundation
import SwiftUI
struct FramePreferenceKey: PreferenceKey {
typealias Value = CGRect
static var defaultValue = CGRect.zero
static func reduce(value: inout CGRect, nextValue: () -> CGRect) {
value = nextValue()
}
}

View File

@@ -0,0 +1,106 @@
//
// ScrollViewMatcher.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 17/09/2021.
//
import Foundation
import SwiftUI
final class ScrollViewMatcher: UIViewControllerRepresentable {
let onMatch: (UIScrollView) -> Void
@Binding var geometryReaderFrame: CGRect
init(onResolve: @escaping (UIScrollView) -> Void, geometryReaderFrame: Binding<CGRect>) {
onMatch = onResolve
_geometryReaderFrame = geometryReaderFrame
}
func makeUIViewController(context _: Context) -> ScrollViewMatcherViewController {
ScrollViewMatcherViewController(onResolve: onMatch, geometryReaderFrame: geometryReaderFrame)
}
func updateUIViewController(_ viewController: ScrollViewMatcherViewController, context _: Context) {
viewController.geometryReaderFrame = geometryReaderFrame
}
}
final class ScrollViewMatcherViewController: UIViewController {
let onMatch: (UIScrollView) -> Void
private var scrollView: UIScrollView? {
didSet {
if oldValue != scrollView,
let scrollView
{
onMatch(scrollView)
}
}
}
var geometryReaderFrame: CGRect {
didSet {
match()
}
}
init(onResolve: @escaping (UIScrollView) -> Void, geometryReaderFrame: CGRect, debug _: Bool = false) {
onMatch = onResolve
self.geometryReaderFrame = geometryReaderFrame
super.init(nibName: nil, bundle: nil)
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("Use init(onMatch:) to instantiate ScrollViewMatcherViewController.")
}
func match() {
// matchUsingHierarchy()
matchUsingGeometry()
}
func matchUsingHierarchy() {
if parent != nil {
// Lookup view ancestry for any `UIScrollView`.
view.searchViewAnchestorsFor { (scrollView: UIScrollView) in
self.scrollView = scrollView
}
}
}
func matchUsingGeometry() {
if let parent {
if let scrollViewsInHierarchy: [UIScrollView] = parent.view.viewsInHierarchy() {
// Return first match if only a single scroll view is found in the hierarchy.
if scrollViewsInHierarchy.count == 1,
let firstScrollViewInHierarchy = scrollViewsInHierarchy.first
{
scrollView = firstScrollViewInHierarchy
// Filter by frame origins if multiple matches found.
} else {
if let firstMatchingFrameOrigin = scrollViewsInHierarchy.filter({
$0.globalFrame.origin.close(to: geometryReaderFrame.origin)
}).first {
scrollView = firstMatchingFrameOrigin
}
}
}
}
}
override func didMove(toParent parent: UIViewController?) {
super.didMove(toParent: parent)
match()
}
}
extension CGPoint {
/// Returns `true` if this point is close the other point (considering a ~1 pt tolerance).
func close(to point: CGPoint) -> Bool {
let inset = Double(1)
let rect = CGRect(x: x - inset, y: y - inset, width: inset * 2, height: inset * 2)
return rect.contains(point)
}
}

View File

@@ -172,7 +172,9 @@
371F2F1A269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; };
371F2F1B269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; };
371F2F1C269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; };
3722AEBC274DA396005EA4D6 /* Badge+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */; };
3722AEBE274DA401005EA4D6 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; };
3726386E2948A4B80043702D /* Badge+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */; };
37270F1C28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; };
37270F1D28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; };
37270F1E28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; };
@@ -322,6 +324,7 @@
37579D5E27864F5F00FD0B98 /* Help.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37579D5C27864F5F00FD0B98 /* Help.swift */; };
37579D5F27864F5F00FD0B98 /* Help.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37579D5C27864F5F00FD0B98 /* Help.swift */; };
3758638A2721B0A9000CB14E /* ChannelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3743B86727216D3600261544 /* ChannelCell.swift */; };
3759234628C26C7B00C052EC /* Refreshable+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3759234528C26C7B00C052EC /* Refreshable+Backport.swift */; };
37599F30272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; };
37599F31272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; };
37599F32272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; };
@@ -429,6 +432,24 @@
37732FF42703D32400F04329 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37732FF32703D32400F04329 /* Sidebar.swift */; };
37732FF52703D32400F04329 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37732FF32703D32400F04329 /* Sidebar.swift */; };
37737786276F9858000521C1 /* Windows.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37737785276F9858000521C1 /* Windows.swift */; };
3773B7FE2ADC076800B5FEF3 /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7F52ADC076800B5FEF3 /* RefreshControl.swift */; };
3773B8012ADC076800B5FEF3 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 3773B7F62ADC076800B5FEF3 /* README */; };
3773B8022ADC076800B5FEF3 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 3773B7F62ADC076800B5FEF3 /* README */; };
3773B8032ADC076800B5FEF3 /* README in Resources */ = {isa = PBXBuildFile; fileRef = 3773B7F62ADC076800B5FEF3 /* README */; };
3773B8042ADC076800B5FEF3 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7F82ADC076800B5FEF3 /* UIView+Extensions.swift */; };
3773B8062ADC076800B5FEF3 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7F82ADC076800B5FEF3 /* UIView+Extensions.swift */; };
3773B8072ADC076800B5FEF3 /* UIResponder+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7F92ADC076800B5FEF3 /* UIResponder+Extensions.swift */; };
3773B8092ADC076800B5FEF3 /* UIResponder+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7F92ADC076800B5FEF3 /* UIResponder+Extensions.swift */; };
3773B80A2ADC076800B5FEF3 /* RefreshControlModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7FA2ADC076800B5FEF3 /* RefreshControlModifier.swift */; };
3773B80D2ADC076800B5FEF3 /* FramePreferenceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7FC2ADC076800B5FEF3 /* FramePreferenceKey.swift */; };
3773B80E2ADC076800B5FEF3 /* FramePreferenceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7FC2ADC076800B5FEF3 /* FramePreferenceKey.swift */; };
3773B80F2ADC076800B5FEF3 /* FramePreferenceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7FC2ADC076800B5FEF3 /* FramePreferenceKey.swift */; };
3773B8102ADC076800B5FEF3 /* ScrollViewMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7FD2ADC076800B5FEF3 /* ScrollViewMatcher.swift */; };
3773B8122ADC076800B5FEF3 /* ScrollViewMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B7FD2ADC076800B5FEF3 /* ScrollViewMatcher.swift */; };
3773B8152ADC081300B5FEF3 /* VisualEffectBlur-iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B8132ADC081300B5FEF3 /* VisualEffectBlur-iOS.swift */; };
3773B8162ADC081300B5FEF3 /* VisualEffectBlur-iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B8132ADC081300B5FEF3 /* VisualEffectBlur-iOS.swift */; };
3773B8172ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B8142ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift */; };
3773B8182ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3773B8142ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift */; };
3774123327387CB000423605 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372915E52687E3B900F5A35B /* Defaults.swift */; };
3774124927387D2300423605 /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF28F26740715007FC770 /* Channel.swift */; };
3774124A27387D2300423605 /* ContentItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FB28402721B22200A57617 /* ContentItem.swift */; };
@@ -500,6 +521,9 @@
377ABC48286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377ABC49286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377ABC4A286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377E17142928265900894889 /* ListRowSeparator+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377E17132928265900894889 /* ListRowSeparator+Backport.swift */; };
377E17152928265900894889 /* ListRowSeparator+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377E17132928265900894889 /* ListRowSeparator+Backport.swift */; };
377E17162928265900894889 /* ListRowSeparator+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377E17132928265900894889 /* ListRowSeparator+Backport.swift */; };
377F9F74294403770043F856 /* Cache in Frameworks */ = {isa = PBXBuildFile; productRef = 377F9F73294403770043F856 /* Cache */; };
377F9F76294403880043F856 /* Cache in Frameworks */ = {isa = PBXBuildFile; productRef = 377F9F75294403880043F856 /* Cache */; };
377F9F7B294403F20043F856 /* VideosCacheModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377F9F7A294403F20043F856 /* VideosCacheModel.swift */; };
@@ -543,8 +567,12 @@
3788AC2726F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; };
3788AC2826F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; };
3788AC2926F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; };
378AE93A274EDFAF006A4EE1 /* Badge+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */; };
378AE93C274EDFB2006A4EE1 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; };
378AE93D274EDFB3006A4EE1 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; };
378AE93E274EDFB4006A4EE1 /* Tint+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */; };
378AE93F274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */; };
378AE940274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */; };
378AE943274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; };
378AE944274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; };
378AE945274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; };
@@ -601,7 +629,6 @@
379DC3D328BA4EB400B09677 /* Seek.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DC3D028BA4EB400B09677 /* Seek.swift */; };
379E7C332A20FE3900AF8118 /* FocusableSearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379E7C322A20FE3900AF8118 /* FocusableSearchTextField.swift */; };
379E7C342A20FE3900AF8118 /* FocusableSearchTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379E7C322A20FE3900AF8118 /* FocusableSearchTextField.swift */; };
379E7C362A2105B900AF8118 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 379E7C352A2105B900AF8118 /* Introspect */; };
379EF9E029AA585F009FE6C6 /* HideShortsButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379EF9DF29AA585F009FE6C6 /* HideShortsButtons.swift */; };
379EF9E129AA585F009FE6C6 /* HideShortsButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379EF9DF29AA585F009FE6C6 /* HideShortsButtons.swift */; };
379EF9E229AA585F009FE6C6 /* HideShortsButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379EF9DF29AA585F009FE6C6 /* HideShortsButtons.swift */; };
@@ -698,7 +725,6 @@
37BD07BC2698AB60003EBB87 /* AppSidebarNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BD07BA2698AB60003EBB87 /* AppSidebarNavigation.swift */; };
37BD07C12698AD3B003EBB87 /* TrendingCountry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B17F267B4DFB00704544 /* TrendingCountry.swift */; };
37BD07C32698AD4F003EBB87 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BD07B42698AA4D003EBB87 /* ContentView.swift */; };
37BD07C72698B27B003EBB87 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 37BD07C62698B27B003EBB87 /* Introspect */; };
37BD07C82698B71C003EBB87 /* AppTabNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B0C32671614700C925CA /* AppTabNavigation.swift */; };
37BD07C92698FBDB003EBB87 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BD07B42698AA4D003EBB87 /* ContentView.swift */; };
37BD672426F13D65004BE0C1 /* AppSidebarPlaylists.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BA794A26DC30EC002A0235 /* AppSidebarPlaylists.swift */; };
@@ -729,9 +755,6 @@
37C194C726F6A9C8005D3B96 /* RecentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C194C626F6A9C8005D3B96 /* RecentsModel.swift */; };
37C194C826F6A9C8005D3B96 /* RecentsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C194C626F6A9C8005D3B96 /* RecentsModel.swift */; };
37C2211D27ADA33300305B41 /* MPVViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C2211C27ADA33300305B41 /* MPVViewController.swift */; };
37C2211F27ADA3A200305B41 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 37C2211E27ADA3A200305B41 /* libz.tbd */; };
37C2212127ADA3A600305B41 /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 37C2212027ADA3A600305B41 /* libbz2.tbd */; };
37C2212327ADA3F200305B41 /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 37C2212227ADA3F200305B41 /* libiconv.tbd */; };
37C2212527ADA40A00305B41 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37C2212427ADA40A00305B41 /* AudioToolbox.framework */; };
37C2212727ADA41000305B41 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37C2212627ADA41000305B41 /* CoreFoundation.framework */; };
37C2212927ADA41400305B41 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37C2212827ADA41400305B41 /* CoreMedia.framework */; };
@@ -751,6 +774,8 @@
37C3A251272366440087A57A /* ChannelPlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C3A250272366440087A57A /* ChannelPlaylistView.swift */; };
37C3A252272366440087A57A /* ChannelPlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C3A250272366440087A57A /* ChannelPlaylistView.swift */; };
37C3A253272366440087A57A /* ChannelPlaylistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C3A250272366440087A57A /* ChannelPlaylistView.swift */; };
37C736782AC32B28007630E1 /* SwiftUIIntrospect in Frameworks */ = {isa = PBXBuildFile; productRef = 37C736772AC32B28007630E1 /* SwiftUIIntrospect */; };
37C7367A2AC33010007630E1 /* SwiftUIIntrospect in Frameworks */ = {isa = PBXBuildFile; productRef = 37C736792AC33010007630E1 /* SwiftUIIntrospect */; };
37C7A1D5267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; };
37C7A1D6267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; };
37C7A1D7267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C7A1D4267BFD9D0010EAD6 /* SponsorBlockSegment.swift */; };
@@ -1068,7 +1093,9 @@
371CC76F29468BDC00979C1A /* SettingsButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsButtons.swift; sourceTree = "<group>"; };
371CC7732946963000979C1A /* ListingStyleButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListingStyleButtons.swift; sourceTree = "<group>"; };
371F2F19269B43D300E4A7AB /* NavigationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModel.swift; sourceTree = "<group>"; };
3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Badge+Backport.swift"; sourceTree = "<group>"; };
3722AEBD274DA401005EA4D6 /* Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Backport.swift; sourceTree = "<group>"; };
3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Tint+Backport.swift"; sourceTree = "<group>"; };
37270F1B28E06E3E00856150 /* String+Localizable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Localizable.swift"; sourceTree = "<group>"; };
3728203F2945E4A8009A0E2D /* SubscriptionsPageButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsPageButton.swift; sourceTree = "<group>"; };
3729037D2739E47400EA99F6 /* MenuCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuCommands.swift; sourceTree = "<group>"; };
@@ -1127,6 +1154,7 @@
3756C2A52861131100E4B059 /* NetworkState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkState.swift; sourceTree = "<group>"; };
3756C2A92861151C00E4B059 /* NetworkStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkStateModel.swift; sourceTree = "<group>"; };
37579D5C27864F5F00FD0B98 /* Help.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Help.swift; sourceTree = "<group>"; };
3759234528C26C7B00C052EC /* Refreshable+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Refreshable+Backport.swift"; sourceTree = "<group>"; };
37599F2F272B42810087F250 /* FavoriteItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteItem.swift; sourceTree = "<group>"; };
37599F33272B44000087F250 /* FavoritesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesModel.swift; sourceTree = "<group>"; };
37599F37272B4D740087F250 /* FavoriteButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteButton.swift; sourceTree = "<group>"; };
@@ -1178,6 +1206,15 @@
37732FEF2703A26300F04329 /* AccountValidationStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountValidationStatus.swift; sourceTree = "<group>"; };
37732FF32703D32400F04329 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; };
37737785276F9858000521C1 /* Windows.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Windows.swift; sourceTree = "<group>"; };
3773B7F52ADC076800B5FEF3 /* RefreshControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControl.swift; sourceTree = "<group>"; };
3773B7F62ADC076800B5FEF3 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
3773B7F82ADC076800B5FEF3 /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = "<group>"; };
3773B7F92ADC076800B5FEF3 /* UIResponder+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+Extensions.swift"; sourceTree = "<group>"; };
3773B7FA2ADC076800B5FEF3 /* RefreshControlModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControlModifier.swift; sourceTree = "<group>"; };
3773B7FC2ADC076800B5FEF3 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = "<group>"; };
3773B7FD2ADC076800B5FEF3 /* ScrollViewMatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollViewMatcher.swift; sourceTree = "<group>"; };
3773B8132ADC081300B5FEF3 /* VisualEffectBlur-iOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "VisualEffectBlur-iOS.swift"; sourceTree = "<group>"; };
3773B8142ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "VisualEffectBlur-macOS.swift"; sourceTree = "<group>"; };
37758C0A2A1D1C8B001FD900 /* HideWatchedButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideWatchedButtons.swift; sourceTree = "<group>"; };
3776924D294630110055EC18 /* ChannelAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelAvatarView.swift; sourceTree = "<group>"; };
3776925129463C310055EC18 /* PlaylistsCacheModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistsCacheModel.swift; sourceTree = "<group>"; };
@@ -1188,6 +1225,7 @@
377ABC3F286E4AD5009C986F /* InstancesManifest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstancesManifest.swift; sourceTree = "<group>"; };
377ABC43286E4B74009C986F /* ManifestedInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManifestedInstance.swift; sourceTree = "<group>"; };
377ABC47286E5887009C986F /* Sequence+Unique.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Unique.swift"; sourceTree = "<group>"; };
377E17132928265900894889 /* ListRowSeparator+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ListRowSeparator+Backport.swift"; sourceTree = "<group>"; };
377F9F7A294403F20043F856 /* VideosCacheModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosCacheModel.swift; sourceTree = "<group>"; };
377F9F7E2944175F0043F856 /* FeedCacheModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedCacheModel.swift; sourceTree = "<group>"; };
377FF88A291A60310028EB0B /* OpenVideosModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVideosModel.swift; sourceTree = "<group>"; };
@@ -1324,6 +1362,12 @@
37DCD3162A191A180059A470 /* AVPlayerViewController+FullScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AVPlayerViewController+FullScreen.swift"; sourceTree = "<group>"; };
37DD87C6271C9CFE0027CBF9 /* PlayerStreams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerStreams.swift; sourceTree = "<group>"; };
37DD9DA22785BBC900539416 /* NoCommentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoCommentsView.swift; sourceTree = "<group>"; };
37DD9DAF2785D58D00539416 /* RefreshControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControl.swift; sourceTree = "<group>"; };
37DD9DB02785D58D00539416 /* RefreshControlModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControlModifier.swift; sourceTree = "<group>"; };
37DD9DB82785D60200539416 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = "<group>"; };
37DD9DB92785D60200539416 /* ScrollViewMatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollViewMatcher.swift; sourceTree = "<group>"; };
37DD9DC12785D63A00539416 /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = "<group>"; };
37DD9DC22785D63A00539416 /* UIResponder+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+Extensions.swift"; sourceTree = "<group>"; };
37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalScrollingFix.swift; sourceTree = "<group>"; };
37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsNavigationLink.swift; sourceTree = "<group>"; };
37E64DD026D597EB00C71877 /* SubscribedChannelsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscribedChannelsModel.swift; sourceTree = "<group>"; };
@@ -1406,11 +1450,8 @@
37C2212727ADA41000305B41 /* CoreFoundation.framework in Frameworks */,
37C2212527ADA40A00305B41 /* AudioToolbox.framework in Frameworks */,
372AA410286D067B0000B1DC /* Repeat in Frameworks */,
37C2212327ADA3F200305B41 /* libiconv.tbd in Frameworks */,
379325D529A265A300181CF1 /* Logging in Frameworks */,
37C2212127ADA3A600305B41 /* libbz2.tbd in Frameworks */,
37EE6DC528A305AD00BFD632 /* Reachability in Frameworks */,
37C2211F27ADA3A200305B41 /* libz.tbd in Frameworks */,
375B8AB128B57F4200397B31 /* KeychainAccess in Frameworks */,
3765917C27237D21009F956E /* PINCache in Frameworks */,
37BD07B72698AB2E003EBB87 /* Defaults in Frameworks */,
@@ -1421,9 +1462,9 @@
3797104928D3D10600D5F53C /* SDWebImageSwiftUI in Frameworks */,
FA97174C2A494700001FF53D /* MPVKit in Frameworks */,
37BD07B92698AB2E003EBB87 /* Siesta in Frameworks */,
37BD07C72698B27B003EBB87 /* Introspect in Frameworks */,
37FB284D2722099E00A57617 /* SDWebImageWebPCoder in Frameworks */,
37CF8B8428535E4F00B71E37 /* SDWebImage in Frameworks */,
37C7367A2AC33010007630E1 /* SwiftUIIntrospect in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1434,12 +1475,12 @@
379325D729A265AE00181CF1 /* Logging in Frameworks */,
372AA414286D06A10000B1DC /* Repeat in Frameworks */,
37F7AB5228A94EB900FB46B5 /* IOKit.framework in Frameworks */,
379E7C362A2105B900AF8118 /* Introspect in Frameworks */,
3703205827D2BAE4007A0CB8 /* Siesta in Frameworks */,
3703206827D2BB45007A0CB8 /* Defaults in Frameworks */,
3703206A27D2BB49007A0CB8 /* Alamofire in Frameworks */,
374D11E72943C56300CB4350 /* Cache in Frameworks */,
3797104B28D3D18800D5F53C /* SDWebImageSwiftUI in Frameworks */,
37C736782AC32B28007630E1 /* SwiftUIIntrospect in Frameworks */,
3703206227D2BB1B007A0CB8 /* SDWebImagePINPlugin in Frameworks */,
371AC0B2294D1C230085989E /* CachedAsyncImage in Frameworks */,
3703206627D2BB35007A0CB8 /* PINCache in Frameworks */,
@@ -1657,9 +1698,15 @@
isa = PBXGroup;
children = (
3722AEBD274DA401005EA4D6 /* Backport.swift */,
3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */,
377E17132928265900894889 /* ListRowSeparator+Backport.swift */,
37136CAB286273060095C0CF /* PersistentSystemOverlays+Backport.swift */,
3773B8132ADC081300B5FEF3 /* VisualEffectBlur-iOS.swift */,
3773B8142ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift */,
3759234528C26C7B00C052EC /* Refreshable+Backport.swift */,
37E80F3F287B472300561799 /* ScrollContentBackground+Backport.swift */,
376E331128AD3B320070E30C /* ScrollDismissesKeyboard+Backport.swift */,
3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */,
37B7CFE82A19603B001B0564 /* ToolbarBackground+Backport.swift */,
37B7CFEA2A1960EC001B0564 /* ToolbarColorScheme+Backport.swift */,
);
@@ -1828,6 +1875,57 @@
path = Modifiers;
sourceTree = "<group>";
};
3773B7D12ADC05FF00B5FEF3 /* Recovered References */ = {
isa = PBXGroup;
children = (
37DD9DC12785D63A00539416 /* UIView+Extensions.swift */,
37DD9DAF2785D58D00539416 /* RefreshControl.swift */,
37DD9DB02785D58D00539416 /* RefreshControlModifier.swift */,
37DD9DB82785D60200539416 /* FramePreferenceKey.swift */,
37DD9DB92785D60200539416 /* ScrollViewMatcher.swift */,
37DD9DC22785D63A00539416 /* UIResponder+Extensions.swift */,
);
name = "Recovered References";
sourceTree = "<group>";
};
3773B7F32ADC076800B5FEF3 /* Vendor */ = {
isa = PBXGroup;
children = (
3773B7F42ADC076800B5FEF3 /* RefreshControl */,
);
path = Vendor;
sourceTree = "<group>";
};
3773B7F42ADC076800B5FEF3 /* RefreshControl */ = {
isa = PBXGroup;
children = (
3773B7F52ADC076800B5FEF3 /* RefreshControl.swift */,
3773B7F62ADC076800B5FEF3 /* README */,
3773B7F72ADC076800B5FEF3 /* Extensions */,
3773B7FA2ADC076800B5FEF3 /* RefreshControlModifier.swift */,
3773B7FB2ADC076800B5FEF3 /* ScrollViewMatcher */,
);
path = RefreshControl;
sourceTree = "<group>";
};
3773B7F72ADC076800B5FEF3 /* Extensions */ = {
isa = PBXGroup;
children = (
3773B7F82ADC076800B5FEF3 /* UIView+Extensions.swift */,
3773B7F92ADC076800B5FEF3 /* UIResponder+Extensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
3773B7FB2ADC076800B5FEF3 /* ScrollViewMatcher */ = {
isa = PBXGroup;
children = (
3773B7FC2ADC076800B5FEF3 /* FramePreferenceKey.swift */,
3773B7FD2ADC076800B5FEF3 /* ScrollViewMatcher.swift */,
);
path = ScrollViewMatcher;
sourceTree = "<group>";
};
377F9F79294403DC0043F856 /* Cache */ = {
isa = PBXGroup;
children = (
@@ -1981,6 +2079,7 @@
37D4B159267164AE00C925CA /* tvOS */,
37D4B1B72672CFE300C925CA /* Model */,
37D4B0C12671614700C925CA /* Shared */,
3773B7F32ADC076800B5FEF3 /* Vendor */,
3722AEBA274DA312005EA4D6 /* Backports */,
37C7A9022679058300E721B4 /* Extensions */,
3748186426A762300084E870 /* Fixtures */,
@@ -1993,6 +2092,7 @@
37D4B0E12671614900C925CA /* Tests macOS */,
3DA101AC287C30F50027D920 /* Xcode-config */,
37D9169A27388A81002B1BAA /* README.md */,
3773B7D12ADC05FF00B5FEF3 /* Recovered References */,
);
sourceTree = "<group>";
};
@@ -2280,7 +2380,6 @@
377FC7D4267A080300A6BBAF /* SwiftyJSON */,
37BD07B62698AB2E003EBB87 /* Defaults */,
37BD07B82698AB2E003EBB87 /* Siesta */,
37BD07C62698B27B003EBB87 /* Introspect */,
37BADCA42699FB72009BE4FB /* Alamofire */,
37FB284C2722099E00A57617 /* SDWebImageWebPCoder */,
37FB285527220D9000A57617 /* SDWebImagePINPlugin */,
@@ -2295,6 +2394,7 @@
371AC0AB294D1A490085989E /* CachedAsyncImage */,
379325D429A265A300181CF1 /* Logging */,
FA97174B2A494700001FF53D /* MPVKit */,
37C736792AC33010007630E1 /* SwiftUIIntrospect */,
);
productName = "Yattee (iOS)";
productReference = 37D4B0C92671614900C925CA /* Yattee.app */;
@@ -2332,8 +2432,8 @@
374D11E62943C56300CB4350 /* Cache */,
371AC0B1294D1C230085989E /* CachedAsyncImage */,
379325D629A265AE00181CF1 /* Logging */,
379E7C352A2105B900AF8118 /* Introspect */,
3704BDFE2ABF260C00370FF7 /* MPVKit */,
37C736772AC32B28007630E1 /* SwiftUIIntrospect */,
);
productName = "Yattee (macOS)";
productReference = 37D4B0CF2671614900C925CA /* Yattee.app */;
@@ -2566,6 +2666,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3773B8012ADC076800B5FEF3 /* README in Resources */,
37D4B0E82671614900C925CA /* Assets.xcassets in Resources */,
375B537428DF6CBB004C1D19 /* Localizable.strings in Resources */,
);
@@ -2575,6 +2676,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3773B8022ADC076800B5FEF3 /* README in Resources */,
37D4B0E92671614900C925CA /* Assets.xcassets in Resources */,
375B537528DF6CBB004C1D19 /* Localizable.strings in Resources */,
);
@@ -2598,6 +2700,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3773B8032ADC076800B5FEF3 /* README in Resources */,
37D4B1862671691600C925CA /* Assets.xcassets in Resources */,
375B537628DF6CBB004C1D19 /* Localizable.strings in Resources */,
37D4B15F267164AF00C925CA /* Assets.xcassets in Resources */,
@@ -2761,6 +2864,7 @@
37A362BE29537AAA00BDF328 /* PlaybackSettings.swift in Sources */,
371B7E612759706A00D21217 /* CommentsView.swift in Sources */,
37D9BA0629507F69002586BD /* PlayerControlsSettings.swift in Sources */,
3773B80A2ADC076800B5FEF3 /* RefreshControlModifier.swift in Sources */,
379DC3D128BA4EB400B09677 /* Seek.swift in Sources */,
371B7E6A2759791900D21217 /* CommentsModel.swift in Sources */,
37E8B0F027B326F30024006F /* Comparable+Clamped.swift in Sources */,
@@ -2784,6 +2888,7 @@
37BD07B52698AA4D003EBB87 /* ContentView.swift in Sources */,
37D2E0D428B67EFC00F64D52 /* Delay.swift in Sources */,
3776925229463C310055EC18 /* PlaylistsCacheModel.swift in Sources */,
3759234628C26C7B00C052EC /* Refreshable+Backport.swift in Sources */,
374924ED2921669B0017D862 /* PreferenceKeys.swift in Sources */,
37130A5B277657090033018A /* Yattee.xcdatamodeld in Sources */,
37152EEA26EFEB95004FB96D /* LazyView.swift in Sources */,
@@ -2828,6 +2933,7 @@
37DD87C7271C9CFE0027CBF9 /* PlayerStreams.swift in Sources */,
37F7D82C289EB05F00E2B3D0 /* SettingsPickerModifier.swift in Sources */,
375EC95D289EEEE000751258 /* QualityProfile.swift in Sources */,
3773B8102ADC076800B5FEF3 /* ScrollViewMatcher.swift in Sources */,
371B7E662759786B00D21217 /* Comment+Fixtures.swift in Sources */,
37BE0BD326A1D4780092E2DB /* AppleAVPlayerView.swift in Sources */,
37A9965E26D6F9B9006E3224 /* HomeView.swift in Sources */,
@@ -2836,8 +2942,10 @@
378AE943274EF00A006A4EE1 /* Color+Background.swift in Sources */,
37F4AE7226828F0900BD60EA /* VerticalCells.swift in Sources */,
376578852685429C00D4EA09 /* CaseIterable+Next.swift in Sources */,
3722AEBC274DA396005EA4D6 /* Badge+Backport.swift in Sources */,
3748186626A7627F0084E870 /* Video+Fixtures.swift in Sources */,
37599F34272B44000087F250 /* FavoritesModel.swift in Sources */,
3773B8152ADC081300B5FEF3 /* VisualEffectBlur-iOS.swift in Sources */,
3717407D2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */,
379ACB512A1F8DB000E01914 /* HomeSettingsButton.swift in Sources */,
37030FF727B0347C00ECDDAA /* MPVPlayerView.swift in Sources */,
@@ -2850,6 +2958,7 @@
37FFC440272734C3009FFD26 /* Throttle.swift in Sources */,
3709528A29283E14001ECA40 /* NoDocumentsView.swift in Sources */,
3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */,
378AE940274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */,
376BE50927347B5F009AD608 /* SettingsHeader.swift in Sources */,
376527BB285F60F700102284 /* PlayerTimeModel.swift in Sources */,
37270F1C28E06E3E00856150 /* String+Localizable.swift in Sources */,
@@ -2917,6 +3026,7 @@
377A20A92693C9A2002842B8 /* TypedContentAccessors.swift in Sources */,
37484C3126FCB8F900287258 /* AccountValidator.swift in Sources */,
377ABC48286E5887009C986F /* Sequence+Unique.swift in Sources */,
3773B8172ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift in Sources */,
37520699285E8DD300CA655F /* Chapter.swift in Sources */,
37C7B21429ABD9F20013C196 /* ChannelPage.swift in Sources */,
37319F0527103F94004ECCD0 /* PlayerQueue.swift in Sources */,
@@ -2931,6 +3041,7 @@
3784B23B272894DA00B09468 /* ShareSheet.swift in Sources */,
379775932689365600DD52A8 /* Array+Next.swift in Sources */,
37CFB48528AFE2510070024C /* VideoDescription.swift in Sources */,
3773B8042ADC076800B5FEF3 /* UIView+Extensions.swift in Sources */,
37B81AFC26D2C9C900675966 /* VideoDetailsPaddingModifier.swift in Sources */,
371CC77029468BDC00979C1A /* SettingsButtons.swift in Sources */,
37C7A1D5267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */,
@@ -2956,6 +3067,7 @@
371AC09F294D13AA0085989E /* UnwatchedFeedCountModel.swift in Sources */,
370015A928BBAE7F000149FD /* ProgressBar.swift in Sources */,
37C3A24927235FAA0087A57A /* ChannelPlaylistCell.swift in Sources */,
377E17142928265900894889 /* ListRowSeparator+Backport.swift in Sources */,
373CFACB26966264003CB2C6 /* SearchQuery.swift in Sources */,
37F7AB4D28A9361F00FB46B5 /* UIDevice+Cellular.swift in Sources */,
37141673267A8E10006CA35D /* Country.swift in Sources */,
@@ -2972,6 +3084,7 @@
37EF5C222739D37B00B03725 /* MenuModel.swift in Sources */,
37599F30272B42810087F250 /* FavoriteItem.swift in Sources */,
374924E729215FB60017D862 /* TapRecognizerViewModifier.swift in Sources */,
3773B8072ADC076800B5FEF3 /* UIResponder+Extensions.swift in Sources */,
373197D92732015300EF734F /* RelatedView.swift in Sources */,
3710A55529488C7D006F8025 /* PlaceholderListItem.swift in Sources */,
37F4AD1B28612B23004D0F66 /* OpeningStream.swift in Sources */,
@@ -2980,6 +3093,7 @@
370E990A2A1EA8C500D144E9 /* WatchModel.swift in Sources */,
371AC0B6294D1D6E0085989E /* PlayingIndicatorView.swift in Sources */,
37E084AC2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */,
3773B7FE2ADC076800B5FEF3 /* RefreshControl.swift in Sources */,
378E9C38294552A700B2D696 /* ThumbnailView.swift in Sources */,
37732FF42703D32400F04329 /* Sidebar.swift in Sources */,
37D4B19726717E1500C925CA /* Video.swift in Sources */,
@@ -3021,6 +3135,7 @@
3784CDE227772EE40055BBF2 /* Watch.swift in Sources */,
37FB285E272225E800A57617 /* ContentItemView.swift in Sources */,
3797758B2689345500DD52A8 /* Store.swift in Sources */,
3773B80D2ADC076800B5FEF3 /* FramePreferenceKey.swift in Sources */,
377F9F7B294403F20043F856 /* VideosCacheModel.swift in Sources */,
37B795902771DAE0001CF27B /* OpenURLHandler.swift in Sources */,
37732FF02703A26300F04329 /* AccountValidationStatus.swift in Sources */,
@@ -3035,6 +3150,7 @@
374710062755291C00CE0F87 /* SearchTextField.swift in Sources */,
37B7CFEC2A197844001B0564 /* AppleAVPlayerView.swift in Sources */,
37F0F4EB286F397E00C06C2E /* SettingsModel.swift in Sources */,
378AE93F274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */,
379ACB4D2A1F8A4100E01914 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */,
37C194C826F6A9C8005D3B96 /* RecentsModel.swift in Sources */,
37737786276F9858000521C1 /* Windows.swift in Sources */,
@@ -3085,6 +3201,7 @@
37192D5828B179D60012EEDD /* ChaptersView.swift in Sources */,
3784CDE327772EE40055BBF2 /* Watch.swift in Sources */,
371AC0B7294D1D6E0085989E /* PlayingIndicatorView.swift in Sources */,
3773B8182ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift in Sources */,
37E80F3D287B107F00561799 /* VideoDetailsOverlay.swift in Sources */,
375DFB5926F9DA010013F468 /* InstancesModel.swift in Sources */,
3705B183267B4E4900704544 /* TrendingCategory.swift in Sources */,
@@ -3115,6 +3232,8 @@
37EAD870267B9ED100D9E01B /* Segment.swift in Sources */,
3788AC2826F6840700F6BAA9 /* FavoriteItemView.swift in Sources */,
377FF88C291A60310028EB0B /* OpenVideosModel.swift in Sources */,
378AE93A274EDFAF006A4EE1 /* Badge+Backport.swift in Sources */,
3773B8162ADC081300B5FEF3 /* VisualEffectBlur-iOS.swift in Sources */,
37599F35272B44000087F250 /* FavoritesModel.swift in Sources */,
376527BC285F60F700102284 /* PlayerTimeModel.swift in Sources */,
37F64FE526FE70A60081B69E /* RedrawOnModifier.swift in Sources */,
@@ -3176,6 +3295,7 @@
3748186F26A769D60084E870 /* DetailBadge.swift in Sources */,
3744A96128B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */,
372915E72687E3B900F5A35B /* Defaults.swift in Sources */,
377E17152928265900894889 /* ListRowSeparator+Backport.swift in Sources */,
371CC76929466ED000979C1A /* AccountsView.swift in Sources */,
37C3A242272359900087A57A /* Double+Format.swift in Sources */,
37B795912771DAE0001CF27B /* OpenURLHandler.swift in Sources */,
@@ -3285,6 +3405,7 @@
377ABC41286E4AD5009C986F /* InstancesManifest.swift in Sources */,
373CFAF02697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */,
3763495226DFF59D00B9A393 /* AppSidebarRecents.swift in Sources */,
3773B80E2ADC076800B5FEF3 /* FramePreferenceKey.swift in Sources */,
370015AA28BBAE7F000149FD /* ProgressBar.swift in Sources */,
371B7E672759786B00D21217 /* Comment+Fixtures.swift in Sources */,
3769C02F2779F18600DDB3EA /* PlaceholderProgressView.swift in Sources */,
@@ -3416,6 +3537,7 @@
376BE50D27349108009AD608 /* BrowsingSettings.swift in Sources */,
37CFB48728AFE2510070024C /* VideoDescription.swift in Sources */,
37DD87C9271C9CFE0027CBF9 /* PlayerStreams.swift in Sources */,
378AE93E274EDFB4006A4EE1 /* Tint+Backport.swift in Sources */,
37FFC442272734C3009FFD26 /* Throttle.swift in Sources */,
377FF88D291A60310028EB0B /* OpenVideosModel.swift in Sources */,
37F4AD2828613B81004D0F66 /* Color+Debug.swift in Sources */,
@@ -3444,6 +3566,7 @@
37A362C429537FED00BDF328 /* PlaybackSettingsPresentationDetents+Backport.swift in Sources */,
37BDFF1929487B99000C6404 /* PlaylistVideosView.swift in Sources */,
37B7CFEF2A197A08001B0564 /* SafeAreaModel.swift in Sources */,
3773B8092ADC076800B5FEF3 /* UIResponder+Extensions.swift in Sources */,
37C0698427260B2100F7F6CB /* ThumbnailsModel.swift in Sources */,
374924DC2921050B0017D862 /* LocationsSettings.swift in Sources */,
37D6025B28C17375009E8D98 /* PlaybackStatsView.swift in Sources */,
@@ -3458,6 +3581,7 @@
37B044B926F7AB9000E1419D /* SettingsView.swift in Sources */,
3743B86A27216D3600261544 /* ChannelCell.swift in Sources */,
3751BA8527E6914F007B1A60 /* ReturnYouTubeDislikeAPI.swift in Sources */,
3773B8062ADC076800B5FEF3 /* UIView+Extensions.swift in Sources */,
37769250294630110055EC18 /* ChannelAvatarView.swift in Sources */,
37030FFD27B0398000ECDDAA /* MPVClient.swift in Sources */,
378E9C4229455A5800B2D696 /* ChannelsView.swift in Sources */,
@@ -3536,6 +3660,7 @@
37C069802725C8D400F7F6CB /* CMTime+DefaultTimescale.swift in Sources */,
37EBD8CC27AF26C200F1C24B /* MPVBackend.swift in Sources */,
3711404126B206A6005B3555 /* SearchModel.swift in Sources */,
3773B80F2ADC076800B5FEF3 /* FramePreferenceKey.swift in Sources */,
37FD77022932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */,
37FEF11527EFD8580033912F /* PlaceholderCell.swift in Sources */,
37FD43F02704A9C00073EE42 /* RecentsModel.swift in Sources */,
@@ -3556,6 +3681,7 @@
37D9BA0829507F69002586BD /* PlayerControlsSettings.swift in Sources */,
37599F32272B42810087F250 /* FavoriteItem.swift in Sources */,
37E8B0EE27B326C00024006F /* TimelineView.swift in Sources */,
3726386E2948A4B80043702D /* Badge+Backport.swift in Sources */,
37141675267A8E10006CA35D /* Country.swift in Sources */,
370F500C27CC1821001B35DC /* MPVViewController.swift in Sources */,
3782B9542755667600990149 /* String+Format.swift in Sources */,
@@ -3593,10 +3719,12 @@
3761ABFF26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */,
37C3A24F272360470087A57A /* ChannelPlaylist+Fixtures.swift in Sources */,
3718B9A02921A9620003DB2E /* VideoDetailsOverlay.swift in Sources */,
377E17162928265900894889 /* ListRowSeparator+Backport.swift in Sources */,
37FB28432721B22200A57617 /* ContentItem.swift in Sources */,
37D2E0D228B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */,
37AAF2A226741C97007FC770 /* FeedView.swift in Sources */,
37484C1B26FC837400287258 /* PlayerSettings.swift in Sources */,
3773B8122ADC076800B5FEF3 /* ScrollViewMatcher.swift in Sources */,
372915E82687E3B900F5A35B /* Defaults.swift in Sources */,
37BAB54C269B39FD00E75ED1 /* TVNavigationView.swift in Sources */,
3718B9A62921A9BE0003DB2E /* PreferenceKeys.swift in Sources */,
@@ -3673,7 +3801,7 @@
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee";
@@ -3684,7 +3812,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = "stream.yattee.app.Open-in-Yattee";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -3704,7 +3832,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist";
@@ -3716,7 +3844,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = "stream.yattee.app.Open-in-Yattee";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -3735,11 +3863,11 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = "net.arekf.Shared-Tests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
@@ -3755,11 +3883,11 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = "net.arekf.Shared-Tests";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
@@ -3919,7 +4047,7 @@
CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -3937,13 +4065,13 @@
INFOPLIST_KEY_UIRequiresFullScreen = YES;
INFOPLIST_KEY_UIStatusBarHidden = NO;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
OTHER_LDFLAGS = (
"-lstdc++",
"-Wl,-no_compact_unwind",
@@ -3972,7 +4100,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1";
@@ -3987,13 +4115,13 @@
INFOPLIST_KEY_UIRequiresFullScreen = YES;
INFOPLIST_KEY_UIStatusBarHidden = NO;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
OTHER_LDFLAGS = (
"-lstdc++",
"-Wl,-no_compact_unwind",
@@ -4024,7 +4152,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
DEAD_CODE_STRIPPING = YES;
ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES;
@@ -4038,11 +4166,9 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.5;
LIBRARY_SEARCH_PATHS = "$(inherited)";
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.5.1;
OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
PRODUCT_BUNDLE_IDENTIFIER = stream.yattee.app;
PRODUCT_NAME = Yattee;
@@ -4065,7 +4191,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
DEAD_CODE_STRIPPING = YES;
"DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ;
ENABLE_APP_SANDBOX = YES;
@@ -4080,11 +4206,9 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.5;
LIBRARY_SEARCH_PATHS = "$(inherited)";
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.5.1;
OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
PRODUCT_BUNDLE_IDENTIFIER = stream.yattee.app;
PRODUCT_NAME = Yattee;
@@ -4102,7 +4226,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4110,7 +4234,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = "stream.yattee.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -4126,7 +4250,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4134,7 +4258,7 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = "stream.yattee.Tests-iOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -4152,7 +4276,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4161,7 +4285,7 @@
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = "stream.yattee.Tests-macOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
@@ -4177,7 +4301,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4186,7 +4310,7 @@
"@loader_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = "stream.yattee.Tests-macOS";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
@@ -4203,7 +4327,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
DEVELOPMENT_ASSET_PATHS = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -4219,7 +4343,7 @@
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
OTHER_LDFLAGS = (
"-Wl,-no_compact_unwind",
"-lstdc++",
@@ -4243,7 +4367,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
DEVELOPMENT_ASSET_PATHS = "";
"DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ;
ENABLE_PREVIEWS = YES;
@@ -4260,7 +4384,7 @@
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
OTHER_LDFLAGS = (
"-Wl,-no_compact_unwind",
"-lstdc++",
@@ -4284,14 +4408,14 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = stream.yattee.YatteeUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
@@ -4308,14 +4432,14 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 162;
CURRENT_PROJECT_VERSION = 169;
GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.5;
MARKETING_VERSION = 1.5.1;
PRODUCT_BUNDLE_IDENTIFIER = stream.yattee.YatteeUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
@@ -4618,8 +4742,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/cxfksword/MPVKit.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.35.1;
branch = main;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */
@@ -4825,11 +4949,6 @@
package = 3799AC0728B03CEC001376F9 /* XCRemoteSwiftPackageReference "ActiveLabel.swift" */;
productName = ActiveLabel;
};
379E7C352A2105B900AF8118 /* Introspect */ = {
isa = XCSwiftPackageProductDependency;
package = 37BD07C52698B27B003EBB87 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */;
productName = Introspect;
};
37BADCA42699FB72009BE4FB /* Alamofire */ = {
isa = XCSwiftPackageProductDependency;
package = 37BADCA32699FB72009BE4FB /* XCRemoteSwiftPackageReference "Alamofire" */;
@@ -4850,10 +4969,15 @@
package = 3797757B268922D100DD52A8 /* XCRemoteSwiftPackageReference "siesta" */;
productName = Siesta;
};
37BD07C62698B27B003EBB87 /* Introspect */ = {
37C736772AC32B28007630E1 /* SwiftUIIntrospect */ = {
isa = XCSwiftPackageProductDependency;
package = 37BD07C52698B27B003EBB87 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */;
productName = Introspect;
productName = SwiftUIIntrospect;
};
37C736792AC33010007630E1 /* SwiftUIIntrospect */ = {
isa = XCSwiftPackageProductDependency;
package = 37BD07C52698B27B003EBB87 /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */;
productName = SwiftUIIntrospect;
};
37CF8B8328535E4F00B71E37 /* SDWebImage */ = {
isa = XCSwiftPackageProductDependency;

View File

@@ -14,8 +14,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire.git",
"state" : {
"revision" : "b2fa556e4e48cbf06cf8c63def138c98f4b811fa",
"version" : "5.8.0"
"revision" : "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad",
"version" : "5.8.1"
}
},
{
@@ -59,8 +59,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/cxfksword/MPVKit.git",
"state" : {
"revision" : "96825b3dc2b38e5550268156148d47798ce6aa74",
"version" : "0.36.0"
"branch" : "main",
"revision" : "dca1e345a26d09a3d621d7656a94e6427f3f7b83"
}
},
{
@@ -105,7 +105,7 @@
"location" : "https://github.com/SDWebImage/SDWebImage",
"state" : {
"branch" : "master",
"revision" : "936f1c7067728d16c362ba4fb93c17df78b5fd79"
"revision" : "fd1950de05a5ad77cb252fd88576c1e1809ee50d"
}
},
{
@@ -122,8 +122,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/SDWebImage/SDWebImageSwiftUI.git",
"state" : {
"revision" : "e837c37d45449fbd3b4745c10c5b5274e73edead",
"version" : "2.2.3"
"revision" : "5f025e54a03d3d33dff24d7a19331f446f00ed9d",
"version" : "2.2.4"
}
},
{
@@ -131,8 +131,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/SDWebImage/SDWebImageWebPCoder.git",
"state" : {
"revision" : "3819cb70faa2454b54d8364779bfacd8c216a6e2",
"version" : "0.13.0"
"revision" : "7e70ec8165b455cc2b97ff5c5ac6a8064c737e6f",
"version" : "0.14.1"
}
},
{

View File

@@ -38,7 +38,7 @@ struct InstancesSettings: View {
if !selectedInstance.isNil, selectedInstance.app.supportsAccounts {
SettingsHeader(text: "Accounts".localized())
List(selection: $selectedAccount) {
let list = List(selection: $selectedAccount) {
if selectedInstanceAccounts.isEmpty {
Text("You have no accounts for this location")
.foregroundColor(.secondary)
@@ -69,7 +69,13 @@ struct InstancesSettings: View {
.tag(account)
}
}
.listStyle(.inset(alternatesRowBackgrounds: true))
if #available(macOS 12.0, *) {
list
.listStyle(.inset(alternatesRowBackgrounds: true))
} else {
list
}
}
if selectedInstance != nil, selectedInstance.app.hasFrontendURL {

View File

@@ -4,6 +4,7 @@ final class MPVOGLView: NSView {
override init(frame frameRect: CGRect) {
super.init(frame: frameRect)
autoresizingMask = [.width, .height]
wantsBestResolutionOpenGLSurface = true
}
@available(*, unavailable)