Compare commits

...

49 Commits

Author SHA1 Message Date
Arkadiusz Fal
39f6319043 Bump build number to 171 2023-12-09 22:08:21 +01:00
Arkadiusz Fal
6a2dc9164e Update CHANGELOG 2023-12-09 22:08:20 +01:00
Arkadiusz Fal
37d3f43596 Add channel view help labels 2023-12-09 22:08:20 +01:00
Arkadiusz Fal
aef0ba6ffd Fix displaying account username 2023-12-09 22:08:20 +01:00
Arkadiusz Fal
1ae12cfa21 Add localizations for fa, es, tr, ru 2023-12-09 22:08:20 +01:00
Arkadiusz Fal
8475669aab Update packages 2023-12-09 22:08:20 +01:00
Arkadiusz Fal
6fec76fcb3 Merge pull request #584 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2023-12-09 22:08:13 +01:00
Arkadiusz Fal
08b2e7ceac Translated using Weblate (Polish)
Currently translated at 100.0% (537 of 537 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/pl/
2023-12-09 22:08:00 +01:00
Anonymous
60972f0c7b Translated using Weblate (English)
Currently translated at 100.0% (537 of 537 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/en/
2023-12-09 22:08:00 +01:00
Arkadiusz Fal
a49db76588 Merge pull request #564 from stonerl/collapsible-chapters
make chapters collapsible and highlight current chapter
2023-12-09 21:51:24 +01:00
Arkadiusz Fal
bd0c86060b Merge pull request #583 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2023-12-09 21:34:14 +01:00
Arkadiusz Fal
9849f31e1f Translated using Weblate (Polish)
Currently translated at 100.0% (535 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/pl/
2023-12-09 21:33:58 +01:00
Arkadiusz Fal
00ac222af6 Merge pull request #568 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2023-12-09 21:25:54 +01:00
Vijay
732a8d7385 Translated using Weblate (Hindi)
Currently translated at 65.7% (352 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/hi/
2023-12-09 21:03:19 +01:00
Vijay
a009ad7d53 Translated using Weblate (Hindi)
Currently translated at 63.5% (340 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/hi/
2023-12-09 21:03:19 +01:00
Kaambiz
91c7c9fc8e Translated using Weblate (Persian)
Currently translated at 78.1% (418 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/fa/
2023-12-09 21:03:19 +01:00
Alper Zengintaş
e836f87c88 Translated using Weblate (Turkish)
Currently translated at 49.9% (267 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/tr/
2023-12-09 21:03:19 +01:00
Kaambiz
1e1a23acd0 Added translation using Weblate (Persian) 2023-12-09 21:03:19 +01:00
Sloom
d8d728a48f Translated using Weblate (Arabic (Najdi))
Currently translated at 0.3% (2 of 533 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ars/
2023-12-09 21:03:19 +01:00
maboroshin
067e8a79bf Translated using Weblate (Japanese)
Currently translated at 99.6% (533 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ja/
2023-12-09 21:03:19 +01:00
joaooliva
576f40360d Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (535 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/pt_BR/
2023-12-09 21:03:19 +01:00
gallegonovato
c679a52903 Translated using Weblate (Spanish)
Currently translated at 100.0% (535 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/es/
2023-12-09 21:03:19 +01:00
Alper Zengintaş
82f109290d Translated using Weblate (Turkish)
Currently translated at 46.7% (250 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/tr/
2023-12-09 21:03:19 +01:00
Ophiushi
765006b185 Translated using Weblate (French)
Currently translated at 100.0% (535 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/fr/
2023-12-09 21:03:19 +01:00
Anonymous
86cddb06e4 Translated using Weblate (English)
Currently translated at 100.0% (535 of 535 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/en/
2023-12-09 21:03:19 +01:00
Sloom
012b5156b7 Added translation using Weblate (Arabic (Najdi)) 2023-12-09 21:03:19 +01:00
Arkadiusz Fal
d6c04540e9 Merge pull request #569 from stonerl/no-180-rotation
disable portraitUpsideDown on iPhones
2023-12-09 21:03:14 +01:00
Arkadiusz Fal
3144b52b55 Merge pull request #578 from stonerl/description-fix
macOS: disable hit testing when not expanded
2023-12-09 21:01:30 +01:00
Toni Förster
b04385ceae macOS: disable hit testing when not expanded
fixes overspilling of text when clicking on collapsed descriptions
2023-12-05 00:36:12 +01:00
Toni Förster
721a97dc41 no need for NotificationCenter 2023-12-05 00:07:36 +01:00
Toni Förster
4ca8adc4dd move onReceive to the chapter header in VideoDetails 2023-12-04 23:00:20 +01:00
Toni Förster
d361ef01d4 move updating the time to PlayerModel
this makes the chapter view much much smoother
2023-12-04 21:58:49 +01:00
Toni Förster
0d9c27319d make time updates work for .mpv and .avp
- time update notifications work for both backends
- only init mpv timers when mpv is the active backend
- move notification extension to playerbackend
2023-12-04 14:47:26 +01:00
Toni Förster
600b8d198b add option to expand vertical chapters by default 2023-12-04 01:04:39 +01:00
Toni Förster
d65224320e chapters can only be clicked if expanded or horizontal 2023-12-04 00:39:29 +01:00
Toni Förster
586cea7d44 subscribe chapters to currentTime notification 2023-12-04 00:07:39 +01:00
Toni Förster
aa5d6733b2 remove superfluous vars and chaptermodel 2023-12-03 20:04:57 +01:00
Toni Förster
982dca1846 highlight current chapter when clicked on it 2023-11-29 00:31:53 +01:00
Toni Förster
7de702ad23 change color to appRed for chapter 2023-11-28 23:06:37 +01:00
Toni Förster
13ef96cd02 separate tvOS View 2023-11-28 20:05:04 +01:00
Toni Förster
4ec6f35c5d highlight current chapter 2023-11-28 16:45:36 +01:00
Toni Förster
7f19f7aa47 disable portraitUpsideDown on iPhones 2023-11-27 18:05:17 +01:00
Toni Förster
fb5cd0f681 vertical chapters are full width and max 3 lines 2023-11-27 14:18:43 +01:00
Toni Förster
3feafc153c remove toggle for vertical chapters 2023-11-27 13:34:18 +01:00
Toni Förster
8f08674527 vertical chapters with images are always collapsed 2023-11-27 12:13:51 +01:00
Toni Förster
a7baaeb485 iOS click on collapsed chapters expands the view 2023-11-26 21:24:52 +01:00
Toni Förster
b0d81cdefd iOS - chapters header is a button now 2023-11-26 21:24:52 +01:00
Toni Förster
a33a1d7658 formatting 2023-11-26 21:24:51 +01:00
Toni Förster
e436dec4ba make chapters collapsible
Chapters are now collapsible by default only the first two chapters are shown. The second will be shown opaque to indicate more chapters.
2023-11-26 21:24:50 +01:00
27 changed files with 910 additions and 218 deletions

View File

@@ -1,14 +1,21 @@
## Build 170 ## 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
* Description is collapsible with a button * Description is collapsible with a button
* Links in description are clickable on macOS * Links in description are clickable on macOS
* Aspect ratio is honored on resize on macOS * Aspect ratio is honored on resize on macOS
* Added support for private Invidious instances * Added support for private Invidious instances
* Updated dependencies
**Big thanks to [@stonerl](https://github.com/stonerl) for these contributions!**
**And to all other project contributors!**
## Previous builds
* Fixed issue where Piped login token would not refresh * Fixed issue where Piped login token would not refresh
* Fixed issue with MPV subtitles not working * Fixed issue with MPV subtitles not working
* Other minor changes and improvements * Other minor changes and improvements

View File

@@ -3,25 +3,25 @@ GEM
specs: specs:
CFPropertyList (3.0.6) CFPropertyList (3.0.6)
rexml rexml
addressable (2.8.5) addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0) public_suffix (>= 2.0.2, < 6.0)
artifactory (3.0.15) artifactory (3.0.15)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.3.0) aws-eventstream (1.3.0)
aws-partitions (1.856.0) aws-partitions (1.864.0)
aws-sdk-core (3.188.0) aws-sdk-core (3.190.0)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0) aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5) aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1) jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.73.0) aws-sdk-kms (1.74.0)
aws-sdk-core (~> 3, >= 3.188.0) aws-sdk-core (~> 3, >= 3.188.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.139.0) aws-sdk-s3 (1.141.0)
aws-sdk-core (~> 3, >= 3.188.0) aws-sdk-core (~> 3, >= 3.189.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.6) aws-sigv4 (~> 1.8)
aws-sigv4 (1.7.0) aws-sigv4 (1.8.0)
aws-eventstream (~> 1, >= 1.0.2) aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4) babosa (1.0.4)
claide (1.1.0) claide (1.1.0)
@@ -35,7 +35,7 @@ GEM
domain_name (0.6.20231109) domain_name (0.6.20231109)
dotenv (2.8.1) dotenv (2.8.1)
emoji_regex (3.2.3) emoji_regex (3.2.3)
excon (0.104.0) excon (0.105.0)
faraday (1.10.3) faraday (1.10.3)
faraday-em_http (~> 1.0) faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0) faraday-em_synchrony (~> 1.0)
@@ -123,11 +123,11 @@ GEM
google-apis-core (>= 0.11.0, < 2.a) google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.29.0) google-apis-storage_v1 (0.29.0)
google-apis-core (>= 0.11.0, < 2.a) google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.6.0) google-cloud-core (1.6.1)
google-cloud-env (~> 1.0) google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0) google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0) google-cloud-env (2.0.1)
faraday (>= 0.17.3, < 3.0) faraday (>= 1.0, < 3.a)
google-cloud-errors (1.3.1) google-cloud-errors (1.3.1)
google-cloud-storage (1.45.0) google-cloud-storage (1.45.0)
addressable (~> 2.8) addressable (~> 2.8)
@@ -137,8 +137,9 @@ GEM
google-cloud-core (~> 1.6) google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a) googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0) mini_mime (~> 1.0)
googleauth (1.8.1) googleauth (1.9.0)
faraday (>= 0.17.3, < 3.a) faraday (>= 1.0, < 3.a)
google-cloud-env (~> 2.0, >= 2.0.1)
jwt (>= 1.4, < 3.0) jwt (>= 1.4, < 3.0)
multi_json (~> 1.11) multi_json (~> 1.11)
os (>= 0.9, < 2.0) os (>= 0.9, < 2.0)
@@ -148,7 +149,7 @@ GEM
domain_name (~> 0.5) domain_name (~> 0.5)
httpclient (2.8.3) httpclient (2.8.3)
jmespath (1.6.2) jmespath (1.6.2)
json (2.6.3) json (2.7.1)
jwt (2.7.1) jwt (2.7.1)
mini_magick (4.12.0) mini_magick (4.12.0)
mini_mime (1.1.5) mini_mime (1.1.5)

View File

@@ -596,6 +596,8 @@ final class AVPlayerBackend: PlayerBackend {
if self.controlsUpdates { if self.controlsUpdates {
self.updateControls() self.updateControls()
} }
self.model.updateTime(self.currentTime!)
} }
} }

