Compare commits

...

49 Commits

Author SHA1 Message Date
Arkadiusz Fal
d1cf45c6a1 Bump build number to 181 2024-04-02 23:14:51 +02:00
Arkadiusz Fal
07f3d841b3 Update CHANGELOG 2024-04-02 23:14:18 +02:00
Arkadiusz Fal
b488f86160 Downgrade MPVKit to 0.36.0-1
commit dca1e345a26d09a3d621d7656a94e6427f3f7b83
2024-04-02 23:14:18 +02:00
Arkadiusz Fal
e64c3a3c77 Update packages 2024-04-02 23:14:17 +02:00
Arkadiusz Fal
576a993faf Merge pull request #631 from stonerl/comments-piped
hopefully fixes #629
2024-04-02 22:51:07 +02:00
Toni Förster
c77c5a6d21 don't add empty comments 2024-04-02 15:08:36 +02:00
Toni Förster
ae16680fc2 removed some unnecessary print() 2024-04-02 14:28:06 +02:00
Toni Förster
807c0a1e2e hopefully fixes #629
should also get rid of empty comments if they couldn't be loaded
2024-04-02 14:28:06 +02:00
Arkadiusz Fal
96a2119a05 Merge pull request #632 from stonerl/invidious-html-comments
iv: use html comments instead of plain text
2024-04-01 23:12:12 +02:00
Arkadiusz Fal
7e940d6304 Merge pull request #624 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2024-04-01 22:59:05 +02:00
mere
11402cc2a6 Translated using Weblate (Romanian)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ro/
2024-04-01 22:58:48 +02:00
floe nele
975d8b0ba0 Translated using Weblate (Dutch)
Currently translated at 44.3% (249 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/nl/
2024-04-01 22:58:48 +02:00
jonnysemon
e349898d9e Translated using Weblate (Arabic)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ar/
2024-04-01 22:58:48 +02:00
rexcsk
a8802da5a7 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/zh_Hant/
2024-04-01 22:58:48 +02:00
maboroshin
19993dfc04 Translated using Weblate (Japanese)
Currently translated at 98.3% (553 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ja/
2024-04-01 22:58:48 +02:00
joaooliva
e99dd442e1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/pt_BR/
2024-04-01 22:58:48 +02:00
gallegonovato
d886113f27 Translated using Weblate (Spanish)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/es/
2024-04-01 22:58:48 +02:00
Ophiushi
ea9b759887 Translated using Weblate (French)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/fr/
2024-04-01 22:58:48 +02:00
rexcsk
0e784be231 Translated using Weblate (Chinese (Traditional))
Currently translated at 99.6% (560 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/zh_Hant/
2024-04-01 22:58:48 +02:00
rexcsk
d0ab73eeb2 Translated using Weblate (English)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/en/
2024-04-01 22:58:48 +02:00
Arkadiusz Fal
2193129818 Merge pull request #622 from rickykresslein/limit-recents-shown
Show/hide recents and limit number of recents shown
2024-04-01 22:58:42 +02:00
Toni Förster
f84c6d319a iv: use html comments instead of plain text
It now correctly displays emojis hyphens
2024-04-01 15:08:08 +02:00
Ricky Kresslein
87337f31a5 Updated importer and exporter to include new defaults 2024-02-28 18:35:03 +01:00
Arkadiusz Fal
cf5262a86e Bump build number to 180 2024-02-28 14:35:54 +01:00
Arkadiusz Fal
d6be0ffa5b Update CHANGELOG 2024-02-28 14:35:54 +01:00
Arkadiusz Fal
1df8241a01 Update packages 2024-02-28 14:35:54 +01:00
Arkadiusz Fal
43e5eae658 Use latest stable Xcode for build 2024-02-28 13:50:03 +01:00
Arkadiusz Fal
71b4560ff8 Merge pull request #623 from rickykresslein/help-text
Add help text to all header buttons
2024-02-28 13:38:33 +01:00
Arkadiusz Fal
f6bb2fe5d1 Merge pull request #621 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2024-02-28 13:38:00 +01:00
rexcsk
272aafe504 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/zh_Hant/
2024-02-28 13:36:29 +01:00
rexcsk
580d782c56 Translated using Weblate (Chinese (Simplified))
Currently translated at 93.9% (528 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/zh_Hans/
2024-02-28 13:36:25 +01:00
Ricky Kresslein
238ddc7ad9 Add help text to all header buttons 2024-02-28 01:03:33 +01:00
Ricky Kresslein
5559e78bc0 Add setting to show/hide recents and limit number of recents shown 2024-02-28 00:56:12 +01:00
rexcsk
6cc38df4e9 Added translation using Weblate (Chinese (Traditional)) 2024-02-27 15:30:55 +01:00
Arkadiusz Fal
7b34c7e72b Bump build number to 179 2024-02-21 10:17:38 +01:00
Arkadiusz Fal
0dd7943849 Update CHANGELOG 2024-02-21 10:17:22 +01:00
Arkadiusz Fal
6745934a78 Update packages 2024-02-21 10:16:05 +01:00
Arkadiusz Fal
76801a34ee Merge pull request #616 from rickykresslein/main
Add skip, play/pause, and fullscreen shortcuts to macOS player
2024-02-21 10:11:57 +01:00
Arkadiusz Fal
4d0318d4b0 Merge pull request #612 from weblate/weblate-yattee-localizable-strings
Translations update from Hosted Weblate
2024-02-21 10:11:19 +01:00
Ricky Kresslein
9d4446a6ef Add skip, play/pause, and fullscreen shortcuts to macOS player 2024-02-17 10:40:27 +01:00
mere
b74017894c Translated using Weblate (Romanian)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ro/
2024-02-09 22:02:08 +01:00
Mohammed Al Otaibi
9fef6c0276 Translated using Weblate (Arabic)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ar/
2024-02-08 10:01:56 +01:00
gallegonovato
fcbeb45d1e Translated using Weblate (Spanish)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/es/
2024-02-08 10:01:55 +01:00
maboroshin
66f7286cdc Translated using Weblate (Japanese)
Currently translated at 98.5% (554 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ja/
2024-02-06 11:01:58 +01:00
jonnysemon
e1e068ba11 Translated using Weblate (Arabic)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/ar/
2024-02-06 11:01:58 +01:00
Ophiushi
524c99dd54 Translated using Weblate (French)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/fr/
2024-02-06 11:01:58 +01:00
joaooliva
b57ed7055c Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/pt_BR/
2024-02-04 22:01:56 +01:00
Arkadiusz Fal
d84d701b07 Translated using Weblate (Polish)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/pl/
2024-02-04 22:01:56 +01:00
Arkadiusz Fal
bcfd4126b6 Translated using Weblate (English)
Currently translated at 100.0% (562 of 562 strings)

Translation: Yattee/Localizable.strings
Translate-URL: https://hosted.weblate.org/projects/yattee/localizable-strings/en/
2024-02-04 22:01:56 +01:00
32 changed files with 1124 additions and 97 deletions

View File

@@ -40,7 +40,7 @@ jobs:
sed -i '' 's/iPhone Developer/iPhone Distribution/' Yattee.xcodeproj/project.pbxproj
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.3.1'
xcode-version: latest-stable
- uses: maierj/fastlane-action@v3.0.0
with:
lane: ${{ matrix.lane }}
@@ -64,7 +64,7 @@ jobs:
sed -i '' 's/3rd Party Mac Developer Application/Developer ID Application/' Yattee.xcodeproj/project.pbxproj
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.3.1'
xcode-version: latest-stable
- uses: maierj/fastlane-action@v3.0.0
with:
lane: mac build_and_notarize

View File

@@ -1,19 +1,25 @@
## Build 178
* Added Settings import via URL for tvOS
* Localization fixes
* Updated dependencies (mpvkit 0.37.0)
* Other minor changes and improvements
## Build 181
* History Setting: hide the recent activity in the sidebar or limit the number of items shown (by @rickykresslein)
* Fix issues with empty comments (by @stonerl)
* Improved Invidious comments (by @stonerl)
* Downgrade MPVKit to 0.36.0-1 due to issues with WebVTT subtitles
* Updated localizations
* Updated dependencies
## Previous builds
* Added Settings Import/Export (iOS, macOS)
* Add skip, play/pause, and fullscreen shortcuts to macOS player (by @rickykresslein)
* Added Settings Import/Export
* Export all settings, instances and accounts
* Import selected elements from the file
* Include unencrypted passwords in the export or provide them during the import
* Import via URL for tvOS
* Added Controls setting "Action button labels" icon or icon and text
* Added Advanced setting for MPV: "deinterlace"
* Updated dependencies
* Add help text to all header buttons (by @rickykresslein)
* Add Chinese (Traditional) localization (by @rexcsk)
* Localization fixes
* Updated localizations
* Fixed reported crash
* Other minor changes and improvements
**Big thanks to the past, current and future project contributors!**
**Big thanks to the current, past and future project contributors!**

View File

@@ -48,29 +48,32 @@ GIT
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.6)
CFPropertyList (3.0.7)
base64
nkf
rexml
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
artifactory (3.0.15)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.887.0)
aws-sdk-core (3.191.0)
aws-partitions (1.906.0)
aws-sdk-core (3.191.6)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.77.0)
aws-sdk-kms (1.78.0)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.143.0)
aws-sdk-s3 (1.146.1)
aws-sdk-core (~> 3, >= 3.191.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8)
aws-sigv4 (1.8.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
claide (1.1.0)
colored (1.2)
colored2 (3.1.2)
@@ -82,7 +85,7 @@ GEM
domain_name (0.6.20240107)
dotenv (2.8.1)
emoji_regex (3.2.3)
excon (0.109.0)
excon (0.110.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -111,7 +114,7 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.3.0)
fastimage (2.3.1)
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
@@ -129,12 +132,12 @@ GEM
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.6.1)
google-cloud-core (1.7.0)
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-errors (1.3.1)
google-cloud-errors (1.4.0)
google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
@@ -155,18 +158,20 @@ GEM
httpclient (2.8.3)
jmespath (1.6.2)
json (2.7.1)
jwt (2.7.1)
jwt (2.8.1)
base64
mini_magick (4.12.0)
mini_mime (1.1.5)
multi_json (1.15.0)
multipart-post (2.3.0)
multipart-post (2.4.0)
nanaimo (0.3.0)
naturally (2.2.1)
nkf (0.2.0)
optparse (0.4.0)
os (1.1.4)
plist (3.7.1)
public_suffix (5.0.4)
rake (13.1.0)
public_suffix (5.0.5)
rake (13.2.0)
representable (3.2.0)
declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0)
@@ -177,7 +182,7 @@ GEM
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
security (0.1.3)
signet (0.18.0)
signet (0.19.0)
addressable (~> 2.8)
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)

