mirror of
https://github.com/yattee/yattee.git
synced 2025-12-14 12:08:15 +00:00
Compare commits
136 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39f6319043 | ||
|
|
6a2dc9164e | ||
|
|
37d3f43596 | ||
|
|
aef0ba6ffd | ||
|
|
1ae12cfa21 | ||
|
|
8475669aab | ||
|
|
6fec76fcb3 | ||
|
|
08b2e7ceac | ||
|
|
60972f0c7b | ||
|
|
a49db76588 | ||
|
|
bd0c86060b | ||
|
|
9849f31e1f | ||
|
|
00ac222af6 | ||
|
|
732a8d7385 | ||
|
|
a009ad7d53 | ||
|
|
91c7c9fc8e | ||
|
|
e836f87c88 | ||
|
|
1e1a23acd0 | ||
|
|
d8d728a48f | ||
|
|
067e8a79bf | ||
|
|
576f40360d | ||
|
|
c679a52903 | ||
|
|
82f109290d | ||
|
|
765006b185 | ||
|
|
86cddb06e4 | ||
|
|
012b5156b7 | ||
|
|
d6c04540e9 | ||
|
|
3144b52b55 | ||
|
|
b04385ceae | ||
|
|
721a97dc41 | ||
|
|
4ca8adc4dd | ||
|
|
d361ef01d4 | ||
|
|
0d9c27319d | ||
|
|
600b8d198b | ||
|
|
d65224320e | ||
|
|
586cea7d44 | ||
|
|
aa5d6733b2 | ||
|
|
982dca1846 | ||
|
|
7de702ad23 | ||
|
|
13ef96cd02 | ||
|
|
4ec6f35c5d | ||
|
|
7f19f7aa47 | ||
|
|
fb5cd0f681 | ||
|
|
3feafc153c | ||
|
|
8f08674527 | ||
|
|
a7baaeb485 | ||
|
|
b0d81cdefd | ||
|
|
a33a1d7658 | ||
|
|
e436dec4ba | ||
|
|
eb1dfe69cd | ||
|
|
9f5720d393 | ||
|
|
675db6f651 | ||
|
|
fb5e86c2cb | ||
|
|
d384a4c520 | ||
|
|
6994271eca | ||
|
|
ed5fa8e4aa | ||
|
|
cbdf295d67 | ||
|
|
5d78946320 | ||
|
|
84fdc22861 | ||
|
|
a57645f824 | ||
|
|
e78f40c555 | ||
|
|
23f5fc9575 | ||
|
|
fc7a7b085f | ||
|
|
7ffa34b0f9 | ||
|
|
177e28121b | ||
|
|
68a35b8804 | ||
|
|
9ec9a680a6 | ||
|
|
7629931747 | ||
|
|
afb22e6c25 | ||
|
|
052fc86388 | ||
|
|
4de51f29c8 | ||
|
|
d1a1f4da38 | ||
|
|
d1153ed97d | ||
|
|
1c356560d5 | ||
|
|
bbd18d921b | ||
|
|
9e4860d97c | ||
|
|
50d42f721f | ||
|
|
9bfccb49e3 | ||
|
|
919126f9b0 | ||
|
|
d00903569f | ||
|
|
25e7b0d3e1 | ||
|
|
2aafe33417 | ||
|
|
e525f36824 | ||
|
|
5a5f5a8696 | ||
|
|
45d2968d9e | ||
|
|
c3e1465f31 | ||
|
|
df47ffb013 | ||
|
|
8900f96ce7 | ||
|
|
ed69780d52 | ||
|
|
691a3305e7 | ||
|
|
987f6dcac8 | ||
|
|
1113a94d67 | ||
|
|
8c6fc7d561 | ||
|
|
fb84927fc8 | ||
|
|
c452e66999 | ||
|
|
7ab91e08f4 | ||
|
|
bdd18dba4e | ||
|
|
026654d3a2 | ||
|
|
e9729bc9b3 | ||
|
|
a04159969e | ||
|
|
3624d186bc | ||
|
|
31ea4860cf | ||
|
|
5a074d7607 | ||
|
|
9d8b20148b | ||
|
|
0ffb9d0606 | ||
|
|
8258d8d5b4 | ||
|
|
94915b0496 | ||
|
|
053b4a22b8 | ||
|
|
e6a9f39477 | ||
|
|
ff4f80b7ef | ||
|
|
7e1218ce13 | ||
|
|
4c707271c3 | ||
|
|
04e56638ce | ||
|
|
674269c4c1 | ||
|
|
2b4627c3d6 | ||
|
|
4260c6d6b5 | ||
|
|
4057021cb9 | ||
|
|
151a99c2a3 | ||
|
|
bd606a4cf8 | ||
|
|
4dbf2551d9 | ||
|
|
8fefbccc83 | ||
|
|
65bc1e4efe | ||
|
|
9a257ec897 | ||
|
|
dd0a966a9f | ||
|
|
cec0327293 | ||
|
|
5b2c94758b | ||
|
|
2dd1d2ac56 | ||
|
|
3be7a5a69f | ||
|
|
3e6ea2633e | ||
|
|
2ef692edb8 | ||
|
|
3edfa5dfe7 | ||
|
|
8976ef04f6 | ||
|
|
cf81aedb60 | ||
|
|
78a225cde4 | ||
|
|
efdbbbc1f4 | ||
|
|
f82056a358 |
15
Backports/Badge+Backport.swift
Normal file
15
Backports/Badge+Backport.swift
Normal 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
|
||||
}
|
||||
}
|
||||
15
Backports/ListRowSeparator+Backport.swift
Normal file
15
Backports/ListRowSeparator+Backport.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Backports/Refreshable+Backport.swift
Normal file
11
Backports/Refreshable+Backport.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Backports/Tint+Backport.swift
Normal file
11
Backports/Tint+Backport.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
97
Backports/VisualEffectBlur-iOS.swift
Normal file
97
Backports/VisualEffectBlur-iOS.swift
Normal 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
|
||||
83
Backports/VisualEffectBlur-macOS.swift
Normal file
83
Backports/VisualEffectBlur-macOS.swift
Normal 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
|
||||
35
CHANGELOG.md
35
CHANGELOG.md
@@ -1,18 +1,21 @@
|
||||
## Build 162
|
||||
* Added support for "Podcasts" and "Releases" channel tabs (Invidious)
|
||||
## Build 171
|
||||
* Collapsible chapters view, player setting "Open vertical chapters expanded"
|
||||
* Current chapter is highlighted
|
||||
* Disabled portrait upside down orientation on iPhone
|
||||
* Fixed issue with handling private Invidious instances requests
|
||||
* Added Persian, Spanish, Turkish and Russian localizations
|
||||
* Fixed issue with displaying account username
|
||||
* Updated dependencies
|
||||
* Other minor changes and improvements
|
||||
|
||||
**Big thanks to [@stonerl](https://github.com/stonerl) for the last contributions!**
|
||||
**And to past, current and future project contributors!**
|
||||
|
||||
## 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
|
||||
* Description is collapsible with a button
|
||||
* Links in description are clickable on macOS
|
||||
* Aspect ratio is honored on resize on macOS
|
||||
* Added support for private Invidious instances
|
||||
* Fixed issue where Piped login token would not refresh
|
||||
* Fixed issue with MPV subtitles not working
|
||||
* Other minor changes and improvements
|
||||
|
||||
67
Gemfile.lock
67
Gemfile.lock
@@ -3,25 +3,25 @@ GEM
|
||||
specs:
|
||||
CFPropertyList (3.0.6)
|
||||
rexml
|
||||
addressable (2.8.5)
|
||||
addressable (2.8.6)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
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-eventstream (~> 1, >= 1.0.2)
|
||||
aws-eventstream (1.3.0)
|
||||
aws-partitions (1.864.0)
|
||||
aws-sdk-core (3.190.0)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sigv4 (~> 1.8)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.71.0)
|
||||
aws-sdk-core (~> 3, >= 3.177.0)
|
||||
aws-sdk-kms (1.74.0)
|
||||
aws-sdk-core (~> 3, >= 3.188.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.135.0)
|
||||
aws-sdk-core (~> 3, >= 3.181.0)
|
||||
aws-sdk-s3 (1.141.0)
|
||||
aws-sdk-core (~> 3, >= 3.189.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.6)
|
||||
aws-sigv4 (1.6.0)
|
||||
aws-sigv4 (~> 1.8)
|
||||
aws-sigv4 (1.8.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
claide (1.1.0)
|
||||
@@ -32,11 +32,10 @@ GEM
|
||||
declarative (0.0.20)
|
||||
digest-crc (0.6.5)
|
||||
rake (>= 12.0.0, < 14.0.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
domain_name (0.6.20231109)
|
||||
dotenv (2.8.1)
|
||||
emoji_regex (3.2.3)
|
||||
excon (0.103.0)
|
||||
excon (0.105.0)
|
||||
faraday (1.10.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
@@ -66,7 +65,7 @@ GEM
|
||||
faraday_middleware (1.2.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.7)
|
||||
fastlane (2.216.0)
|
||||
fastlane (2.217.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.8, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
@@ -107,9 +106,9 @@ 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.53.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-core (0.11.1)
|
||||
google-apis-core (0.11.2)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
httpclient (>= 2.8.1, < 3.a)
|
||||
@@ -122,24 +121,25 @@ GEM
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-playcustomapp_v1 (0.13.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-apis-storage_v1 (0.19.0)
|
||||
google-apis-core (>= 0.9.0, < 2.a)
|
||||
google-cloud-core (1.6.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-apis-storage_v1 (0.29.0)
|
||||
google-apis-core (>= 0.11.0, < 2.a)
|
||||
google-cloud-core (1.6.1)
|
||||
google-cloud-env (>= 1.0, < 3.a)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.6.0)
|
||||
faraday (>= 0.17.3, < 3.0)
|
||||
google-cloud-env (2.0.1)
|
||||
faraday (>= 1.0, < 3.a)
|
||||
google-cloud-errors (1.3.1)
|
||||
google-cloud-storage (1.44.0)
|
||||
google-cloud-storage (1.45.0)
|
||||
addressable (~> 2.8)
|
||||
digest-crc (~> 0.4)
|
||||
google-apis-iamcredentials_v1 (~> 0.1)
|
||||
google-apis-storage_v1 (~> 0.19.0)
|
||||
google-apis-storage_v1 (~> 0.29.0)
|
||||
google-cloud-core (~> 1.6)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (1.8.1)
|
||||
faraday (>= 0.17.3, < 3.a)
|
||||
googleauth (1.9.0)
|
||||
faraday (>= 1.0, < 3.a)
|
||||
google-cloud-env (~> 2.0, >= 2.0.1)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
@@ -149,7 +149,7 @@ GEM
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
jmespath (1.6.2)
|
||||
json (2.6.3)
|
||||
json (2.7.1)
|
||||
jwt (2.7.1)
|
||||
mini_magick (4.12.0)
|
||||
mini_mime (1.1.5)
|
||||
@@ -160,8 +160,8 @@ GEM
|
||||
optparse (0.1.1)
|
||||
os (1.1.4)
|
||||
plist (3.7.0)
|
||||
public_suffix (5.0.3)
|
||||
rake (13.0.6)
|
||||
public_suffix (5.0.4)
|
||||
rake (13.1.0)
|
||||
representable (3.2.0)
|
||||
declarative (< 0.1.0)
|
||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||
@@ -189,10 +189,7 @@ GEM
|
||||
tty-spinner (0.9.3)
|
||||
tty-cursor (~> 0.7)
|
||||
uber (0.1.0)
|
||||
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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -596,6 +596,8 @@ final class AVPlayerBackend: PlayerBackend {
|
||||
if self.controlsUpdates {
|
||||
self.updateControls()
|
||||
}
|
||||
|
||||
self.model.updateTime(self.currentTime!)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,6 +668,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 {
|
||||
|
||||
@@ -182,13 +182,21 @@ final class MPVBackend: PlayerBackend {
|
||||
}
|
||||
|
||||
init() {
|
||||
// swiftlint:disable shorthand_optional_binding
|
||||
clientTimer = .init(interval: .seconds(Self.timeUpdateInterval), mode: .infinite) { [weak self] _ in
|
||||
self?.getTimeUpdates()
|
||||
guard let self = self, self.model.activeBackend == .mpv else {
|
||||
return
|
||||
}
|
||||
self.getTimeUpdates()
|
||||
}
|
||||
|
||||
networkStateTimer = .init(interval: .seconds(Self.networkStateUpdateInterval), mode: .infinite) { [weak self] _ in
|
||||
self?.updateNetworkState()
|
||||
guard let self = self, self.model.activeBackend == .mpv else {
|
||||
return
|
||||
}
|
||||
self.updateNetworkState()
|
||||
}
|
||||
// swiftlint:enable shorthand_optional_binding
|
||||
}
|
||||
|
||||
typealias AreInIncreasingOrder = (Stream, Stream) -> Bool
|
||||
@@ -432,6 +440,8 @@ final class MPVBackend: PlayerBackend {
|
||||
timeObserverThrottle.execute {
|
||||
self.model.updateWatch(time: self.currentTime)
|
||||
}
|
||||
|
||||
self.model.updateTime(self.currentTime!)
|
||||
}
|
||||
|
||||
private func stopClientUpdates() {
|
||||
|
||||
@@ -131,6 +131,8 @@ final class PlayerModel: ObservableObject {
|
||||
@Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen
|
||||
#endif
|
||||
|
||||
@Published var currentChapterIndex: Int?
|
||||
|
||||
var accounts: AccountsModel { .shared }
|
||||
var comments: CommentsModel { .shared }
|
||||
var controls: PlayerControlsModel { .shared }
|
||||
@@ -1112,4 +1114,36 @@ final class PlayerModel: ObservableObject {
|
||||
onPlayStream.forEach { $0(stream) }
|
||||
onPlayStream.removeAll()
|
||||
}
|
||||
|
||||
func updateTime(_ cmTime: CMTime) {
|
||||
let time = CMTimeGetSeconds(cmTime)
|
||||
let newChapterIndex = chapterForTime(time)
|
||||
if currentChapterIndex != newChapterIndex {
|
||||
DispatchQueue.main.async {
|
||||
self.currentChapterIndex = newChapterIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func chapterForTime(_ time: Double) -> Int? {
|
||||
guard let chapters = self.videoForDisplay?.chapters else {
|
||||
return nil
|
||||
}
|
||||
|
||||
for (index, chapter) in chapters.enumerated() {
|
||||
let nextChapterStartTime = index < (chapters.count - 1) ? chapters[index + 1].start : nil
|
||||
|
||||
if let nextChapterStart = nextChapterStartTime {
|
||||
if time >= chapter.start, time < nextChapterStart {
|
||||
return index
|
||||
}
|
||||
} else {
|
||||
if time >= chapter.start {
|
||||
return index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,7 @@ extension PlayerModel {
|
||||
|
||||
func playerAPI(_ video: Video) -> VideosAPI? {
|
||||
guard let url = video.instanceURL else { return accounts.api }
|
||||
if accounts.current?.url == url { return accounts.api }
|
||||
switch video.app {
|
||||
case .local:
|
||||
return nil
|
||||
|
||||
@@ -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!
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
@@ -357,6 +364,7 @@ struct ChannelVideosView: View {
|
||||
}
|
||||
} label: {
|
||||
Label("Unsubscribe", systemImage: "xmark.circle")
|
||||
.help("Unsubscribe")
|
||||
#if os(iOS)
|
||||
.labelStyle(.automatic)
|
||||
#else
|
||||
@@ -373,6 +381,7 @@ struct ChannelVideosView: View {
|
||||
}
|
||||
} label: {
|
||||
Label("Subscribe", systemImage: "circle")
|
||||
.help("Subscribe")
|
||||
#if os(iOS)
|
||||
.labelStyle(.automatic)
|
||||
#else
|
||||
@@ -406,6 +415,7 @@ struct ChannelVideosView: View {
|
||||
feed.markChannelAsWatched(channel.id)
|
||||
} label: {
|
||||
Label("Mark channel feed as watched", systemImage: "checkmark.circle.fill")
|
||||
.help("Mark channel feed as watched")
|
||||
}
|
||||
.disabled(!feed.canMarkAllFeedAsWatched)
|
||||
}
|
||||
@@ -416,6 +426,7 @@ struct ChannelVideosView: View {
|
||||
feed.markChannelAsUnwatched(channel.id)
|
||||
} label: {
|
||||
Label("Mark channel feed as unwatched", systemImage: "checkmark.circle")
|
||||
.help("Mark channel feed as unwatched")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ extension Defaults.Keys {
|
||||
static let expandVideoDescriptionDefault = true
|
||||
#endif
|
||||
static let expandVideoDescription = Key<Bool>("expandVideoDescription", default: expandVideoDescriptionDefault)
|
||||
static let collapsedLinesDescription = Key<Int>("collapsedLinesDescription", default: 5)
|
||||
|
||||
static let showChannelAvatarInChannelsLists = Key<Bool>("showChannelAvatarInChannelsLists", default: true)
|
||||
static let showChannelAvatarInVideosListing = Key<Bool>("showChannelAvatarInVideosListing", default: true)
|
||||
@@ -263,6 +264,9 @@ 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 expandChapters = Key<Bool>("expandChapters", default: true)
|
||||
static let showRelated = Key<Bool>("showRelated", default: true)
|
||||
static let widgetsSettings = Key<[WidgetSettings]>("widgetsSettings", default: [])
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ struct DocumentsView: View {
|
||||
}
|
||||
.navigationTitle(directoryLabel)
|
||||
.padding(.horizontal)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode)
|
||||
.backport
|
||||
.refreshable {
|
||||
DispatchQueue.main.async {
|
||||
self.refresh()
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
@@ -26,7 +30,6 @@ struct AccountViewButton: View {
|
||||
|
||||
if accountPickerDisplaysUsername {
|
||||
label
|
||||
.labelStyle(.titleOnly)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,6 +46,6 @@ struct AccountViewButton: View {
|
||||
}
|
||||
|
||||
private var label: some View {
|
||||
Label(model.current?.description ?? "Select Account", systemImage: "globe")
|
||||
Text(model.current?.description ?? "Select Account")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -38,6 +38,7 @@ struct AppSidebarPlaylists: View {
|
||||
|
||||
if accounts.app.userPlaylistsEndpointIncludesVideos, !playlist.videos.isEmpty {
|
||||
label
|
||||
.backport
|
||||
.badge(Text("\(playlist.videos.count)"))
|
||||
} else {
|
||||
label
|
||||
|
||||
@@ -33,6 +33,7 @@ struct AppSidebarSubscriptions: View {
|
||||
Spacer()
|
||||
}
|
||||
.lineLimit(1)
|
||||
.backport
|
||||
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil)
|
||||
}
|
||||
.contextMenu {
|
||||
|
||||
@@ -95,6 +95,7 @@ struct AppTabNavigation: View {
|
||||
.accessibility(label: Text("Subscriptions"))
|
||||
}
|
||||
.tag(TabSelection.subscriptions)
|
||||
.backport
|
||||
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedText : nil)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -18,9 +18,8 @@ struct RelatedView: View {
|
||||
|
||||
Color.clear.padding(.bottom, 50)
|
||||
.listRowBackground(Color.clear)
|
||||
#if os(iOS)
|
||||
.listRowSeparator(.hidden)
|
||||
#endif
|
||||
.backport
|
||||
.listRowSeparator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,28 +2,85 @@ import Foundation
|
||||
import SDWebImageSwiftUI
|
||||
import SwiftUI
|
||||
|
||||
struct ChapterView: View {
|
||||
var chapter: Chapter
|
||||
#if !os(tvOS)
|
||||
struct ChapterView: View {
|
||||
var chapter: Chapter
|
||||
|
||||
var player = PlayerModel.shared
|
||||
var chapterIndex: Int
|
||||
@ObservedObject private var player = PlayerModel.shared
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
player.backend.seek(to: chapter.start, seekType: .userInteracted)
|
||||
} label: {
|
||||
Group {
|
||||
#if os(tvOS)
|
||||
horizontalChapter
|
||||
#else
|
||||
verticalChapter
|
||||
#endif
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
var isCurrentChapter: Bool {
|
||||
player.currentChapterIndex == chapterIndex
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Button(action: {
|
||||
player.backend.seek(to: chapter.start, seekType: .userInteracted)
|
||||
}) {
|
||||
Group {
|
||||
verticalChapter
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
|
||||
var verticalChapter: some View {
|
||||
VStack(spacing: 12) {
|
||||
if !chapter.image.isNil {
|
||||
smallImage(chapter)
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(chapter.title)
|
||||
.lineLimit(3)
|
||||
.multilineTextAlignment(.leading)
|
||||
.font(.headline)
|
||||
.foregroundColor(isCurrentChapter ? Color("AppRedColor") : .primary)
|
||||
Text(chapter.start.formattedAsPlaybackTime(allowZero: true) ?? "")
|
||||
.font(.system(.subheadline).monospacedDigit())
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.frame(maxWidth: !chapter.image.isNil ? Self.thumbnailWidth : nil, alignment: .leading)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func smallImage(_ chapter: Chapter) -> some View {
|
||||
WebImage(url: chapter.image, options: [.lowPriority])
|
||||
.resizable()
|
||||
.placeholder {
|
||||
ProgressView()
|
||||
}
|
||||
.indicator(.activity)
|
||||
.frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight)
|
||||
|
||||
.mask(RoundedRectangle(cornerRadius: 6))
|
||||
}
|
||||
|
||||
static var thumbnailWidth: Double {
|
||||
250
|
||||
}
|
||||
|
||||
static var thumbnailHeight: Double {
|
||||
thumbnailWidth / 1.7777
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
|
||||
#if os(tvOS)
|
||||
#else
|
||||
struct ChapterViewTVOS: View {
|
||||
var chapter: Chapter
|
||||
var player = PlayerModel.shared
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
player.backend.seek(to: chapter.start, seekType: .userInteracted)
|
||||
} label: {
|
||||
Group {
|
||||
horizontalChapter
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
|
||||
var horizontalChapter: some View {
|
||||
HStack(spacing: 12) {
|
||||
@@ -41,53 +98,36 @@ struct ChapterView: View {
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
#else
|
||||
var verticalChapter: some View {
|
||||
VStack(spacing: 12) {
|
||||
if !chapter.image.isNil {
|
||||
smallImage(chapter)
|
||||
|
||||
@ViewBuilder func smallImage(_ chapter: Chapter) -> some View {
|
||||
WebImage(url: chapter.image, options: [.lowPriority])
|
||||
.resizable()
|
||||
.placeholder {
|
||||
ProgressView()
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(chapter.title)
|
||||
.lineLimit(2)
|
||||
.multilineTextAlignment(.leading)
|
||||
.font(.headline)
|
||||
Text(chapter.start.formattedAsPlaybackTime(allowZero: true) ?? "")
|
||||
.font(.system(.subheadline).monospacedDigit())
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.frame(maxWidth: Self.thumbnailWidth, alignment: .leading)
|
||||
}
|
||||
.indicator(.activity)
|
||||
.frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight)
|
||||
.mask(RoundedRectangle(cornerRadius: 12))
|
||||
}
|
||||
#endif
|
||||
|
||||
@ViewBuilder func smallImage(_ chapter: Chapter) -> some View {
|
||||
WebImage(url: chapter.image, options: [.lowPriority])
|
||||
.resizable()
|
||||
.placeholder {
|
||||
ProgressView()
|
||||
}
|
||||
.indicator(.activity)
|
||||
.frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight)
|
||||
#if os(tvOS)
|
||||
.mask(RoundedRectangle(cornerRadius: 12))
|
||||
#else
|
||||
.mask(RoundedRectangle(cornerRadius: 6))
|
||||
#endif
|
||||
}
|
||||
static var thumbnailWidth: Double {
|
||||
250
|
||||
}
|
||||
|
||||
static var thumbnailWidth: Double {
|
||||
250
|
||||
static var thumbnailHeight: Double {
|
||||
thumbnailWidth / 1.7777
|
||||
}
|
||||
}
|
||||
|
||||
static var thumbnailHeight: Double {
|
||||
thumbnailWidth / 1.7777
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct ChapterView_Preview: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ChapterView(chapter: .init(title: "Chapter", start: 30))
|
||||
.injectFixtureEnvironmentObjects()
|
||||
#if os(tvOS)
|
||||
ChapterViewTVOS(chapter: .init(title: "Chapter", start: 30))
|
||||
.injectFixtureEnvironmentObjects()
|
||||
#else
|
||||
ChapterView(chapter: .init(title: "Chapter", start: 30), chapterIndex: 0)
|
||||
.injectFixtureEnvironmentObjects()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import SwiftUI
|
||||
|
||||
struct ChaptersView: View {
|
||||
@ObservedObject private var player = PlayerModel.shared
|
||||
@Binding var expand: Bool
|
||||
|
||||
var chapters: [Chapter] {
|
||||
player.videoForDisplay?.chapters ?? []
|
||||
@@ -15,45 +16,71 @@ struct ChaptersView: View {
|
||||
|
||||
var body: some View {
|
||||
if !chapters.isEmpty {
|
||||
#if os(tvOS)
|
||||
List {
|
||||
Section {
|
||||
ForEach(chapters) { chapter in
|
||||
ChapterView(chapter: chapter)
|
||||
}
|
||||
}
|
||||
.listRowBackground(Color.clear)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
#else
|
||||
if chaptersHaveImages {
|
||||
ScrollView(.horizontal) {
|
||||
LazyHStack(spacing: 20) {
|
||||
if chaptersHaveImages {
|
||||
#if os(tvOS)
|
||||
List {
|
||||
Section {
|
||||
ForEach(chapters) { chapter in
|
||||
ChapterView(chapter: chapter)
|
||||
ChapterViewTVOS(chapter: chapter)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 15)
|
||||
.listRowBackground(Color.clear)
|
||||
}
|
||||
.frame(minHeight: ChapterView.thumbnailHeight + 100)
|
||||
} else {
|
||||
.listStyle(.plain)
|
||||
#else
|
||||
ScrollView(.horizontal) {
|
||||
LazyHStack(spacing: 20) { chapterViews(for: chapters[...]) }.padding(.horizontal, 15)
|
||||
}
|
||||
#endif
|
||||
} else if expand {
|
||||
#if os(tvOS)
|
||||
Section {
|
||||
ForEach(chapters) { chapter in
|
||||
ChapterView(chapter: chapter)
|
||||
ChapterViewTVOS(chapter: chapter)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
NoCommentsView(text: "No chapters information available".localized(), systemImage: "xmark.circle.fill")
|
||||
#else
|
||||
Section { chapterViews(for: chapters[...]) }.padding(.horizontal)
|
||||
#endif
|
||||
} else {
|
||||
#if os(iOS)
|
||||
Button(action: {
|
||||
self.expand.toggle()
|
||||
}) {
|
||||
Section {
|
||||
chapterViews(for: chapters.prefix(3), opacity: 0.3, clickable: false)
|
||||
}.padding(.horizontal)
|
||||
}
|
||||
#elseif os(macOS)
|
||||
Section {
|
||||
chapterViews(for: chapters.prefix(3), opacity: 0.3, clickable: false)
|
||||
}.padding(.horizontal)
|
||||
#else
|
||||
Section {
|
||||
ForEach(chapters) { chapter in
|
||||
ChapterViewTVOS(chapter: chapter)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
private func chapterViews(for chaptersToShow: ArraySlice<Chapter>, opacity: Double = 1.0, clickable: Bool = true) -> some View {
|
||||
ForEach(Array(chaptersToShow.indices), id: \.self) { index in
|
||||
let chapter = chaptersToShow[index]
|
||||
ChapterView(chapter: chapter, chapterIndex: index)
|
||||
.opacity(index == 0 ? 1.0 : opacity)
|
||||
.allowsHitTesting(clickable)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct ChaptersView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ChaptersView()
|
||||
ChaptersView(expand: .constant(false))
|
||||
.injectFixtureEnvironmentObjects()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -6,11 +6,10 @@ import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct VideoDescription: View {
|
||||
static let collapsedLines = 5
|
||||
|
||||
private var search: SearchModel { .shared }
|
||||
@Default(.showKeywords) private var showKeywords
|
||||
@Default(.expandVideoDescription) private var expandVideoDescription
|
||||
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
|
||||
|
||||
var video: Video
|
||||
var detailsSize: CGSize?
|
||||
@@ -21,56 +20,90 @@ struct VideoDescription: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
if !expandVideoDescription && !expand {
|
||||
Button {
|
||||
expand = true
|
||||
} label: {
|
||||
descriptionView
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
} else {
|
||||
descriptionView
|
||||
descriptionView.id(video.videoID)
|
||||
}
|
||||
|
||||
@ViewBuilder var descriptionView: some View {
|
||||
if !expand && collapsedLinesDescription == 0 {
|
||||
EmptyView()
|
||||
} else {
|
||||
VStack {
|
||||
#if os(iOS)
|
||||
ActiveLabelDescriptionRepresentable(
|
||||
description: description,
|
||||
detailsSize: detailsSize,
|
||||
expand: expand
|
||||
)
|
||||
#else
|
||||
textDescription
|
||||
#endif
|
||||
|
||||
keywords
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.overlay(
|
||||
Group {
|
||||
#if canImport(UIKit)
|
||||
if !expand {
|
||||
Button(action: { expand.toggle() }) {
|
||||
Rectangle()
|
||||
.foregroundColor(.clear)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
)
|
||||
}
|
||||
.id(video.videoID)
|
||||
}
|
||||
|
||||
var descriptionView: some View {
|
||||
VStack {
|
||||
#if os(iOS)
|
||||
ActiveLabelDescriptionRepresentable(
|
||||
description: description,
|
||||
detailsSize: detailsSize,
|
||||
expand: shouldExpand
|
||||
)
|
||||
#else
|
||||
textDescription
|
||||
#endif
|
||||
|
||||
keywords
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
}
|
||||
|
||||
var shouldExpand: Bool {
|
||||
expandVideoDescription || expand
|
||||
}
|
||||
|
||||
@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)
|
||||
#if canImport(AppKit)
|
||||
Group {
|
||||
if #available(macOS 12, *) {
|
||||
DescriptionWithLinks(description: description, detailsSize: detailsSize)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(expand ? 500 : collapsedLinesDescription)
|
||||
.textSelection(.enabled)
|
||||
} else {
|
||||
Text(description)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.lineLimit(expand ? 500 : collapsedLinesDescription)
|
||||
}
|
||||
}
|
||||
.multilineTextAlignment(.leading)
|
||||
.font(.system(size: 14))
|
||||
.lineSpacing(3)
|
||||
.allowsHitTesting(expand)
|
||||
#endif
|
||||
}
|
||||
|
||||
// If possibe convert URLs to clickable links
|
||||
#if canImport(AppKit)
|
||||
@available(macOS 12, *)
|
||||
struct DescriptionWithLinks: View {
|
||||
let description: String
|
||||
let detailsSize: CGSize?
|
||||
let separators = CharacterSet(charactersIn: " \n")
|
||||
|
||||
var formattedString: AttributedString {
|
||||
var attrString = AttributedString(description)
|
||||
let words = description.unicodeScalars.split(whereSeparator: separators.contains).map(String.init)
|
||||
words.forEach { word in
|
||||
if word.hasPrefix("https://") || word.hasPrefix("http://"), let url = URL(string: String(word)) {
|
||||
if let range = attrString.range(of: word) {
|
||||
attrString[range].link = url
|
||||
}
|
||||
}
|
||||
}
|
||||
return attrString
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Text(formattedString)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ViewBuilder var keywords: some View {
|
||||
if showKeywords {
|
||||
ScrollView(.horizontal, showsIndicators: showScrollIndicators) {
|
||||
@@ -101,7 +134,7 @@ struct VideoDescription: View {
|
||||
}
|
||||
|
||||
var showScrollIndicators: Bool {
|
||||
#if os(macOS)
|
||||
#if canImport(AppKit)
|
||||
false
|
||||
#else
|
||||
true
|
||||
@@ -119,6 +152,8 @@ struct VideoDescription: View {
|
||||
|
||||
@Environment(\.openURL) private var openURL
|
||||
|
||||
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
|
||||
|
||||
var player = PlayerModel.shared
|
||||
|
||||
func makeUIView(context _: Context) -> some UIView {
|
||||
@@ -152,7 +187,12 @@ struct VideoDescription: View {
|
||||
}
|
||||
|
||||
func updateNumberOfLines() {
|
||||
label.numberOfLines = expand ? 0 : VideoDescription.collapsedLines
|
||||
if expand || collapsedLinesDescription > 0 {
|
||||
label.numberOfLines = expand ? 0 : collapsedLinesDescription
|
||||
label.isHidden = false
|
||||
} else {
|
||||
label.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
func urlTapHandler(_ url: URL) {
|
||||
|
||||
@@ -169,6 +169,7 @@ struct VideoDetails: View {
|
||||
@State private var subscriptionToggleButtonDisabled = false
|
||||
@State private var page = DetailsPage.info
|
||||
@State private var descriptionExpanded = false
|
||||
@State private var chaptersExpanded = false
|
||||
|
||||
@Environment(\.navigationStyle) private var navigationStyle
|
||||
#if os(iOS)
|
||||
@@ -184,10 +185,13 @@ 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
|
||||
@Default(.expandVideoDescription) private var expandVideoDescription
|
||||
@Default(.expandChapters) private var expandChapters
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
@@ -241,6 +245,10 @@ struct VideoDetails: View {
|
||||
}
|
||||
})
|
||||
.background(colorScheme == .dark ? Color.black : .white)
|
||||
.onAppear {
|
||||
descriptionExpanded = expandVideoDescription
|
||||
chaptersExpanded = expandChapters
|
||||
}
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
@@ -309,29 +317,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(expand: $chaptersExpanded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,25 +413,78 @@ struct VideoDetails: View {
|
||||
}
|
||||
|
||||
var descriptionHeader: some View {
|
||||
HStack {
|
||||
Text("Description".localized())
|
||||
|
||||
if !expandVideoDescription, !descriptionExpanded {
|
||||
Spacer()
|
||||
Image(systemName: "arrow.up.and.down")
|
||||
.imageScale(.small)
|
||||
#if canImport(UIKit)
|
||||
Button(action: {
|
||||
descriptionExpanded.toggle()
|
||||
}) {
|
||||
HStack {
|
||||
Text("Description".localized())
|
||||
Spacer()
|
||||
Image(systemName: descriptionExpanded ? "chevron.up" : "chevron.down")
|
||||
.imageScale(.small)
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
#elseif canImport(AppKit)
|
||||
HStack {
|
||||
Text("Description".localized())
|
||||
Spacer()
|
||||
Button { descriptionExpanded.toggle()
|
||||
} label: {
|
||||
Image(systemName: descriptionExpanded ? "chevron.up" : "chevron.down")
|
||||
.imageScale(.small)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
var chaptersHeader: some View {
|
||||
Text("Chapters".localized())
|
||||
.padding(.horizontal)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
#endif
|
||||
}
|
||||
|
||||
var chaptersHaveImages: Bool {
|
||||
player.videoForDisplay?.chapters.allSatisfy { $0.image != nil } ?? false
|
||||
}
|
||||
|
||||
var chaptersHeader: some View {
|
||||
Group {
|
||||
if !chaptersHaveImages {
|
||||
#if canImport(UIKit)
|
||||
Button(action: {
|
||||
chaptersExpanded.toggle()
|
||||
}) {
|
||||
HStack {
|
||||
Text("Chapters".localized())
|
||||
Spacer()
|
||||
Image(systemName: chaptersExpanded ? "chevron.up" : "chevron.down")
|
||||
.imageScale(.small)
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
#elseif canImport(AppKit)
|
||||
HStack {
|
||||
Text("Chapters".localized())
|
||||
Spacer()
|
||||
Button(action: { chaptersExpanded.toggle() }) {
|
||||
Image(systemName: chaptersExpanded ? "chevron.up" : "chevron.down")
|
||||
.imageScale(.small)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
#endif
|
||||
} else {
|
||||
// No button, just the title when there are images
|
||||
Text("Chapters".localized())
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
.padding(.horizontal)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,10 +27,7 @@ struct VideoPlayerSizeModifier: ViewModifier {
|
||||
content
|
||||
.frame(width: geometry.size.width)
|
||||
.frame(maxHeight: maxHeight)
|
||||
|
||||
#if !os(macOS)
|
||||
.aspectRatio(ratio, contentMode: usedAspectRatioContentMode)
|
||||
#endif
|
||||
}
|
||||
|
||||
var ratio: CGFloat? { // swiftlint:disable:this no_cgfloat
|
||||
@@ -46,10 +43,10 @@ struct VideoPlayerSizeModifier: ViewModifier {
|
||||
}
|
||||
|
||||
var usedAspectRatioContentMode: ContentMode {
|
||||
#if os(iOS)
|
||||
fullScreen ? .fill : .fit
|
||||
#else
|
||||
#if os(tvOS)
|
||||
.fit
|
||||
#else
|
||||
fullScreen ? .fill : .fit
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ struct VideoPlayerView: View {
|
||||
static let defaultAspectRatio = 16 / 9.0
|
||||
static var defaultMinimumHeightLeft: Double {
|
||||
#if os(macOS)
|
||||
300
|
||||
335
|
||||
#else
|
||||
200
|
||||
#endif
|
||||
@@ -156,7 +156,7 @@ struct VideoPlayerView: View {
|
||||
.persistentSystemOverlays(!fullScreenPlayer)
|
||||
#endif
|
||||
#if os(macOS)
|
||||
.frame(minWidth: 1100, minHeight: 700)
|
||||
.frame(minWidth: playerSidebar != .never ? 1100 : 650, minHeight: 700)
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -294,6 +294,9 @@ struct VideoPlayerView: View {
|
||||
}
|
||||
})
|
||||
#endif
|
||||
|
||||
.background(Color.black)
|
||||
|
||||
if !detailsHiddenInFullScreen {
|
||||
VideoDetails(
|
||||
video: player.videoForDisplay,
|
||||
|
||||
@@ -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() }
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ struct PlayerSettings: View {
|
||||
@Default(.showKeywords) private var showKeywords
|
||||
#if !os(tvOS)
|
||||
@Default(.showScrollToTopInComments) private var showScrollToTopInComments
|
||||
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
|
||||
#endif
|
||||
@Default(.expandVideoDescription) private var expandVideoDescription
|
||||
@Default(.pauseOnHidingPlayer) private var pauseOnHidingPlayer
|
||||
@@ -30,6 +31,9 @@ struct PlayerSettings: View {
|
||||
@Default(.enableReturnYouTubeDislike) private var enableReturnYouTubeDislike
|
||||
|
||||
@Default(.showInspector) private var showInspector
|
||||
@Default(.showChapters) private var showChapters
|
||||
@Default(.expandChapters) private var expandChapters
|
||||
@Default(.showRelated) private var showRelated
|
||||
|
||||
@ObservedObject private var accounts = AccountsModel.shared
|
||||
|
||||
@@ -73,8 +77,21 @@ struct PlayerSettings: View {
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
Section(header: SettingsHeader(text: "Inspector".localized())) {
|
||||
inspectorVisibilityPicker
|
||||
Section(header: SettingsHeader(text: "Info".localized())) {
|
||||
expandVideoDescriptionToggle
|
||||
collapsedLineDescriptionStepper
|
||||
showChaptersToggle
|
||||
expandChaptersToggle
|
||||
showRelatedToggle
|
||||
#if os(macOS)
|
||||
HStack {
|
||||
Text("Inspector")
|
||||
inspectorVisibilityPicker
|
||||
}
|
||||
.padding(.leading, 20)
|
||||
#else
|
||||
inspectorVisibilityPicker
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -96,9 +113,6 @@ struct PlayerSettings: View {
|
||||
showScrollToTopInCommentsToggle
|
||||
#endif
|
||||
|
||||
#if !os(tvOS)
|
||||
expandVideoDescriptionToggle
|
||||
#endif
|
||||
returnYouTubeDislikeToggle
|
||||
}
|
||||
}
|
||||
@@ -184,6 +198,24 @@ struct PlayerSettings: View {
|
||||
Toggle("Open video description expanded", isOn: $expandVideoDescription)
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
private var collapsedLineDescriptionStepper: some View {
|
||||
LazyVStack {
|
||||
Stepper(value: $collapsedLinesDescription, in: 0 ... 10) {
|
||||
Text("Description preview")
|
||||
#if os(macOS)
|
||||
Spacer()
|
||||
#endif
|
||||
if collapsedLinesDescription == 0 {
|
||||
Text("No preview")
|
||||
} else {
|
||||
Text("\(collapsedLinesDescription) lines")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private var returnYouTubeDislikeToggle: some View {
|
||||
Toggle("Enable Return YouTube Dislike", isOn: $enableReturnYouTubeDislike)
|
||||
}
|
||||
@@ -240,15 +272,31 @@ 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 (if available)", isOn: $showChapters)
|
||||
}
|
||||
|
||||
private var expandChaptersToggle: some View {
|
||||
Toggle("Open vertical chapters expanded", isOn: $expandChapters)
|
||||
.disabled(!showChapters)
|
||||
.foregroundColor(showChapters ? .primary : .secondary)
|
||||
}
|
||||
|
||||
private var showRelatedToggle: some View {
|
||||
Toggle("Related", isOn: $showRelated)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct PlayerSettings_Previews: PreviewProvider {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ struct SettingsView: View {
|
||||
case .browsing:
|
||||
return 800
|
||||
case .player:
|
||||
return 480
|
||||
return 500
|
||||
case .controls:
|
||||
return 920
|
||||
case .quality:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
4
Shared/ars.lproj/Localizable.strings
Normal file
4
Shared/ars.lproj/Localizable.strings
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
|
||||
" subscribers" = " المشتركين";
|
||||
"%@ Channel" = "القناة";
|
||||
@@ -93,10 +93,10 @@
|
||||
"Player" = "Player";
|
||||
"Charging" = "Aufladen";
|
||||
"Clear" = "Löschen";
|
||||
"Clear Search History..." = "Suchverlauf löschen...";
|
||||
"Clear Search History..." = "Suchverlauf löschen …";
|
||||
"Filter: active" = "Filter: aktiv";
|
||||
"Find Other" = "Andere finden";
|
||||
"Edit..." = "Bearbeiten...";
|
||||
"Edit..." = "Bearbeiten …";
|
||||
|
||||
/* Selected video has just finished playing */
|
||||
"Just watched" = "Kürzlich angesehen";
|
||||
@@ -133,7 +133,7 @@
|
||||
"Are you sure you want to restore default quality profiles?" = "Möchten Sie die Standardqualitätsprofile wirklich wiederherstellen?";
|
||||
"Autoplaying Next" = "Nächstes Element automatisch abspielen";
|
||||
"Based on system color scheme" = "Basierend auf System Farbschema";
|
||||
"Buffering stream..." = "Lädt…";
|
||||
"Buffering stream..." = "Lädt …";
|
||||
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "Fehler und tolle Ideen für Funktionen können an den Github Issue Tracker gesendet werden. ";
|
||||
"Categories to Skip" = "Zu überspringende Kategorien";
|
||||
"Close PiP and open player when application enters foreground" = "Schließe Bild-in-Bild und öffne den Player wenn die App in den Vordergrund geholt wird";
|
||||
@@ -167,7 +167,7 @@
|
||||
"Issues Tracker" = "Issues Tracker";
|
||||
"Enter fullscreen in landscape" = "Vollbild im Querformat aufrufen";
|
||||
"Error when accessing playlist" = "Fehler beim Zugriff auf Wiedergabeliste";
|
||||
"Finding something to play..." = "Etwas zu spielen finden...";
|
||||
"Finding something to play..." = "Etwas zu spielen finden …";
|
||||
"Fullscreen size" = "Vollbildgröße";
|
||||
|
||||
/* Video date filter in search */
|
||||
@@ -182,7 +182,7 @@
|
||||
"Large" = "Groß";
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Loading streams..." = "Lädt Streams...";
|
||||
"Loading streams..." = "Lädt Streams …";
|
||||
|
||||
/* Video duration filter in search */
|
||||
"Long" = "Lang";
|
||||
@@ -199,7 +199,7 @@
|
||||
"More info can be found in:" = "Weitere Informationen finden Sie in:";
|
||||
"Movies" = "Filme";
|
||||
"Music" = "Musik";
|
||||
"Loading..." = "Lädt...";
|
||||
"Loading..." = "Lädt …";
|
||||
"Lock portrait mode" = "Hochformatmodus sperren";
|
||||
"Mark as watched" = "Als gesehen markieren";
|
||||
"Mark video as watched after playing" = "Video nach dem Abspielen als angesehen markieren";
|
||||
@@ -210,7 +210,7 @@
|
||||
"Only when signed in" = "Nur wenn Sie eingeloggt sind";
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Opening %@ stream..." = "Öffne %@-stream...";
|
||||
"Opening %@ stream..." = "Öffne %@-stream …";
|
||||
"Connection failed" = "Verbindung fehlgeschlagen";
|
||||
"Continue from %@" = "Ab %@ fortsetzen";
|
||||
"Contributing" = "Beitragen";
|
||||
@@ -227,7 +227,7 @@
|
||||
"I want to ask a question" = "Ich möchte eine Frage stellen";
|
||||
"If you are interested what's coming in future updates, you can track project Milestones." = "Wenn Sie sich für künftige Updates interessieren, können Sie die Meilensteine des Projekts verfolgen.";
|
||||
"Large layout is not suitable for all devices and using it may cause controls not to fit on the screen." = "Das große Layout ist nicht für alle Geräte geeignet und kann dazu führen, dass die Bedienelemente nicht auf den Bildschirm passen.";
|
||||
"Opening audio stream..." = "Audiostream wird geöffnet...";
|
||||
"Opening audio stream..." = "Audiostream wird geöffnet …";
|
||||
"Orientation" = "Ausrichtung";
|
||||
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "Die Wiedergabeliste \"%@\" wird gelöscht.\nDies kann nicht rückgängig gemacht werden.";
|
||||
"Preferred Formats" = "Bevorzugte Formate";
|
||||
@@ -248,7 +248,7 @@
|
||||
/* Video sort order in search */
|
||||
"Rating" = "Bewertung";
|
||||
"Settings" = "Einstellungen";
|
||||
"Share..." = "Teilen...";
|
||||
"Share..." = "Teilen …";
|
||||
"Remove from Playlist" = "Aus Wiedergabeliste entfernen";
|
||||
"Remove from the queue" = "Aus der Warteschlange entfernen";
|
||||
"Replies" = "Antworten anzeigen";
|
||||
@@ -257,7 +257,7 @@
|
||||
"Resolution" = "Auflösung";
|
||||
"Restart the app to apply the settings above." = "Starten Sie die App neu, um die Einstellungen zu übernehmen.";
|
||||
"Restart/Play next" = "Von Anfang an/Als Nächstes spielen";
|
||||
"Restore default profiles..." = "Standardprofile wiederherstellen...";
|
||||
"Restore default profiles..." = "Standardprofile wiederherstellen …";
|
||||
"Rotate to portrait when exiting fullscreen" = "Auf Hochformat drehen, wenn der Vollbildmodus beendet wird";
|
||||
"Round corners" = "Runde Ecken";
|
||||
"Switch to public locations" = "Zu öffentlichen Adressen wechseln";
|
||||
@@ -271,10 +271,10 @@
|
||||
|
||||
/* Video sort order in search */
|
||||
"Views" = "Aufrufe";
|
||||
"Watched" = "Beobachtet";
|
||||
"Watched" = "Gesehen";
|
||||
|
||||
/* Selected video was played on given date */
|
||||
"Watched %@" = "Beobachtet %@";
|
||||
"Watched %@" = "%@ gesehen";
|
||||
|
||||
/* Selected video is being played */
|
||||
"Watching now" = "Jetzt anschauen";
|
||||
@@ -309,7 +309,7 @@
|
||||
/* Player controls layout size for TV */
|
||||
"TV" = "Fernsehen";
|
||||
"unknown" = "unbekannt";
|
||||
"Unsubscribe" = "Deabonnieren";
|
||||
"Unsubscribe" = "Abbestellen";
|
||||
"Upload date" = "Uploaddatum";
|
||||
"URL" = "URL";
|
||||
"Wi-Fi" = "Wi-Fi";
|
||||
@@ -357,7 +357,7 @@
|
||||
"Hardware decoder" = "Hardware-Decoder";
|
||||
"Save history of searches, channels and playlists" = "Verlauf von Suchen, Kanälen und Wiedergabelisten speichern";
|
||||
"Search history is empty" = "Suchverlauf ist leer";
|
||||
"Search..." = "Suche...";
|
||||
"Search..." = "Suche …";
|
||||
"Sections" = "Abschnitte";
|
||||
"Seek gesture sensitivity" = "Suchgesten-Sensibilität";
|
||||
"Seek gesture speed" = "Geschwindigkeit der Suchgesten";
|
||||
@@ -427,7 +427,7 @@
|
||||
"Could not refresh Trending" = "Trends kann nicht aktualisiert werden";
|
||||
"Could not open channel" = "Kanal kann nicht geöffnet werden";
|
||||
"This URL could not be opened" = "Diese URL kann nicht geöffnet werden";
|
||||
"Share Logs..." = "Logs teilen…";
|
||||
"Share Logs..." = "Logs teilen …";
|
||||
"Channel could not be found" = "Der Kanal konnte nicht gefunden werden";
|
||||
"Could not refresh Subscriptions" = "Abonnements konnten nicht aktualisiert werden";
|
||||
"If you want this app to be available in your language, join translation project." = "Wenn Sie wünschen, dass diese App auch in Ihrer Sprache verfügbar ist, nehmen Sie am Übersetzungsprojekt teil.";
|
||||
@@ -439,11 +439,11 @@
|
||||
"Show Home" = "Startseite anzeigen";
|
||||
"Video Details" = "Videodetails";
|
||||
"Share files from Finder on a Mac\nor iTunes on Windows" = "Teilen von Dateien über den Finder auf einem Mac\noder iTunes unter Windows";
|
||||
"Recent History" = "Neueste Verlauf";
|
||||
"Recent History" = "Neuester Verlauf";
|
||||
"Show Open Videos toolbar button" = "Schaltfläche \"Videos öffnen\" in der Symbolleiste anzeigen";
|
||||
"Edit Favorites…" = "Favoriten bearbeiten…";
|
||||
"Edit Favorites…" = "Favoriten bearbeiten …";
|
||||
"Show Documents" = "Dokumente anzeigen";
|
||||
"Buttons labels" = "Tasten-Etiketten";
|
||||
"Buttons labels" = "Schaltflächen-Etiketten";
|
||||
"Inspector visibility" = "Sichtbarkeit der Inspector";
|
||||
"Pages toolbar position" = "Position der Seitensymbolleiste";
|
||||
"Clear Queue before opening" = "Warteschlange vor dem Öffnen löschen";
|
||||
@@ -482,7 +482,7 @@
|
||||
"Sample Rate" = "Samplerate";
|
||||
"Files" = "Dateien";
|
||||
"Could not find any links to open in your clipboard" = "Kann keine Links zum Öffnen in Ihrer Zwischenablage finden";
|
||||
"Remove…" = "Entfernen…";
|
||||
"Remove…" = "Entfernen …";
|
||||
"Show Inspector" = "Inspector einblenden";
|
||||
"Actions buttons" = "Aktionsschaltflächen";
|
||||
"Show sidebar" = "Seitenleiste anzeigen";
|
||||
@@ -503,7 +503,7 @@
|
||||
"Verified" = "Verifiziert";
|
||||
"Channel" = "Kanal";
|
||||
"Short videos: visible" = "Kurze Videos: sichtbar";
|
||||
"Player Bar" = "Spielerleiste";
|
||||
"Player Bar" = "Video-Player-Leiste";
|
||||
"Short videos: hidden" = "Kurze Videos: versteckt";
|
||||
"Play all unwatched" = "Alle ungesehen abspielen";
|
||||
"Double tap gesture" = "Doppeltippgeste";
|
||||
@@ -539,7 +539,7 @@
|
||||
"Subscribe/Unsubscribe" = "Abonnieren/abbestellen";
|
||||
"Are you sure you want to clear cache?" = "Möchten Sie den Cache wirklich löschen?";
|
||||
"Single tap gesture" = "Einmalige Antippen-Geste";
|
||||
"Seeking" = "Suchend";
|
||||
"Seeking" = "Suchen";
|
||||
"List" = "Liste";
|
||||
"Cells" = "Zellen";
|
||||
"Show Next in Queue" = "Nächste in Warteschlange anzeigen";
|
||||
@@ -564,12 +564,12 @@
|
||||
"Lock" = "Sperre";
|
||||
"Description" = "Beschreibung";
|
||||
"Seek" = "Suchen";
|
||||
"Enter account credentials to connect..." = "Geben Sie die Kontozugangsdaten ein, um eine Verbindung herzustellen...";
|
||||
"Enter account credentials to connect..." = "Geben Sie die Kontozugangsdaten ein, um eine Verbindung herzustellen …";
|
||||
"Show scroll to top button in comments" = "Schaltfläche Nach oben scrollen in Kommentaren anzeigen";
|
||||
"Enter location address to connect..." = "Geben Sie die Internetadresse ein, um eine Verbindung herzustellen...";
|
||||
"Enter location address to connect..." = "Geben Sie die Internetadresse ein, um eine Verbindung herzustellen …";
|
||||
"Opened File" = "Geöffnete Datei";
|
||||
"File Extension" = "Dateierweiterung";
|
||||
"Opening file..." = "Datei öffnen...";
|
||||
"Opening file..." = "Datei öffnen …";
|
||||
"Close video and player on end" = "Video und Player am Ende beenden";
|
||||
"Use system controls with AVPlayer" = "Systemsteuerung mit AVPlayer verwenden";
|
||||
"Public account" = "Öffentliches Konto";
|
||||
@@ -582,12 +582,12 @@
|
||||
"Available" = "Verfügbar";
|
||||
"Startup section" = "Bereich Startup";
|
||||
"Home Settings" = "Startseite Einstellungen";
|
||||
"Watched: hidden" = "Beobachtet: versteckt";
|
||||
"(watched and shorts hidden)" = "(beobachtet und shorts versteckt)";
|
||||
"Watched: visible" = "Beobachtet: sichtbar";
|
||||
"Watched: hidden" = "Gesehene: versteckt";
|
||||
"(watched and shorts hidden)" = "(gesehene und Shorts versteckt)";
|
||||
"Watched: visible" = "Gesehene: sichtbar";
|
||||
"No videos to show" = "Keine Videos zu zeigen";
|
||||
"(watched hidden)" = "(versteckt beobachtet)";
|
||||
"(shorts hidden)" = "(shorts versteckt)";
|
||||
"(watched hidden)" = "(gesehene versteckt)";
|
||||
"(shorts hidden)" = "(Shorts versteckt)";
|
||||
"Disable filters" = "Filter deaktivieren";
|
||||
"Limit" = "Grenze";
|
||||
"Are you sure you want to remove %@ from Favorites?" = "Möchten Sie %@ wirklich aus den Favoriten entfernen?";
|
||||
@@ -597,3 +597,6 @@
|
||||
"Play Now in AVPlayer" = "Jetzt in AVPlayer abspielen";
|
||||
"Show channel avatars in videos lists" = "Kanal-Avatare in Videolisten anzeigen";
|
||||
"Show channel avatars in channels lists" = "Kanal-Avatare in Kanallisten anzeigen";
|
||||
"Podcasts" = "Podcasts";
|
||||
"Add %@" = "%@ hinzufügen";
|
||||
"Releases" = "Veröffentlichungen";
|
||||
|
||||
@@ -595,3 +595,10 @@
|
||||
"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 %@";
|
||||
"Description preview" = "Description preview";
|
||||
"No preview" = "No preview";
|
||||
"Open vertical chapters expanded" = "Open vertical chapters expanded";
|
||||
"Chapters (if available)" = "Chapters (if available)";
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
"Are you sure you want to restore default quality profiles?" = "¿Estás seguro de que quieres restablecer los ajustes por defecto de los perfiles de calidad?";
|
||||
"Are you sure you want to unsubscribe from %@?" = "¿Estás seguro de que quieres dejar de estar suscrito a %@?";
|
||||
"Cancel" = "Cancelar";
|
||||
"Autoplaying Next" = "Autorreproducir el siguiente";
|
||||
"Autoplaying Next" = "Autoreproducir el siguiente";
|
||||
"Based on system color scheme" = "Basado en el tema del sistema";
|
||||
"Clear Search History..." = "Limpiar el historial de búsqueda...";
|
||||
"Battery" = "Batería";
|
||||
@@ -169,7 +169,7 @@
|
||||
"Stream & Player" = "Transmisión y reproductor";
|
||||
"Picture in Picture" = "Imagen en imagen";
|
||||
"Visibility" = "Visibilidad";
|
||||
"Edit Favorites…" = "Editar Favoritos...";
|
||||
"Edit Favorites…" = "Editar los favoritos…";
|
||||
"Center" = "Centrar";
|
||||
"Wiki" = "Wiki";
|
||||
"Live Streams" = "Transmisiones en vivo";
|
||||
@@ -250,7 +250,7 @@
|
||||
"Actions buttons" = "Botones de acciones";
|
||||
"Files" = "Archivos";
|
||||
"Sign In Required" = "Inicio de sesión requerido";
|
||||
"Buttons labels" = "Etiquetas de botones";
|
||||
"Buttons labels" = "Etiquetas de los botones";
|
||||
"Next" = "Siguiente";
|
||||
"Default Profile" = "Perfil por defecto";
|
||||
"Paste" = "Pegar";
|
||||
@@ -258,7 +258,7 @@
|
||||
"File" = "Archivo";
|
||||
"Right" = "Derecha";
|
||||
"Reset search filters" = "Restablecer filtros de búsqueda";
|
||||
"Channel" = "Vanal";
|
||||
"Channel" = "Canal";
|
||||
"Open Files" = "Abrir archivos";
|
||||
"You can find information about using Yattee in the Wiki pages." = "Puede encontrar información sobre el uso de Yattee en la Wiki.";
|
||||
"Lock portrait mode" = "Bloquear modo retrato";
|
||||
@@ -266,7 +266,7 @@
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Loading streams..." = "Cargando secuencias...";
|
||||
"Public Locations" = "Ubicaciones Públicas";
|
||||
"Public Locations" = "Ubicaciones públicas";
|
||||
"Yattee" = "Yattee";
|
||||
"No results" = "No hay resultados";
|
||||
"Driver" = "Driver";
|
||||
@@ -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:";
|
||||
|
||||
@@ -397,7 +397,7 @@
|
||||
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "Se eliminará la lista de reproducción \"%@\".\nNo se puede revertir.";
|
||||
"Playlists" = "Listas de reproducción";
|
||||
"Popular" = "Popular";
|
||||
"Proxy videos" = "Proxy videos";
|
||||
"Proxy videos" = "Utilizar un proxy para ver los vídeos";
|
||||
"Regular size" = "Tamaño regular";
|
||||
"Related" = "Relacionado";
|
||||
|
||||
@@ -456,7 +456,7 @@
|
||||
"Press and hold remote button to open captions and quality menus" = "Mantenga presionado el botón del control remoto para abrir subtítulos y menús de calidad";
|
||||
"Comments are disabled" = "Los comentarios están deshabilitados";
|
||||
"No comments" = "Sin comentarios";
|
||||
"Share Logs..." = "Compartir registros...";
|
||||
"Share Logs..." = "Compartir registros…";
|
||||
"Open logs in Finder" = "Abrir registros en Finder";
|
||||
"Could not open video" = "No se pudo abrir el video";
|
||||
"Channel could not be found" = "No se pudo encontrar el canal";
|
||||
@@ -481,14 +481,14 @@
|
||||
"Playback" = "Reproducción";
|
||||
"Restart/Play next" = "Reiniciar/Reproducir siguiente";
|
||||
"This cannot be reverted" = "Esto no se puede revertir";
|
||||
"This cannot be reverted. You might need to switch between views or restart the app to see changes." = "Esto no se puede revertir. Es posible que deba cambiar entre vistas o reiniciar la aplicación para ver los cambios";
|
||||
"This cannot be reverted. You might need to switch between views or restart the app to see changes." = "Esto no se puede revertir. Es posible que deba cambiar entre vistas o reiniciar la aplicación para ver los cambios.";
|
||||
"Could not open channel" = "No se pudo abrir el canal";
|
||||
"Recent History" = "Historial reciente";
|
||||
"Share files from Finder on a Mac\nor iTunes on Windows" = "Comparta archivos desde Finder en una Mac\no iTunes en Windows";
|
||||
"Pages toolbar position" = "Posición de la barra de herramientas de páginas";
|
||||
"Video actions buttons" = "Botones de acciones de video";
|
||||
"Video" = "Video";
|
||||
"Show Open Videos toolbar button" = "Mostrar el botón de la barra de herramientas Abrir videos";
|
||||
"Show Open Videos toolbar button" = "Mostrar el botón de los vídeos abiertos en la barra de herramientas";
|
||||
"Show Documents" = "Mostrar documentos";
|
||||
"Clear Queue before opening" = "Borrar cola antes de abrir";
|
||||
"Open" = "Abrir";
|
||||
@@ -498,7 +498,107 @@
|
||||
"Audio" = "Audio";
|
||||
"Codec" = "Codec";
|
||||
"Size" = "Tamaño";
|
||||
"Remove…" = "Eliminar...";
|
||||
"Remove…" = "Eliminar…";
|
||||
"Playback history is empty" = "El historial de reproducción está vacío";
|
||||
"Copy%@link" = "Copiar%@enlace";
|
||||
"Share%@link" = "Compartir%@enlace";
|
||||
"Open expanded" = "Abrir maximizado";
|
||||
"Single tap gesture" = "Gesto de 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" = "Videos cortos: visible";
|
||||
"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 expandido";
|
||||
"Short videos: hidden" = "Videos cortos: oculto";
|
||||
"Clear all" = "Borrar todo";
|
||||
"Always show controls buttons" = "Mostrar siempre los botones de control";
|
||||
"Mark channel feed as unwatched" = "Marcar el feed del canal como no visto";
|
||||
"Play all unwatched" = "Reproducir todo lo no visto";
|
||||
"Mark channel feed as watched" = "Marcar el feed del canal como visto";
|
||||
"Double tap gesture" = "Gesto de doble toque";
|
||||
"Player Bar" = "Barra del reproductor";
|
||||
"Controls Buttons" = "Botones de control";
|
||||
"Seeking" = "Buscando";
|
||||
"Total size: %@" = "Tamaño total: %@";
|
||||
"Gesture: backwards" = "Gesto: atrás";
|
||||
"Gesture: fowards" = "Gesto: adelante";
|
||||
"System controls" = "Controles del sistema";
|
||||
"Close video" = "Cerrar vídeo";
|
||||
"Controls button: backwards" = "Botón de control: hacia atrás";
|
||||
"Controls button: forwards" = "Botón de control: hacia delante";
|
||||
"Show unwatched feed badges" = "Mostrar insignias de feeds no vistos";
|
||||
"Gesture settings control skipping interval for double tap gesture on left/right side of the player. Changing system controls settings requires restart." = "Los ajustes de los gestos controlan el intervalo de salto para el gesto de doble toque en el lado izquierdo/derecho del reproductor. Para cambiar los ajustes de los controles del sistema es necesario reiniciar.";
|
||||
"Gesture settings control skipping interval for double click on left/right side of the player. Changing system controls settings requires restart." = "Los ajustes gestuales controlan el intervalo de salto para el doble clic en el lado izquierdo/derecho del reproductor. Para cambiar la configuración de los controles del sistema es necesario reiniciar.";
|
||||
"Open channels with description expanded" = "Canales abiertos con la descripción ampliada";
|
||||
"Subscribe/Unsubscribe" = "Suscribirse/Desuscribirse";
|
||||
"Are you sure you want to clear cache?" = "¿Seguro que quieres borrar la caché?";
|
||||
"Lock orientation" = "Bloquear orientación";
|
||||
"Cache" = "Cache";
|
||||
"Actions Buttons" = "Botones de Acción";
|
||||
"Music Mode" = "Modo Música";
|
||||
"Play next item" = "Reproducir siguiente elemento";
|
||||
"Gesture settings control skipping interval for remote arrow buttons (for 2nd generation Siri Remote or newer). Changing system controls settings requires restart." = "Los ajustes gestuales controlan el intervalo del salto de los botones de la flecha del mando a distancia (para Siri Remote de 2ª generación o posterior). Para cambiar los ajustes de los controles del sistema es necesario reiniciar.";
|
||||
"Show cache status" = "Mostrar estado de cache";
|
||||
"Show Next in Queue" = "Mostrar el siguiente en la cola";
|
||||
"Hide player" = "Ocultar al jugador";
|
||||
"Toggle player" = "Alternar el reproductor";
|
||||
"Inspector" = "Inspector";
|
||||
"Playback Settings" = "Ajustes de la reproducción";
|
||||
"Show toggle watch status button" = "Mostrar el botón para alternar estado de la visualización";
|
||||
"Queue - shuffled" = "Cola - aleatoria";
|
||||
"Cells" = "Celdas";
|
||||
"Do nothing" = "No hacer nada";
|
||||
"Next in Queue" = "Siguiente en la cola";
|
||||
"Open video description expanded" = "Abrir la descripción del vídeo ampliada";
|
||||
"Mark all as unwatched" = "Marcar todo como no visto";
|
||||
"Mark all as watched" = "Marcar todo como visto";
|
||||
"List" = "Lista";
|
||||
"Toggle size" = "Alternar el tamaño";
|
||||
"Open channel" = "Abrir el canal";
|
||||
"Feed" = "Feed";
|
||||
"Available" = "Disponible";
|
||||
"Loop one" = "Bucle uno";
|
||||
"Use system controls with AVPlayer" = "Utilizar los controles del sistema con AVPlayer";
|
||||
"Opening file..." = "Abriendo el archivo...";
|
||||
"No videos to show" = "No hay vídeos que mostrar";
|
||||
"Autoplay next" = "Reproducir automáticamente la siguiente";
|
||||
"Home Settings" = "Ajustes iniciales";
|
||||
"Watched: visible" = "Visto: visible";
|
||||
"Fullscreen" = "A pantalla completa";
|
||||
"Seek" = "Buscar";
|
||||
"Landscape left" = "Apaisado a la izquierda";
|
||||
"(watched and shorts hidden)" = "(ocultar videos reproducidos y cortos)";
|
||||
"Rotate when entering fullscreen on landscape video" = "Rotar al entrar en pantalla completa en un vídeo apaisado";
|
||||
"Enter account credentials to connect..." = "Introduce las credenciales de la cuenta para conectarte...";
|
||||
"Watched: hidden" = "Visto: oculto";
|
||||
"Stream" = "Stream";
|
||||
"Replay" = "Repetir";
|
||||
"(watched hidden)" = "(ocultar lo reproducido)";
|
||||
"Show scroll to top button in comments" = "Mostrar el botón de desplazamiento hacia arriba en los comentarios";
|
||||
"Enter location address to connect..." = "Introduzca la dirección para conectarse...";
|
||||
"File Extension" = "Extensión del archivo";
|
||||
"Opened File" = "Archivo abierto";
|
||||
"Public account" = "Cuenta pública";
|
||||
"Lock" = "Bloquear";
|
||||
"No rotation" = "Sin rotación";
|
||||
"Startup section" = "Sección de inicio";
|
||||
"Browse without account" = "Navegar sin cuenta";
|
||||
"Close video and player on end" = "Cerrar el vídeo y el reproductor al final";
|
||||
"Landscape right" = "Apaisado a la derecha";
|
||||
"Your Accounts" = "Tus cuentas";
|
||||
"Description" = "Descripción";
|
||||
"Maximum feed items" = "Número máximo de elementos en el feed";
|
||||
"Are you sure you want to remove %@ from Favorites?" = "¿Estás seguro de que quieres eliminar %@ de favoritos?";
|
||||
"Limit" = "Límite";
|
||||
"Keep channels with unwatched videos on top of subscriptions list" = "Mantén los canales con los vídeos sin ver en la parte superior de la lista de suscripciones";
|
||||
"(shorts hidden)" = "(cortos ocultos)";
|
||||
"Disable filters" = "Desactivar los filtros";
|
||||
"Podcasts" = "Podcasts";
|
||||
"Releases" = "Lanzamientos";
|
||||
"Show channel avatars in channels lists" = "Mostrar los avatares de los canales en las listas de los canales";
|
||||
"Play Now in MPV" = "Reproducir ahora en MPV";
|
||||
"Show channel avatars in videos lists" = "Mostrar los avatares de los canales en las listas de los vídeos";
|
||||
"Add %@" = "Añada %@";
|
||||
"Show video context menu options to force selected backend" = "Mostrar las opciones del menú contextual del vídeo para forzar el backend seleccionado";
|
||||
"Play Now in AVPlayer" = "Reproducir ahora en AVPlayer";
|
||||
"Description preview" = "Vista previa de la descripción";
|
||||
"No preview" = "Sin vista previa";
|
||||
|
||||
485
Shared/fa.lproj/Localizable.strings
Normal file
485
Shared/fa.lproj/Localizable.strings
Normal file
@@ -0,0 +1,485 @@
|
||||
|
||||
|
||||
"Podcasts" = "پادکستها";
|
||||
"Reset watched status when playing again" = "بازنشانی وضعیت تماشای ویدیو هنگام تماشای مجدد";
|
||||
"Finding something to play..." = "یافتن چیزی برای پخش…";
|
||||
"Available" = "در دسترس";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Very Large" = "خیلی بزرگ";
|
||||
"Audio" = "صدا";
|
||||
"Custom Locations" = "سرویس دهندگان سفارشی";
|
||||
"Always use AVPlayer for live videos" = "همیشه از AVPlayer برای ویدیوهای پخش زنده استفاده کن";
|
||||
"Clear Search History..." = "پاک کردن سابقهٔ جست و جو…";
|
||||
"Related" = "مرتبط";
|
||||
"Close Video" = "بستن پخش کننده";
|
||||
"Add to %@" = "افزودن به %@";
|
||||
"Could not open playlist" = "فهرست پخش باز نشد";
|
||||
"Disabled" = "غیرفعال";
|
||||
"Share..." = "اشتراک گذاری…";
|
||||
"For videos which feature music as the primary content." = "برای ویدیوهایی که محتوای اصلیشان موسیقی است.";
|
||||
"Save history of searches, channels and playlists" = "ذخیرهٔ سابقهٔ جست و جو، کانالها و فهرستهای پخش";
|
||||
"Clear Queue before opening" = "صف را پیش از باز کردن خالی کن";
|
||||
"Show playback statistics" = "نمایش آمار پخش";
|
||||
"Could not extract channel information" = "اطلاعات کانال دریافت نشد";
|
||||
"Video" = "ویدیو";
|
||||
"Matrix Chat" = "چت Matrix";
|
||||
"Loop one" = "پخش دوبارهٔ تکی";
|
||||
"Settings" = "تنظیمات";
|
||||
"10 seconds forwards/backwards" = "۱۰ ثانیه جلو/عقب";
|
||||
"Show progress of watching on thumbnails" = "پیشرفت پخش را روی تصویر بندانگشتی نشان بده";
|
||||
"Recents" = "تازهترینها";
|
||||
"Could not open channel" = "کانال باز نمیشود";
|
||||
"Select location closest to you:" = "نزدیکترین سرویس دهنده را انتخاب کنید:";
|
||||
"Fullscreen size" = "ابعاد تمام صفحه";
|
||||
"No Playlists" = "بدون فهرست پخش";
|
||||
"Highest quality" = "بالاترین کیفیت";
|
||||
"Edit..." = "ویرایش…";
|
||||
"Based on system color scheme" = "براساس طرح رنگ سیستم";
|
||||
"Quality" = "کیفیت";
|
||||
"Pause" = "مکث";
|
||||
"Controls Buttons" = "دکمههای کنترل";
|
||||
|
||||
/* Subscriptions title */
|
||||
"Subscriptions" = "اشتراکها";
|
||||
" subscribers" = " مشترکان";
|
||||
"Channels" = "کانالها";
|
||||
"Resolution" = "وضوح تصویر";
|
||||
"Button" = "دکمه";
|
||||
"Badge & Decreased opacity" = "نشان و کاهش شفافیت";
|
||||
"Milestones" = "نقطهٔ عطف";
|
||||
"Are you sure you want to restore default quality profiles?" = "آیا از بازنشانی نمایههای کیفیت پیشفرض مطمئنید؟";
|
||||
"Show sidebar" = "نمایش نوار کناری";
|
||||
"Error" = "خطا";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Week" = "هفته";
|
||||
"Make default" = "پیش فرض شو";
|
||||
"Verified" = "تاییدشده";
|
||||
"Subscribe/Unsubscribe" = "اشتراک/لغو اشتراک";
|
||||
"Close player when closing video" = "هنگامی که ویدیو بسته میشود پخش کننده را ببند";
|
||||
"It can be changed later in settings. You can use your own locations too." = "میتوانید بعدا در تنظیمات تغییر دهید. همچنان میتوانید از سرویس دهندهٔ خودتان استفاده کنید.";
|
||||
"Comments are disabled" = "نظرها غیرفعال است";
|
||||
"Queue is empty" = "صف خالیست";
|
||||
"Playback Mode" = "وضعیت پخش";
|
||||
"Country" = "کشور";
|
||||
"Share" = "اشتراکگذاری";
|
||||
"Play in PiP" = "در تصویر-در-تصویر پخش کن";
|
||||
"System controls buttons" = "دکمههای کنترل سیستم";
|
||||
"Picture in Picture" = "تصویر-در-تصویر";
|
||||
"Comments" = "نظرها";
|
||||
"\"%@\" will be irreversibly removed from this device." = "\"%@\" از دستگاه حذف شده و غیرقابل بازگردانی خواهد بود.";
|
||||
"Now Playing" = "در حال پخش";
|
||||
"Charging" = "در حال شارژ";
|
||||
"Refresh" = "تازهسازی";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Large" = "بزرگ";
|
||||
"Are you sure you want to unsubscribe from %@?" = "آیا از لفو اشتراک %@ مطمئنید؟";
|
||||
|
||||
/* Video duration filter in search */
|
||||
"Short" = "Short";
|
||||
"Switch to public locations" = "به سرویس دهندهٔ عمومی منتقل شو";
|
||||
"Profiles" = "نمایهها";
|
||||
"New Playlist" = "فهرست پخش جدید";
|
||||
"Automatic" = "خودکار";
|
||||
"Opening file..." = "در حال باز کردن فایل…";
|
||||
"Add Quality Profile" = "افزودن نمایهٔ کیفیت";
|
||||
"Close video after playing last in the queue" = "ویدیو را پس از پخش آخرین مورد فهرست ببند";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Small" = "کوچک";
|
||||
"Clear" = "پاک کردن";
|
||||
"Anonymous" = "ناشناس";
|
||||
"Channel could not be found" = "کانال پیدا نشد";
|
||||
"Add to Favorites" = "افزودن به موردعلاقهها";
|
||||
"Total size: %@" = "مجموع اندازه: %@";
|
||||
"Wi-Fi" = "اینترنت Wi-Fi";
|
||||
|
||||
/* Selected video is being played */
|
||||
"Watching now" = "در حال تماشا";
|
||||
"Size" = "اندازه";
|
||||
"Connection failed" = "اتصال موفق نبود";
|
||||
"Could not open video" = "ویدیو باز نشد";
|
||||
"Badge color" = "رنگ نشان";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Medium" = "متوسط";
|
||||
"Reset search filters" = "بازنشانی صافیهای جست و جو";
|
||||
"Play" = "پخش";
|
||||
|
||||
/* Trending category, section containing all kinds of videos */
|
||||
"All" = "همه";
|
||||
"No videos to show" = "ویدیویی برای نمایش نیست";
|
||||
"Username" = "نام کاربری";
|
||||
"Don't use public locations" = "از سرویس دهندگان عمومی استفاده نکنید";
|
||||
"I have a feature request" = "درخواست ویژگی و قابلیت دارم";
|
||||
"Clear All Recents" = "همهٔ موارد اخیر را پاک کن";
|
||||
"Regular size" = "ابعاد معمولی";
|
||||
"Autoplay next" = "پخش خودکار بعدی";
|
||||
"Shuffle" = "شافل";
|
||||
"This cannot be reverted" = "این گزینه غیرقابل بازگشت است";
|
||||
"unknown" = "ناشناخته";
|
||||
"Could not create share link" = "پیوند اشتراکگذاری ساخته نشد";
|
||||
"Home Settings" = "تنظیمات صفحهٔ اصلی";
|
||||
"You have no Playlists" = "فهرست پخشی ندارید";
|
||||
"Watched: visible" = "تماشاشدهها: قابل رویت";
|
||||
"Are you sure you want to remove this document?" = "از حذف این سند مطمئنید؟";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Rating" = "امتیازدهی";
|
||||
|
||||
|
||||
"Public" = "عمومی";
|
||||
"Add to Playlist..." = "افزودن به فهرست پخش…";
|
||||
"Category" = "دستهبندی";
|
||||
"Fullscreen" = "تمام صفحه";
|
||||
"No description" = "بدون شرح";
|
||||
"Gaming" = "بازی";
|
||||
"Apply to all" = "اعمال روی همه";
|
||||
"Close" = "بستن";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Year" = "سال";
|
||||
"Continue" = "ادامه";
|
||||
"Show channel name" = "نمایش نام کانال";
|
||||
"Remove Location" = "حذف سرویس دهنده";
|
||||
"Large layout is not suitable for all devices and using it may cause controls not to fit on the screen." = "چیدمان بزرگ مناسب همهٔ دستگاهها نیست و استفاده از آن ممکن است باعث بیرون ماندن کنترلها از صفحهٔ نمایش شود.";
|
||||
"Shorts" = "Shortها";
|
||||
"Show Favorites" = "نمایش موردعلاقهها";
|
||||
"Interface" = "رابط کاربری";
|
||||
"Unsubscribe" = "لغو اشتراک";
|
||||
"URL" = "نشانی";
|
||||
"Short videos: visible" = "ویدیوهای Short: قابل رویت";
|
||||
"Hardware decoder" = "دکودر سختافزاری";
|
||||
"Search history is empty" = "سابقهٔ جست و جو خالیست";
|
||||
"Playback Settings" = "تنظیمات پخش";
|
||||
"Are you sure you want to clear search history?" = "آیا از حذف سابقهٔ جست و جو مطمئنید؟";
|
||||
"Could not load video" = "ویدیو دریافت نشد";
|
||||
"Show video length" = "طول ویدیو را نشان بده";
|
||||
"Hide" = "مخفی کردن";
|
||||
"Clear Search History" = "پاک کردن سابقهٔ جست و جو";
|
||||
"Play Now in MPV" = "الان در MPV پخش کن";
|
||||
"Switch to other public location" = "به یک سرویس دهندهٔ عمومی دیگر منتقل شو";
|
||||
"Restart the app to apply the settings above." = "برای اعمال تنظیمات بالا اپ را دوباره راهاندازی کنید.";
|
||||
"Are you sure you want to clear cache?" = "آیا از حذف حافظهٔ مخفی مطمئنید؟";
|
||||
"Filter" = "صافی";
|
||||
"Open Settings" = "باز کردن تنظیمات";
|
||||
"Buffering stream..." = "بافر کردن استریم…";
|
||||
"Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "فهرست پخش خالیست\n\nروی ویدیو ضربه بزنید و نگه دارید، سپس\n\"افزودن به فهرست پخش\" را انتخاب کنید";
|
||||
"Playback history is empty" = "سابقهٔ پخش خالیست";
|
||||
"Chapters" = "فصلهای ویدیو";
|
||||
"(watched and shorts hidden)" = "(تماشاشدهها و Shortها مخفی)";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Views" = "بازدیدها";
|
||||
"I want to ask a question" = "میخواهم سوالی بپرسم";
|
||||
"Show keywords" = "نمایش کلیدواژهها";
|
||||
"Edit" = "ویرایش";
|
||||
"Could not refresh Playlists" = "فهرست پخش بازسازی نشد";
|
||||
"Categories to Skip" = "دستهبندیهایی که رد میشوند";
|
||||
"Private" = "خصوصی";
|
||||
"This video could not be opened" = "این ویدیو باز نمیشود";
|
||||
"Center" = "وسط";
|
||||
"High" = "بالا";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Today" = "امروز";
|
||||
"Remove from Playlist" = "حذف از فهرست پخش";
|
||||
"URL to Open" = "نشانی برای باز کردن";
|
||||
"Replies" = "پاسخها";
|
||||
"Movies" = "فیلمها";
|
||||
"Unlisted" = "فهرست نشده";
|
||||
"Wiki" = "ویکی";
|
||||
"Sort" = "ترتیب";
|
||||
"Frontend URL" = "نشانی Frontend";
|
||||
"Restore default profiles..." = "بازنشانی نمایههای پیشفرض…";
|
||||
"Any format" = "هر فرمتی";
|
||||
"Open" = "باز کردن";
|
||||
"Filter: active" = "صافی: فعال";
|
||||
"Play Music" = "موسیقی را پخش کن";
|
||||
"Clear All" = "همه را پاک کن";
|
||||
"Add Account" = "افزودن حساب کاربری";
|
||||
"Cancel" = "لغو";
|
||||
"Accounts are not supported for the application of this instance" = "حساب کاربری در این سرویس دهنده پشتیبانی نمیشود";
|
||||
"System controls" = "کنترلهای سیستم";
|
||||
"Hide player" = "پخشکننده را مخفی کن";
|
||||
"Lock orientation" = "قفل چرخش صفحه";
|
||||
"Cache" = "حافظهٔ مخفی";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Hour" = "ساعت";
|
||||
"Open Videos" = "باز کردن ویدیو";
|
||||
"Add" = "افزودن";
|
||||
"Show icons and text when space permits" = "اگر جا بود متن و آیکنها را نشان بده";
|
||||
"Documents" = "مستندات";
|
||||
"Play Next" = "بعدی را پخش کن";
|
||||
"Battery" = "باتری";
|
||||
"Rotate to portrait when exiting fullscreen" = "پس از خروج از تمام صفحه به حالت عمودی بچرخ";
|
||||
"Could not delete document" = "سند حذف نشد";
|
||||
"Show account username" = "نمایش نام کاربری";
|
||||
"Queue - shuffled" = "صف - شافل";
|
||||
"Source" = "منبع";
|
||||
"Always" = "همیشه";
|
||||
|
||||
/* Video duration filter in search */
|
||||
"Long" = "دراز";
|
||||
"Mark video as watched after playing" = "ویدیو را پس از پخش به عنوان تماشا شده نشانه بگذار";
|
||||
"%@ Playlist" = "%@ فهرست پخش";
|
||||
"Playback queue is empty" = "صف پخش خالیست";
|
||||
"Add profile..." = "افزودن نمایه…";
|
||||
"Short videos: hidden" = "ویدیوهای Short: مخفی";
|
||||
"No documents" = "بدون مستندات";
|
||||
"Lowest" = "پایینترین";
|
||||
"Not available" = "در دسترس نیست";
|
||||
"Add Location" = "افزودن سرویس دهنده";
|
||||
"Public Locations" = "سرویس دهندگان عمومی";
|
||||
"Remove from history" = "حذف از سابقه";
|
||||
"Could not update your token." = "Token شما به روز نشد.";
|
||||
"Channel" = "کانال";
|
||||
"Limit" = "محدود";
|
||||
|
||||
/* Locations settings, custom instance is selected as current */
|
||||
"Custom" = "سفارشی";
|
||||
"Close video" = "ویدیو را ببند";
|
||||
"Remove from Favorites" = "حذف از موردعلاقهها";
|
||||
"Watched: hidden" = "تماشاشده: مخفی";
|
||||
"Close PiP and open player when application enters foreground" = "هنگامی که اپ باز میشود تصویر-در-تصویر را ببند و پخشکننده را باز کن";
|
||||
"Show Documents" = "نمایش مستندات";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Outro" = "انتها";
|
||||
"Music Mode" = "وضعیت موسیقی";
|
||||
"Edit Playlist" = "ویرایش فهرست پخش";
|
||||
"Mark as watched" = "نشانه گذاری به عنوان تماشا شده";
|
||||
"Stream" = "استریم";
|
||||
"Remove…" = "حذف…";
|
||||
"Add Location..." = "افزودن سرویس دهنده…";
|
||||
"%@ subscribers" = "%@ مشترکان";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Sponsor" = "حامی مالی";
|
||||
"Remove from the queue" = "حذف از صف";
|
||||
"Quality Profile" = "نمایهٔ کیفیت";
|
||||
"LIVE" = "زنده";
|
||||
"Accounts" = "حسابها";
|
||||
"Done" = "انجام شد";
|
||||
"Enter links to open, one per line" = "پیوندها را وارد کنید تا باز شوند، هر خط یک پیوند";
|
||||
"Files" = "فایلها";
|
||||
"No results" = "بدون نتیجه";
|
||||
"Current: %@\n%@" = "فعلی: %@\n%@";
|
||||
"Donations" = "حمایت مالی";
|
||||
"%@ Channel" = "%@ کانال";
|
||||
"Do nothing" = "کاری نکن";
|
||||
"File" = "فایل";
|
||||
"Yattee %@ (build %@)" = "Yattee %@ (بیلد %@)";
|
||||
"Proxy videos" = "پروکسی کردن ویدیوها";
|
||||
"Player" = "پخشکننده";
|
||||
"Play next item" = "مورد بعدی را پخش کن";
|
||||
"Controls" = "کنترلها";
|
||||
"This URL could not be opened" = "این نشانی باز نمیشود";
|
||||
"Trending" = "پرطرفدار";
|
||||
"Opening audio stream..." = "باز کردن استریم صوتی…";
|
||||
"Statistics" = "آمار";
|
||||
"Pause when player is closed" = "پس از بسته شدن پخشکننده مکث کن";
|
||||
"Play All" = "همه را پخش کن";
|
||||
"Sort: %@" = "ترتیب: %@";
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Opening %@ stream..." = "باز کردن استریم %@…";
|
||||
"Next in Queue" = "مورد بعد در صف";
|
||||
"Honor orientation lock" = "قفل چرخش صفحه را در نظر بگیر";
|
||||
"Rate" = "امتیاز";
|
||||
"Playing Next" = "پخش بعدی";
|
||||
"%lld videos" = "%lld ویدیو";
|
||||
"Enable Return YouTube Dislike" = "فعال کردن بازگرداندن YouTube Dislike";
|
||||
"Country Name or Code" = "نام یا کد کشور";
|
||||
"Clear the queue" = "پاک کردن صف";
|
||||
"Could not extract playlist ID" = "شناسهٔ فهرست پخش دریافت نشد";
|
||||
"Could not load streams" = "استریم قابل دریافت نیست";
|
||||
"Are you sure you want to clear history of watched videos?" = "آیا از حذف سابقهٔ تماشا مطمئنید؟";
|
||||
"Mark all as unwatched" = "همه را به عنوان تماشانشده نشانه بگذار";
|
||||
"Thumbnails" = "بندانگشتیها";
|
||||
"Left" = "چپ";
|
||||
"Open \"Playlists\" tab to create new one" = "زبانهٔ «فهرست پخش» را باز کنید تا یک فهرست جدید بسازید";
|
||||
"Replay" = "پخش دوباره";
|
||||
"Remove" = "حذف کردن";
|
||||
"Close player when starting PiP" = "هنگامی که تصویر-در-تصویر آغاز میشود پخش کننده را ببند";
|
||||
"Controls button: backwards" = "دکمههای کنترل: عقب";
|
||||
"I am lost" = "گم شدهام";
|
||||
"Show only icons" = "فقط آیکنها را نشان بده";
|
||||
"Clear all" = "همه را پاک کن";
|
||||
"Shuffle All" = "شافل کردن همه";
|
||||
"Discord Server" = "سرور Discord";
|
||||
"Subscribe" = "اشتراک";
|
||||
"Loading..." = "درحال دریافت…";
|
||||
"Edit Favorites…" = "ویرایش موردعلاقهها…";
|
||||
"Sections" = "بخشها";
|
||||
"Play Last" = "آخرین را پخش کن";
|
||||
"Pages buttons" = "دکمههای صفحهها";
|
||||
"No comments" = "بدون نظر";
|
||||
"Connected successfully (%@)" = "با موفقیت وصل شد (%@)";
|
||||
"(watched hidden)" = "(تماشاشدهها مخفی)";
|
||||
"Enable logging" = "فعال کردن ثبت log";
|
||||
"Are you sure you want to delete playlist?" = "آیا از حذف فهرست پخش مطمئنید؟";
|
||||
"Description preview" = "پیشنمایش شرح";
|
||||
"Open Files" = "باز کردن فایلها";
|
||||
"Hide sidebar" = "نوار کناری را مخفی کن";
|
||||
"Show anonymous accounts" = "نمایش حسابهای ناشناس";
|
||||
"Always show controls buttons" = "همیشه دکمههای کنترل را نشان بده";
|
||||
"Mark all as watched" = "همه را به عنوان تماشاشده نشانه بگذار";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Smaller" = "کوچکتر";
|
||||
"Search" = "جست و جو";
|
||||
"Favorites" = "مورد علاقهها";
|
||||
"Address" = "نشانی";
|
||||
"MPV Documentation" = "مستندات MPV";
|
||||
"If you are reporting a bug, include all relevant details (especially: app version, used device and system version, steps to reproduce)." = "اگر ایرادی را گزارش میکنید، همهٔ جزییات مربوط (به ویژه نسخهٔ اپ، دستگاه مورد استفاده و نسخهٔ سیستم عامل و گامهایی که برای بازسازی ایراد لازم است) را ذکر کنید.";
|
||||
"Only when signed in" = "تنها پس از ورود";
|
||||
"Sign In Required" = "لازم است که وارد شوید";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Self-promotion" = "تبلیغ شخصی";
|
||||
"Only for local files and URLs" = "فقط برای فایلهای محلی و پیوندها";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Interaction" = "تعامل";
|
||||
"Preferred Formats" = "فرمتهای ترجیحی";
|
||||
"Reset" = "بازنشانی";
|
||||
"Badge" = "نشان";
|
||||
"Error when accessing playlist" = "خطا هنگام دسترسی به فهرست پخش";
|
||||
"Right" = "راست";
|
||||
"Blue" = "آبی";
|
||||
"Low quality" = "کیفیت پایین";
|
||||
"Popular" = "محبوب";
|
||||
"List" = "فهرست";
|
||||
"Create Playlist" = "ساخت فهرست پخش";
|
||||
"Show sidebar when space permits" = "اگر جا بود نوارکناری را نشان بده";
|
||||
"Locations" = "سرویس دهندگان";
|
||||
"Playlists" = "فهرستهای پخش";
|
||||
"Current Location" = "سرویس دهندهٔ فعلی";
|
||||
"Could not open Files" = "فایل باز نشد";
|
||||
"Regular Size" = "ابعاد معمولی";
|
||||
"Could not refresh Popular" = "محبوبترینها به روز نمیشود";
|
||||
"Recent History" = "سابقهٔ اخیر";
|
||||
"Clear History" = "پاک کردن سابقه";
|
||||
"Play all unwatched" = "همهٔ دیدهنشدهها را پخش کن";
|
||||
"Show Home" = "نمایش صفحهٔ اصلی";
|
||||
"More info can be found in:" = "اطلاعات بیشتر در:";
|
||||
"Name" = "نام";
|
||||
"History" = "سابقه";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Month" = "ماه";
|
||||
"Matrix Channel" = "کانال Matrix";
|
||||
"Round corners" = "گوشههای گرد";
|
||||
"Pause when entering background" = "پس از ورود به پسزمینه مکث کن";
|
||||
"Music" = "موسیقی";
|
||||
"I like this app!" = "از این اپ خوشم میآید!";
|
||||
"Upload date" = "تاریخ انتشار";
|
||||
"Save history of played videos" = "ذخیرهٔ سابقهٔ ویدیوهای پخش شده";
|
||||
"Add Account..." = "افزودن حساب کاربری…";
|
||||
"Public account" = "حساب کاربری عمومی";
|
||||
"Add %@" = "افزودن %@";
|
||||
"Autoplaying Next" = "پخش خودکار بعدی";
|
||||
"You have no playlists\n\nTap on \"New Playlist\" to create one" = "فهرست پخش ندارید\n\nروی «فهرست جدید» ضربه بزنید و یکی بسازید";
|
||||
"No chapters information available" = "اطلاعاتی در مورد فصلهای ویدیو در دسترس نیست";
|
||||
"Lock" = "قفل";
|
||||
"Nothing" = "هیچ";
|
||||
"Cellular" = "اینترنت همراه";
|
||||
"Password" = "رمز عبور";
|
||||
"Add to Playlist" = "افزودن به فهرست پخش";
|
||||
"(shorts hidden)" = "(Shortها مخفی)";
|
||||
"Are you sure you want to remove %@ location?" = "از حذف سرویس دهندهٔ \"%@\" مطمئنید؟";
|
||||
"Current Playlist" = "فهرست پخش فعلی";
|
||||
|
||||
/* Selected video was played on given date */
|
||||
"Watched %@" = "تماشا شده %@";
|
||||
"Videos" = "ویدیوها";
|
||||
"No locations available at the moment" = "در حال حاضر سرویس دهندهای در دسترس نیست";
|
||||
"Show history" = "نمایش سابقه";
|
||||
"Default Profile" = "نمایهٔ پیشفرض";
|
||||
"Red" = "قرمز";
|
||||
"No preview" = "بدون پیشنمایش";
|
||||
"Info" = "اطلاعات";
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Loading streams..." = "درحال دریافت استریم…";
|
||||
"No rotation" = "بدون چرخش";
|
||||
"Codec" = "کدک (Codec)";
|
||||
"Startup section" = "بخش آغازین";
|
||||
"Edit Quality Profile" = "ویرایش نمایهٔ کیفیت";
|
||||
"Browse without account" = "استفاده بدون حساب کاربری";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Relevance" = "ارتباط";
|
||||
"Help" = "کمک";
|
||||
"Find Other" = "یافتن دیگری";
|
||||
"Play Now" = "الان پخش کن";
|
||||
"Close PiP when starting playing other video" = "هنگامی که ویدیوی دیگری آغاز به پخش میکند تصویر-در-تصویر را ببند";
|
||||
"Show cache status" = "نمایش وضعیت حافظهٔ مخفی";
|
||||
"Play Now in AVPlayer" = "الان در AVPlayer پخش کن";
|
||||
"Medium quality" = "کیفیت متوسط";
|
||||
"Stream & Player" = "استریم و پخشکننده";
|
||||
"Contributing" = "مشارکت";
|
||||
"Save" = "ذخیره";
|
||||
"Buttons labels" = "برچسب دکمهها";
|
||||
"Close video and player on end" = "در پایان ویدیو و پخشکننده را ببند";
|
||||
"Delete" = "حذف";
|
||||
|
||||
/* Player controls layout size for TV */
|
||||
"TV" = "تلویزیون";
|
||||
"Continue from %@" = "از %@ ادامه بده";
|
||||
"I found a bug /" = "ایرادی پیدا کردهام /";
|
||||
"Recent Documents" = "مستندات تازه";
|
||||
"Orientation" = "چرخش صفحه";
|
||||
"Low" = "پایین";
|
||||
"Restart" = "راهاندازی دوباره";
|
||||
"Search..." = "جست و جو…";
|
||||
"Open Video" = "ویدیو را باز کن";
|
||||
"Sidebar" = "نوار کناری";
|
||||
"Translations" = "ترجمهها";
|
||||
"Duration" = "مدت زمان";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Date" = "تاریخ";
|
||||
"Disable filters" = "غیرفعال کردن صافیها";
|
||||
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "فهرست پخش \"%@\" حذف خواهد شد.\nقابل بازگردانی نیست.";
|
||||
"Enter link to open" = "پیوند را وارد کنید تا باز شود";
|
||||
"Restart/Play next" = "پخش دوباره/بعدی";
|
||||
"Your Accounts" = "حساب کاربری شما";
|
||||
"Open channel" = "کانال را باز کن";
|
||||
"Queue" = "صف";
|
||||
"Controls button: forwards" = "دکمههای کنترل: جلو";
|
||||
"Normal" = "عادی";
|
||||
"Next" = "بعدی";
|
||||
"Home" = "صفحهٔ اصلی";
|
||||
"Contact" = "تماس";
|
||||
"Show Next in Queue" = "مورد بعدی صف را نشان بده";
|
||||
"Browsing" = "مرور";
|
||||
"Watched" = "تماشا شده";
|
||||
"Highest" = "بالاترین";
|
||||
"You can find information about using Yattee in the Wiki pages." = "اطلاعات در مورد چگونگی استفاده از Yattee را میتوانید در صفحات ویکی پیدا کنید.";
|
||||
"Captions" = "زیرنویس";
|
||||
"Playlist" = "فهرست پخش";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Intro" = "مقدمه";
|
||||
"Description" = "شرح";
|
||||
"Instance of current account" = "سرویس دهندهٔ حساب کاربری فعلی";
|
||||
"Advanced" = "پیشرفته";
|
||||
"Welcome" = "خوش آمدید";
|
||||
|
||||
/* Selected video has just finished playing */
|
||||
"Just watched" = "همین الان تماشا کردم";
|
||||
"Close PiP when player is opened" = "هنگامی که پخشکننده باز میشود تصویر-در-تصویر را ببند";
|
||||
"Lock portrait mode" = "قفل حالت عمودی";
|
||||
|
||||
/* Video date filter in search
|
||||
Video duration filter in search */
|
||||
"Any" = "هر";
|
||||
"Mark watched videos with" = "نشانه گذاری ویدیوها به عنوان تماشا شده با";
|
||||
"Not Playing" = "پخش نمیشود";
|
||||
"Video Details" = "جزییات ویدیو";
|
||||
"Live Streams" = "پخش زنده";
|
||||
@@ -597,3 +597,8 @@
|
||||
"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 %@";
|
||||
"Description preview" = "Aperçu de la description";
|
||||
"No preview" = "Aucun aperçu";
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
|
||||
|
||||
"%@ Channel" = "%@ चैनल";
|
||||
"%@ Playlist" = "%@ प्लेलिस्ट";
|
||||
"%@ Playlist" = "%@ गीतमाला";
|
||||
"%@ subscribers" = "%@ सदस्य";
|
||||
"%lld videos" = "%lld वीडियों";
|
||||
"%lld videos" = "%lld वीडियो";
|
||||
" subscribers" = " सदस्य";
|
||||
"10 seconds forwards/backwards" = "10 पल आगे/पीछे";
|
||||
"Accounts" = "खातें";
|
||||
"Accounts are not supported for the application of this instance" = "इस इन्सटेंस के लिए खातों उपलब्ध नहीं हैं";
|
||||
"10 seconds forwards/backwards" = "10 सेकंड आगे/पीछे";
|
||||
"Accounts" = "खाते";
|
||||
"Accounts are not supported for the application of this instance" = "इस इन्सटेंस के लिए खाते उपलब्ध नहीं हैं";
|
||||
"Add to Playlist..." = "गीतमाला में जोड़ें…";
|
||||
"Advanced" = "उन्नत";
|
||||
|
||||
/* Trending category, section containing all kinds of videos */
|
||||
"All" = "सभी";
|
||||
"Always use AVPlayer for live videos" = "लाइव वीडियो के लिए सदा ए.वी. प्लेयर का उपयोग करें";
|
||||
"Always use AVPlayer for live videos" = "लाइव वीडियो के लिए सदा AVPlayer का उपयोग करें";
|
||||
"Anonymous" = "गुप्त";
|
||||
|
||||
/* Video date filter in search
|
||||
@@ -24,16 +24,16 @@
|
||||
"Are you sure you want to clear search history?" = "क्या आप निश्चित रूप से खोज का इतिहास मिटाना चाहते हैं?";
|
||||
"Close PiP and open player when application enters foreground" = "PiP बंद करें और प्लेयर खोलें जब ऐप्लिकेशन मुख्यभूमी में जाता है";
|
||||
"Close PiP when player is opened" = "PiP बंद करें जब प्लेयर खुले";
|
||||
"Close PiP when starting playing other video" = "PiP बंद करें जब दूसरा वीडियो प्ले हो";
|
||||
"Close player when closing video" = "प्लेयर बंद करें जब वीडियो बंद हो";
|
||||
"Close player when starting PiP" = "प्लेयर बंद करें जब PiP चालू हो";
|
||||
"Close PiP when starting playing other video" = "PiP बंद करें जब दूसरा वीडियो चालू हो";
|
||||
"Close player when closing video" = "जब वीडियो बंद हो तब प्लेयर बंद करें";
|
||||
"Close player when starting PiP" = "जब PiP चालू हो रहा हो तब प्लेयर बंद करें";
|
||||
"Close Video" = "वीडियो बंद करें";
|
||||
"Close video after playing last in the queue" = "कतार में आख़िरी समाप्त होने के पश्चात वीडियो बंद करें";
|
||||
"Close video after playing last in the queue" = "अंतिम पंक्तिबद्ध समाप्त होने के पश्चात वीडियो बंद करें";
|
||||
"Comments" = "टिप्पणियाँ";
|
||||
"Connected successfully (%@)" = "जुड़ाव सफल";
|
||||
"Connected successfully (%@)" = "जुड़ाव सफल (%@)";
|
||||
"Connection failed" = "जुड़ाव असफल";
|
||||
"Contact" = "संपर्क";
|
||||
"Continue" = "जारी";
|
||||
"Continue" = "जारी रखें";
|
||||
"Disabled" = "निर्योग्य";
|
||||
"Discord Server" = "डिस्कॉर्ड सर्वर";
|
||||
"Discussions take place in Discord and Matrix. It's a good spot for general questions." = "चर्चाएँ डिस्कॉर्ड एवं मेट्रिक्स पर होतीं हैं। यह सामान्य प्रश्नों के लिए अच्छा मंच है।";
|
||||
@@ -154,18 +154,18 @@
|
||||
"Play Now" = "अभी चलाएँ";
|
||||
"Playback" = "प्लेबैक";
|
||||
"Player" = "प्लेयर";
|
||||
"Playlist" = "प्लेलिस्ट";
|
||||
"Playlist" = "गीतमाला";
|
||||
"Decreased opacity" = "पारदर्शिता घटी";
|
||||
"Continue from %@" = "%@ से जारी करें";
|
||||
"Continue from %@" = "%@ से जारी रखें";
|
||||
"Current: %@\n%@" = "वर्तमान: %@\n%@";
|
||||
"Contributing" = "योगदान दें";
|
||||
"Contributing" = "योगदान";
|
||||
"Controls" = "नियंत्रक";
|
||||
"Copy %@ link" = "%@ लिंक नक़ल करें";
|
||||
"Copy %@ link" = "%@ लिंक कॉपी करें";
|
||||
"Country" = "देश";
|
||||
"Country Name or Code" = "देश नाम एवं कोड";
|
||||
"Could not load locations manifest" = "लोकेशन मैनिफ़ेस्ट लोड नहीं हो पाई";
|
||||
"Country Name or Code" = "देश का नाम एवं कोड";
|
||||
"Could not load locations manifest" = "लोकेशन मैनिफ़ेस्ट लोड नहीं हो सका";
|
||||
"Custom Locations" = "कस्टम स्थान";
|
||||
"Copy %@ link with time" = "%@ लिंक समय के साथ नक़ल करें";
|
||||
"Copy %@ link with time" = "%@ लिंक समय के साथ कॉपी करें";
|
||||
"Add Account" = "खाता जोड़ें";
|
||||
"Add Account..." = "खाता जोड़ें…";
|
||||
"Add Location" = "स्थान जोड़ें";
|
||||
@@ -177,35 +177,35 @@
|
||||
"Add to %@" = "%@ में जोड़ें";
|
||||
"Badge color" = "बिल्ले का रंग";
|
||||
"Category" = "श्रेणी";
|
||||
"Clear Search History..." = "खोज इतिहास साफ़ करें…";
|
||||
"Clear Search History..." = "खोज इतिहास हटायें…";
|
||||
"Are you sure you want to restore default quality profiles?" = "क्या आप निश्चित रूप से डीफ़ॉल्ट गुणवत्ता प्रोफ़ाइल को पुनः प्राप्त करना चाहते हैं?";
|
||||
"Based on system color scheme" = "मूल तंत्र रंग प्रणाली पर निर्भर";
|
||||
"Based on system color scheme" = "सिस्टम के रंग प्रणाली पर निर्भर";
|
||||
"Categories to Skip" = "श्रेणियाँ जिन्हें छोड़ें";
|
||||
"Chapters" = "अध्यायें";
|
||||
"Chapters" = "अध्याय";
|
||||
"Are you sure you want to delete playlist?" = "क्या आप निश्चित रूप से इस गीतमाला को मिटाना चाहते हैं?";
|
||||
"Are you sure you want to unsubscribe from %@?" = "क्या आप निश्चित रूप से %@ की सदस्यता छोड़ना चाहते हैं?";
|
||||
"Automatic" = "स्वतः";
|
||||
"Autoplaying Next" = "अगला ऑटोप्ले हो रहा";
|
||||
"Automatic" = "स्वचालित";
|
||||
"Autoplaying Next" = "अगला स्वतः चालू हो रहा";
|
||||
"Badge" = "बिल्ला";
|
||||
"Blue" = "नीला";
|
||||
"Browsing" = "ब्राउज़ करना";
|
||||
"Buffering stream..." = "स्ट्रीम बफ़र हो रहा…";
|
||||
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "आप बग एवं फ़ीचर सुझाव गिटहब के इशु ट्रैकर पर भेज सकते हैं ";
|
||||
"Cancel" = "रद्द";
|
||||
"Captions" = "कैप्शन";
|
||||
"Charging" = "चार्ज हो रहा";
|
||||
"Clear" = "साफ़";
|
||||
"Clear All" = "सभी साफ़";
|
||||
"Clear All Recents" = "सभी हालिया साफ़ करें";
|
||||
"Clear History" = "इतिहास साफ़ करें";
|
||||
"Clear Search History" = "खोज इतिहास साफ़ करें";
|
||||
"Clear the queue" = "क़तार साफ़ करें";
|
||||
"Captions" = "अनुशीर्षक";
|
||||
"Charging" = "चार्ज हो रहा है";
|
||||
"Clear" = "हटायें";
|
||||
"Clear All" = "सभी हटायें";
|
||||
"Clear All Recents" = "सभी हालिया हटायें";
|
||||
"Clear History" = "इतिहास हटायें";
|
||||
"Clear Search History" = "खोज इतिहास हटायें";
|
||||
"Clear the queue" = "पंक्तिबद्ध हटायें";
|
||||
"Close" = "बंद";
|
||||
"Backend" = "बैकऐंड";
|
||||
"Backend" = "पृष्ठभाग";
|
||||
"Badge & Decreased opacity" = "बिल्ला एवं पारदर्शिता में कमी";
|
||||
"Battery" = "बैटरी";
|
||||
"Button" = "बटन";
|
||||
"Cellular" = "मोबाइल डाटा";
|
||||
"Cellular" = "मोबाइल";
|
||||
"Create Playlist" = "गीतमाला बनाएँ";
|
||||
|
||||
/* Player controls layout size */
|
||||
@@ -267,7 +267,7 @@
|
||||
"Statistics" = "आँकड़े";
|
||||
"Hardware decoder" = "हार्डवेयर डीकोडर";
|
||||
"Stream FPS" = "स्ट्रीम FPS";
|
||||
"Playlists" = "प्लेलिस्ट";
|
||||
"Playlists" = "गीतमाला";
|
||||
"Popular" = "लोकप्रिय";
|
||||
"Preferred Formats" = "पसंदीदा प्रारूप";
|
||||
"Profiles" = "प्रोफ़ाइल";
|
||||
@@ -415,7 +415,7 @@
|
||||
"Locations Manifest" = "";
|
||||
"Could not delete document" = "";
|
||||
"Show Inspector" = "";
|
||||
"Could not load streams" = "";
|
||||
"Could not load streams" = "स्ट्रीम्स नहीं खोला जा सका";
|
||||
"Address" = "";
|
||||
"Playback Mode" = "";
|
||||
"Left" = "";
|
||||
@@ -447,17 +447,17 @@
|
||||
"Verified" = "";
|
||||
"No documents" = "";
|
||||
"Show Open Videos toolbar button" = "";
|
||||
"Could not refresh Subscriptions" = "";
|
||||
"Could not refresh Subscriptions" = "सदस्यता पुनर्स्थापित नहीं किया जा सका";
|
||||
"Remove Location" = "";
|
||||
"Only for local files and URLs" = "";
|
||||
"Codec" = "";
|
||||
"File" = "";
|
||||
"Could not extract playlist ID" = "";
|
||||
"Paste" = "";
|
||||
"Could not extract SID from received cookies: %@" = "";
|
||||
"Could not extract SID from received cookies: %@" = "प्राप्त कुकीज़ से SID नहीं निकाला जा सका: %@";
|
||||
"Files" = "";
|
||||
"Show Home" = "";
|
||||
"Could not extract channel information" = "";
|
||||
"Could not extract channel information" = "चैनल की जानकारी नहीं निकाली जा सकी";
|
||||
"Enter link to open" = "";
|
||||
"Home" = "";
|
||||
"No locations available at the moment" = "";
|
||||
@@ -469,7 +469,7 @@
|
||||
"Format" = "";
|
||||
"Share files from Finder on a Mac\nor iTunes on Windows" = "";
|
||||
"Share%@link" = "";
|
||||
"Could not open video" = "";
|
||||
"Could not open video" = "वीडियो नहीं खोला जा सका";
|
||||
"Center" = "";
|
||||
"Size" = "";
|
||||
"Recent Documents" = "";
|
||||
@@ -484,14 +484,14 @@
|
||||
"Could not create share link" = "";
|
||||
"Sample Rate" = "";
|
||||
"Translations" = "";
|
||||
"Open logs in Finder" = "";
|
||||
"Open logs in Finder" = "लॉग को Finder में खोलें";
|
||||
"Could not refresh Playlists" = "";
|
||||
"Could not update your token." = "";
|
||||
"Could not refresh Trending" = "";
|
||||
"Could not update your token." = "आपका टोकन अपडेट नहीं हो सका।";
|
||||
"Could not refresh Trending" = "ट्रेंडिंग को पुनर्स्थापित नहीं किया जा सका";
|
||||
"Could not open playlist" = "";
|
||||
"This URL could not be opened" = "";
|
||||
"Could not open channel" = "";
|
||||
"Channel could not be found" = "";
|
||||
"This URL could not be opened" = "इस URL को नहीं खोला जा सका";
|
||||
"Could not open channel" = "चैनल नहीं खुल सका";
|
||||
"Channel could not be found" = "चैनल नहीं मिला";
|
||||
"Could not refresh Popular" = "";
|
||||
"Could not extract video ID" = "";
|
||||
"Channel" = "";
|
||||
@@ -501,4 +501,4 @@
|
||||
"Pages toolbar position" = "";
|
||||
"Default Profile" = "";
|
||||
"Copy%@link" = "";
|
||||
"Share Logs..." = "";
|
||||
"Share Logs..." = "लॉग साझा करें…";
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
"Not available" = "利用できません";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Offtopic in Music Videos" = "音楽動画の脱線した内容";
|
||||
"Offtopic in Music Videos" = "音楽動画の非音楽部分";
|
||||
"Only when signed in" = "ログイン時のみ";
|
||||
"Orientation" = "向き";
|
||||
"Opening audio stream..." = "音声ストリーム 開始中...";
|
||||
@@ -487,13 +487,13 @@
|
||||
"Category" = "分類";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Interaction" = "操作の要求";
|
||||
"Interaction" = "操作の依頼";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Self-promotion" = "自己宣伝";
|
||||
"Quality" = "品質";
|
||||
"Are you sure you want to clear search history?" = "検索履歴を消去しますか?";
|
||||
"For videos which feature music as the primary content." = "音楽を主なコンテンツとする動画用です。";
|
||||
"For videos which feature music as the primary content." = "音楽が主な内容の動画が対象です。";
|
||||
"Always use AVPlayer for live videos" = "ライブ配信には常に AVPlayer を使用";
|
||||
"Clear Search History" = "検索履歴を消去";
|
||||
"Disabled" = "無効化";
|
||||
@@ -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,8 @@
|
||||
"Landscape right" = "右を下に横長";
|
||||
"Show channel avatars in channels lists" = "チャンネル一覧にチャンネルのアイコンを表示";
|
||||
"Show channel avatars in videos lists" = "動画一覧にチャンネルのアイコンを表示";
|
||||
"Podcasts" = "ポッドキャスト";
|
||||
"Releases" = "リリース";
|
||||
"Add %@" = "追加 %@";
|
||||
"Description preview" = "説明のプレビュー";
|
||||
"No preview" = "プレビューなし";
|
||||
|
||||
@@ -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å";
|
||||
|
||||
@@ -598,3 +598,10 @@
|
||||
"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 %@";
|
||||
"Description preview" = "Podgląd opisu";
|
||||
"No preview" = "Brak podglądu";
|
||||
"Open vertical chapters expanded" = "Otwórz pionowe rozdziały rozwinięte";
|
||||
"Chapters (if available)" = "Rozdziały (jeśli dostępne)";
|
||||
|
||||
@@ -597,3 +597,8 @@
|
||||
"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 %@";
|
||||
"Description preview" = "Descrição da prévia";
|
||||
"No preview" = "Sem prévia";
|
||||
|
||||
@@ -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ă %@";
|
||||
|
||||
@@ -294,15 +294,15 @@
|
||||
"Hide" = "";
|
||||
"Playing Next" = "";
|
||||
"Are you sure you want to remove this document?" = "";
|
||||
"Show channel name" = "";
|
||||
"Show channel name" = "Kanal adını göster";
|
||||
"Unlisted" = "";
|
||||
"Paste" = "";
|
||||
"Rate & Captions" = "";
|
||||
"Format" = "";
|
||||
"Right" = "";
|
||||
"Right" = "Sağ";
|
||||
"Stream FPS" = "";
|
||||
"Cached time" = "";
|
||||
"Sign In Required" = "";
|
||||
"Sign In Required" = "Giriş yapmanız gerekiyor";
|
||||
"Could not create share link" = "";
|
||||
"Locations Manifest" = "";
|
||||
"When partially watched video is played" = "";
|
||||
@@ -323,19 +323,19 @@
|
||||
"Show Documents" = "";
|
||||
"Press and hold remote button to open captions and quality menus" = "";
|
||||
"No locations available at the moment" = "";
|
||||
"Show account username" = "";
|
||||
"Show account username" = "Hesabın kullanıcı adını göster";
|
||||
"Used to create links from videos, channels and playlists" = "";
|
||||
"Size" = "";
|
||||
"You have no playlists\n\nTap on \"New Playlist\" to create one" = "";
|
||||
"Sort: %@" = "";
|
||||
"Select location closest to you:" = "";
|
||||
"Sort: %@" = "Sırala: %@";
|
||||
"Select location closest to you:" = "Size en yakın konumu seçin:";
|
||||
"Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "";
|
||||
|
||||
/* Video duration filter in search */
|
||||
"Short" = "";
|
||||
"Short" = "Kısa";
|
||||
"Home" = "";
|
||||
"Remove Location" = "";
|
||||
"Edit Favorites…" = "";
|
||||
"Edit Favorites…" = "Favorileri düzenle…";
|
||||
"Show Open Videos toolbar button" = "";
|
||||
"Sample Rate" = "";
|
||||
"Private" = "";
|
||||
@@ -365,14 +365,14 @@
|
||||
"Subscriptions" = "";
|
||||
"Upload date" = "";
|
||||
"This information will be processed only on your device and used to connect you to the server in the specified country." = "";
|
||||
"Shuffle" = "";
|
||||
"Shuffle" = "Karıştır";
|
||||
"Buttons labels" = "";
|
||||
"Share %@ link" = "";
|
||||
"Share %@ link" = "%@ bağlantısını paylaş";
|
||||
"Could not load streams" = "";
|
||||
"Playback history is empty" = "";
|
||||
"Show icons and text when space permits" = "";
|
||||
"unknown" = "";
|
||||
"Share..." = "";
|
||||
"Share..." = "Paylaş...";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Views" = "";
|
||||
@@ -382,7 +382,7 @@
|
||||
"Could not refresh Playlists" = "";
|
||||
"Actions buttons" = "";
|
||||
"Any format" = "";
|
||||
"Show playback statistics" = "";
|
||||
"Show playback statistics" = "Oynatma istatistiklerini göster";
|
||||
"Pages buttons" = "";
|
||||
"Videos" = "";
|
||||
"Codec" = "";
|
||||
@@ -396,7 +396,7 @@
|
||||
"Open" = "";
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Opening %@ stream..." = "";
|
||||
"Opening %@ stream..." = "%@ akışı açılıyor...";
|
||||
"Clear Queue before opening" = "";
|
||||
"Copy %@ link with time" = "Bağlantıyı %@ zaman ile kopyala";
|
||||
"Show Inspector" = "";
|
||||
@@ -412,15 +412,15 @@
|
||||
|
||||
/* Video date filter in search */
|
||||
"Week" = "";
|
||||
"Sidebar" = "";
|
||||
"Sidebar" = "Kenar çubuğu";
|
||||
"Show only icons" = "";
|
||||
"Current: %@\n%@" = "Şuan: %@\n%@";
|
||||
"Show anonymous accounts" = "";
|
||||
"Show anonymous accounts" = "Anonim hesapları göster";
|
||||
"Could not open playlist" = "";
|
||||
"Round corners" = "";
|
||||
"URL" = "";
|
||||
"Recents" = "";
|
||||
"Show sidebar when space permits" = "";
|
||||
"Show sidebar when space permits" = "Alan olduğu sürece kenar çubuğunu göster";
|
||||
"System controls buttons" = "";
|
||||
"Could not extract channel information" = "";
|
||||
"Public Locations" = "";
|
||||
@@ -431,22 +431,22 @@
|
||||
"Continue from %@" = "% devam et";
|
||||
"Copy %@ link" = "Bağlantıyı %@ kopyala";
|
||||
"Seek gesture sensitivity" = "";
|
||||
"Show keywords" = "";
|
||||
"Show keywords" = "Anahtar kelimeleri göster";
|
||||
"Wiki" = "";
|
||||
"Username" = "";
|
||||
"Could not extract video ID" = "";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Smaller" = "";
|
||||
"Sort" = "";
|
||||
"Smaller" = "Küçült";
|
||||
"Sort" = "Sırala";
|
||||
"This cannot be reverted" = "";
|
||||
"Public Manifest" = "";
|
||||
"You have no Playlists" = "";
|
||||
"Watched" = "";
|
||||
"Could not open video" = "";
|
||||
"Channel could not be found" = "";
|
||||
"Show video length" = "";
|
||||
"Source" = "";
|
||||
"Show video length" = "Video uzunluğunu göster";
|
||||
"Source" = "Kaynak";
|
||||
"Welcome" = "";
|
||||
"Wi-Fi" = "";
|
||||
"Could not open channel" = "";
|
||||
@@ -454,13 +454,13 @@
|
||||
"Could not extract playlist ID" = "";
|
||||
"Could not load video" = "";
|
||||
"Decreased opacity" = "Düşük şeffaflık";
|
||||
"Shuffle All" = "";
|
||||
"Share %@ link with time" = "";
|
||||
"Shuffle All" = "Tümünü karıştır";
|
||||
"Share %@ link with time" = "%@ bağlantısını zaman bilgisiyle birlikte paylaş";
|
||||
"This cannot be reverted. You might need to switch between views or restart the app to see changes." = "";
|
||||
"Unsubscribe" = "";
|
||||
"Current Location" = "";
|
||||
"Stream & Player" = "";
|
||||
"Hardware decoder" = "";
|
||||
"Hardware decoder" = "Donanımsal çözücü";
|
||||
"Honor orientation lock" = "";
|
||||
"Seek with horizontal swipe on video" = "";
|
||||
"Segments typically found at the start of a video that include an animation, still frame or clip which are also seen in other videos by the same creator." = "";
|
||||
@@ -473,12 +473,12 @@
|
||||
"Self-promotion" = "";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Small" = "";
|
||||
"Small" = "Küçük";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Sponsor" = "";
|
||||
"Sponsor" = "Sponsor";
|
||||
"System controls show buttons for %@" = "";
|
||||
"Show history" = "";
|
||||
"Show history" = "Kullanım geçmişini göster";
|
||||
"Could not extract SID from received cookies: %@" = "";
|
||||
"This will remove all your custom profiles and return their default values. This cannot be reverted." = "";
|
||||
"Switch to other public location" = "";
|
||||
@@ -502,3 +502,6 @@
|
||||
"Share" = "";
|
||||
"File" = "";
|
||||
"Share%@link" = "";
|
||||
"Cache" = "Önbellek";
|
||||
"Enter account credentials to connect..." = "Bağlanmak için hesap bilgilerini girin...";
|
||||
"Show scroll to top button in comments" = "Yorumlarda yukarıya götür düğmesini göster";
|
||||
|
||||
15
Vendor/RefreshControl/Extensions/UIResponder+Extensions.swift
vendored
Normal file
15
Vendor/RefreshControl/Extensions/UIResponder+Extensions.swift
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
70
Vendor/RefreshControl/Extensions/UIView+Extensions.swift
vendored
Normal file
70
Vendor/RefreshControl/Extensions/UIView+Extensions.swift
vendored
Normal 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)")
|
||||
}
|
||||
}
|
||||
56
Vendor/RefreshControl/RefreshControl.swift
vendored
Normal file
56
Vendor/RefreshControl/RefreshControl.swift
vendored
Normal 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
|
||||
}
|
||||
}
|
||||
46
Vendor/RefreshControl/RefreshControlModifier.swift
vendored
Normal file
46
Vendor/RefreshControl/RefreshControlModifier.swift
vendored
Normal 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))
|
||||
}
|
||||
}
|
||||
18
Vendor/RefreshControl/ScrollViewMatcher/FramePreferenceKey.swift
vendored
Normal file
18
Vendor/RefreshControl/ScrollViewMatcher/FramePreferenceKey.swift
vendored
Normal 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()
|
||||
}
|
||||
}
|
||||
106
Vendor/RefreshControl/ScrollViewMatcher/ScrollViewMatcher.swift
vendored
Normal file
106
Vendor/RefreshControl/ScrollViewMatcher/ScrollViewMatcher.swift
vendored
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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>"; };
|
||||
@@ -1155,6 +1183,10 @@
|
||||
376578902685490700D4EA09 /* PlaylistsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistsView.swift; sourceTree = "<group>"; };
|
||||
37658ED428E1C567004BF6A2 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
376787BA291C43CD00D356A4 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3767F3312B2504F800F257BC /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3767F3322B25053B00F257BC /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3767F3332B25058300F257BC /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3767F3342B2505EF00F257BC /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3768122C28E8D0BC0036FC8D /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
3769C02D2779F18600DDB3EA /* PlaceholderProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderProgressView.swift; sourceTree = "<group>"; };
|
||||
376A33DF2720CAD6000C1D6B /* VideosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosApp.swift; sourceTree = "<group>"; };
|
||||
@@ -1178,6 +1210,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 +1229,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 +1366,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 +1454,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 +1466,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 +1479,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 +1702,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 +1879,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 +2083,7 @@
|
||||
37D4B159267164AE00C925CA /* tvOS */,
|
||||
37D4B1B72672CFE300C925CA /* Model */,
|
||||
37D4B0C12671614700C925CA /* Shared */,
|
||||
3773B7F32ADC076800B5FEF3 /* Vendor */,
|
||||
3722AEBA274DA312005EA4D6 /* Backports */,
|
||||
37C7A9022679058300E721B4 /* Extensions */,
|
||||
3748186426A762300084E870 /* Fixtures */,
|
||||
@@ -1993,6 +2096,7 @@
|
||||
37D4B0E12671614900C925CA /* Tests macOS */,
|
||||
3DA101AC287C30F50027D920 /* Xcode-config */,
|
||||
37D9169A27388A81002B1BAA /* README.md */,
|
||||
3773B7D12ADC05FF00B5FEF3 /* Recovered References */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -2280,7 +2384,6 @@
|
||||
377FC7D4267A080300A6BBAF /* SwiftyJSON */,
|
||||
37BD07B62698AB2E003EBB87 /* Defaults */,
|
||||
37BD07B82698AB2E003EBB87 /* Siesta */,
|
||||
37BD07C62698B27B003EBB87 /* Introspect */,
|
||||
37BADCA42699FB72009BE4FB /* Alamofire */,
|
||||
37FB284C2722099E00A57617 /* SDWebImageWebPCoder */,
|
||||
37FB285527220D9000A57617 /* SDWebImagePINPlugin */,
|
||||
@@ -2295,6 +2398,7 @@
|
||||
371AC0AB294D1A490085989E /* CachedAsyncImage */,
|
||||
379325D429A265A300181CF1 /* Logging */,
|
||||
FA97174B2A494700001FF53D /* MPVKit */,
|
||||
37C736792AC33010007630E1 /* SwiftUIIntrospect */,
|
||||
);
|
||||
productName = "Yattee (iOS)";
|
||||
productReference = 37D4B0C92671614900C925CA /* Yattee.app */;
|
||||
@@ -2332,8 +2436,8 @@
|
||||
374D11E62943C56300CB4350 /* Cache */,
|
||||
371AC0B1294D1C230085989E /* CachedAsyncImage */,
|
||||
379325D629A265AE00181CF1 /* Logging */,
|
||||
379E7C352A2105B900AF8118 /* Introspect */,
|
||||
3704BDFE2ABF260C00370FF7 /* MPVKit */,
|
||||
37C736772AC32B28007630E1 /* SwiftUIIntrospect */,
|
||||
);
|
||||
productName = "Yattee (macOS)";
|
||||
productReference = 37D4B0CF2671614900C925CA /* Yattee.app */;
|
||||
@@ -2506,6 +2610,10 @@
|
||||
pt,
|
||||
"pt-BR",
|
||||
ja,
|
||||
fa,
|
||||
es,
|
||||
tr,
|
||||
ru,
|
||||
);
|
||||
mainGroup = 37D4B0BC2671614700C925CA;
|
||||
packageReferences = (
|
||||
@@ -2566,6 +2674,7 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3773B8012ADC076800B5FEF3 /* README in Resources */,
|
||||
37D4B0E82671614900C925CA /* Assets.xcassets in Resources */,
|
||||
375B537428DF6CBB004C1D19 /* Localizable.strings in Resources */,
|
||||
);
|
||||
@@ -2575,6 +2684,7 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3773B8022ADC076800B5FEF3 /* README in Resources */,
|
||||
37D4B0E92671614900C925CA /* Assets.xcassets in Resources */,
|
||||
375B537528DF6CBB004C1D19 /* Localizable.strings in Resources */,
|
||||
);
|
||||
@@ -2598,6 +2708,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 +2872,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 +2896,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 +2941,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 +2950,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 +2966,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 +3034,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 +3049,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 +3075,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 +3092,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 +3101,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 +3143,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 +3158,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 +3209,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 +3240,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 +3303,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 +3413,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 +3545,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 +3574,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 +3589,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 +3668,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 +3689,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 +3727,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 */,
|
||||
@@ -3659,6 +3795,10 @@
|
||||
37E868FE29AA402D003128D0 /* pt */,
|
||||
37E868FF29AA407B003128D0 /* pt-BR */,
|
||||
37ABD5FE29BE7FA800DDCAD7 /* ja */,
|
||||
3767F3312B2504F800F257BC /* fa */,
|
||||
3767F3322B25053B00F257BC /* es */,
|
||||
3767F3332B25058300F257BC /* tr */,
|
||||
3767F3342B2505EF00F257BC /* ru */,
|
||||
);
|
||||
name = Localizable.strings;
|
||||
sourceTree = "<group>";
|
||||
@@ -3673,7 +3813,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 = 171;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee";
|
||||
@@ -3684,7 +3824,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 +3844,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
||||
@@ -3716,7 +3856,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 +3875,11 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
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 +3895,11 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
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 +4059,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
@@ -3937,13 +4077,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 +4112,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1";
|
||||
@@ -3987,13 +4127,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 +4164,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@@ -4038,11 +4178,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 +4203,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 = 171;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
@@ -4080,11 +4218,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 +4238,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4110,7 +4246,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 +4262,7 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4134,7 +4270,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 +4288,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4161,7 +4297,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 +4313,7 @@
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4186,7 +4322,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 +4339,7 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -4219,7 +4355,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 +4379,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 = 171;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
"DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -4260,7 +4396,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 +4420,14 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
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 +4444,14 @@
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 162;
|
||||
CURRENT_PROJECT_VERSION = 171;
|
||||
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 +4754,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 +4961,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 +4981,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;
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -42,7 +42,7 @@
|
||||
"location" : "https://github.com/kishikawakatsumi/KeychainAccess.git",
|
||||
"state" : {
|
||||
"branch" : "master",
|
||||
"revision" : "ecb18d8ce4d88277cc4fb103973352d91e18c535"
|
||||
"revision" : "e0c7eebc5a4465a3c4680764f26b7a61f567cdaf"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -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" : "fbe79221b146aa6647dceb5a5c75873a48b69519"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -122,8 +122,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/SDWebImage/SDWebImageSwiftUI.git",
|
||||
"state" : {
|
||||
"revision" : "e837c37d45449fbd3b4745c10c5b5274e73edead",
|
||||
"version" : "2.2.3"
|
||||
"revision" : "aee64ef39b570c44ccf0f884c440fc6494a23c76",
|
||||
"version" : "2.2.5"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -131,8 +131,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/SDWebImage/SDWebImageWebPCoder.git",
|
||||
"state" : {
|
||||
"revision" : "3819cb70faa2454b54d8364779bfacd8c216a6e2",
|
||||
"version" : "0.13.0"
|
||||
"revision" : "db4603921b31a6ce0f8c26d36d6a3fffc2dba481",
|
||||
"version" : "0.14.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -86,9 +86,11 @@ public class OrientationTracker {
|
||||
if accelerometerData.acceleration.y <= -threshold {
|
||||
return .portrait
|
||||
}
|
||||
if accelerometerData.acceleration.y >= threshold {
|
||||
|
||||
if UIDevice.current.userInterfaceIdiom == .pad && accelerometerData.acceleration.y >= threshold {
|
||||
return .portraitUpsideDown
|
||||
}
|
||||
|
||||
return currentDeviceOrientation
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -4,6 +4,7 @@ final class MPVOGLView: NSView {
|
||||
override init(frame frameRect: CGRect) {
|
||||
super.init(frame: frameRect)
|
||||
autoresizingMask = [.width, .height]
|
||||
wantsBestResolutionOpenGLSurface = true
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
|
||||
@@ -130,7 +130,7 @@ struct NowPlayingView: View {
|
||||
} else {
|
||||
Section(header: Text("Chapters")) {
|
||||
ForEach(video.chapters) { chapter in
|
||||
ChapterView(chapter: chapter)
|
||||
ChapterViewTVOS(chapter: chapter)
|
||||
.padding(.horizontal, 40)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user