View File

@@ -182,13 +182,21 @@ final class MPVBackend: PlayerBackend {
} }
init() { init() {
// swiftlint:disable shorthand_optional_binding
clientTimer = .init(interval: .seconds(Self.timeUpdateInterval), mode: .infinite) { [weak self] _ in 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 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 typealias AreInIncreasingOrder = (Stream, Stream) -> Bool
@@ -432,6 +440,8 @@ final class MPVBackend: PlayerBackend {
timeObserverThrottle.execute { timeObserverThrottle.execute {
self.model.updateWatch(time: self.currentTime) self.model.updateWatch(time: self.currentTime)
} }
self.model.updateTime(self.currentTime!)
} }
private func stopClientUpdates() { private func stopClientUpdates() {

View File

@@ -131,6 +131,8 @@ final class PlayerModel: ObservableObject {
@Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen @Default(.rotateToLandscapeOnEnterFullScreen) private var rotateToLandscapeOnEnterFullScreen
#endif #endif
@Published var currentChapterIndex: Int?
var accounts: AccountsModel { .shared } var accounts: AccountsModel { .shared }
var comments: CommentsModel { .shared } var comments: CommentsModel { .shared }
var controls: PlayerControlsModel { .shared } var controls: PlayerControlsModel { .shared }
@@ -1112,4 +1114,36 @@ final class PlayerModel: ObservableObject {
onPlayStream.forEach { $0(stream) } onPlayStream.forEach { $0(stream) }
onPlayStream.removeAll() 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
}
} }

View File

@@ -364,6 +364,7 @@ struct ChannelVideosView: View {
} }
} label: { } label: {
Label("Unsubscribe", systemImage: "xmark.circle") Label("Unsubscribe", systemImage: "xmark.circle")
.help("Unsubscribe")
#if os(iOS) #if os(iOS)
.labelStyle(.automatic) .labelStyle(.automatic)
#else #else
@@ -380,6 +381,7 @@ struct ChannelVideosView: View {
} }
} label: { } label: {
Label("Subscribe", systemImage: "circle") Label("Subscribe", systemImage: "circle")
.help("Subscribe")
#if os(iOS) #if os(iOS)
.labelStyle(.automatic) .labelStyle(.automatic)
#else #else
@@ -413,6 +415,7 @@ struct ChannelVideosView: View {
feed.markChannelAsWatched(channel.id) feed.markChannelAsWatched(channel.id)
} label: { } label: {
Label("Mark channel feed as watched", systemImage: "checkmark.circle.fill") Label("Mark channel feed as watched", systemImage: "checkmark.circle.fill")
.help("Mark channel feed as watched")
} }
.disabled(!feed.canMarkAllFeedAsWatched) .disabled(!feed.canMarkAllFeedAsWatched)
} }
@@ -423,6 +426,7 @@ struct ChannelVideosView: View {
feed.markChannelAsUnwatched(channel.id) feed.markChannelAsUnwatched(channel.id)
} label: { } label: {
Label("Mark channel feed as unwatched", systemImage: "checkmark.circle") Label("Mark channel feed as unwatched", systemImage: "checkmark.circle")
.help("Mark channel feed as unwatched")
} }
} }