View File

@@ -123,7 +123,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
content.json.dictionaryValue["videos"]?.arrayValue.map(self.extractVideo) ?? []
}
["latest", "playlists", "streams", "shorts", "channels", "videos", "releases", "podcasts"].forEach { type in
for type in ["latest", "playlists", "streams", "shorts", "channels", "videos", "releases", "podcasts"] {
configureTransformer(pathPattern("channels/*/\(type)"), requestMethods: [.get]) { (content: Entity<JSON>) -> ChannelPage in
self.extractChannelPage(from: content.json)
}
@@ -691,6 +691,8 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
let author = details["author"]?.string ?? ""
let channelId = details["authorId"]?.string ?? UUID().uuidString
let authorAvatarURL = details["authorThumbnails"]?.arrayValue.last?.dictionaryValue["url"]?.string ?? ""
let htmlContent = details["contentHtml"]?.string ?? ""
let decodedContent = decodeHtml(htmlContent)
return Comment(
id: UUID().uuidString,
author: author,
@@ -699,12 +701,25 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
pinned: false,
hearted: false,
likeCount: details["likeCount"]?.int ?? 0,
text: details["content"]?.string ?? "",
text: decodedContent,
repliesPage: details["replies"]?.dictionaryValue["continuation"]?.string,
channel: Channel(app: .invidious, id: channelId, name: author)
)
}
private func decodeHtml(_ htmlEncodedString: String) -> String {
if let data = htmlEncodedString.data(using: .utf8) {
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
.documentType: NSAttributedString.DocumentType.html,
.characterEncoding: String.Encoding.utf8.rawValue
]
if let attributedString = try? NSAttributedString(data: data, options: options, documentAttributes: nil) {
return attributedString.string
}
}
return htmlEncodedString
}
private func extractCaptions(from content: JSON) -> [Captions] {
content["captions"].arrayValue.compactMap { details in
guard let url = URL(string: details["url"].stringValue, relativeTo: account.url) else { return nil }

View File

@@ -113,8 +113,11 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
content.json.arrayValue.compactMap { self.extractVideo(from: $0) }
}
configureTransformer(pathPattern("comments/*")) { (content: Entity<JSON>) -> CommentsPage in
let details = content.json.dictionaryValue
configureTransformer(pathPattern("comments/*")) { (content: Entity<JSON>?) -> CommentsPage in
guard let details = content?.json.dictionaryValue else {
return CommentsPage(comments: [], nextPage: nil, disabled: true)
}
let comments = details["comments"]?.arrayValue.compactMap { self.extractComment(from: $0) } ?? []
let nextPage = details["nextpage"]?.string
let disabled = details["disabled"]?.bool ?? false
@@ -663,16 +666,16 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
let videoStreams = content.dictionaryValue["videoStreams"]?.arrayValue ?? []
videoStreams.forEach { videoStream in
for videoStream in videoStreams {
let videoCodec = videoStream.dictionaryValue["codec"]?.string ?? ""
if Self.disallowedVideoCodecs.contains(where: videoCodec.contains) {
return
continue
}
guard let audioAssetUrl = audioStream.dictionaryValue["url"]?.url,
let videoAssetUrl = videoStream.dictionaryValue["url"]?.url
else {
return
continue
}
let audioAsset = AVURLAsset(url: audioAssetUrl)
@@ -724,15 +727,23 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
let commentorUrl = details["commentorUrl"]?.string
let channelId = commentorUrl?.components(separatedBy: "/")[2] ?? ""
let commentText = extractCommentText(from: details["commentText"]?.stringValue)
let commentId = details["commentId"]?.string ?? UUID().uuidString
// Sanity checks: return nil if required data is missing
if commentText.isEmpty || commentId.isEmpty || author.isEmpty {
return nil
}
return Comment(
id: details["commentId"]?.string ?? UUID().uuidString,
id: commentId,
author: author,
authorAvatarURL: details["thumbnail"]?.string ?? "",
time: details["commentedTime"]?.string ?? "",
pinned: details["pinned"]?.bool ?? false,
hearted: details["hearted"]?.bool ?? false,
likeCount: details["likeCount"]?.int ?? 0,
text: extractCommentText(from: details["commentText"]?.stringValue),
text: commentText,
repliesPage: details["repliesPage"]?.string,
channel: Channel(app: .piped, id: channelId, name: author)
)

View File

@@ -35,26 +35,22 @@ final class CommentsModel: ObservableObject {
func load(page: String? = nil) {
guard let video = player.currentVideo else { return }
if !firstPage && !nextPageAvailable {
return
}
firstPage = page.isNil || page!.isEmpty
guard firstPage || nextPageAvailable else { return }
player
.playerAPI(video)?
.comments(video.videoID, page: page)?
.load()
.onSuccess { [weak self] response in
if let page: CommentsPage = response.typedContent() {
self?.all += page.comments
self?.nextPage = page.nextPage
self?.disabled = page.disabled
guard let self = self else { return }
if let commentsPage: CommentsPage = response.typedContent() {
self.all += commentsPage.comments
self.nextPage = commentsPage.nextPage
self.disabled = commentsPage.disabled
}
}
.onFailure { [weak self] requestError in
self?.disabled = !requestError.json.dictionaryValue["error"].isNil
.onFailure { [weak self] _ in
self?.disabled = true
}
.onCompletion { [weak self] _ in
self?.loaded = true

View File

@@ -15,7 +15,11 @@ final class HistorySettingsGroupExporter: SettingsGroupExporter {
"watchedVideoStyle": Defaults[.watchedVideoStyle].rawValue,
"watchedVideoBadgeColor": Defaults[.watchedVideoBadgeColor].rawValue,
"showToggleWatchedStatusButton": Defaults[.showToggleWatchedStatusButton]
"showToggleWatchedStatusButton": Defaults[.showToggleWatchedStatusButton],
"showRecents": Defaults[.showRecents],
"limitRecents": Defaults[.limitRecents],
"limitRecentsAmount": Defaults[.limitRecentsAmount]
]
}
}

View File

@@ -50,5 +50,17 @@ struct HistorySettingsGroupImporter {
if let showToggleWatchedStatusButton = json["showToggleWatchedStatusButton"].bool {
Defaults[.showToggleWatchedStatusButton] = showToggleWatchedStatusButton
}
if let showRecents = json["showRecents"].bool {
Defaults[.showRecents] = showRecents
}
if let limitRecents = json["limitRecents"].bool {
Defaults[.limitRecents] = limitRecents
}
if let limitRecentsAmount = json["limitRecentsAmount"].int {
Defaults[.limitRecentsAmount] = limitRecentsAmount
}
}
}

View File

@@ -176,6 +176,11 @@ final class PlayerModel: ObservableObject {
@Default(.resetWatchedStatusOnPlaying) var resetWatchedStatusOnPlaying
@Default(.playerRate) var playerRate
@Default(.systemControlsSeekDuration) var systemControlsSeekDuration
#if os(macOS)
@Default(.buttonBackwardSeekDuration) private var buttonBackwardSeekDuration
@Default(.buttonForwardSeekDuration) private var buttonForwardSeekDuration
#endif
#if !os(macOS)
@Default(.closePiPAndOpenPlayerOnEnteringForeground) var closePiPAndOpenPlayerOnEnteringForeground
@@ -187,6 +192,10 @@ final class PlayerModel: ObservableObject {
var onPlayStream = [(Stream) -> Void]()
var rateToRestore: Float?
private var remoteCommandCenterConfigured = false
#if os(macOS)
var keyPressMonitor: Any?
#endif
init() {
#if !os(macOS)
@@ -212,6 +221,7 @@ final class PlayerModel: ObservableObject {
#if os(macOS)
if presentingPlayer {
Windows.player.focus()
assignKeyPressMonitor()
return
}
#endif
@@ -227,6 +237,7 @@ final class PlayerModel: ObservableObject {
#if os(macOS)
Windows.player.open()
Windows.player.focus()
assignKeyPressMonitor()
#endif
}
@@ -246,6 +257,7 @@ final class PlayerModel: ObservableObject {
}
#if os(macOS)
destroyKeyPressMonitor()
Windows.player.hide()
#endif
}
@@ -1146,4 +1158,46 @@ final class PlayerModel: ObservableObject {
return nil
}
#if os(macOS)
private func assignKeyPressMonitor() {
keyPressMonitor = NSEvent.addLocalMonitorForEvents(matching: .keyDown) { keyEvent -> NSEvent? in
switch keyEvent.keyCode {
case 124:
if !self.liveStreamInAVPlayer {
let interval = TimeInterval(self.buttonForwardSeekDuration) ?? 10
self.backend.seek(
relative: .secondsInDefaultTimescale(interval),
seekType: .userInteracted
)
}
case 123:
if !self.liveStreamInAVPlayer {
let interval = TimeInterval(self.buttonBackwardSeekDuration) ?? 10
self.backend.seek(
relative: .secondsInDefaultTimescale(-interval),
seekType: .userInteracted
)
}
case 3:
self.toggleFullscreen(
self.playingFullScreen,
showControls: false
)
case 49:
if !self.controls.isLoadingVideo {
self.backend.togglePlay()
}
default: return keyEvent
}
return nil
}
}
private func destroyKeyPressMonitor() {
if let keyPressMonitor = keyPressMonitor {
NSEvent.removeMonitor(keyPressMonitor)
}
}
#endif
}

View File

@@ -225,6 +225,9 @@ extension Defaults.Keys {
static let saveRecents = Key<Bool>("saveRecents", default: true)
static let saveHistory = Key<Bool>("saveHistory", default: true)
static let showRecents = Key<Bool>("showRecents", default: true)
static let limitRecents = Key<Bool>("limitRecents", default: false)
static let limitRecentsAmount = Key<Int>("limitRecentsAmount", default: 10)
static let showWatchingProgress = Key<Bool>("showWatchingProgress", default: true)
static let saveLastPlayed = Key<Bool>("saveLastPlayed", default: false)

View File

@@ -5,12 +5,14 @@ struct AppSidebarRecents: View {
var recents = RecentsModel.shared
@Default(.recentlyOpened) private var recentItems
@Default(.limitRecents) private var limitRecents
@Default(.limitRecentsAmount) private var limitRecentsAmount
var body: some View {
Group {
if !recentItems.isEmpty {
Section(header: Text("Recents")) {
ForEach(recentItems.reversed()) { recent in
ForEach(recentItems.reversed().prefix(limitRecents ? limitRecentsAmount : recentItems.count)) { recent in
Group {
switch recent.type {
case .channel:

View File

@@ -13,6 +13,7 @@ struct Sidebar: View {
@Default(.showDocuments) private var showDocuments
#endif
@Default(.showUnwatchedFeedBadges) private var showUnwatchedFeedBadges
@Default(.showRecents) private var showRecents
var body: some View {
ScrollViewReader { scrollView in
@@ -20,8 +21,10 @@ struct Sidebar: View {
mainNavigationLinks
if !accounts.isEmpty {
AppSidebarRecents()
.id("recentlyOpened")
if showRecents {
AppSidebarRecents()
.id("recentlyOpened")
}
if accounts.api.signedIn {
if visibleSections.contains(.subscriptions), accounts.app.supportsSubscriptions {

View File

@@ -10,6 +10,9 @@ struct HistorySettings: View {
@Default(.saveRecents) private var saveRecents
@Default(.saveLastPlayed) private var saveLastPlayed
@Default(.saveHistory) private var saveHistory
@Default(.showRecents) private var showRecents
@Default(.limitRecents) private var limitRecents
@Default(.limitRecentsAmount) private var limitRecentsAmount
@Default(.showWatchingProgress) private var showWatchingProgress
@Default(.watchedThreshold) private var watchedThreshold
@Default(.watchedVideoStyle) private var watchedVideoStyle
@@ -56,6 +59,26 @@ struct HistorySettings: View {
Section(header: SettingsHeader(text: "History".localized())) {
Toggle("Save history of searches, channels and playlists", isOn: $saveRecents)
Toggle("Save history of played videos", isOn: $saveHistory)
Toggle("Show recents in sidebar", isOn: $showRecents)
#if os(macOS)
HStack {
Toggle("Limit recents shown", isOn: $limitRecents)
.frame(minWidth: 140, alignment: .leading)
.disabled(!showRecents)
Spacer()
counterButtons(for: $limitRecentsAmount)
.disabled(!limitRecents)
}
#else
Toggle("Limit recents shown", isOn: $limitRecents)
.disabled(!showRecents)
HStack {
Text("Recents shown")
Spacer()
counterButtons(for: $limitRecentsAmount)
.disabled(!limitRecents)
}
#endif
Toggle("Show progress of watching on thumbnails", isOn: $showWatchingProgress)
.disabled(!saveHistory)
Toggle("Keep last played video in the queue after restart", isOn: $saveLastPlayed)
@@ -169,6 +192,71 @@ struct HistorySettings: View {
.foregroundColor(.red)
}
}
private func counterButtons(for _value: Binding<Int>) -> some View {
var value: Binding<Int> {
Binding(
get: { return _value.wrappedValue },
set: {
if $0 < 1 {
_value.wrappedValue = 1
} else {
_value.wrappedValue = $0
}
}
)
}
return HStack {
#if !os(tvOS)
Label("Minus", systemImage: "minus")
.imageScale(.large)
.labelStyle(.iconOnly)
.padding(7)
.foregroundColor(limitRecents ? .accentColor : .gray)
.accessibilityAddTraits(.isButton)
#if os(iOS)
.frame(minHeight: 35)
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(lineWidth: 1).foregroundColor(.accentColor))
#endif
.contentShape(Rectangle())
.onTapGesture {
value.wrappedValue -= 1
}
#endif
#if os(tvOS)
let textFieldWidth = 100.00
#else
let textFieldWidth = 30.00
#endif
TextField("Duration", value: value, formatter: NumberFormatter())
.frame(width: textFieldWidth, alignment: .trailing)
.multilineTextAlignment(.center)
.labelsHidden()
.foregroundColor(limitRecents ? .accentColor : .gray)
#if !os(macOS)
.keyboardType(.numberPad)
#endif
#if !os(tvOS)
Label("Plus", systemImage: "plus")
.imageScale(.large)
.labelStyle(.iconOnly)
.padding(7)
.foregroundColor(limitRecents ? .accentColor : .gray)
.accessibilityAddTraits(.isButton)
#if os(iOS)
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(lineWidth: 1).foregroundColor(.accentColor))
#endif
.contentShape(Rectangle())
.onTapGesture {
value.wrappedValue += 1
}
#endif
}
}
}
struct HistorySettings_Previews: PreviewProvider {

View File

@@ -66,6 +66,7 @@ struct HomeSettings: View {
.font(.system(size: 30))
#endif
}
.help("Add to Favorites")
#if !os(tvOS)
.buttonStyle(.borderless)
#endif

View File

@@ -113,6 +113,7 @@ struct SubscriptionsView: View {
} label: {
Label("Play all unwatched", systemImage: "play")
}
.help("Play all unwatched")
.disabled(!feed.canPlayUnwatchedFeed)
}
@@ -130,6 +131,7 @@ struct SubscriptionsView: View {
} label: {
Label("Mark all as watched", systemImage: "checkmark.circle.fill")
}
.help("Mark all as watched")
.disabled(!feed.canMarkAllFeedAsWatched)
}
@@ -139,6 +141,7 @@ struct SubscriptionsView: View {
} label: {
Label("Mark all as unwatched", systemImage: "checkmark.circle")
}
.help("Mark all as unwatched")
}
}

View File

@@ -37,6 +37,7 @@ struct FavoriteButton: View {
.contentShape(Rectangle())
#endif
}
.help(isFavorite ? "Remove from Favorites" : "Add to Favorites")
.disabled(item.isNil)
.onAppear {
isFavorite = item.isNil ? false : favorites.contains(item)

View File

@@ -11,6 +11,7 @@ struct HomeSettingsButton: View {
}
.font(.caption)
.imageScale(.small)
.help("Home Settings")
}
}

View File

@@ -16,6 +16,7 @@ struct ListingStyleButtons: View {
.imageScale(.small)
#endif
}
.help(listingStyle == .cells ? "List" : "Cells")
#endif
}

View File

@@ -38,6 +38,7 @@ struct ShareButton<LabelView: View>: View {
label
}
.menuStyle(.borderlessButton)
.help("Share")
#if os(macOS)
.frame(maxWidth: 60)
#endif

View File

@@ -3,7 +3,7 @@
"Add Account" = "إضافة حساب";
"Add Account..." = "إضافة حساب…";
"Add Location" = "إضافة موقع";
"Add Location..." = "إضافة موقع...";
"Add Location..." = "أضِف موقع..";
"%@ Playlist" = "قائمة تشغيل %@";
"%@ Channel" = "قناة %@";
"%@ subscribers" = "مشتركين %@";
@@ -387,7 +387,7 @@
"Backend" = "الواجهة الخلفية";
"Badge" = "الشارة";
"Close PiP when starting playing other video" = "غلق الفيديو المصغر عند بدء تشغيل فيديو آخر";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "تذكيرات صريحة لإبداء الإعجاب بها أو الإشتراك فيها أو التفاعل معها على أي منصة (منصات) مدفوعة أو مجانية (مثل النقر فوق مقطع الفيديو).";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "تذكيرات صريحة لإبداء الإعجاب بها أو الإشتراك فيها أو التفاعل معها على أي منصة (منصات) مدفوعة أو مجانية (مثل النقر فوق مقطع الفيديو).\n";
"Filter" = " عامل التصفية";
"Frontend URL" = "عنوان URL للواجهة الأمامية";
"Fullscreen size" = "حجم ملء الشاشة";
@@ -604,3 +604,28 @@
"Podcasts" = "‏بودكاست";
"Releases" = "الإصدارات";
"Add %@" = "إضافة %@";
"Import Settings..." = "إستيراد الإعدادات...";
"Accounts passwords (unencrypted)" = "كلمات مرور الحسابات (غير مشفرة)";
"Other data" = "بيانات أخرى";
"Export..." = "تصدير…";
"Export" = "تصدير";
"File information" = "معلومات الملف";
"Build" = "بناء";
"Platform" = "المنصة";
"Import" = "‏إستيراد";
"Action button labels" = "تسميات زر الإجراء";
"Icon only" = "أيقونة فقط";
"Icon and text" = "أيقونة و نص";
"Custom Location not selected for import" = "لم يتم تحديد الموقع المخصّص للإستيراد";
"Account already exists" = "الحساب موجود بالفعل";
"Export Settings" = "تصدير الإعدادات";
"Other" = "أخرى";
"Other data include last used playback preferences and listing options" = "بيانات أخرى تتضمن آخر تفضيلات التشغيل المستخدمة وخيارات القائمة";
"Are you sure you want to export unencrypted passwords?" = "هل أنت متأكد من أنك تريد تصدير كلمات المرور غير المشفرة؟";
"Do not share this file with anyone or you can lose access to your accounts. If you don't select to export passwords you will be asked to provide them during import" = "لا تشارك هذا الملف مع أي شخص وإلا قد تفقد إمكانية الوصول إلى حساباتك. إذا لم تحدّد تصدير كلمات المرور، فسوف يُطلب منك تقديمها أثناء الإستيراد";
"Custom Location selected for import" = "حدّد الموقع المخصّص للإستيراد";
"Custom Location already exists" = "الموقع المخصّص موجود بالفعل";
"Password required to import" = "كلمة المرور مطلوبة للإستيراد";
"Password saved in import file" = "كلمة المرور محفوظة في ملف الإستيراد";
"Export in progress..." = "جارِ التصدير...";
"In progress..." = "في تَقَدم…";

View File

@@ -9,7 +9,7 @@
"Add Account" = "Add Account";
"Add Account..." = "Add Account...";
"Add Location" = "Add Location";
"Add Location..." = "Add Location...";
"Add Location..." = "Add Location..";
"Add profile..." = "Add profile...";
"Add Quality Profile" = "Add Quality Profile";
"Add to %@" = "Add to %@";
@@ -108,7 +108,7 @@
"Enter fullscreen in landscape" = "Enter fullscreen in landscape";
"Error" = "Error";
"Error when accessing playlist" = "Error when accessing playlist";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video).";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video).\n";
"Favorites" = "Favorites";
"Filter" = "Filter";
"Filter: active" = "Filter: active";
@@ -626,3 +626,4 @@
"Account already exists" = "Account already exists";
"Password saved in import file" = "Password saved in import file";
"Export in progress..." = "Export in progress...";
"In progress..." = "In progress…";

View File

@@ -112,12 +112,12 @@
"Help" = "Ayuda";
"Hide sidebar" = "Ocultar barra lateral";
"Add Location" = "Añadir ubicación";
"Add Location..." = "Añadir ubicación...";
"Add Location..." = "Añadir ubicación..";
"Decrease rate" = "Tasa de disminución";
"Decreased opacity" = "Opacidad disminuida";
"High" = "Alto";
"%lld videos" = "%lld videos";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Recordatorios explícitos para marquen \"me gusta\", se suscriban o interactúen con ellos en cualquier plataforma de pago o gratuita (por ejemplo, haciendo clic en un vídeo).";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Recordatorios explícitos para que indiquen les guste, se suscriban o interactúen con ellos en cualquier plataforma de pago o gratuita (por ejemplo, haciendo clic en un vídeo).\n";
"Formats will be selected in order as listed.\nHLS is an adaptive format (resolution setting does not apply)." = "Los formatos se seleccionarán en orden como se indica.\nHLS es un formato adaptable (no aplica la configuración de resolución).";
"Fullscreen size" = "Tamaño de pantalla completa";
"Badge & Decreased opacity" = "Insignia y opacidad dosminuída";
@@ -604,3 +604,28 @@
"No preview" = "Sin vista previa";
"Open vertical chapters expanded" = "Abrir capítulos verticales ampliados";
"Chapters (if available)" = "Capítulos (si están disponibles)";
"Password required to import" = "Se requiere contraseña para importar";
"Export Settings" = "Ajustes de exportación";
"Other" = "Otro";
"Other data" = "Información adicional";
"Export..." = "Exportar…";
"Are you sure you want to export unencrypted passwords?" = "¿Estás seguro de que quieres exportar las contraseñas sin cifrar?";
"Export" = "Exportar";
"Build" = "Compilación";
"Platform" = "Plataforma";
"Import" = "Importar";
"Action button labels" = "Etiquetas para los botones de acción";
"Icon only" = "Solo icono";
"Icon and text" = "Icono y texto";
"Custom Location already exists" = "Ya existe una ubicación personalizada";
"Custom Location selected for import" = "Ubicación personalizada seleccionada para la importación";
"Custom Location not selected for import" = "Ubicación personalizada no seleccionada para la importación";
"Password saved in import file" = "Contraseña guardada en el archivo de importación";
"Export in progress..." = "Exportación en curso...";
"In progress..." = "En proceso…";
"Import Settings..." = "Importar configuración...";
"Accounts passwords (unencrypted)" = "Contraseñas de las cuentas (no cifradas)";
"Other data include last used playback preferences and listing options" = "Información adicional incluye las últimas preferencias de reproducción utilizadas y las opciones de listado";
"Do not share this file with anyone or you can lose access to your accounts. If you don't select to export passwords you will be asked to provide them during import" = "No compartas este archivo con nadie o puedes perder el acceso a tus cuentas. Si no selecciona exportar contraseñas se le pedirá que las proporcione durante la importación";
"File information" = "Información del archivo";
"Account already exists" = "La cuenta ya existe";

View File

@@ -1,7 +1,7 @@
" subscribers" = " abonnés";
"Add Location..." = "Ajouter une instance";
"Add Location..." = "Ajouter une instance..";
"Add profile..." = "Ajouter un profil…";
"Add Quality Profile" = "Ajouter un profil de qualité";
"Delete" = "Supprimer";
@@ -264,7 +264,7 @@
"Don't use public locations" = "Ne pas utiliser d'instances publiques";
"Enable Return YouTube Dislike" = "Activer Return YouTube Dislike";
"Enter fullscreen in landscape" = "Entrer en plein écran en mode paysage";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Rappels d'aimer la vidéo, de s'abonner ou d'interagir avec le créateur sur une plateforme gratuite ou payante.";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Rappels d'aimer la vidéo, de s'abonner ou d'interagir avec le créateur sur une plateforme gratuite ou payante.\n";
"Frontend URL" = "URL frontale";
"Public Locations" = "Instances publiques";
"Public Manifest" = "Manifeste publique";
@@ -604,3 +604,28 @@
"No preview" = "Aucun aperçu";
"Open vertical chapters expanded" = "Ouvrir les chapitres verticaux étendus";
"Chapters (if available)" = "Chapitres (si disponibles)";
"Accounts passwords (unencrypted)" = "Mots de passe des comptes (non chiffrés)";
"Export..." = "Exporter…";
"Export" = "Exporter";
"Build" = "Build";
"Import" = "Importer";
"Action button labels" = "Textes des boutons d'action";
"File information" = "Informations sur le fichier";
"Export Settings" = "Paramètres d'exportation";
"Import Settings..." = "Importer des paramètres...";
"Other" = "Autres";
"Other data" = "Autres données";
"Other data include last used playback preferences and listing options" = "Les autres données incluent les dernières préférences de lecture et de liste utilisées";
"Are you sure you want to export unencrypted passwords?" = "Êtes-vous sûr de vouloir exporter les mots de passe non chiffrés?";
"Do not share this file with anyone or you can lose access to your accounts. If you don't select to export passwords you will be asked to provide them during import" = "Ne partagez pas ce fichier avec qui que ce soit, sinon vous risquez de perdre l'accès à vos comptes. Si vous ne choisissez pas d'exporter les mots de passe, il vous sera demandé de les fournir lors de l'importation";
"Platform" = "Plateforme";
"Icon only" = "Icône uniquement";
"Icon and text" = "Icône et texte";
"Custom Location already exists" = "L'emplacement personnalisé existe déjà";
"Custom Location selected for import" = "Emplacement personnalisé sélectionné pour l'importation";
"Custom Location not selected for import" = "Emplacement personnalisé non sélectionné pour l'importation";
"Password required to import" = "Mot de passe requis pour l'importation";
"Account already exists" = "Le compte existe déjà";
"Password saved in import file" = "Mot de passe enregistré dans le fichier d'importation";
"Export in progress..." = "Exportation en cours...";
"In progress..." = "En cours…";

View File

@@ -529,7 +529,7 @@
"For custom locations you can configure Frontend URL in Locations settings" = "場所を指定するには、場所の設定からフロントエンドのURLを設定します";
"Public Locations" = "公開された場所";
"Switch to public locations" = "公開された場所に切り替え";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "有料/無料のプラットフォームかを問わず、いいね、登録などを明示的に操作を促す(例: 動画をクリック)。";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "有料/無料のプラットフォームかを問わず、いいね、登録などを明示的に操作を促す(例: 動画をクリック)。\n";
"Proxy videos" = "動画閲覧にプロキシ使用";
"Sections" = "表示するボタン";
"System controls show buttons for %@" = "システム制御「%@」用のボタンを表示";
@@ -604,3 +604,28 @@
"No preview" = "プレビューなし";
"Open vertical chapters expanded" = "チャプターを縦方向に開く";
"Chapters (if available)" = "チャプター (あれば)";
"Password required to import" = "取り込むにはパスワードが必要です";
"Export..." = "出力…";
"Other data include last used playback preferences and listing options" = "ほかのデータには、最後に使った再生設定と一覧オプションを含む";
"File information" = "ファイル情報";
"Platform" = "プラットフォーム";
"Icon and text" = "アイコンと文字";
"Custom Location not selected for import" = "指定の場所は取り込み用に選択されていません";
"Import Settings..." = "設定の取り込み...";
"Export Settings" = "設定を出力";
"Accounts passwords (unencrypted)" = "アカウントのパスワード (暗号化なし)";
"Other" = "ほか";
"Other data" = "ほかのデータ";
"Are you sure you want to export unencrypted passwords?" = "暗号化のないパスワードを本当に出力しますか?";
"Custom Location selected for import" = "指定の場所は取り込み用に選択済み";
"Export" = "出力";
"Build" = "ビルド";
"Import" = "取り込み";
"Icon only" = "アイコンのみ";
"Action button labels" = "操作ボタンの表示";
"Export in progress..." = "エクスポート中...";
"In progress..." = "実行中…";
"Password saved in import file" = "取り込みファイルにパスワードを保存しました";
"Account already exists" = "アカウントは既に存在します";
"Do not share this file with anyone or you can lose access to your accounts. If you don't select to export passwords you will be asked to provide them during import" = "このファイルを他の人と共有しないでください。パスワードを出力していなければ、取り込み時にパスワードが求められます";
"Custom Location already exists" = "指定の場所は既に存在します";

View File

@@ -145,7 +145,7 @@
"I want to ask a question" = "Ik wil een vraag stellen";
"If you are interested what's coming in future updates, you can track project Milestones." = "Als je geïnteresseerd bent in toekomstige updates, kan je Milestones van het project volgen.";
"Increase rate" = "Verhoog tempo";
"Info" = "";
"Info" = "Info";
"Instance of current account" = "Instantie van huidig account";
/* SponsorBlock category name */
@@ -259,3 +259,38 @@
"Save history of played videos" = "Sla geschiedenis van afgespeelde videos op";
"Save history of searches, channels and playlists" = "Sla geschiedenis van zoekopdrachten, kanalen en afspeellijsten op";
"Search" = "Zoeken";
"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." = "Stukken normaal in het begin van een video met een animatie, stil plaatje, of stukje van een andere video van dezelfde maker.";
"Discord Server" = "Discord Server";
"Enable logging" = "Loggen inschakelen";
"Interface" = "Interface";
/* SponsorBlock category name */
"Intro" = "Intro";
"LIVE" = "LIVE";
"Matrix Chat" = "Matrix Chat";
/* SponsorBlock category name */
"Outro" = "Outro";
"Proxy videos" = "Video's door proxyserver leiden";
"Reset" = "Herstellen";
"Search history is empty" = "Zoekgeschiedenis is leeg";
"Search..." = "Zoeken...";
"Sections" = "Secties";
"Seek gesture sensitivity" = "Zoek gebaar gevoeligheid";
"Seek gesture speed" = "Zoek gebaar snelheid";
"Seek with horizontal swipe on video" = "Scrollen met horizontale sleep op video";
"Select location closest to you:" = "Selecteer de dichtstbijzijnde locatie:";
/* SponsorBlock category name */
"Self-promotion" = "Zelfpromotie";
"Settings" = "Instellingen";
"Share %@ link" = "%@ link delen";
"Share %@ link with time" = "%@ link met tijd delen";
"Share..." = "Delen...";
/* Video duration filter in search */
"Short" = "Kort";
"Show account username" = "Gebruikersnaam van account laten zien";
"Show anonymous accounts" = "Anonieme accounts laten zien";
"Show channel name" = "Naam van kanaal laten zien";
"Show history" = "Geschiedenis laten zien";

View File

@@ -629,3 +629,4 @@
"Password saved in import file" = "Hasło zapisane w importowanym pliku";
"Account already exists" = "Konto już istnieje";
"Export in progress..." = "Eksport w toku…";
"In progress..." = "W trakcie…";

View File

@@ -355,7 +355,7 @@
"Could not extract channel information" = "Não pôde extrair informação do canal";
"For custom locations you can configure Frontend URL in Locations settings" = "Para localizações personalizadas você pode configurar URL do frontend nas configurações de localização";
"Add Location" = "Adicionar Localização";
"Add Location..." = "Adicionar Localização";
"Add Location..." = "Adicionar Localização..";
"For videos which feature music as the primary content." = "Para vídeos que têm música como conteúdo principal.";
"Close video after playing last in the queue" = "Fechar vídeo depois de tocar o último na fila";
"Clear Search History" = "Limpar Histórico de Busca";
@@ -406,7 +406,7 @@
"Country" = "País";
"Clear All" = "Limpar Tudo";
"Clear All Recents" = "Limpar Todos os Recentes";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Lembretes explícitos de dar like, se inscrever ou interagir com eles em qualquer plataforma, paga ou grátis (p.ex. clique em um vídeo).";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Lembretes explícitos de dar like, se inscrever ou interagir com eles em qualquer plataforma, paga ou grátis (p.ex. clicar em um vídeo).\n";
"Duration" = "Duração";
"Edit Quality Profile" = "Editar Perfil de Qualidade";
"Discussions take place in Discord and Matrix. It's a good spot for general questions." = "Discussões acontecem no Discord e no Matrix. É um bom lugar para perguntas gerais.";
@@ -604,3 +604,28 @@
"No preview" = "Sem prévia";
"Open vertical chapters expanded" = "Abrir capítulos verticais expandidos";
"Chapters (if available)" = "Capítulos (se disponível)";
"Password required to import" = "Senha necessária para importar";
"Export Settings" = "Exportar Ajustes";
"Accounts passwords (unencrypted)" = "Senhas das contas (não encriptadas)";
"Other" = "Outro";
"Export" = "Exportar";
"Build" = "Compilação";
"Action button labels" = "Rótulos dos botões de ação";
"Icon and text" = "Ícone e texto";
"Password saved in import file" = "Senha salva em arquivo de importação";
"Export in progress..." = "Exportação em progresso…";
"In progress..." = "Em progresso…";
"Import Settings..." = "Importar Ajustes…";
"Other data" = "Outros dados";
"Other data include last used playback preferences and listing options" = "Outros dados incluem as preferências de playback usadas pela última vez e opções de listagem";
"Export..." = "Exportar…";
"Platform" = "Plataforma";
"Are you sure you want to export unencrypted passwords?" = "Tem certeza que deseja exportar senhas sem criptografia?";
"Icon only" = "Apenas ícone";
"Custom Location already exists" = "Localização Personalizada já existe";
"Custom Location selected for import" = "Localização Personalizada selecionada para importação";
"Do not share this file with anyone or you can lose access to your accounts. If you don't select to export passwords you will be asked to provide them during import" = "Não compartilhe este arquivo com ninguém, ou você poderá perder acesso às suas contas. Se você não selecionar a exportação de senhas, será perguntado por elas durante a importação";
"File information" = "Informação do arquivo";
"Import" = "Importar";
"Custom Location not selected for import" = "Localização Personalizada não selecionada para importação";
"Account already exists" = "Conta já existe";

View File

@@ -10,7 +10,7 @@
"Accounts are not supported for the application of this instance" = "Conturile nu sunt acceptate pentru aplicaţia acestei instanțe";
"%lld videos" = "%lld videoclipuri";
"Add Location" = "Adaugă locație";
"Add Location..." = "Adaugă locație...";
"Add Location..." = "Adaugă locație..";
"Add profile..." = "Adaugă profil...";
"Add to %@" = "Adaugă la %@";
"Add to Playlist" = "Adaugă la playlist";
@@ -62,7 +62,7 @@
"Edit" = "Editați";
"Edit Playlist" = "Editați Playlist";
"Enter fullscreen in landscape" = "Introduceți ecranul complet în peisaj";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Mementouri explicite de a aprecia, de a vă abona sau de a interacționa cu ele pe orice platformă (platforme) plătite sau gratuite (de exemplu, faceți clic pe un videoclip).";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Mementouri explicite de a aprecia, de a vă abona sau de a interacționa cu ele pe orice platformă (platforme) plătite sau gratuite (de exemplu, faceți clic pe un videoclip).\n";
"Find Other" = "Găsiți alte";
"Finding something to play..." = "Să găsești ceva de jucat...";
"For videos which feature music as the primary content." = "Pentru videoclipurile care includ muzica ca conținut principal.";
@@ -604,3 +604,28 @@
"Description preview" = "Descriere preview";
"No preview" = "Fără previzualizare";
"Chapters (if available)" = "Capitole (dacă există)";
"Password required to import" = "Parolă necesară pentru a importa";
"Import Settings..." = "Importă Setări...";
"Export Settings" = "Exportă Setări";
"Other" = "Alte";
"Other data" = "Alte date";
"Export..." = "Exportă…";
"Other data include last used playback preferences and listing options" = "Alte date includ ultimele preferințe de redare utilizate și opțiunile de listare";
"Are you sure you want to export unencrypted passwords?" = "Sigur doriți să exportați parole necriptate?";
"Export" = "Exportă";
"File information" = "Informații despre fișier";
"Build" = "Build";
"Platform" = "Platformă";
"Import" = "Importă";
"Action button labels" = "Etichete pentru butoanele de acțiune";
"Icon only" = "Doar pictogramă";
"Icon and text" = "Pictogramă și text";
"Custom Location already exists" = "Locația customizată există deja";
"Custom Location not selected for import" = "Locația customizată nu este selectată pentru importare";
"Account already exists" = "Există deja un cont";
"Password saved in import file" = "Parolă salvată în fișierul de import";
"Export in progress..." = "Export în curs...";
"In progress..." = "În curs…";
"Custom Location selected for import" = "Locație customizată selectată pentru importare";
"Accounts passwords (unencrypted)" = "Parolele conturilor (necriptate)";
"Do not share this file with anyone or you can lose access to your accounts. If you don't select to export passwords you will be asked to provide them during import" = "Nu partajați acest fișier cu nimeni, altfel puteți pierde accesul la conturile tale. Dacă nu selectați să exportați parolele, vi se va cere să le furnizați în timpul importului";

View File

@@ -90,7 +90,7 @@
"Delete" = "删除";
"Disabled" = "禁用";
"Discord Server" = "Discord 服务器";
"Discussions take place in Discord and Matrix. It's a good spot for general questions." = "讨论在 Discord 及 Matrix 中行,您可以在里面询问一些普通的问题。";
"Discussions take place in Discord and Matrix. It's a good spot for general questions." = "討論在 Discord 及 Matrix 中行,您可以在裡面詢問一些簡單的問題。";
"Don't use public locations" = "不要使用公开地址";
"Donations" = "捐赠";
"Done" = "完成";

View File

@@ -0,0 +1,631 @@
"Format" = "格式";
"Driver" = "驅動";
"Audio" = "音效";
"Show only icons" = "只顯示圖標";
"Center" = "正中";
"File" = "文件";
"Documents" = "文件";
"Video" = "視頻";
"Codec" = "編碼";
"Size" = "大小";
"Sample Rate" = "取樣率";
"Mark channel feed as watched" = "標記頻道為已觀看";
"Clear all" = "清除所有";
"\"%@\" will be irreversibly removed from this device." = "\"%@\" 將會於此裝置上被永久移除。";
"Music Mode" = "音樂模式";
"Close video" = "關閉視頻";
"Play next item" = "播放下一項目";
"Maximum width expanded" = "最大寬度已展開";
"Show unwatched feed badges" = "顯示未觀看的\"最新影片\"標誌";
"Gesture: fowards" = "手勢: 向前";
"Gesture settings control skipping interval for remote arrow buttons (for 2nd generation Siri Remote or newer). Changing system controls settings requires restart." = "手勢設置控制遠程箭頭按鈕的跳過間隔(用於第二代 Siri Remote 或更新版本)。更改系統控制設置需要重新啓動。";
"Opened File" = "已打開文件";
"Landscape left" = "橫屏左邊";
"Landscape right" = "橫屏右邊";
"Gesture settings control skipping interval for double tap gesture on left/right side of the player. Changing system controls settings requires restart." = "手勢設置控制玩家左右兩側雙擊手勢的跳過間隔。更改系統控制設置需要重新啓動。";
"Show scroll to top button in comments" = "在評論中顯示滾動到頂部按鈕";
"(watched and shorts hidden)" = "(隱藏已觀看及短片)";
"(watched hidden)" = "(隱藏已觀看)";
"Show video context menu options to force selected backend" = "顯示視頻內容目錄選項來強制已選取的後端";
"Other data" = "其他資料";
"Other data include last used playback preferences and listing options" = "其他資料包括上次的播放喜好和清單選項";
"File information" = "檔案資訊";
"Build" = "版本";
"Action button labels" = "動作按鈕標籤";
"Icon and text" = "圖示及文字";
"Password required to import" = "需要匯入的密碼";
"Edit" = "編輯";
"Enable Return YouTube Dislike" = "啟用YouTube 不喜歡回報";
"Enter fullscreen in landscape" = "橫屏下進入全屏";
"Error when accessing playlist" = "播放清單出錯";
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "明確提醒在任何付費或免費平台上按讚、訂閱或與他們互動(例如點擊影片)。\n";
"For videos which feature music as the primary content." = "以音樂為主要內容的視頻。";
"I like this app!" = "我喜歡這app!";
"If you are interested what's coming in future updates, you can track project Milestones." = "如果您對將來的功能更新感興趣,您可以追蹤我們的專案里程碑。";
"Increase rate" = "增长率";
/* SponsorBlock category name */
"Intro" = "簡介";
"Issues Tracker" = "問題追蹤介面";
/* Selected video has just finished playing */
"Just watched" = "已觀看";
/* Player controls layout size */
"Large" = "大";
"Large layout is not suitable for all devices and using it may cause controls not to fit on the screen." = "大佈局並不適合所有設備,使用它可能導致控制按鈕在屏幕上並不貼合。";
"LIVE" = "直播";
"Low quality" = "低畫質";
"Low" = "低";
"Mark video as watched after playing" = "播放後標記為已觀看";
"MPV Documentation" = "MPV 文檔";
"Orientation" = "方向";
"Music" = "音樂";
"Part of a video promoting a product or service not directly related to the creator. The creator will receive payment or compensation in the form of money or free products." = "視頻宣傳產品或服務的一部分,與創作者沒有直接關係。創作者將以金錢或免費產品的形式獲得報酬或補償。";
"Remove from Playlist" = "從播放清單中移除";
"Replies" = "回覆";
"Reset" = "重設";
"Restart the app to apply the settings above." = "重啟app 以應用以上設置。";
"Sections" = "章節";
"Share..." = "分享...";
"Show account username" = "顯示帳戶名稱";
"Show channel name" = "顯示頻道名稱";
"This cannot be reverted. You might need to switch between views or restart the app to see changes." = "這不能復原。你可能需要轉換顯示或重啟app 才能顯示變更。";
/* Player controls layout size for TV */
"TV" = "電視";
"unknown" = "不明";
"Unsubscribe" = "取消訂閱";
"Typically near or at the end of the video when the credits pop up and/or endcards are shown." = "通常在視頻結束時或接近視頻結尾時,出現 Credits Pop Up 和結束卡片。";
"Upload date" = "上載日期";
"URL" = "網址";
"Used to create links from videos, channels and playlists" = "用於從視頻、頻道和播放清單創建連結";
/* Player controls layout size */
"Very Large" = "非常大";
"Videos" = "視頻";
/* Video sort order in search */
"Views" = "觀看次數";
"Watched" = "已觀看";
"No chapters information available" = "沒有章節資訊";
"Share Logs..." = "分享日誌…";
"Any format" = "任何格式";
"%@ formats" = "%@ 格式";
"Keep last played video in the queue after restart" = "重啟後保留最後播放視頻至隊列";
"Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "播放清單空白\n\n點擊並按住視頻然後\n\"加至播放清單\"";
"Could not refresh Subscriptions" = "無法更新訂閱列表";
"Could not load streams" = "無法加載視頻";
"Could not open video" = "無法開啟視頻";
"Channel could not be found" = "無法找到頻道";
"For custom locations you can configure Frontend URL in Locations settings" = "對於自定義站台,您可以在設置中配置前端 URL";
"This URL could not be opened" = "無法打開此URL";
"Could not open channel" = "無法打開頻道";
/* Selected video is being played */
"Watching now" = "觀看中";
/* Video date filter in search */
"Week" = "星期";
"Yattee" = "Yattee";
"Could not update your token." = "無法更新你的權仗(Token)。";
"Could not refresh Trending" = "無法更新趨勢";
"Could not extract channel information" = "無法獲取頻道資訊";
"Yattee %@ (build %@)" = "Yattee %@ (版本 %@)";
/* Video date filter in search */
"Year" = "年";
"You can find information about using Yattee in the Wiki pages." = "您可以在 GitHub 相關頁面中找到有關使用 Yattee 的信息。";
"You can use automatic profile selection based on current device status or switch it in video playback settings controls." = "您可以使用基於當前設備狀態的自動配置文件選擇,或在視頻播放設置控件中進行切換。";
"Could not extract playlist ID" = "無法提取播放清單ID";
"Could not load video" = "無法載入視頻";
"You need to create an instance and accounts\nto access %@ section" = "你需要建立站台及帳戶\n來存取 %@ 部分";
"You need to select an account\nto access %@ section" = "你需要選擇帳戶\n來存取 %@ 部分";
"If you want this app to be available in your language, join translation project." = "如果你想此app 以你的語言顯示,請加入翻譯專案。";
"Private" = "私人";
"Playback queue is empty" = "播放隊列空白";
"Playing Next" = "播放下一個";
"You can switch between profiles in playback settings controls." = "您可以在播放設置控件中切換配置文件。";
"Current Playlist" = "當前播放清單";
"Stream & Player" = "串流及播放器";
"Statistics" = "數據";
"Hardware decoder" = "硬體解碼";
"Stream FPS" = "串流 FPS";
"Cached time" = "緩存時間";
"Rate & Captions" = "評分及字幕";
"Dropped frames" = "損失幀數";
"Could not create share link" = "無法建立分享連結";
"%@ Channel" = "%@ 頻道";
"%@ Playlist" = "%@ 播放清單";
"%@ subscribers" = "%@ 訂閱者";
"Accounts" = "帳戶";
"Accounts are not supported for the application of this instance" = "本站並不支持帳戶";
"Add Account" = "新增帳戶";
"%lld videos" = "%lld 視頻";
"Add Account..." = "新增帳戶...";
"Add Location" = "新增站點";
"Add Location..." = "新增站點..";
"Add profile..." = "新增配置...";
"Add Quality Profile" = "新增畫質配置";
"Add to %@" = "添加到 %@";
"Add to Favorites" = "加至我的最愛";
"Add to Playlist" = "加至播放清單";
"Add to Playlist..." = "加至播放清單...";
"Advanced" = "高級";
/* Trending category, section containing all kinds of videos */
"All" = "所有";
"Always use AVPlayer for live videos" = "總是使用AVPlayer(直播)";
"Anonymous" = "匿名";
/* Video date filter in search
Video duration filter in search */
"Any" = "任何";
"Apply to all" = "套用至全部";
"Are you sure you want to unsubscribe from %@?" = "確定要取消訂閱 %@";
"Automatic" = "自動";
"Autoplaying Next" = "自動播放下一個";
"Backend" = "後台";
"Categories to Skip" = "要跳過的類別";
"Cellular" = "流動網絡";
"Chapters" = "章節";
"Charging" = "充電中";
"Clear" = "清除";
"Clear All" = "清除所有";
"Clear All Recents" = "清除所有最近";
"Clear History" = "清除記錄";
"Clear Search History" = "清除搜尋記錄";
"Clear Search History..." = "清除搜尋記錄...";
"Clear the queue" = "清除隊列";
"Close" = "關閉";
"Close PiP when player is opened" = "當播放器打開時,關閉 PiP";
"Close player when closing video" = "當關閉視頻時,關閉播放器";
"Close player when starting PiP" = "當啟動PiP時關閉播放器";
"Close Video" = "關閉視頻";
"Close video after playing last in the queue" = "播放完最後隊列後關閉視頻";
"Connected successfully (%@)" = "連接成功 (%@)";
"Connection failed" = "連接失敗";
"Contact" = "聯繫";
"Continue" = "繼續";
"Continue from %@" = "從 %@繼續";
"Contributing" = "貢獻";
"Controls" = "控制";
"Copy %@ link" = "複製 %@ 連結";
"Copy %@ link with time" = "複製 %@ 連結(含時間)";
"Could not load locations manifest" = "無法加載站台列表";
"Country Name or Code" = "國家名稱或代碼";
"Create Playlist" = "新建播放清單";
"Current: %@\n%@" = "現在: %@\n%@";
/* Locations settings, custom instance is selected as current */
"Custom" = "自定義";
"Custom Locations" = "自定義站台";
/* Video sort order in search */
"Date" = "日期";
"Decrease rate" = "下降率";
"Decreased opacity" = "減少透明度";
"Delete" = "刪除";
"Disabled" = "禁用";
"Discord Server" = "Discord 伺服器";
"Discussions take place in Discord and Matrix. It's a good spot for general questions." = "討論在 Discord 及 Matrix 中進行,您可以在裡面詢問一些簡單的問題。";
"Don't use public locations" = "不使用公開站台";
"Donations" = "捐贈";
"Done" = "完成";
"Duration" = "時長";
"Edit Playlist" = "編輯播放清單";
"Edit Quality Profile" = "編輯質量配置";
"Edit..." = "編輯...";
"Enable logging" = "啟用日誌";
"Error" = "錯誤";
"Favorites" = "我的最愛";
"Filter" = "篩選";
"Filter: active" = "篩選: 啟用";
"Find Other" = "搜尋其他";
"Finding something to play..." = "正在尋找視頻...";
"Formats will be selected in order as listed.\nHLS is an adaptive format (resolution setting does not apply)." = "格式將按列出的順序選擇。\nHLS是一種自適應格式解析度設定不適用。";
"Frontend URL" = "前端網址";
"Fullscreen size" = "全屏大小";
"Gaming" = "遊戲";
"Help" = "幫助";
"Hide sidebar" = "隱藏側邊欄";
"High" = "高";
"Highest" = "最高";
"Highest quality" = "最高畫質";
"History" = "歷史";
"Honor orientation lock" = "方向鎖";
/* Video date filter in search */
"Hour" = "小時";
"I am lost" = "我迷失了";
"I found a bug /" = "我發現bug";
"I have a feature request" = "我有一個功能需要";
"I want to ask a question" = "我想問問題";
"If you are reporting a bug, include all relevant details (especially: app version, used device and system version, steps to reproduce)." = "如果你要反饋一個程式錯誤請包括所有相關資料特別是App 版本,使用設備以及系統版本,重現步驟)。";
"Info" = "資訊";
"Instance of current account" = "此帳戶站台";
/* SponsorBlock category name */
"Interaction" = "交互";
"Interface" = "介面";
/* Loading stream OSD */
"Loading streams..." = "加載中...";
"Loading..." = "加載中...";
"Locations" = "地址";
"Lock portrait mode" = "鎖定直屏";
/* Video duration filter in search */
"Long" = "長";
"Lowest" = "最低";
"Mark as watched" = "標記為已觀看";
"Mark watched videos with" = "標記已觀看視頻";
"Matrix Channel" = "Matrix 頻道";
"Matrix Chat" = "Matrix 聊天";
/* Player controls layout size */
"Medium" = "中";
"Medium quality" = "中畫質";
"Milestones" = "里程碑";
/* Video date filter in search */
"Month" = "月";
"More info can be found in:" = "更多資訊可在:";
"Movies" = "電影";
"Name" = "名稱";
"New Playlist" = "新播放清單";
"Next" = "下一個";
"No description" = "無簡介";
"No Playlists" = "沒有播放清單";
"No results" = "沒有結果";
"Normal" = "正常";
"Not available" = "不可用";
"Not Playing" = "沒有播放";
"Nothing" = "沒有東西";
/* SponsorBlock category name */
"Offtopic in Music Videos" = "在音樂視頻中的無關內容";
"Only when signed in" = "僅當登錄後";
"Open \"Playlists\" tab to create new one" = "打開「播放清單」 頁面來創建新的";
"Open Settings" = "打開設置";
/* Loading stream OSD */
"Opening %@ stream..." = "正在打開 %@ ...";
"Opening audio stream..." = "正在打開音訊...";
/* SponsorBlock category name */
"Outro" = "結尾";
"Password" = "密碼";
"Pause" = "暫停";
"Pause when entering background" = "進入後台時暫停";
"Pause when player is closed" = "播放器關閉時暫停";
"Picture in Picture" = "畫中畫";
"Play" = "播放";
"Play All" = "全部播放";
"Play in PiP" = "在畫中畫播放";
"Play Last" = "播放最後";
"Play Music" = "播放音樂";
"Play Next" = "播放下一部";
"Play Now" = "即時播放";
"Playback" = "播放";
"Player" = "播放器";
"Playlist" = "播放清單";
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "播放清單 “%@” 將被删除。\n此操作不可恢復。";
"Playlists" = "播放清單";
"Popular" = "熱播";
"Preferred Formats" = "喜好格式";
"Profiles" = "配置";
"Promoting a product or service that is directly related to the creator themselves. This usually includes merchandise or promotion of monetized platforms." = "推廣與創作者本身直接相關的產品或服務。這通常包括商品或盈利平台的推廣。";
"Proxy videos" = "代理視頻";
"Public Locations" = "公共站台";
"Public Manifest" = "公共清單";
"Quality" = "畫質";
"Quality Profile" = "畫質配置";
"Queue" = "隊列";
"Queue is empty" = "隊列為空";
"Rate" = "速度";
/* Video sort order in search */
"Rating" = "評級";
"Recents" = "最近";
"Red" = "紅";
"Refresh" = "更新";
"Regular size" = "正常大小";
"Regular Size" = "正常大小";
"Related" = "相關";
/* Video sort order in search */
"Relevance" = "相關度";
"Remove" = "移除";
"Remove from Favorites" = "從我的最愛中移除";
"Remove from history" = "從歷史中移除";
"Remove from the queue" = "從隊列中移除";
"Reset search filters" = "重設搜尋篩選";
"Reset watched status when playing again" = "重新播放後重設播放狀態";
"Resolution" = "分辨率";
"Restart" = "重新啟動";
"Restart/Play next" = "重新播放/播放下一個";
"Restore default profiles..." = "重置默認配置文件...";
"Rotate to portrait when exiting fullscreen" = "退出全屏後旋轉為直屏";
"Round corners" = "圓角";
"Save" = "儲存";
"Save history of played videos" = "儲存已播放視頻記錄";
"Save history of searches, channels and playlists" = "儲存搜尋,頻道及播放清單記錄";
"Search" = "搜尋";
"Search history is empty" = "搜尋歷史為空";
"Search..." = "搜尋...";
"Seek gesture sensitivity" = "手勢靈敏度";
"Seek gesture speed" = "手勢速度";
"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." = "通常在視頻開頭找到的片段,包括動畫、靜止幀或剪輯,這些片段也可以由同一創作者在其他視頻中看到。";
"Select location closest to you:" = "選取離你最近的站台:";
/* SponsorBlock category name */
"Self-promotion" = "自我推銷";
"Settings" = "設置";
"Share %@ link" = "分享 %@ 連結";
"Share %@ link with time" = "分享 %@ 連結(含時間)";
/* Video duration filter in search */
"Short" = "短";
"Show anonymous accounts" = "顯示匿名帳戶";
"Show history" = "顯示歷史";
"Show keywords" = "顯示關鍵字";
"Show playback statistics" = "顯示播放統計";
"Show progress of watching on thumbnails" = "縮圖顯示播放進度";
"Show sidebar when space permits" = "空間充裕時顯示側邊欄";
"Show video length" = "顯示視頻長度";
"Shuffle" = "隨機播放";
"Shuffle All" = "隨機播放全部";
"Sidebar" = "側邊欄";
"Sign In Required" = "需要登錄";
/* Player controls layout size */
"Small" = "小";
/* Player controls layout size */
"Smaller" = "更小";
"Sort" = "排序";
"Sort: %@" = "排序: %@";
"Source" = "源";
/* SponsorBlock category name */
"Sponsor" = "宣傳";
"SponsorBlock" = "SponsorBlock (跳過贊助廣告)";
"SponsorBlock API Instance" = "SponsorBlock API 站台";
"Subscribe" = "訂閱";
/* Subscriptions title */
"Subscriptions" = "訂閱";
"Switch to other public location" = "轉換至其他公共站台";
"Switch to public locations" = "轉換至公共站台";
"System controls buttons" = "系統控制鍵";
"System controls show buttons for %@" = "系統控制%@鍵";
"That's nice to hear. It is fun to deliver apps other people want to use. You can consider donating to the project or help by contributing to new features development." = "很高興聽到您這麼說。提供人們想要的應用程序是一件很有趣的事情。您可以考慮為項目捐款,或為新功能開發做出貢獻。";
"This cannot be reverted" = "這不能復原";
"This information will be processed only on your device and used to connect you to the server in the specified country." = "此信息將僅在您的設備上處理,並用於將您連接到指定國家/地區的服務器。";
"This will remove all your custom profiles and return their default values. This cannot be reverted." = "這將刪除所有自定義配置文件並還原為其默認值。此操作無法復原。";
"Thumbnails" = "縮圖";
/* Video date filter in search */
"Today" = "今日";
"Trending" = "趨勢";
"Username" = "用戶名稱";
/* Selected video was played on given date */
"Watched %@" = "已觀看 %@";
"Welcome" = "歡迎";
"Wi-Fi" = "無線網絡";
"Wiki" = "GitHub";
"You have no Playlists" = "你沒有播放清單";
"You have no playlists\n\nTap on \"New Playlist\" to create one" = "你沒有播放清單\n\n點擊\"新建播放清單\"建立";
"Public" = "公開";
"Unlisted" = "未列出";
"Now Playing" = "現正播放";
"Current Location" = "現在位置";
"Add Channels, Playlists and Searches to Favorites using" = "添加頻道、播放清單和搜尋到我的最愛";
"Make default" = "設為預設";
"Visibility" = "可見度";
"It can be changed later in settings. You can use your own locations too." = "稍後可以在設置中更改。你也可以使用自己的地址。";
"Press and hold remote button to open captions and quality menus" = "按住遙控按鈕打開字幕和畫質功能表";
"Comments are disabled" = "留言被關閉";
"No comments" = "沒有留言";
"Open logs in Finder" = "在Finder 中開啟日誌";
"Could not extract SID from received cookies: %@" = "無法從Cookies 提取SID: %@";
"Could not refresh Popular" = "無法更新熱播";
"Could not open playlist" = "無法打開播放清單";
"Could not extract video ID" = "無法提取視頻ID";
"This video could not be opened" = "這視頻無法打開";
"No locations available at the moment" = "現時沒有可用地址";
"Could not refresh Playlists" = "無法更新播放清單";
"Translations" = "翻譯";
"No documents" = "沒有文件";
"Recent Documents" = "最近文件";
"Home" = "主頁";
"Share files from Finder on a Mac\nor iTunes on Windows" = "在 Windows iTunes 或 Mac 上\n共享 Finder 中的文件";
"Show Home" = "顯示主頁";
"Show Open Videos quick actions" = "顯示打開視頻快速操作";
"Recent History" = "最近歷史";
"Show Favorites" = "顯示我的最愛";
"Inspector visibility" = "檢查器可見度";
"Edit Favorites…" = "編輯我的最愛…";
"Show Open Videos toolbar button" = "顯示打開視頻工具按鈕";
"Buttons labels" = "按鈕標簽";
"Files" = "文件";
"Show Documents" = "顯示文件";
"Pages toolbar position" = "頁面工具列位置";
"Video Details" = "視頻詳情";
"Show Inspector" = "顯示檢查器";
"Reload manifest" = "重新載入清單";
"Clear Queue before opening" = "開啟前清除隊列";
"Open" = "打開";
"Video actions buttons" = "視頻操作按鈕";
"Pages buttons" = "頁面按鈕";
"URL to Open" = "要打開的URL";
"Enter link to open" = "輸入要打開的連結";
"Could not open Files" = "無法打開文件";
"Paste" = "貼上";
"Open Videos" = "打開視頻";
"Enter links to open, one per line" = "輸入需要打開的連結,每行一個";
"Playback Mode" = "播放模式";
"Add" = "添加";
"Hide" = "隱藏";
"Always" = "總是";
"Only for local files and URLs" = "僅針對本地文件以及連結";
"Right" = "右";
"Channels" = "頻道";
"Open Files" = "打開文件";
"Share" = "分享";
"Show icons and text when space permits" = "在空間允許時顯示圖標和文字";
"Left" = "左";
"FPS" = "FPS";
"Address" = "地址";
"Remove…" = "移除…";
"Show sidebar" = "顯示側邊欄";
"Locations Manifest" = "地址清單";
"Remove Location" = "移除地址";
"Open Video" = "打開視頻";
"Default Profile" = "預設配置";
"Playback history is empty" = "播放記錄空白";
"Copy%@link" = "複製%@連結";
"Share%@link" = "分享%@連結";
"Are you sure you want to remove this document?" = "你確定要移除文件?";
"Could not delete document" = "無法刪除文件";
"Live Streams" = "直播";
"Shorts" = "短片";
"Channel" = "頻道";
"Mark channel feed as unwatched" = "標記頻道為未觀看";
"Could not find any links to open in your clipboard" = "無法在你的剪輯版中找到任何可以打開的連結";
"Actions buttons" = "動作按鈕";
"Are you sure you want to remove %@ location?" = "你確定想要刪除 %@ 地址?";
"Verified" = "已認證";
"Open expanded" = "展開";
"Short videos: visible" = "短片: 可見";
"Player Bar" = "播放器控制條";
"Short videos: hidden" = "短片: 隱藏";
"Play all unwatched" = "播放所有未觀看";
"Double tap gesture" = "雙擊手勢";
"Tap and hold channel thumbnail to open context menu with more actions" = "點擊並按住頻道縮圖以打開包含更多操作的選單";
"Always show controls buttons" = "總是顯示控制按鈕";
"Single tap gesture" = "單擊手勢";
"Seeking" = "搜索中";
"Right click channel thumbnail to open context menu with more actions" = "右鍵單擊頻道縮圖以打開具有更多操作的選單";
"Controls Buttons" = "控制按鈕";
"System controls" = "系統控制";
"Controls button: backwards" = "控制按鈕: 向後";
"Controls button: forwards" = "控制按鈕: 向前";
"Gesture: backwards" = "手勢: 向後";
"Hide player" = "隱藏播放器";
"Gesture settings control skipping interval for double click on left/right side of the player. Changing system controls settings requires restart." = "手勢設置控制雙擊播放器左/右的跳躍間隔。更改系統控制設置需要重新啓動。";
"Lock orientation" = "鎖定方向";
"Cache" = "緩存";
"Actions Buttons" = "動作按鈕";
"Total size: %@" = "總大小: %@";
"Open channels with description expanded" = "打開頻道(含描述展開)";
"Subscribe/Unsubscribe" = "訂閱/取消訂閱";
"Show cache status" = "顯示緩存狀態";
"Maximum feed items" = "最大\"最新影片\"數目";
"Open channel" = "打開頻道";
"Inspector" = "檢查器";
"Open video description expanded" = "打開視頻描述";
"Mark all as unwatched" = "標記所有為未觀看";
"Mark all as watched" = "標記所有為已觀看";
"Playback Settings" = "播放設定";
"Replay" = "重播";
"Fullscreen" = "全屏幕";
"Lock" = "鎖定";
"Description" = "描述";
"Autoplay next" = "自動播放下一個";
"Stream" = "串流";
"Are you sure you want to clear cache?" = "你確定要清除緩存嗎?";
"Show Next in Queue" = "在隊列中顯示下一個";
"Show toggle watch status button" = "顯示切換觀看狀態按鈕";
"Next in Queue" = "隊列中下一個";
"List" = "列表";
"Cells" = "網格";
"Toggle size" = "替換大小";
"Toggle player" = "替換播放器";
"Do nothing" = "不做";
"Feed" = "最新影片";
"Queue - shuffled" = "隊列 - 隨機";
"Loop one" = "單個循環";
"File Extension" = "副檔名";
"Opening file..." = "正在打開文件...";
"Public account" = "公共帳戶";
"Enter account credentials to connect..." = "輸入帳號密碼來連接...";
"Enter location address to connect..." = "輸入站台地址來連接...";
"Seek" = "搜索";
"Your Accounts" = "你的帳戶";
"Browse without account" = "匿名瀏覽";
"Close video and player on end" = "播放結束時關閉視頻及播放器";
"Use system controls with AVPlayer" = "在AVPlayer 時使用系統控制按鈕";
"Rotate when entering fullscreen on landscape video" = "觀看橫向全屏視頻時旋轉";
"Available" = "可用";
"Home Settings" = "主頁設置";
"Watched: hidden" = "已觀看: 隱藏";
"No rotation" = "不要旋轉";
"Startup section" = "啟動部分";
"Watched: visible" = "已觀看: 可見";
"No videos to show" = "沒有視頻顯示";
"(shorts hidden)" = "(隱藏短片)";
"Disable filters" = "禁用過濾";
"Limit" = "上限";
"Are you sure you want to remove %@ from Favorites?" = "你確定要從我的最愛中刪除 %@ 嗎?";
"Keep channels with unwatched videos on top of subscriptions list" = "保留頻道內未觀看視頻在訂閱列表頂端";
"Play Now in MPV" = "在MPV 中播放";
"Play Now in AVPlayer" = "在AVPlayer 中播放";
"Show channel avatars in videos lists" = "在視頻列表中顯示頻道頭像";
"Show channel avatars in channels lists" = "在頻道列表中顯示頻道頭像";
"Podcasts" = "播客";
"Releases" = "發布";
"Add %@" = "添加 %@";
"Description preview" = "描述預覽";
"No preview" = "沒有預覽";
"Open vertical chapters expanded" = "展開垂直章節";
"Chapters (if available)" = "章節(如有)";
"Import Settings..." = "匯入設定...";
"Export Settings" = "匯出設定";
"Accounts passwords (unencrypted)" = "帳戶密碼 (非加密)";
"Other" = "其他";
"Export..." = "匯出…";
"Are you sure you want to export unencrypted passwords?" = "你確定要匯出未加密的密碼?";
"Icon only" = "僅圖示";
"Export" = "匯出";
"Import" = "匯入";
"Platform" = "平台";
"Custom Location already exists" = "自定義站台已存在";
"Custom Location selected for import" = "選擇導入的自定義站台";
"Custom Location not selected for import" = "未選擇導入的自定義站台";
"Account already exists" = "帳戶已存在";
"Password saved in import file" = "密碼已儲存在匯入文件";
"Export in progress..." = "匯出中...";
"In progress..." = "進行中…";
" subscribers" = " 訂閱者";
"10 seconds forwards/backwards" = "前放/回放10秒";
"Are you sure you want to clear history of watched videos?" = "確定要清除播放歷史?";
"Are you sure you want to clear search history?" = "確定要清除搜尋歷史?";
"Are you sure you want to delete playlist?" = "確定要刪除播放清單?";
"Are you sure you want to restore default quality profiles?" = "確定要回復預設質量配置?";
"Badge" = "標記";
"Badge & Decreased opacity" = "標記及降低透明度";
"Badge color" = "標記顏色";
"Based on system color scheme" = "根據系統配置";
"Battery" = "電池";
"Blue" = "藍";
"Browsing" = "瀏覽";
"Buffering stream..." = "緩衝中...";
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "程式錯誤及出色的功能構思也可以在 GitHub 問題追蹤介面提出。 ";
"Cancel" = "取消";
"Button" = "按鈕";
"Captions" = "字幕";
"Category" = "類別";
"Close PiP and open player when application enters foreground" = "當應用程式進入前台時,關閉 PiP 並打開播放器";
"Close PiP when starting playing other video" = "當播放其他視頻時,關閉 PiP";
"Comments" = "留言";
"Country" = "國家";
"When partially watched video is played" = "播放未完全觀看視頻時";
"Do not share this file with anyone or you can lose access to your accounts. If you don't select to export passwords you will be asked to provide them during import" = "請勿與任何人共用此文件,否則您可能會失去對帳戶的存取權限。如果您不選擇匯出密碼,系統將要求您在匯入過程中提供密碼";

View File

@@ -1196,6 +1196,7 @@
3730D89F2712E2B70020ED53 /* NowPlayingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingView.swift; sourceTree = "<group>"; };
373197D82732015300EF734F /* RelatedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelatedView.swift; sourceTree = "<group>"; };
37319F0427103F94004ECCD0 /* PlayerQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerQueue.swift; sourceTree = "<group>"; };
37367E582B8F63C200436163 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
3738535329451DC800D2D0CB /* BookmarksCacheModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksCacheModel.swift; sourceTree = "<group>"; };
373C8FE3275B955100CB5936 /* CommentsPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentsPage.swift; sourceTree = "<group>"; };
373CFACA26966264003CB2C6 /* SearchQuery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchQuery.swift; sourceTree = "<group>"; };
@@ -2773,6 +2774,7 @@
es,
tr,
ru,
"zh-Hant",
);
mainGroup = 37D4B0BC2671614700C925CA;
packageReferences = (
@@ -4045,6 +4047,7 @@
3767F3322B25053B00F257BC /* es */,
3767F3332B25058300F257BC /* tr */,
3767F3342B2505EF00F257BC /* ru */,
37367E582B8F63C200436163 /* zh-Hant */,
);
name = Localizable.strings;
sourceTree = "<group>";
@@ -4059,7 +4062,7 @@
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee";
@@ -4090,7 +4093,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist";
@@ -4121,7 +4124,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0;
@@ -4141,7 +4144,7 @@
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0;
@@ -4305,7 +4308,7 @@
CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -4358,7 +4361,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1";
@@ -4410,7 +4413,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
DEAD_CODE_STRIPPING = YES;
ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES;
@@ -4449,7 +4452,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
DEAD_CODE_STRIPPING = YES;
"DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ;
ENABLE_APP_SANDBOX = YES;
@@ -4484,7 +4487,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4508,7 +4511,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4534,7 +4537,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4559,7 +4562,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4585,7 +4588,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
DEVELOPMENT_ASSET_PATHS = "";
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -4625,7 +4628,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
DEVELOPMENT_ASSET_PATHS = "";
"DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ;
ENABLE_PREVIEWS = YES;
@@ -4666,7 +4669,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -4690,7 +4693,7 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 178;
CURRENT_PROJECT_VERSION = 181;
GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -5000,8 +5003,8 @@
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/cxfksword/MPVKit.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.36.0;
kind = revision;
revision = dca1e345a26d09a3d621d7656a94e6427f3f7b83;
};
};
/* End XCRemoteSwiftPackageReference section */

View File

@@ -15,8 +15,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire.git",
"state" : {
"revision" : "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad",
"version" : "5.8.1"
"revision" : "f455c2975872ccd2d9c81594c658af65716e9b9a",
"version" : "5.9.1"
}
},
{
@@ -25,7 +25,7 @@
"location" : "https://github.com/hyperoslo/Cache.git",
"state" : {
"branch" : "master",
"revision" : "d048bf404a5c8362c6cf840c2096d5777975cd27"
"revision" : "f44a8f6b5ec27730198725ccc542fef0d1cc6b3d"
}
},
{
@@ -60,8 +60,7 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/cxfksword/MPVKit.git",
"state" : {
"revision" : "645f430ff0b99ccc2c61062727ad7e8bf32ca72a",
"version" : "0.37.0"
"revision" : "dca1e345a26d09a3d621d7656a94e6427f3f7b83"
}
},
{
@@ -87,8 +86,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/ashleymills/Reachability.swift",
"state" : {
"revision" : "c01127cb51f591045696128effe43c16840d08bf",
"version" : "5.2.0"
"revision" : "7b7018a69c84ea94ac2a38dff626e16ea81d1db9",
"version" : "5.2.1"
}
},
{
@@ -106,7 +105,7 @@
"location" : "https://github.com/SDWebImage/SDWebImage",
"state" : {
"branch" : "master",
"revision" : "a41be90abd89b125cd7588f20b9788108254091a"
"revision" : "f6afa0132961d593f07970d84e2d8b588c29ea04"
}
},
{
@@ -123,8 +122,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/SDWebImage/SDWebImageSwiftUI.git",
"state" : {
"revision" : "261b6cec35686d2dc192b809ab50742b4502a73b",
"version" : "2.2.6"
"revision" : "53573d6dd017e354c0e7d8f1c86b77ef1383c996",
"version" : "2.2.7"
}
},
{
@@ -132,8 +131,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/SDWebImage/SDWebImageWebPCoder.git",
"state" : {
"revision" : "acfb824ca5cd9dbde2c43dc6b5a008c6757dee85",
"version" : "0.14.3"
"revision" : "8a33fb3ca75a01267f775f891f7d61f675e95072",
"version" : "0.14.5"
}
},
{
@@ -177,8 +176,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/SwiftyJSON/SwiftyJSON.git",
"state" : {
"revision" : "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07",
"version" : "5.0.1"
"revision" : "af76cf3ef710b6ca5f8c05f3a31307d44a3c5828",
"version" : "5.0.2"
}
}
],