View File

@@ -265,6 +265,7 @@ extension Defaults.Keys {
static let hideWatched = Key<Bool>("hideWatched", default: false) static let hideWatched = Key<Bool>("hideWatched", default: false)
static let showInspector = Key<ShowInspectorSetting>("showInspector", default: .onlyLocal) static let showInspector = Key<ShowInspectorSetting>("showInspector", default: .onlyLocal)
static let showChapters = Key<Bool>("showChapters", default: true) 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 showRelated = Key<Bool>("showRelated", default: true)
static let widgetsSettings = Key<[WidgetSettings]>("widgetsSettings", default: []) static let widgetsSettings = Key<[WidgetSettings]>("widgetsSettings", default: [])
} }

View File

@@ -30,7 +30,6 @@ struct AccountViewButton: View {
if accountPickerDisplaysUsername { if accountPickerDisplaysUsername {
label label
.labelStyle(.titleOnly)
} }
} }
} }
@@ -47,6 +46,6 @@ struct AccountViewButton: View {
} }
private var label: some View { private var label: some View {
Label(model.current?.description ?? "Select Account", systemImage: "globe") Text(model.current?.description ?? "Select Account")
} }
} }

View File

@@ -2,28 +2,85 @@ import Foundation
import SDWebImageSwiftUI import SDWebImageSwiftUI
import SwiftUI import SwiftUI
struct ChapterView: View { #if !os(tvOS)
var chapter: Chapter struct ChapterView: View {
var chapter: Chapter
var player = PlayerModel.shared var chapterIndex: Int
@ObservedObject private var player = PlayerModel.shared
var body: some View { var isCurrentChapter: Bool {
Button { player.currentChapterIndex == chapterIndex
player.backend.seek(to: chapter.start, seekType: .userInteracted) }
} label: {
Group { var body: some View {
#if os(tvOS) Button(action: {
horizontalChapter player.backend.seek(to: chapter.start, seekType: .userInteracted)
#else }) {
verticalChapter Group {
#endif verticalChapter
} }
.contentShape(Rectangle()) .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 { var horizontalChapter: some View {
HStack(spacing: 12) { HStack(spacing: 12) {
@@ -41,53 +98,36 @@ struct ChapterView: View {
} }
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
} }
#else
var verticalChapter: some View { @ViewBuilder func smallImage(_ chapter: Chapter) -> some View {
VStack(spacing: 12) { WebImage(url: chapter.image, options: [.lowPriority])
if !chapter.image.isNil { .resizable()
smallImage(chapter) .placeholder {
ProgressView()
} }
VStack(alignment: .leading, spacing: 4) { .indicator(.activity)
Text(chapter.title) .frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight)
.lineLimit(2) .mask(RoundedRectangle(cornerRadius: 12))
.multilineTextAlignment(.leading)
.font(.headline)
Text(chapter.start.formattedAsPlaybackTime(allowZero: true) ?? "")
.font(.system(.subheadline).monospacedDigit())
.foregroundColor(.secondary)
}
.frame(maxWidth: Self.thumbnailWidth, alignment: .leading)
}
} }
#endif
@ViewBuilder func smallImage(_ chapter: Chapter) -> some View { static var thumbnailWidth: Double {
WebImage(url: chapter.image, options: [.lowPriority]) 250
.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 { static var thumbnailHeight: Double {
250 thumbnailWidth / 1.7777
}
} }
#endif
static var thumbnailHeight: Double {
thumbnailWidth / 1.7777
}
}
struct ChapterView_Preview: PreviewProvider { struct ChapterView_Preview: PreviewProvider {
static var previews: some View { static var previews: some View {
ChapterView(chapter: .init(title: "Chapter", start: 30)) #if os(tvOS)
.injectFixtureEnvironmentObjects() ChapterViewTVOS(chapter: .init(title: "Chapter", start: 30))
.injectFixtureEnvironmentObjects()
#else
ChapterView(chapter: .init(title: "Chapter", start: 30), chapterIndex: 0)
.injectFixtureEnvironmentObjects()
#endif
} }
} }

View File

@@ -4,6 +4,7 @@ import SwiftUI
struct ChaptersView: View { struct ChaptersView: View {
@ObservedObject private var player = PlayerModel.shared @ObservedObject private var player = PlayerModel.shared
@Binding var expand: Bool
var chapters: [Chapter] { var chapters: [Chapter] {
player.videoForDisplay?.chapters ?? [] player.videoForDisplay?.chapters ?? []
@@ -15,45 +16,71 @@ struct ChaptersView: View {
var body: some View { var body: some View {
if !chapters.isEmpty { if !chapters.isEmpty {
#if os(tvOS) if chaptersHaveImages {
List { #if os(tvOS)
Section { List {
ForEach(chapters) { chapter in Section {
ChapterView(chapter: chapter)
}
}
.listRowBackground(Color.clear)
}
.listStyle(.plain)
#else
if chaptersHaveImages {
ScrollView(.horizontal) {
LazyHStack(spacing: 20) {
ForEach(chapters) { chapter in ForEach(chapters) { chapter in
ChapterView(chapter: chapter) ChapterViewTVOS(chapter: chapter)
} }
} }
.padding(.horizontal, 15) .listRowBackground(Color.clear)
} }
.frame(minHeight: ChapterView.thumbnailHeight + 100) .listStyle(.plain)
} else { #else
ScrollView(.horizontal) {
LazyHStack(spacing: 20) { chapterViews(for: chapters[...]) }.padding(.horizontal, 15)
}
#endif
} else if expand {
#if os(tvOS)
Section { Section {
ForEach(chapters) { chapter in ForEach(chapters) { chapter in
ChapterView(chapter: chapter) ChapterViewTVOS(chapter: chapter)
} }
} }
.padding(.horizontal) #else
} Section { chapterViews(for: chapters[...]) }.padding(.horizontal)
#endif #endif
} else { } else {
NoCommentsView(text: "No chapters information available".localized(), systemImage: "xmark.circle.fill") #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 { struct ChaptersView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
ChaptersView() ChaptersView(expand: .constant(false))
.injectFixtureEnvironmentObjects() .injectFixtureEnvironmentObjects()
} }
} }

View File

@@ -56,27 +56,24 @@ struct VideoDescription: View {
} }
} }
var shouldExpand: Bool {
expand
}
@ViewBuilder var textDescription: some View { @ViewBuilder var textDescription: some View {
#if canImport(AppKit) #if canImport(AppKit)
Group { Group {
if #available(macOS 12, *) { if #available(macOS 12, *) {
DescriptionWithLinks(description: description, detailsSize: detailsSize) DescriptionWithLinks(description: description, detailsSize: detailsSize)
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : collapsedLinesDescription) .lineLimit(expand ? 500 : collapsedLinesDescription)
.textSelection(.enabled) .textSelection(.enabled)
} else { } else {
Text(description) Text(description)
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : collapsedLinesDescription) .lineLimit(expand ? 500 : collapsedLinesDescription)
} }
} }
.multilineTextAlignment(.leading) .multilineTextAlignment(.leading)
.font(.system(size: 14)) .font(.system(size: 14))
.lineSpacing(3) .lineSpacing(3)
.allowsHitTesting(expand)
#endif #endif
} }

View File

@@ -169,6 +169,7 @@ struct VideoDetails: View {
@State private var subscriptionToggleButtonDisabled = false @State private var subscriptionToggleButtonDisabled = false
@State private var page = DetailsPage.info @State private var page = DetailsPage.info
@State private var descriptionExpanded = false @State private var descriptionExpanded = false
@State private var chaptersExpanded = false
@Environment(\.navigationStyle) private var navigationStyle @Environment(\.navigationStyle) private var navigationStyle
#if os(iOS) #if os(iOS)
@@ -190,6 +191,7 @@ struct VideoDetails: View {
@Default(.showScrollToTopInComments) private var showScrollToTopInComments @Default(.showScrollToTopInComments) private var showScrollToTopInComments
#endif #endif
@Default(.expandVideoDescription) private var expandVideoDescription @Default(.expandVideoDescription) private var expandVideoDescription
@Default(.expandChapters) private var expandChapters
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 0) { VStack(alignment: .leading, spacing: 0) {
@@ -245,6 +247,7 @@ struct VideoDetails: View {
.background(colorScheme == .dark ? Color.black : .white) .background(colorScheme == .dark ? Color.black : .white)
.onAppear { .onAppear {
descriptionExpanded = expandVideoDescription descriptionExpanded = expandVideoDescription
chaptersExpanded = expandChapters
} }
} }
@@ -320,7 +323,7 @@ struct VideoDetails: View {
!video.chapters.isEmpty !video.chapters.isEmpty
{ {
Section(header: chaptersHeader) { Section(header: chaptersHeader) {
ChaptersView() ChaptersView(expand: $chaptersExpanded)
} }
} }
@@ -440,11 +443,48 @@ struct VideoDetails: View {
#endif #endif
} }
var chaptersHaveImages: Bool {
player.videoForDisplay?.chapters.allSatisfy { $0.image != nil } ?? false
}
var chaptersHeader: some View { var chaptersHeader: some View {
Text("Chapters".localized()) Group {
.padding(.horizontal) if !chaptersHaveImages {
.font(.caption) #if canImport(UIKit)
.foregroundColor(.secondary) 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)
}
}
} }
} }

View File

@@ -32,6 +32,7 @@ struct PlayerSettings: View {
@Default(.showInspector) private var showInspector @Default(.showInspector) private var showInspector
@Default(.showChapters) private var showChapters @Default(.showChapters) private var showChapters
@Default(.expandChapters) private var expandChapters
@Default(.showRelated) private var showRelated @Default(.showRelated) private var showRelated
@ObservedObject private var accounts = AccountsModel.shared @ObservedObject private var accounts = AccountsModel.shared
@@ -80,6 +81,7 @@ struct PlayerSettings: View {
expandVideoDescriptionToggle expandVideoDescriptionToggle
collapsedLineDescriptionStepper collapsedLineDescriptionStepper
showChaptersToggle showChaptersToggle
expandChaptersToggle
showRelatedToggle showRelatedToggle
#if os(macOS) #if os(macOS)
HStack { HStack {
@@ -282,7 +284,13 @@ struct PlayerSettings: View {
} }
private var showChaptersToggle: some View { private var showChaptersToggle: some View {
Toggle("Chapters", isOn: $showChapters) 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 { private var showRelatedToggle: some View {

View File

@@ -0,0 +1,4 @@
" subscribers" = " المشتركين";
"%@ Channel" = "القناة";

View File

@@ -598,3 +598,7 @@
"Podcasts" = "Podcasts"; "Podcasts" = "Podcasts";
"Releases" = "Releases"; "Releases" = "Releases";
"Add %@" = "Add %@"; "Add %@" = "Add %@";
"Description preview" = "Description preview";
"No preview" = "No preview";
"Open vertical chapters expanded" = "Open vertical chapters expanded";
"Chapters (if available)" = "Chapters (if available)";

View File

@@ -600,3 +600,5 @@
"Add %@" = "Añada %@"; "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"; "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"; "Play Now in AVPlayer" = "Reproducir ahora en AVPlayer";
"Description preview" = "Vista previa de la descripción";
"No preview" = "Sin vista previa";

View 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" = "پخش زنده";

View File

@@ -600,3 +600,5 @@
"Podcasts" = "Podcasts"; "Podcasts" = "Podcasts";
"Releases" = "Sorties"; "Releases" = "Sorties";
"Add %@" = "Ajouter %@"; "Add %@" = "Ajouter %@";
"Description preview" = "Aperçu de la description";
"No preview" = "Aucun aperçu";

View File

@@ -1,19 +1,19 @@
"%@ Channel" = "%@ चैनल"; "%@ Channel" = "%@ चैनल";
"%@ Playlist" = "%@ प्लेलिस्ट"; "%@ Playlist" = "%@ गीतमाला";
"%@ subscribers" = "%@ सदस्य"; "%@ subscribers" = "%@ सदस्य";
"%lld videos" = "%lld वीडियो"; "%lld videos" = "%lld वीडियो";
" subscribers" = " सदस्य"; " subscribers" = " सदस्य";
"10 seconds forwards/backwards" = "10 पल आगे/पीछे"; "10 seconds forwards/backwards" = "10 सेकंड आगे/पीछे";
"Accounts" = "खाते"; "Accounts" = "खाते";
"Accounts are not supported for the application of this instance" = "इस इन्सटेंस के लिए खातों उपलब्ध नहीं हैं"; "Accounts are not supported for the application of this instance" = "इस इन्सटेंस के लिए खात उपलब्ध नहीं हैं";
"Add to Playlist..." = "गीतमाला में जोड़ें…"; "Add to Playlist..." = "गीतमाला में जोड़ें…";
"Advanced" = "उन्नत"; "Advanced" = "उन्नत";
/* Trending category, section containing all kinds of videos */ /* Trending category, section containing all kinds of videos */
"All" = "सभी"; "All" = "सभी";
"Always use AVPlayer for live videos" = "लाइव वीडियो के लिए सदा ए.वी. प्लेयर का उपयोग करें"; "Always use AVPlayer for live videos" = "लाइव वीडियो के लिए सदा AVPlayer का उपयोग करें";
"Anonymous" = "गुप्त"; "Anonymous" = "गुप्त";
/* Video date filter in search /* Video date filter in search
@@ -24,16 +24,16 @@
"Are you sure you want to clear search history?" = "क्या आप निश्चित रूप से खोज का इतिहास मिटाना चाहते हैं?"; "Are you sure you want to clear search history?" = "क्या आप निश्चित रूप से खोज का इतिहास मिटाना चाहते हैं?";
"Close PiP and open player when application enters foreground" = "PiP बंद करें और प्लेयर खोलें जब ऐप्लिकेशन मुख्यभूमी में जाता है"; "Close PiP and open player when application enters foreground" = "PiP बंद करें और प्लेयर खोलें जब ऐप्लिकेशन मुख्यभूमी में जाता है";
"Close PiP when player is opened" = "PiP बंद करें जब प्लेयर खुले"; "Close PiP when player is opened" = "PiP बंद करें जब प्लेयर खुले";
"Close PiP when starting playing other video" = "PiP बंद करें जब दूसरा वीडियो प्ले हो"; "Close PiP when starting playing other video" = "PiP बंद करें जब दूसरा वीडियो चालू हो";
"Close player when closing video" = "प्लेयर बंद करें जब वीडियो बंद हो"; "Close player when closing video" = "जब वीडियो बंद हो तब प्लेयर बंद करें";
"Close player when starting PiP" = "प्लेयर बंद करें जब PiP चालू हो"; "Close player when starting PiP" = "जब PiP चालू हो रहा हो तब प्लेयर बंद करें";
"Close Video" = "वीडियो बंद करें"; "Close Video" = "वीडियो बंद करें";
"Close video after playing last in the queue" = "कतार में आख़िरी समाप्त होने के पश्चात वीडियो बंद करें"; "Close video after playing last in the queue" = "अंतिम पंक्तिबद्ध समाप्त होने के पश्चात वीडियो बंद करें";
"Comments" = "टिप्पणियाँ"; "Comments" = "टिप्पणियाँ";
"Connected successfully (%@)" = "जुड़ाव सफल"; "Connected successfully (%@)" = "जुड़ाव सफल (%@)";
"Connection failed" = "जुड़ाव असफल"; "Connection failed" = "जुड़ाव असफल";
"Contact" = "संपर्क"; "Contact" = "संपर्क";
"Continue" = "जारी"; "Continue" = "जारी रखें";
"Disabled" = "निर्योग्य"; "Disabled" = "निर्योग्य";
"Discord Server" = "डिस्कॉर्ड सर्वर"; "Discord Server" = "डिस्कॉर्ड सर्वर";
"Discussions take place in Discord and Matrix. It's a good spot for general questions." = "चर्चाएँ डिस्कॉर्ड एवं मेट्रिक्स पर होतीं हैं। यह सामान्य प्रश्नों के लिए अच्छा मंच है।"; "Discussions take place in Discord and Matrix. It's a good spot for general questions." = "चर्चाएँ डिस्कॉर्ड एवं मेट्रिक्स पर होतीं हैं। यह सामान्य प्रश्नों के लिए अच्छा मंच है।";
@@ -154,18 +154,18 @@
"Play Now" = "अभी चलाएँ"; "Play Now" = "अभी चलाएँ";
"Playback" = "प्लेबैक"; "Playback" = "प्लेबैक";
"Player" = "प्लेयर"; "Player" = "प्लेयर";
"Playlist" = "प्लेलिस्ट"; "Playlist" = "गीतमाला";
"Decreased opacity" = "पारदर्शिता घटी"; "Decreased opacity" = "पारदर्शिता घटी";
"Continue from %@" = "%@ से जारी रें"; "Continue from %@" = "%@ से जारी रें";
"Current: %@\n%@" = "वर्तमान: %@\n%@"; "Current: %@\n%@" = "वर्तमान: %@\n%@";
"Contributing" = "योगदान दें"; "Contributing" = "योगदान";
"Controls" = "नियंत्रक"; "Controls" = "नियंत्रक";
"Copy %@ link" = "%@ लिंक नक़ल करें"; "Copy %@ link" = "%@ लिंक कॉपी करें";
"Country" = "देश"; "Country" = "देश";
"Country Name or Code" = "देश नाम एवं कोड"; "Country Name or Code" = "देश का नाम एवं कोड";
"Could not load locations manifest" = "लोकेशन मैनिफ़ेस्ट लोड नहीं हो पाई"; "Could not load locations manifest" = "लोकेशन मैनिफ़ेस्ट लोड नहीं हो सका";
"Custom Locations" = "कस्टम स्थान"; "Custom Locations" = "कस्टम स्थान";
"Copy %@ link with time" = "%@ लिंक समय के साथ नक़ल करें"; "Copy %@ link with time" = "%@ लिंक समय के साथ कॉपी करें";
"Add Account" = "खाता जोड़ें"; "Add Account" = "खाता जोड़ें";
"Add Account..." = "खाता जोड़ें…"; "Add Account..." = "खाता जोड़ें…";
"Add Location" = "स्थान जोड़ें"; "Add Location" = "स्थान जोड़ें";
@@ -177,35 +177,35 @@
"Add to %@" = "%@ में जोड़ें"; "Add to %@" = "%@ में जोड़ें";
"Badge color" = "बिल्ले का रंग"; "Badge color" = "बिल्ले का रंग";
"Category" = "श्रेणी"; "Category" = "श्रेणी";
"Clear Search History..." = "खोज इतिहास साफ़ करें…"; "Clear Search History..." = "खोज इतिहास हटायें…";
"Are you sure you want to restore default quality profiles?" = "क्या आप निश्चित रूप से डीफ़ॉल्ट गुणवत्ता प्रोफ़ाइल को पुनः प्राप्त करना चाहते हैं?"; "Are you sure you want to restore default quality profiles?" = "क्या आप निश्चित रूप से डीफ़ॉल्ट गुणवत्ता प्रोफ़ाइल को पुनः प्राप्त करना चाहते हैं?";
"Based on system color scheme" = "मूल तंत्र रंग प्रणाली पर निर्भर"; "Based on system color scheme" = "सिस्टम के रंग प्रणाली पर निर्भर";
"Categories to Skip" = "श्रेणियाँ जिन्हें छोड़ें"; "Categories to Skip" = "श्रेणियाँ जिन्हें छोड़ें";
"Chapters" = "अध्यायें"; "Chapters" = "अध्याय";
"Are you sure you want to delete playlist?" = "क्या आप निश्चित रूप से इस गीतमाला को मिटाना चाहते हैं?"; "Are you sure you want to delete playlist?" = "क्या आप निश्चित रूप से इस गीतमाला को मिटाना चाहते हैं?";
"Are you sure you want to unsubscribe from %@?" = "क्या आप निश्चित रूप से %@ की सदस्यता छोड़ना चाहते हैं?"; "Are you sure you want to unsubscribe from %@?" = "क्या आप निश्चित रूप से %@ की सदस्यता छोड़ना चाहते हैं?";
"Automatic" = "स्वत"; "Automatic" = "स्वचालित";
"Autoplaying Next" = "अगला ऑटोप्ले हो रहा"; "Autoplaying Next" = "अगला स्वतः चालू हो रहा";
"Badge" = "बिल्ला"; "Badge" = "बिल्ला";
"Blue" = "नीला"; "Blue" = "नीला";
"Browsing" = "ब्राउज़ करना"; "Browsing" = "ब्राउज़ करना";
"Buffering stream..." = "स्ट्रीम बफ़र हो रहा…"; "Buffering stream..." = "स्ट्रीम बफ़र हो रहा…";
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "आप बग एवं फ़ीचर सुझाव गिटहब के इशु ट्रैकर पर भेज सकते हैं "; "Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "आप बग एवं फ़ीचर सुझाव गिटहब के इशु ट्रैकर पर भेज सकते हैं ";
"Cancel" = "रद्द"; "Cancel" = "रद्द";
"Captions" = "कैप्शन"; "Captions" = "अनुशीर्षक";
"Charging" = "चार्ज हो रहा"; "Charging" = "चार्ज हो रहा है";
"Clear" = "साफ़"; "Clear" = "हटायें";
"Clear All" = "सभी साफ़"; "Clear All" = "सभी हटायें";
"Clear All Recents" = "सभी हालिया साफ़ करें"; "Clear All Recents" = "सभी हालिया हटायें";
"Clear History" = "इतिहास साफ़ करें"; "Clear History" = "इतिहास हटायें";
"Clear Search History" = "खोज इतिहास साफ़ करें"; "Clear Search History" = "खोज इतिहास हटायें";
"Clear the queue" = "क़तार साफ़ करें"; "Clear the queue" = "पंक्तिबद्ध हटायें";
"Close" = "बंद"; "Close" = "बंद";
"Backend" = "बैकऐंड"; "Backend" = "पृष्ठभाग";
"Badge & Decreased opacity" = "बिल्ला एवं पारदर्शिता में कमी"; "Badge & Decreased opacity" = "बिल्ला एवं पारदर्शिता में कमी";
"Battery" = "बैटरी"; "Battery" = "बैटरी";
"Button" = "बटन"; "Button" = "बटन";
"Cellular" = "मोबाइल डाटा"; "Cellular" = "मोबाइल";
"Create Playlist" = "गीतमाला बनाएँ"; "Create Playlist" = "गीतमाला बनाएँ";
/* Player controls layout size */ /* Player controls layout size */
@@ -267,7 +267,7 @@
"Statistics" = "आँकड़े"; "Statistics" = "आँकड़े";
"Hardware decoder" = "हार्डवेयर डीकोडर"; "Hardware decoder" = "हार्डवेयर डीकोडर";
"Stream FPS" = "स्ट्रीम FPS"; "Stream FPS" = "स्ट्रीम FPS";
"Playlists" = "प्लेलिस्ट"; "Playlists" = "गीतमाला";
"Popular" = "लोकप्रिय"; "Popular" = "लोकप्रिय";
"Preferred Formats" = "पसंदीदा प्रारूप"; "Preferred Formats" = "पसंदीदा प्रारूप";
"Profiles" = "प्रोफ़ाइल"; "Profiles" = "प्रोफ़ाइल";
@@ -415,7 +415,7 @@
"Locations Manifest" = ""; "Locations Manifest" = "";
"Could not delete document" = ""; "Could not delete document" = "";
"Show Inspector" = ""; "Show Inspector" = "";
"Could not load streams" = ""; "Could not load streams" = "स्ट्रीम्स नहीं खोला जा सका";
"Address" = ""; "Address" = "";
"Playback Mode" = ""; "Playback Mode" = "";
"Left" = ""; "Left" = "";
@@ -447,17 +447,17 @@
"Verified" = ""; "Verified" = "";
"No documents" = ""; "No documents" = "";
"Show Open Videos toolbar button" = ""; "Show Open Videos toolbar button" = "";
"Could not refresh Subscriptions" = ""; "Could not refresh Subscriptions" = "सदस्यता पुनर्स्थापित नहीं किया जा सका";
"Remove Location" = ""; "Remove Location" = "";
"Only for local files and URLs" = ""; "Only for local files and URLs" = "";
"Codec" = ""; "Codec" = "";
"File" = ""; "File" = "";
"Could not extract playlist ID" = ""; "Could not extract playlist ID" = "";
"Paste" = ""; "Paste" = "";
"Could not extract SID from received cookies: %@" = ""; "Could not extract SID from received cookies: %@" = "प्राप्त कुकीज़ से SID नहीं निकाला जा सका: %@";
"Files" = ""; "Files" = "";
"Show Home" = ""; "Show Home" = "";
"Could not extract channel information" = ""; "Could not extract channel information" = "चैनल की जानकारी नहीं निकाली जा सकी";
"Enter link to open" = ""; "Enter link to open" = "";
"Home" = ""; "Home" = "";
"No locations available at the moment" = ""; "No locations available at the moment" = "";
@@ -469,7 +469,7 @@
"Format" = ""; "Format" = "";
"Share files from Finder on a Mac\nor iTunes on Windows" = ""; "Share files from Finder on a Mac\nor iTunes on Windows" = "";
"Share%@link" = ""; "Share%@link" = "";
"Could not open video" = ""; "Could not open video" = "वीडियो नहीं खोला जा सका";
"Center" = ""; "Center" = "";
"Size" = ""; "Size" = "";
"Recent Documents" = ""; "Recent Documents" = "";
@@ -484,14 +484,14 @@
"Could not create share link" = ""; "Could not create share link" = "";
"Sample Rate" = ""; "Sample Rate" = "";
"Translations" = ""; "Translations" = "";
"Open logs in Finder" = ""; "Open logs in Finder" = "लॉग को Finder में खोलें";
"Could not refresh Playlists" = ""; "Could not refresh Playlists" = "";
"Could not update your token." = ""; "Could not update your token." = "आपका टोकन अपडेट नहीं हो सका।";
"Could not refresh Trending" = ""; "Could not refresh Trending" = "ट्रेंडिंग को पुनर्स्थापित नहीं किया जा सका";
"Could not open playlist" = ""; "Could not open playlist" = "";
"This URL could not be opened" = ""; "This URL could not be opened" = "इस URL को नहीं खोला जा सका";
"Could not open channel" = ""; "Could not open channel" = "चैनल नहीं खुल सका";
"Channel could not be found" = ""; "Channel could not be found" = "चैनल नहीं मिला";
"Could not refresh Popular" = ""; "Could not refresh Popular" = "";
"Could not extract video ID" = ""; "Could not extract video ID" = "";
"Channel" = ""; "Channel" = "";
@@ -501,4 +501,4 @@
"Pages toolbar position" = ""; "Pages toolbar position" = "";
"Default Profile" = ""; "Default Profile" = "";
"Copy%@link" = ""; "Copy%@link" = "";
"Share Logs..." = ""; "Share Logs..." = "लॉग साझा करें…";

View File

@@ -600,3 +600,5 @@
"Podcasts" = "ポッドキャスト"; "Podcasts" = "ポッドキャスト";
"Releases" = "リリース"; "Releases" = "リリース";
"Add %@" = "追加 %@"; "Add %@" = "追加 %@";
"Description preview" = "説明のプレビュー";
"No preview" = "プレビューなし";

View File

@@ -601,3 +601,7 @@
"Podcasts" = "Podkasty"; "Podcasts" = "Podkasty";
"Releases" = "Wydania"; "Releases" = "Wydania";
"Add %@" = "Dodaj %@"; "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)";

View File

@@ -600,3 +600,5 @@
"Podcasts" = "Podcasts"; "Podcasts" = "Podcasts";
"Releases" = "Lançamentos"; "Releases" = "Lançamentos";
"Add %@" = "Adicionar %@"; "Add %@" = "Adicionar %@";
"Description preview" = "Descrição da prévia";
"No preview" = "Sem prévia";

View File

@@ -294,15 +294,15 @@
"Hide" = ""; "Hide" = "";
"Playing Next" = ""; "Playing Next" = "";
"Are you sure you want to remove this document?" = ""; "Are you sure you want to remove this document?" = "";
"Show channel name" = ""; "Show channel name" = "Kanal adını göster";
"Unlisted" = ""; "Unlisted" = "";
"Paste" = ""; "Paste" = "";
"Rate & Captions" = ""; "Rate & Captions" = "";
"Format" = ""; "Format" = "";
"Right" = ""; "Right" = "Sağ";
"Stream FPS" = ""; "Stream FPS" = "";
"Cached time" = ""; "Cached time" = "";
"Sign In Required" = ""; "Sign In Required" = "Giriş yapmanız gerekiyor";
"Could not create share link" = ""; "Could not create share link" = "";
"Locations Manifest" = ""; "Locations Manifest" = "";
"When partially watched video is played" = ""; "When partially watched video is played" = "";
@@ -323,19 +323,19 @@
"Show Documents" = ""; "Show Documents" = "";
"Press and hold remote button to open captions and quality menus" = ""; "Press and hold remote button to open captions and quality menus" = "";
"No locations available at the moment" = ""; "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" = ""; "Used to create links from videos, channels and playlists" = "";
"Size" = ""; "Size" = "";
"You have no playlists\n\nTap on \"New Playlist\" to create one" = ""; "You have no playlists\n\nTap on \"New Playlist\" to create one" = "";
"Sort: %@" = ""; "Sort: %@" = "Sırala: %@";
"Select location closest to you:" = ""; "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\"" = ""; "Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "";
/* Video duration filter in search */ /* Video duration filter in search */
"Short" = ""; "Short" = "Kısa";
"Home" = ""; "Home" = "";
"Remove Location" = ""; "Remove Location" = "";
"Edit Favorites…" = ""; "Edit Favorites…" = "Favorileri düzenle…";
"Show Open Videos toolbar button" = ""; "Show Open Videos toolbar button" = "";
"Sample Rate" = ""; "Sample Rate" = "";
"Private" = ""; "Private" = "";
@@ -365,14 +365,14 @@
"Subscriptions" = ""; "Subscriptions" = "";
"Upload date" = ""; "Upload date" = "";
"This information will be processed only on your device and used to connect you to the server in the specified country." = ""; "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" = ""; "Buttons labels" = "";
"Share %@ link" = ""; "Share %@ link" = "%@ bağlantısını paylaş";
"Could not load streams" = ""; "Could not load streams" = "";
"Playback history is empty" = ""; "Playback history is empty" = "";
"Show icons and text when space permits" = ""; "Show icons and text when space permits" = "";
"unknown" = ""; "unknown" = "";
"Share..." = ""; "Share..." = "Paylaş...";
/* Video sort order in search */ /* Video sort order in search */
"Views" = ""; "Views" = "";
@@ -382,7 +382,7 @@
"Could not refresh Playlists" = ""; "Could not refresh Playlists" = "";
"Actions buttons" = ""; "Actions buttons" = "";
"Any format" = ""; "Any format" = "";
"Show playback statistics" = ""; "Show playback statistics" = "Oynatma istatistiklerini göster";
"Pages buttons" = ""; "Pages buttons" = "";
"Videos" = ""; "Videos" = "";
"Codec" = ""; "Codec" = "";
@@ -396,7 +396,7 @@
"Open" = ""; "Open" = "";
/* Loading stream OSD */ /* Loading stream OSD */
"Opening %@ stream..." = ""; "Opening %@ stream..." = "%@ akışıılıyor...";
"Clear Queue before opening" = ""; "Clear Queue before opening" = "";
"Copy %@ link with time" = "Bağlantıyı %@ zaman ile kopyala"; "Copy %@ link with time" = "Bağlantıyı %@ zaman ile kopyala";
"Show Inspector" = ""; "Show Inspector" = "";
@@ -412,15 +412,15 @@
/* Video date filter in search */ /* Video date filter in search */
"Week" = ""; "Week" = "";
"Sidebar" = ""; "Sidebar" = "Kenar çubuğu";
"Show only icons" = ""; "Show only icons" = "";
"Current: %@\n%@" = "Şuan: %@\n%@"; "Current: %@\n%@" = "Şuan: %@\n%@";
"Show anonymous accounts" = ""; "Show anonymous accounts" = "Anonim hesapları göster";
"Could not open playlist" = ""; "Could not open playlist" = "";
"Round corners" = ""; "Round corners" = "";
"URL" = ""; "URL" = "";
"Recents" = ""; "Recents" = "";
"Show sidebar when space permits" = ""; "Show sidebar when space permits" = "Alan olduğu sürece kenar çubuğunu göster";
"System controls buttons" = ""; "System controls buttons" = "";
"Could not extract channel information" = ""; "Could not extract channel information" = "";
"Public Locations" = ""; "Public Locations" = "";
@@ -431,22 +431,22 @@
"Continue from %@" = "% devam et"; "Continue from %@" = "% devam et";
"Copy %@ link" = "Bağlantıyı %@ kopyala"; "Copy %@ link" = "Bağlantıyı %@ kopyala";
"Seek gesture sensitivity" = ""; "Seek gesture sensitivity" = "";
"Show keywords" = ""; "Show keywords" = "Anahtar kelimeleri göster";
"Wiki" = ""; "Wiki" = "";
"Username" = ""; "Username" = "";
"Could not extract video ID" = ""; "Could not extract video ID" = "";
/* Player controls layout size */ /* Player controls layout size */
"Smaller" = ""; "Smaller" = "Küçült";
"Sort" = ""; "Sort" = "Sırala";
"This cannot be reverted" = ""; "This cannot be reverted" = "";
"Public Manifest" = ""; "Public Manifest" = "";
"You have no Playlists" = ""; "You have no Playlists" = "";
"Watched" = ""; "Watched" = "";
"Could not open video" = ""; "Could not open video" = "";
"Channel could not be found" = ""; "Channel could not be found" = "";
"Show video length" = ""; "Show video length" = "Video uzunluğunu göster";
"Source" = ""; "Source" = "Kaynak";
"Welcome" = ""; "Welcome" = "";
"Wi-Fi" = ""; "Wi-Fi" = "";
"Could not open channel" = ""; "Could not open channel" = "";
@@ -454,13 +454,13 @@
"Could not extract playlist ID" = ""; "Could not extract playlist ID" = "";
"Could not load video" = ""; "Could not load video" = "";
"Decreased opacity" = "Düşük şeffaflık"; "Decreased opacity" = "Düşük şeffaflık";
"Shuffle All" = ""; "Shuffle All" = "Tümünü karıştır";
"Share %@ link with time" = ""; "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." = ""; "This cannot be reverted. You might need to switch between views or restart the app to see changes." = "";
"Unsubscribe" = ""; "Unsubscribe" = "";
"Current Location" = ""; "Current Location" = "";
"Stream & Player" = ""; "Stream & Player" = "";
"Hardware decoder" = ""; "Hardware decoder" = "Donanımsal çözücü";
"Honor orientation lock" = ""; "Honor orientation lock" = "";
"Seek with horizontal swipe on video" = ""; "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." = ""; "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" = ""; "Self-promotion" = "";
/* Player controls layout size */ /* Player controls layout size */
"Small" = ""; "Small" = "Küçük";
/* SponsorBlock category name */ /* SponsorBlock category name */
"Sponsor" = ""; "Sponsor" = "Sponsor";
"System controls show buttons for %@" = ""; "System controls show buttons for %@" = "";
"Show history" = ""; "Show history" = "Kullanım geçmişini göster";
"Could not extract SID from received cookies: %@" = ""; "Could not extract SID from received cookies: %@" = "";
"This will remove all your custom profiles and return their default values. This cannot be reverted." = ""; "This will remove all your custom profiles and return their default values. This cannot be reverted." = "";
"Switch to other public location" = ""; "Switch to other public location" = "";
@@ -502,3 +502,6 @@
"Share" = ""; "Share" = "";
"File" = ""; "File" = "";
"Share%@link" = ""; "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";

View File

@@ -1183,6 +1183,10 @@
376578902685490700D4EA09 /* PlaylistsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaylistsView.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 376A33DF2720CAD6000C1D6B /* VideosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosApp.swift; sourceTree = "<group>"; };
@@ -2606,6 +2610,10 @@
pt, pt,
"pt-BR", "pt-BR",
ja, ja,
fa,
es,
tr,
ru,
); );
mainGroup = 37D4B0BC2671614700C925CA; mainGroup = 37D4B0BC2671614700C925CA;
packageReferences = ( packageReferences = (
@@ -3787,6 +3795,10 @@
37E868FE29AA402D003128D0 /* pt */, 37E868FE29AA402D003128D0 /* pt */,
37E868FF29AA407B003128D0 /* pt-BR */, 37E868FF29AA407B003128D0 /* pt-BR */,
37ABD5FE29BE7FA800DDCAD7 /* ja */, 37ABD5FE29BE7FA800DDCAD7 /* ja */,
3767F3312B2504F800F257BC /* fa */,
3767F3322B25053B00F257BC /* es */,
3767F3332B25058300F257BC /* tr */,
3767F3342B2505EF00F257BC /* ru */,
); );
name = Localizable.strings; name = Localizable.strings;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -3801,7 +3813,7 @@
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements"; CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist"; INFOPLIST_FILE = "Open in Yattee/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee"; INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee";
@@ -3832,7 +3844,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist"; INFOPLIST_FILE = "Open in Yattee/Info.plist";
@@ -3863,7 +3875,7 @@
buildSettings = { buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
@@ -3883,7 +3895,7 @@
buildSettings = { buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
@@ -4047,7 +4059,7 @@
CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements"; CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1", "DEBUG=1",
@@ -4100,7 +4112,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1"; GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1";
@@ -4152,7 +4164,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
ENABLE_APP_SANDBOX = YES; ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -4191,7 +4203,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
"DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ; "DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ;
ENABLE_APP_SANDBOX = YES; ENABLE_APP_SANDBOX = YES;
@@ -4226,7 +4238,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@@ -4250,7 +4262,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@@ -4276,7 +4288,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@@ -4301,7 +4313,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@@ -4327,7 +4339,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -4367,7 +4379,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
"DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ; "DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -4408,7 +4420,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@@ -4432,7 +4444,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 170; CURRENT_PROJECT_VERSION = 171;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",

View File

@@ -105,7 +105,7 @@
"location" : "https://github.com/SDWebImage/SDWebImage", "location" : "https://github.com/SDWebImage/SDWebImage",
"state" : { "state" : {
"branch" : "master", "branch" : "master",
"revision" : "191b94cd545274603fcffce275dd4c1247587b6e" "revision" : "fbe79221b146aa6647dceb5a5c75873a48b69519"
} }
}, },
{ {
@@ -122,8 +122,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/SDWebImage/SDWebImageSwiftUI.git", "location" : "https://github.com/SDWebImage/SDWebImageSwiftUI.git",
"state" : { "state" : {
"revision" : "5f025e54a03d3d33dff24d7a19331f446f00ed9d", "revision" : "aee64ef39b570c44ccf0f884c440fc6494a23c76",
"version" : "2.2.4" "version" : "2.2.5"
} }
}, },
{ {

View File

@@ -86,9 +86,11 @@ public class OrientationTracker {
if accelerometerData.acceleration.y <= -threshold { if accelerometerData.acceleration.y <= -threshold {
return .portrait return .portrait
} }
if accelerometerData.acceleration.y >= threshold {
if UIDevice.current.userInterfaceIdiom == .pad && accelerometerData.acceleration.y >= threshold {
return .portraitUpsideDown return .portraitUpsideDown
} }
return currentDeviceOrientation return currentDeviceOrientation
} }
} }

View File

@@ -130,7 +130,7 @@ struct NowPlayingView: View {
} else { } else {
Section(header: Text("Chapters")) { Section(header: Text("Chapters")) {
ForEach(video.chapters) { chapter in ForEach(video.chapters) { chapter in
ChapterView(chapter: chapter) ChapterViewTVOS(chapter: chapter)
.padding(.horizontal, 40) .padding(.horizontal, 40)
} }
} }