mirror of
https://github.com/yattee/yattee.git
synced 2025-12-13 11:38:15 +00:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc3492fd96 | ||
|
|
c7365a7dc1 | ||
|
|
fc9fc194f2 | ||
|
|
317ac63a3f | ||
|
|
dc7cee7388 | ||
|
|
1c5d909201 | ||
|
|
146da6b9cc | ||
|
|
6be13451e0 | ||
|
|
0c41ab6aa2 | ||
|
|
1b1e95711a | ||
|
|
13d4a592bc | ||
|
|
ab493614ba | ||
|
|
0b57187435 | ||
|
|
e7928d1016 | ||
|
|
b3d73aae92 | ||
|
|
bafcacb9a1 | ||
|
|
931d373d41 | ||
|
|
5d1620b0a0 | ||
|
|
44cfe8e6bc | ||
|
|
8220bbc3fe | ||
|
|
f01836010c | ||
|
|
37ccb27c8e | ||
|
|
93eb2eb258 | ||
|
|
ce9db8cd12 | ||
|
|
d361690d13 | ||
|
|
ded9699a3a | ||
|
|
101ddf79d5 | ||
|
|
d11c5a8c42 | ||
|
|
b2a84ef01b | ||
|
|
6c4eb0c840 | ||
|
|
2b41c73d56 | ||
|
|
516e305cd3 | ||
|
|
8921a38504 | ||
|
|
61d589a9b5 | ||
|
|
55cbd1fe80 | ||
|
|
d501cb938c | ||
|
|
8e97d3f42f | ||
|
|
64a18678ce | ||
|
|
522aecfbc1 | ||
|
|
f5e509c091 | ||
|
|
08c922f57c | ||
|
|
0e8436ab40 | ||
|
|
f3c876acf6 | ||
|
|
70d821fe5d | ||
|
|
9a450c9503 | ||
|
|
7e346bf49c | ||
|
|
35534bcbb1 | ||
|
|
94577332a1 | ||
|
|
56b17b0aa1 | ||
|
|
5512337984 |
23
CHANGELOG.md
23
CHANGELOG.md
@@ -1,10 +1,14 @@
|
||||
## Build 187
|
||||
* Allow import of accounts to manually added (not imported) instances
|
||||
* Add import export of missing settings
|
||||
* tvOS: Allow account picker by long pressing channels button in subscriptions view by @patelhiren in https://github.com/yattee/yattee/pull/704
|
||||
* macOS: Fix settings windows layout
|
||||
* Fix seek OSD layout on tvOS, revert OSD position
|
||||
* Translations update from Hosted Weblate by @weblate in https://github.com/yattee/yattee/pull/694
|
||||
## Build 188
|
||||
* Improved thumbnail handling by @stonerl in https://github.com/yattee/yattee/pull/740
|
||||
* iOS: make timestamps in comments touchable by @stonerl in https://github.com/yattee/yattee/pull/741
|
||||
* Improvements to opening channels from Videos by @stonerl in https://github.com/yattee/yattee/pull/742
|
||||
* Allow hiding comments by @stonerl in https://github.com/yattee/yattee/pull/744
|
||||
* Add option to exit fullscreen on end by @stonerl in https://github.com/yattee/yattee/pull/570
|
||||
* Only updateWatch status while video is playing by @stonerl in https://github.com/yattee/yattee/pull/745
|
||||
* Xcode 16 - update recommended settings by @stonerl in https://github.com/yattee/yattee/pull/737
|
||||
* Translations update from Hosted Weblate by @weblate in https://github.com/yattee/yattee/pull/724
|
||||
* Updated dependencies
|
||||
* Other minor changes and improvements
|
||||
|
||||
## Previous builds
|
||||
* Add skip, play/pause, and fullscreen shortcuts to macOS player (by @rickykresslein)
|
||||
@@ -19,6 +23,11 @@
|
||||
* 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)
|
||||
* Allow import of accounts to manually added (not imported) instances
|
||||
* Add import export of missing settings
|
||||
* macOS: Fix settings windows layout
|
||||
* Fix seek OSD layout on tvOS, revert OSD position
|
||||
* tvOS: Allow account picker by long pressing channels button in subscriptions view by @patelhiren in https://github.com/yattee/yattee/pull/704
|
||||
* tvOS: Refined Subscriptions View by @patelhiren in https://github.com/yattee/yattee/pull/697
|
||||
* More responsive UI when Favorites are used. by @stonerl in https://github.com/yattee/yattee/pull/695
|
||||
* Improved conditional proxying by @stonerl in https://github.com/yattee/yattee/pull/696
|
||||
|
||||
@@ -6,8 +6,10 @@ extension UIViewController {
|
||||
}
|
||||
|
||||
public class func swizzleHomeIndicatorProperty() {
|
||||
swizzle(origSelector: #selector(getter: UIViewController.prefersHomeIndicatorAutoHidden),
|
||||
withSelector: #selector(getter: UIViewController.swizzle_prefersHomeIndicatorAutoHidden),
|
||||
forClass: UIViewController.self)
|
||||
swizzle(
|
||||
origSelector: #selector(getter: UIViewController.prefersHomeIndicatorAutoHidden),
|
||||
withSelector: #selector(getter: UIViewController.swizzle_prefersHomeIndicatorAutoHidden),
|
||||
forClass: UIViewController.self
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
30
Gemfile.lock
30
Gemfile.lock
@@ -10,20 +10,20 @@ GEM
|
||||
artifactory (3.0.17)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.3.0)
|
||||
aws-partitions (1.952.0)
|
||||
aws-sdk-core (3.201.1)
|
||||
aws-partitions (1.968.0)
|
||||
aws-sdk-core (3.201.5)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.8)
|
||||
aws-sigv4 (~> 1.9)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.88.0)
|
||||
aws-sdk-core (~> 3, >= 3.201.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sdk-s3 (1.156.0)
|
||||
aws-sdk-s3 (1.159.0)
|
||||
aws-sdk-core (~> 3, >= 3.201.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sigv4 (1.8.0)
|
||||
aws-sigv4 (1.9.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
base64 (0.2.0)
|
||||
@@ -38,7 +38,7 @@ GEM
|
||||
domain_name (0.6.20240107)
|
||||
dotenv (2.8.1)
|
||||
emoji_regex (3.2.3)
|
||||
excon (0.110.0)
|
||||
excon (0.111.0)
|
||||
faraday (1.10.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
@@ -60,7 +60,7 @@ GEM
|
||||
faraday-httpclient (1.0.1)
|
||||
faraday-multipart (1.0.4)
|
||||
multipart-post (~> 2)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http (1.0.2)
|
||||
faraday-net_http_persistent (1.2.0)
|
||||
faraday-patron (1.0.0)
|
||||
faraday-rack (1.0.0)
|
||||
@@ -68,7 +68,7 @@ GEM
|
||||
faraday_middleware (1.2.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.3.1)
|
||||
fastlane (2.221.1)
|
||||
fastlane (2.222.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.8, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
@@ -126,7 +126,7 @@ 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.7.0)
|
||||
google-cloud-core (1.7.1)
|
||||
google-cloud-env (>= 1.0, < 3.a)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.6.0)
|
||||
@@ -147,14 +147,14 @@ GEM
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (>= 0.16, < 2.a)
|
||||
highline (2.0.3)
|
||||
http-cookie (1.0.6)
|
||||
http-cookie (1.0.7)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
jmespath (1.6.2)
|
||||
json (2.7.2)
|
||||
jwt (2.8.2)
|
||||
base64
|
||||
mini_magick (4.13.1)
|
||||
mini_magick (4.13.2)
|
||||
mini_mime (1.1.5)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.4.1)
|
||||
@@ -164,14 +164,14 @@ GEM
|
||||
optparse (0.5.0)
|
||||
os (1.1.4)
|
||||
plist (3.7.1)
|
||||
public_suffix (6.0.0)
|
||||
public_suffix (6.0.1)
|
||||
rake (13.2.1)
|
||||
representable (3.2.0)
|
||||
declarative (< 0.1.0)
|
||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rexml (3.2.9)
|
||||
rexml (3.3.6)
|
||||
strscan
|
||||
rouge (2.0.7)
|
||||
ruby2_keywords (0.0.5)
|
||||
@@ -197,13 +197,13 @@ GEM
|
||||
uber (0.1.0)
|
||||
unicode-display_width (2.5.0)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.24.0)
|
||||
xcodeproj (1.25.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
rexml (>= 3.3.2, < 4.0)
|
||||
xcpretty (0.3.0)
|
||||
rouge (~> 2.0.7)
|
||||
xcpretty-travis-formatter (1.0.1)
|
||||
|
||||
@@ -81,7 +81,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
|
||||
|
||||
configureTransformer(pathPattern("search/suggestions"), requestMethods: [.get]) { (content: Entity<JSON>) -> [String] in
|
||||
if let suggestions = content.json.dictionaryValue["suggestions"] {
|
||||
return suggestions.arrayValue.map { $0.stringValue.replacingHTMLEntities }
|
||||
return suggestions.arrayValue.map(\.stringValue).map(\.replacingHTMLEntities)
|
||||
}
|
||||
|
||||
return []
|
||||
|
||||
@@ -13,6 +13,7 @@ struct ChannelPlaylistsCacheModel: CacheModel {
|
||||
var storage = try? Storage<String, JSON>(
|
||||
diskConfig: Self.diskConfig,
|
||||
memoryConfig: Self.memoryConfig,
|
||||
fileManager: FileManager.default,
|
||||
transformer: BaseCacheModel.jsonTransformer
|
||||
)
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ struct ChannelsCacheModel: CacheModel {
|
||||
let storage = try? Storage<String, JSON>(
|
||||
diskConfig: Self.diskConfig,
|
||||
memoryConfig: Self.memoryConfig,
|
||||
fileManager: FileManager.default,
|
||||
transformer: BaseCacheModel.jsonTransformer
|
||||
)
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ struct FeedCacheModel: CacheModel {
|
||||
let storage = try? Storage<String, JSON>(
|
||||
diskConfig: Self.diskConfig,
|
||||
memoryConfig: Self.memoryConfig,
|
||||
fileManager: FileManager.default,
|
||||
transformer: BaseCacheModel.jsonTransformer
|
||||
)
|
||||
|
||||
@@ -22,7 +23,7 @@ struct FeedCacheModel: CacheModel {
|
||||
let date = iso8601DateFormatter.string(from: Date())
|
||||
logger.info("caching feed \(account.feedCacheKey) -- \(date)")
|
||||
let feedTimeObject: JSON = ["date": date]
|
||||
let videosObject: JSON = ["videos": videos.prefix(cacheLimit).map { $0.json.object }]
|
||||
let videosObject: JSON = ["videos": videos.prefix(cacheLimit).map(\.json.object)]
|
||||
try? storage?.setObject(feedTimeObject, forKey: feedTimeCacheKey(account.feedCacheKey))
|
||||
try? storage?.setObject(videosObject, forKey: account.feedCacheKey)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ struct PlaylistsCacheModel: CacheModel {
|
||||
let storage = try? Storage<String, JSON>(
|
||||
diskConfig: Self.diskConfig,
|
||||
memoryConfig: Self.memoryConfig,
|
||||
fileManager: FileManager.default,
|
||||
transformer: BaseCacheModel.jsonTransformer
|
||||
)
|
||||
|
||||
@@ -21,7 +22,7 @@ struct PlaylistsCacheModel: CacheModel {
|
||||
let date = iso8601DateFormatter.string(from: Date())
|
||||
logger.info("caching \(playlistCacheKey(account)) -- \(date)")
|
||||
let feedTimeObject: JSON = ["date": date]
|
||||
let playlistsObject: JSON = ["playlists": playlists.map { $0.json.object }]
|
||||
let playlistsObject: JSON = ["playlists": playlists.map(\.json.object)]
|
||||
try? storage?.setObject(feedTimeObject, forKey: playlistTimeCacheKey(account))
|
||||
try? storage?.setObject(playlistsObject, forKey: playlistCacheKey(account))
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ final class SubscribedChannelsModel: ObservableObject, CacheModel {
|
||||
let storage = try? Storage<String, JSON>(
|
||||
diskConfig: SubscribedChannelsModel.diskConfig,
|
||||
memoryConfig: SubscribedChannelsModel.memoryConfig,
|
||||
fileManager: FileManager.default,
|
||||
transformer: BaseCacheModel.jsonTransformer
|
||||
)
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ struct VideosCacheModel: CacheModel {
|
||||
let storage = try? Storage<String, JSON>(
|
||||
diskConfig: Self.diskConfig,
|
||||
memoryConfig: Self.memoryConfig,
|
||||
fileManager: FileManager.default,
|
||||
transformer: BaseCacheModel.jsonTransformer
|
||||
)
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ struct Channel: Identifiable, Hashable {
|
||||
"subscriptionsText": subscriptionsText as Any,
|
||||
"totalViews": totalViews as Any,
|
||||
"verified": verified as Any,
|
||||
"videos": videos.map { $0.json.object }
|
||||
"videos": videos.map(\.json.object)
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ struct ChannelPlaylist: Identifiable {
|
||||
"title": title,
|
||||
"thumbnailURL": thumbnailURL?.absoluteString ?? "",
|
||||
"channel": channel?.json.object ?? "",
|
||||
"videos": videos.map { $0.json.object },
|
||||
"videos": videos.map(\.json.object),
|
||||
"videosCount": String(videosCount ?? 0)
|
||||
]
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ final class CommentsModel: ObservableObject {
|
||||
.comments(video.videoID, page: page)?
|
||||
.load()
|
||||
.onSuccess { [weak self] response in
|
||||
guard let self = self else { return }
|
||||
guard let self else { return }
|
||||
if let commentsPage: CommentsPage = response.typedContent() {
|
||||
self.all += commentsPage.comments
|
||||
self.nextPage = commentsPage.nextPage
|
||||
|
||||
@@ -274,7 +274,7 @@ extension Country {
|
||||
|
||||
private static func filteredCountries(_ predicate: (String) -> Bool) -> [Country] {
|
||||
Country.allCases
|
||||
.map { $0.name }
|
||||
.map(\.name)
|
||||
.filter(predicate)
|
||||
.compactMap { string in Country.allCases.first { $0.name == string } }
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ final class FeedModel: ObservableObject, CacheModel {
|
||||
backgroundContext.perform { [weak self] in
|
||||
guard let self else { return }
|
||||
|
||||
let watched = self.watchFetchRequestResult(feed, context: self.backgroundContext).filter { $0.finished }
|
||||
let watched = self.watchFetchRequestResult(feed, context: self.backgroundContext).filter(\.finished)
|
||||
let unwatched = feed.filter { video in !watched.contains { $0.videoID == video.videoID } }
|
||||
let unwatchedCount = max(0, feed.count - watched.count)
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ extension PlayerModel {
|
||||
}
|
||||
|
||||
func updateWatch(finished: Bool = false, time: CMTime? = nil) {
|
||||
guard let currentVideo, saveHistory else { return }
|
||||
guard let currentVideo, saveHistory, isPlaying else { return }
|
||||
|
||||
let id = currentVideo.videoID
|
||||
let time = time ?? backend.currentTime
|
||||
|
||||
@@ -7,6 +7,7 @@ final class PlayerSettingsGroupExporter: SettingsGroupExporter {
|
||||
"playerInstanceID": Defaults[.playerInstanceID] ?? "",
|
||||
"pauseOnHidingPlayer": Defaults[.pauseOnHidingPlayer],
|
||||
"closeVideoOnEOF": Defaults[.closeVideoOnEOF],
|
||||
"exitFullscreenOnEOF": Defaults[.exitFullscreenOnEOF],
|
||||
"expandVideoDescription": Defaults[.expandVideoDescription],
|
||||
"collapsedLinesDescription": Defaults[.collapsedLinesDescription],
|
||||
"showChapters": Defaults[.showChapters],
|
||||
@@ -36,6 +37,8 @@ final class PlayerSettingsGroupExporter: SettingsGroupExporter {
|
||||
export["pauseOnEnteringBackground"].bool = Defaults[.pauseOnEnteringBackground]
|
||||
#endif
|
||||
|
||||
export["showComments"].bool = Defaults[.showComments]
|
||||
|
||||
#if !os(tvOS)
|
||||
export["showScrollToTopInComments"].bool = Defaults[.showScrollToTopInComments]
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,10 @@ struct PlayerSettingsGroupImporter {
|
||||
Defaults[.closeVideoOnEOF] = closeVideoOnEOF
|
||||
}
|
||||
|
||||
if let exitFullscreenOnEOF = json["exitFullscreenOnEOF"].bool {
|
||||
Defaults[.exitFullscreenOnEOF] = exitFullscreenOnEOF
|
||||
}
|
||||
|
||||
if let expandVideoDescription = json["expandVideoDescription"].bool {
|
||||
Defaults[.expandVideoDescription] = expandVideoDescription
|
||||
}
|
||||
@@ -83,6 +87,9 @@ struct PlayerSettingsGroupImporter {
|
||||
}
|
||||
#endif
|
||||
|
||||
if let showComments = json["showComments"].bool {
|
||||
Defaults[.showComments] = showComments
|
||||
}
|
||||
#if !os(tvOS)
|
||||
if let showScrollToTopInComments = json["showScrollToTopInComments"].bool {
|
||||
Defaults[.showScrollToTopInComments] = showScrollToTopInComments
|
||||
|
||||
@@ -464,8 +464,6 @@ final class MPVBackend: PlayerBackend {
|
||||
timeObserverThrottle.execute {
|
||||
self.model.updateWatch(time: self.currentTime)
|
||||
}
|
||||
|
||||
self.model.updateTime(self.currentTime!)
|
||||
}
|
||||
|
||||
private func stopClientUpdates() {
|
||||
|
||||
@@ -111,15 +111,22 @@ extension PlayerBackend {
|
||||
model.prepareCurrentItemForHistory(finished: true)
|
||||
|
||||
if model.queue.isEmpty {
|
||||
if Defaults[.closeVideoOnEOF] {
|
||||
#if os(tvOS)
|
||||
#if os(tvOS)
|
||||
if Defaults[.closeVideoOnEOF] {
|
||||
if model.activeBackend == .appleAVPlayer {
|
||||
model.avPlayerBackend.controller?.dismiss(animated: false)
|
||||
}
|
||||
#endif
|
||||
model.resetQueue()
|
||||
model.hide()
|
||||
}
|
||||
model.resetQueue()
|
||||
model.hide()
|
||||
}
|
||||
#else
|
||||
if Defaults[.closeVideoOnEOF] {
|
||||
model.resetQueue()
|
||||
model.hide()
|
||||
} else if Defaults[.exitFullscreenOnEOF], model.playingFullScreen {
|
||||
model.exitFullScreen()
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
model.advanceToNextItem()
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ final class PlayerModel: ObservableObject {
|
||||
}}
|
||||
@Published var aspectRatio = VideoPlayerView.defaultAspectRatio
|
||||
@Published var stream: Stream?
|
||||
@Published var currentRate: Double = 1.0 { didSet { handleCurrentRateChange() } }
|
||||
@Published var currentRate = 1.0 { didSet { handleCurrentRateChange() } }
|
||||
|
||||
@Published var qualityProfileSelection: QualityProfile? { didSet { handleQualityProfileChange() } }
|
||||
|
||||
@@ -1001,6 +1001,7 @@ final class PlayerModel: ObservableObject {
|
||||
|
||||
logger.info("entering fullscreen")
|
||||
toggleFullscreen(false, showControls: showControls)
|
||||
self.playingFullScreen = true
|
||||
}
|
||||
|
||||
func exitFullScreen(showControls: Bool = true) {
|
||||
@@ -1008,6 +1009,7 @@ final class PlayerModel: ObservableObject {
|
||||
|
||||
logger.info("exiting fullscreen")
|
||||
toggleFullscreen(true, showControls: showControls)
|
||||
self.playingFullScreen = false
|
||||
}
|
||||
|
||||
func updateNowPlayingInfo() {
|
||||
|
||||
@@ -74,7 +74,7 @@ extension PlayerModel {
|
||||
preservedTime = currentItem.playbackTime
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard let self else { return }
|
||||
guard let video = item.video else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@ struct ScreenSaverManager {
|
||||
return false
|
||||
}
|
||||
|
||||
noSleepReturn = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep as CFString,
|
||||
IOPMAssertionLevel(kIOPMAssertionLevelOn),
|
||||
reason as CFString,
|
||||
&noSleepAssertion)
|
||||
noSleepReturn = IOPMAssertionCreateWithName(
|
||||
kIOPMAssertionTypeNoDisplaySleep as CFString,
|
||||
IOPMAssertionLevel(kIOPMAssertionLevelOn),
|
||||
reason as CFString,
|
||||
&noSleepAssertion
|
||||
)
|
||||
return noSleepReturn == kIOReturnSuccess
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ struct QualityProfileBridge: Defaults.Bridge {
|
||||
"name": value.name ?? "",
|
||||
"backend": value.backend.rawValue,
|
||||
"resolution": value.resolution.rawValue,
|
||||
"formats": value.formats.map { $0.rawValue }.joined(separator: Self.formatsSeparator),
|
||||
"formats": value.formats.map(\.rawValue).joined(separator: Self.formatsSeparator),
|
||||
"order": value.order.map { String($0) }.joined(separator: Self.formatsSeparator) // New line
|
||||
]
|
||||
}
|
||||
|
||||
@@ -20,21 +20,23 @@ final class ThumbnailsModel: ObservableObject {
|
||||
return unloadable.contains(url)
|
||||
}
|
||||
|
||||
func best(_ video: Video) -> URL? {
|
||||
func best(_ video: Video) -> (url: URL?, quality: Thumbnail.Quality?) {
|
||||
for quality in availableQualitites {
|
||||
let url = video.thumbnailURL(quality: quality)
|
||||
if !isUnloadable(url) {
|
||||
return url
|
||||
return (url, quality)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return (nil, nil)
|
||||
}
|
||||
|
||||
private var availableQualitites: [Thumbnail.Quality] {
|
||||
switch Defaults[.thumbnailsQuality] {
|
||||
case .highest:
|
||||
return [.maxresdefault, .medium, .default]
|
||||
return [.maxres, .high, .medium, .default]
|
||||
case .high:
|
||||
return [.high, .medium, .default]
|
||||
case .medium:
|
||||
return [.medium, .default]
|
||||
case .low:
|
||||
|
||||
@@ -380,7 +380,7 @@ struct ChannelVideosView: View {
|
||||
navigation.sidebarSectionChanged.toggle()
|
||||
}
|
||||
} label: {
|
||||
Label("Subscribe", systemImage: "circle")
|
||||
Label("Subscribe", systemImage: "star.circle")
|
||||
.help("Subscribe")
|
||||
#if os(iOS)
|
||||
.labelStyle(.automatic)
|
||||
|
||||
@@ -4,6 +4,8 @@ import SwiftUI
|
||||
|
||||
enum Constants {
|
||||
static let overlayAnimation = Animation.linear(duration: 0.2)
|
||||
static let aspectRatio16x9 = 16.0 / 9.0
|
||||
static let aspectRatio4x3 = 4.0 / 3.0
|
||||
|
||||
static var isAppleTV: Bool {
|
||||
#if os(iOS)
|
||||
|
||||
@@ -75,6 +75,7 @@ extension Defaults.Keys {
|
||||
static let expandVideoDescription = Key<Bool>("expandVideoDescription", default: expandVideoDescriptionDefault)
|
||||
|
||||
static let collapsedLinesDescription = Key<Int>("collapsedLinesDescription", default: 5)
|
||||
static let exitFullscreenOnEOF = Key<Bool>("exitFullscreenOnEOF", default: true)
|
||||
|
||||
static let showChapters = Key<Bool>("showChapters", default: true)
|
||||
static let showChapterThumbnails = Key<Bool>("showChapterThumbnails", default: true)
|
||||
@@ -85,6 +86,7 @@ extension Defaults.Keys {
|
||||
|
||||
static let playerSidebar = Key<PlayerSidebarSetting>("playerSidebar", default: .defaultValue)
|
||||
static let showKeywords = Key<Bool>("showKeywords", default: false)
|
||||
static let showComments = Key<Bool>("showComments", default: true)
|
||||
#if !os(tvOS)
|
||||
static let showScrollToTopInComments = Key<Bool>("showScrollToTopInComments", default: true)
|
||||
#endif
|
||||
@@ -462,12 +464,14 @@ enum ButtonLabelStyle: String, CaseIterable, Defaults.Serializable {
|
||||
}
|
||||
|
||||
enum ThumbnailsQuality: String, CaseIterable, Defaults.Serializable {
|
||||
case highest, medium, low
|
||||
case highest, high, medium, low
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .highest:
|
||||
return "Highest quality".localized()
|
||||
return "Best quality".localized()
|
||||
case .high:
|
||||
return "High quality".localized()
|
||||
case .medium:
|
||||
return "Medium quality".localized()
|
||||
case .low:
|
||||
@@ -607,7 +611,7 @@ enum SponsorBlockColors: String {
|
||||
case music_offtopic = "#FF9900" // Orange
|
||||
|
||||
// Define all cases, can be used to iterate over the colors
|
||||
static let allCases: [SponsorBlockColors] = [.sponsor, .selfpromo, .interaction, .intro, .outro, .preview, .filler, .music_offtopic]
|
||||
static let allCases: [SponsorBlockColors] = [Self.sponsor, Self.selfpromo, Self.interaction, Self.intro, Self.outro, Self.preview, Self.filler, Self.music_offtopic]
|
||||
|
||||
// Create a dictionary with the category names as keys and colors as values
|
||||
static let dictionary: [String: String] = {
|
||||
|
||||
@@ -51,59 +51,108 @@ enum LanguageCodes: String, CaseIterable {
|
||||
|
||||
var description: String {
|
||||
switch self {
|
||||
case .Afrikaans: return "Afrikaans"
|
||||
case .Arabic: return "Arabic"
|
||||
case .Azerbaijani: return "Azerbaijani"
|
||||
case .Bengali: return "Bengali"
|
||||
case .Catalan: return "Catalan"
|
||||
case .Czech: return "Czech"
|
||||
case .Welsh: return "Welsh"
|
||||
case .Danish: return "Danish"
|
||||
case .German: return "German"
|
||||
case .Greek: return "Greek"
|
||||
case .English: return "English"
|
||||
case .English_GB: return "English (United Kingdom)"
|
||||
case .Spanish: return "Spanish"
|
||||
case .Persian: return "Persian"
|
||||
case .Finnish: return "Finnish"
|
||||
case .Filipino: return "Filipino"
|
||||
case .French: return "French"
|
||||
case .Irish: return "Irish"
|
||||
case .Hebrew: return "Hebrew"
|
||||
case .Hindi: return "Hindi"
|
||||
case .Hungarian: return "Hungarian"
|
||||
case .Indonesian: return "Indonesian"
|
||||
case .Italian: return "Italian"
|
||||
case .Japanese: return "Japanese"
|
||||
case .Javanese: return "Javanese"
|
||||
case .Korean: return "Korean"
|
||||
case .Lithuanian: return "Lithuanian"
|
||||
case .Malay: return "Malay"
|
||||
case .Maltese: return "Maltese"
|
||||
case .Dutch: return "Dutch"
|
||||
case .Norwegian: return "Norwegian"
|
||||
case .Polish: return "Polish"
|
||||
case .Portuguese: return "Portuguese"
|
||||
case .Romanian: return "Romanian"
|
||||
case .Russian: return "Russian"
|
||||
case .Slovak: return "Slovak"
|
||||
case .Slovene: return "Slovene"
|
||||
case .Swedish: return "Swedish"
|
||||
case .Swahili: return "Swahili"
|
||||
case .Thai: return "Thai"
|
||||
case .Tagalog: return "Tagalog"
|
||||
case .Turkish: return "Turkish"
|
||||
case .Ukrainian: return "Ukrainian"
|
||||
case .Urdu: return "Urdu"
|
||||
case .Uzbek: return "Uzbek"
|
||||
case .Vietnamese: return "Vietnamese"
|
||||
case .Xhosa: return "Xhosa"
|
||||
case .Chinese: return "Chinese"
|
||||
case .Zulu: return "Zulu"
|
||||
case .Afrikaans:
|
||||
return "Afrikaans"
|
||||
case .Arabic:
|
||||
return "Arabic"
|
||||
case .Azerbaijani:
|
||||
return "Azerbaijani"
|
||||
case .Bengali:
|
||||
return "Bengali"
|
||||
case .Catalan:
|
||||
return "Catalan"
|
||||
case .Czech:
|
||||
return "Czech"
|
||||
case .Welsh:
|
||||
return "Welsh"
|
||||
case .Danish:
|
||||
return "Danish"
|
||||
case .German:
|
||||
return "German"
|
||||
case .Greek:
|
||||
return "Greek"
|
||||
case .English:
|
||||
return "English"
|
||||
case .English_GB:
|
||||
return "English (United Kingdom)"
|
||||
case .Spanish:
|
||||
return "Spanish"
|
||||
case .Persian:
|
||||
return "Persian"
|
||||
case .Finnish:
|
||||
return "Finnish"
|
||||
case .Filipino:
|
||||
return "Filipino"
|
||||
case .French:
|
||||
return "French"
|
||||
case .Irish:
|
||||
return "Irish"
|
||||
case .Hebrew:
|
||||
return "Hebrew"
|
||||
case .Hindi:
|
||||
return "Hindi"
|
||||
case .Hungarian:
|
||||
return "Hungarian"
|
||||
case .Indonesian:
|
||||
return "Indonesian"
|
||||
case .Italian:
|
||||
return "Italian"
|
||||
case .Japanese:
|
||||
return "Japanese"
|
||||
case .Javanese:
|
||||
return "Javanese"
|
||||
case .Korean:
|
||||
return "Korean"
|
||||
case .Lithuanian:
|
||||
return "Lithuanian"
|
||||
case .Malay:
|
||||
return "Malay"
|
||||
case .Maltese:
|
||||
return "Maltese"
|
||||
case .Dutch:
|
||||
return "Dutch"
|
||||
case .Norwegian:
|
||||
return "Norwegian"
|
||||
case .Polish:
|
||||
return "Polish"
|
||||
case .Portuguese:
|
||||
return "Portuguese"
|
||||
case .Romanian:
|
||||
return "Romanian"
|
||||
case .Russian:
|
||||
return "Russian"
|
||||
case .Slovak:
|
||||
return "Slovak"
|
||||
case .Slovene:
|
||||
return "Slovene"
|
||||
case .Swedish:
|
||||
return "Swedish"
|
||||
case .Swahili:
|
||||
return "Swahili"
|
||||
case .Thai:
|
||||
return "Thai"
|
||||
case .Tagalog:
|
||||
return "Tagalog"
|
||||
case .Turkish:
|
||||
return "Turkish"
|
||||
case .Ukrainian:
|
||||
return "Ukrainian"
|
||||
case .Urdu:
|
||||
return "Urdu"
|
||||
case .Uzbek:
|
||||
return "Uzbek"
|
||||
case .Vietnamese:
|
||||
return "Vietnamese"
|
||||
case .Xhosa:
|
||||
return "Xhosa"
|
||||
case .Chinese:
|
||||
return "Chinese"
|
||||
case .Zulu:
|
||||
return "Zulu"
|
||||
}
|
||||
}
|
||||
|
||||
static func languageName(for code: String) -> String {
|
||||
return LanguageCodes(rawValue: code)?.description ?? "Unknown"
|
||||
return Self(rawValue: code)?.description ?? "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ struct OpenURLHandler {
|
||||
return accounts.api.channelByName(name)
|
||||
}
|
||||
|
||||
if let instance = InstancesModel.shared.all.first(where: { $0.app.supportsOpeningChannelsByName }) {
|
||||
if let instance = InstancesModel.shared.all.first(where: \.app.supportsOpeningChannelsByName) {
|
||||
return instance.anonymous.channelByName(name)
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ struct OpenURLHandler {
|
||||
return accounts.api.channelByUsername(username)
|
||||
}
|
||||
|
||||
if let instance = InstancesModel.shared.all.first(where: { $0.app.supportsOpeningChannelsByName }) {
|
||||
if let instance = InstancesModel.shared.all.first(where: \.app.supportsOpeningChannelsByName) {
|
||||
return instance.anonymous.channelByUsername(username)
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,8 @@ final class AppleAVPlayerViewController: UIViewController {
|
||||
_ sections: [NowPlayingView.ViewSection],
|
||||
title: String
|
||||
) -> UIHostingController<AnyView> {
|
||||
let controller = UIHostingController(rootView:
|
||||
let controller = UIHostingController(
|
||||
rootView:
|
||||
AnyView(
|
||||
NowPlayingView(sections: sections, inInfoViewController: true)
|
||||
.frame(maxHeight: 600)
|
||||
|
||||
@@ -265,7 +265,7 @@ struct PlayerControls: View {
|
||||
|
||||
var controlsBackgroundURL: URL? {
|
||||
if let video = player.videoForDisplay,
|
||||
let url = thumbnails.best(video)
|
||||
let url = thumbnails.best(video).url
|
||||
{
|
||||
return url
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ struct TimelineView: View {
|
||||
@State private var dragOffset: Double = 0
|
||||
@State private var draggedFrom: Double = 0
|
||||
|
||||
private var start: Double = 0.0
|
||||
private var start = 0.0
|
||||
private var height = 8.0
|
||||
|
||||
var cornerRadius: Double
|
||||
|
||||
@@ -90,8 +90,9 @@ final class PlayerViewController: UIViewController {
|
||||
_ sections: [NowPlayingView.ViewSection],
|
||||
title: String
|
||||
) -> UIHostingController<AnyView> {
|
||||
let controller = UIHostingController(rootView:
|
||||
AnyView(
|
||||
let controller = UIHostingController(
|
||||
rootView:
|
||||
AnyV/Users/arek/Developer/Yattee/Shared/Player/PlayerViewController.swift.iew(
|
||||
NowPlayingView(sections: sections, inInfoViewController: true)
|
||||
.frame(maxHeight: 600)
|
||||
.environmentObject(commentsModel)
|
||||
|
||||
@@ -65,7 +65,7 @@ import SwiftUI
|
||||
}
|
||||
|
||||
static var thumbnailHeight: Double {
|
||||
thumbnailWidth / (16 / 9)
|
||||
thumbnailWidth / Constants.aspectRatio16x9
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ import SwiftUI
|
||||
}
|
||||
|
||||
static var thumbnailHeight: Double {
|
||||
thumbnailWidth / 1.7777
|
||||
thumbnailWidth / Constants.aspectRatio16x9
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#if os(iOS)
|
||||
import ActiveLabel
|
||||
#endif
|
||||
import SDWebImageSwiftUI
|
||||
import SwiftUI
|
||||
|
||||
struct CommentView: View {
|
||||
let comment: Comment
|
||||
@Binding var repliesID: Comment.ID?
|
||||
var availableWidth: CGFloat
|
||||
|
||||
@State private var subscribed = false
|
||||
|
||||
@@ -127,7 +131,9 @@ struct CommentView: View {
|
||||
|
||||
Text(comment.time)
|
||||
.font(.caption2)
|
||||
#if !os(tvOS)
|
||||
.foregroundColor(.secondary)
|
||||
#endif
|
||||
}
|
||||
.lineLimit(1)
|
||||
}
|
||||
@@ -155,11 +161,11 @@ struct CommentView: View {
|
||||
Text("\(comment.likeCount.formattedAsAbbreviation())")
|
||||
}
|
||||
#if !os(tvOS)
|
||||
.foregroundColor(.secondary)
|
||||
.font(.system(size: 12))
|
||||
#endif
|
||||
}
|
||||
}
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
private var repliesButton: some View {
|
||||
@@ -177,7 +183,8 @@ struct CommentView: View {
|
||||
Text("Replies")
|
||||
}
|
||||
#if os(tvOS)
|
||||
.padding(10)
|
||||
.font(.system(size: 26))
|
||||
.padding(.vertical, 3)
|
||||
#endif
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
@@ -204,7 +211,7 @@ struct CommentView: View {
|
||||
Group {
|
||||
let last = comments.replies.last
|
||||
ForEach(comments.replies) { comment in
|
||||
Self(comment: comment, repliesID: $repliesID)
|
||||
Self(comment: comment, repliesID: $repliesID, availableWidth: availableWidth - 22)
|
||||
#if os(tvOS)
|
||||
.focusable()
|
||||
#endif
|
||||
@@ -220,22 +227,27 @@ struct CommentView: View {
|
||||
|
||||
private var commentText: some View {
|
||||
Group {
|
||||
let text = Text(comment.text)
|
||||
#if os(macOS)
|
||||
.font(.system(size: 14))
|
||||
#elseif os(iOS)
|
||||
.font(.system(size: 15))
|
||||
#endif
|
||||
.lineSpacing(3)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
|
||||
let rawText = comment.text
|
||||
if #available(iOS 15.0, macOS 12.0, *) {
|
||||
text
|
||||
#if !os(tvOS)
|
||||
.textSelection(.enabled)
|
||||
#if os(iOS)
|
||||
ActiveLabelCommentRepresentable(
|
||||
text: rawText,
|
||||
availableWidth: availableWidth
|
||||
)
|
||||
#elseif os(macOS)
|
||||
Text(rawText)
|
||||
.font(.system(size: 14))
|
||||
.lineSpacing(3)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.textSelection(.enabled)
|
||||
#else
|
||||
Text(comment.text)
|
||||
#endif
|
||||
} else {
|
||||
text
|
||||
Text(rawText)
|
||||
.font(.system(size: 15))
|
||||
.lineSpacing(3)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,13 +260,78 @@ struct CommentView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
struct ActiveLabelCommentRepresentable: UIViewRepresentable {
|
||||
var text: String
|
||||
var availableWidth: CGFloat
|
||||
|
||||
@State private var label = ActiveLabel()
|
||||
|
||||
@Environment(\.openURL) private var openURL
|
||||
|
||||
var player = PlayerModel.shared
|
||||
|
||||
func makeUIView(context _: Context) -> some UIView {
|
||||
customizeLabel()
|
||||
return label
|
||||
}
|
||||
|
||||
func updateUIView(_: UIViewType, context _: Context) {
|
||||
label.preferredMaxLayoutWidth = availableWidth
|
||||
}
|
||||
|
||||
func customizeLabel() {
|
||||
label.customize { label in
|
||||
label.enabledTypes = [.url, .timestamp]
|
||||
label.text = text
|
||||
label.font = .systemFont(ofSize: 15)
|
||||
label.lineSpacing = 3
|
||||
label.preferredMaxLayoutWidth = availableWidth
|
||||
label.URLColor = UIColor(Color.accentColor)
|
||||
label.timestampColor = UIColor(Color.accentColor)
|
||||
label.handleURLTap(urlTapHandler(_:))
|
||||
label.handleTimestampTap(timestampTapHandler(_:))
|
||||
label.numberOfLines = 0
|
||||
}
|
||||
}
|
||||
|
||||
private func urlTapHandler(_ url: URL) {
|
||||
var urlToOpen = url
|
||||
|
||||
if var components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
|
||||
components.scheme = "yattee"
|
||||
if let yatteeURL = components.url {
|
||||
let parser = URLParser(url: urlToOpen, allowFileURLs: false)
|
||||
let destination = parser.destination
|
||||
if destination == .video,
|
||||
parser.videoID == player.currentVideo?.videoID,
|
||||
let time = parser.time
|
||||
{
|
||||
player.backend.seek(to: Double(time), seekType: .userInteracted)
|
||||
return
|
||||
}
|
||||
if destination != nil {
|
||||
urlToOpen = yatteeURL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
openURL(urlToOpen)
|
||||
}
|
||||
|
||||
private func timestampTapHandler(_ timestamp: Timestamp) {
|
||||
player.backend.seek(to: timestamp.timeInterval, seekType: .userInteracted)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct CommentView_Previews: PreviewProvider {
|
||||
static var fixture: Comment {
|
||||
Comment.fixture
|
||||
}
|
||||
|
||||
static var previews: some View {
|
||||
CommentView(comment: fixture, repliesID: .constant(fixture.id))
|
||||
CommentView(comment: fixture, repliesID: .constant(fixture.id), availableWidth: 375)
|
||||
.padding(5)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import SwiftUI
|
||||
|
||||
struct CommentsView: View {
|
||||
@State private var repliesID: Comment.ID?
|
||||
@State private var availableWidth = 0.0
|
||||
|
||||
@ObservedObject private var comments = CommentsModel.shared
|
||||
|
||||
@@ -14,16 +15,21 @@ struct CommentsView: View {
|
||||
} else if !comments.loaded {
|
||||
PlaceholderProgressView()
|
||||
} else {
|
||||
let last = comments.all.last
|
||||
LazyVStack {
|
||||
ForEach(comments.all) { comment in
|
||||
CommentView(comment: comment, repliesID: $repliesID)
|
||||
CommentView(comment: comment, repliesID: $repliesID, availableWidth: availableWidth)
|
||||
.onAppear {
|
||||
comments.loadNextPageIfNeeded(current: comment)
|
||||
}
|
||||
.borderBottom(height: comment != last ? 0.5 : 0, color: Color("ControlsBorderColor"))
|
||||
.borderBottom(height: comment != comments.all.last ? 0.5 : 0, color: Color("ControlsBorderColor"))
|
||||
}
|
||||
}
|
||||
.background(GeometryReader { geometry in
|
||||
Color.clear
|
||||
.onAppear {
|
||||
self.availableWidth = Double(geometry.size.width)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
|
||||
@@ -47,6 +47,12 @@ struct VideoDetails: View {
|
||||
.frame(width: 40, height: 40)
|
||||
.buttonStyle(.plain)
|
||||
.padding(.trailing, 5)
|
||||
// TODO: when setting tvOS minimum to 16, the platform modifier can be removed
|
||||
#if !os(tvOS)
|
||||
.simultaneousGesture(
|
||||
TapGesture() // Ensures the button tap is recognized
|
||||
)
|
||||
#endif
|
||||
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
HStack {
|
||||
@@ -55,6 +61,14 @@ struct VideoDetails: View {
|
||||
.font(.subheadline)
|
||||
.fontWeight(.semibold)
|
||||
.lineLimit(1)
|
||||
// TODO: when setting tvOS minimum to 16, the platform modifier can be removed
|
||||
#if !os(tvOS)
|
||||
.onTapGesture {
|
||||
guard let channel = video?.channel else { return }
|
||||
NavigationModel.shared.openChannel(channel, navigationStyle: .sidebar)
|
||||
}
|
||||
.accessibilityAddTraits(.isButton)
|
||||
#endif
|
||||
} else if model.videoBeingOpened != nil {
|
||||
Text("Yattee")
|
||||
.font(.subheadline)
|
||||
@@ -189,6 +203,7 @@ struct VideoDetails: View {
|
||||
@Default(.showChapterThumbnails) private var showChapterThumbnails
|
||||
@Default(.showChapterThumbnailsOnlyWhenDifferent) private var showChapterThumbnailsOnlyWhenDifferent
|
||||
@Default(.showRelated) private var showRelated
|
||||
@Default(.showComments) private var showComments
|
||||
#if !os(tvOS)
|
||||
@Default(.showScrollToTopInComments) private var showScrollToTopInComments
|
||||
#endif
|
||||
@@ -208,16 +223,18 @@ struct VideoDetails: View {
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.contentShape(Rectangle())
|
||||
.padding(.horizontal, 16)
|
||||
// swiftlint:disable trailing_closure
|
||||
// TODO: when setting tvOS minimum to 16, the platform modifier can be removed
|
||||
#if !os(tvOS)
|
||||
.tapRecognizer(
|
||||
tapSensitivity: 0.2,
|
||||
doubleTapAction: {
|
||||
.simultaneousGesture( // Simultaneous gesture to prioritize button tap
|
||||
TapGesture(count: 2).onEnded {
|
||||
withAnimation(.default) {
|
||||
fullScreen.toggle()
|
||||
}
|
||||
}
|
||||
)
|
||||
#endif
|
||||
// swiftlint:enable trailing_closure
|
||||
|
||||
VideoActions(video: player.videoForDisplay)
|
||||
.padding(.vertical, 5)
|
||||
@@ -284,6 +301,8 @@ struct VideoDetails: View {
|
||||
switch page {
|
||||
case .queue:
|
||||
return !sidebarQueue && player.isAdvanceToNextItemAvailable
|
||||
case .comments:
|
||||
return showComments
|
||||
default:
|
||||
return !video.isLocal
|
||||
}
|
||||
@@ -362,10 +381,12 @@ struct VideoDetails: View {
|
||||
PlayerQueueView(sidebarQueue: false)
|
||||
.padding(.horizontal)
|
||||
case .comments:
|
||||
CommentsView()
|
||||
.onAppear {
|
||||
comments.loadIfNeeded()
|
||||
}
|
||||
if showComments {
|
||||
CommentsView()
|
||||
.onAppear {
|
||||
comments.loadIfNeeded()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.bottom, 60)
|
||||
|
||||
@@ -19,7 +19,7 @@ struct VideoPlayerView: View {
|
||||
static let hiddenOffset = 0.0
|
||||
#endif
|
||||
|
||||
static let defaultAspectRatio = 16 / 9.0
|
||||
static let defaultAspectRatio = Constants.aspectRatio16x9
|
||||
static var defaultMinimumHeightLeft: Double {
|
||||
#if os(macOS)
|
||||
335
|
||||
@@ -281,7 +281,7 @@ struct VideoPlayerView: View {
|
||||
}
|
||||
.gesture(player.controls.presentingOverlays ? nil : playerDragGesture)
|
||||
#if os(macOS)
|
||||
.onAppear(perform: {
|
||||
.onAppear {
|
||||
NSEvent.addLocalMonitorForEvents(matching: [.mouseMoved]) {
|
||||
hoverThrottle.execute {
|
||||
if !player.currentItem.isNil, hoveringPlayer {
|
||||
@@ -291,7 +291,7 @@ struct VideoPlayerView: View {
|
||||
|
||||
return $0
|
||||
}
|
||||
})
|
||||
}
|
||||
#endif
|
||||
|
||||
.background(Color.black)
|
||||
|
||||
@@ -15,7 +15,7 @@ struct SearchTextField: View {
|
||||
#if os(macOS)
|
||||
Image(systemName: "magnifyingglass")
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.scaledToFill()
|
||||
.frame(width: 12, height: 12)
|
||||
.padding(.horizontal, 8)
|
||||
.opacity(0.8)
|
||||
|
||||
@@ -8,9 +8,11 @@ struct PlayerSettings: View {
|
||||
@Default(.playerSidebar) private var playerSidebar
|
||||
|
||||
@Default(.showKeywords) private var showKeywords
|
||||
@Default(.showComments) private var showComments
|
||||
#if !os(tvOS)
|
||||
@Default(.showScrollToTopInComments) private var showScrollToTopInComments
|
||||
@Default(.collapsedLinesDescription) private var collapsedLinesDescription
|
||||
@Default(.exitFullscreenOnEOF) private var exitFullscreenOnEOF
|
||||
#endif
|
||||
@Default(.expandVideoDescription) private var expandVideoDescription
|
||||
@Default(.pauseOnHidingPlayer) private var pauseOnHidingPlayer
|
||||
@@ -85,6 +87,9 @@ struct PlayerSettings: View {
|
||||
}
|
||||
pauseOnHidingPlayerToggle
|
||||
closeVideoOnEOFToggle
|
||||
#if !os(tvOS)
|
||||
exitFullscreenOnEOFToggle
|
||||
#endif
|
||||
#if !os(macOS)
|
||||
pauseOnEnteringBackgroundToogle
|
||||
#endif
|
||||
@@ -175,6 +180,7 @@ struct PlayerSettings: View {
|
||||
if !accounts.isEmpty {
|
||||
keywordsToggle
|
||||
|
||||
commentsToggle
|
||||
#if !os(tvOS)
|
||||
showScrollToTopInCommentsToggle
|
||||
#endif
|
||||
@@ -250,9 +256,13 @@ struct PlayerSettings: View {
|
||||
.modifier(SettingsPickerModifier())
|
||||
}
|
||||
|
||||
private var commentsToggle: some View {
|
||||
Toggle("Show comments", isOn: $showComments)
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
private var showScrollToTopInCommentsToggle: some View {
|
||||
Toggle("Show scroll to top button in comments", isOn: $showScrollToTopInComments)
|
||||
Toggle("Show scroll to top button in comments", isOn: $showScrollToTopInComments).disabled(!showComments)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -294,6 +304,13 @@ struct PlayerSettings: View {
|
||||
Toggle("Close video and player on end", isOn: $closeVideoOnEOF)
|
||||
}
|
||||
|
||||
#if !os(tvOS)
|
||||
private var exitFullscreenOnEOFToggle: some View {
|
||||
Toggle("Exit fullscreen on end", isOn: $exitFullscreenOnEOF)
|
||||
.disabled(closeVideoOnEOF)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !os(macOS)
|
||||
private var pauseOnEnteringBackgroundToogle: some View {
|
||||
Toggle("Pause when entering background", isOn: $pauseOnEnteringBackground)
|
||||
|
||||
@@ -380,7 +380,7 @@ struct QualityProfileForm: View {
|
||||
func submitForm() {
|
||||
guard valid else { return }
|
||||
|
||||
let activeFormats = orderedFormats.filter { $0.isActive }.map { $0.format }
|
||||
let activeFormats = orderedFormats.filter(\.isActive).map(\.format)
|
||||
|
||||
let formProfile = QualityProfile(
|
||||
id: qualityProfile?.id ?? UUID().uuidString,
|
||||
|
||||
@@ -15,7 +15,7 @@ struct FeedView: View {
|
||||
#endif
|
||||
|
||||
var videos: [ContentItem] {
|
||||
guard let selectedChannel = selectedChannel else {
|
||||
guard let selectedChannel else {
|
||||
return ContentItem.array(of: feed.videos)
|
||||
}
|
||||
return ContentItem.array(of: feed.videos.filter {
|
||||
@@ -24,9 +24,7 @@ struct FeedView: View {
|
||||
}
|
||||
|
||||
var channels: [Channel] {
|
||||
feed.videos.map {
|
||||
$0.channel
|
||||
}.unique()
|
||||
feed.videos.map(\.channel).unique()
|
||||
}
|
||||
|
||||
@State private var selectedChannel: Channel?
|
||||
@@ -272,7 +270,7 @@ struct FeedView: View {
|
||||
}
|
||||
|
||||
var channelHeaderView: some View {
|
||||
guard let selectedChannel = selectedChannel else {
|
||||
guard let selectedChannel else {
|
||||
return AnyView(
|
||||
Text("All Channels")
|
||||
.font(.caption)
|
||||
|
||||
@@ -6,7 +6,7 @@ struct TrendingCountry: View {
|
||||
|
||||
@StateObject private var store = Store(Country.allCases)
|
||||
|
||||
@State private var query: String = ""
|
||||
@State private var query = ""
|
||||
@State private var selection: Country?
|
||||
|
||||
@Environment(\.colorScheme) private var colorScheme
|
||||
|
||||
@@ -26,8 +26,7 @@ struct URLParser {
|
||||
urlString.contains("youtube.com") ||
|
||||
urlString.contains("youtu.be") ||
|
||||
urlString.contains("youtube-nocookie.com"),
|
||||
let url = URL(string: "https://\(urlString)"
|
||||
)
|
||||
let url = URL(string: "https://\(urlString)")
|
||||
{
|
||||
self.url = url
|
||||
}
|
||||
@@ -176,10 +175,8 @@ struct URLParser {
|
||||
private func removePrefixes(_ value: String, _ prefixes: [String]) -> String {
|
||||
var value = value
|
||||
|
||||
for prefix in prefixes {
|
||||
if value.hasPrefix(prefix) {
|
||||
value.removeFirst(prefix.count)
|
||||
}
|
||||
for prefix in prefixes where value.hasPrefix(prefix) {
|
||||
value.removeFirst(prefix.count)
|
||||
}
|
||||
|
||||
return value
|
||||
|
||||
@@ -219,22 +219,18 @@ struct VideoBanner: View {
|
||||
return watch!.finished ? 0.5 : 1
|
||||
}
|
||||
|
||||
private var thumbnailWidth: Double {
|
||||
#if os(tvOS)
|
||||
356
|
||||
#else
|
||||
120
|
||||
#endif
|
||||
}
|
||||
|
||||
private var thumbnailHeight: Double {
|
||||
#if os(tvOS)
|
||||
200
|
||||
#else
|
||||
72
|
||||
75
|
||||
#endif
|
||||
}
|
||||
|
||||
private var thumbnailWidth: Double {
|
||||
thumbnailHeight * Constants.aspectRatio16x9
|
||||
}
|
||||
|
||||
private var videoDurationLabel: String? {
|
||||
guard videoDuration != 0 else { return nil }
|
||||
return (videoDuration ?? video?.length)?.formattedAsPlaybackTime()
|
||||
|
||||
@@ -440,7 +440,7 @@ struct VideoCell: View {
|
||||
#endif
|
||||
}
|
||||
.mask(RoundedRectangle(cornerRadius: thumbnailRoundingCornerRadius))
|
||||
.modifier(AspectRatioModifier())
|
||||
.aspectRatio(Constants.aspectRatio16x9, contentMode: .fill)
|
||||
}
|
||||
|
||||
private var time: String? {
|
||||
@@ -471,24 +471,6 @@ struct VideoCell: View {
|
||||
.lineLimit(lineLimit)
|
||||
.truncationMode(.middle)
|
||||
}
|
||||
|
||||
struct AspectRatioModifier: ViewModifier {
|
||||
@Environment(\.horizontalCells) private var horizontalCells
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
Group {
|
||||
if horizontalCells {
|
||||
content
|
||||
} else {
|
||||
content
|
||||
.aspectRatio(
|
||||
VideoPlayerView.defaultAspectRatio,
|
||||
contentMode: .fill
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct VideoCellThumbnail: View {
|
||||
@@ -496,7 +478,15 @@ struct VideoCellThumbnail: View {
|
||||
@ObservedObject private var thumbnails = ThumbnailsModel.shared
|
||||
|
||||
var body: some View {
|
||||
ThumbnailView(url: thumbnails.best(video))
|
||||
GeometryReader { geometry in
|
||||
let (url, quality) = thumbnails.best(video)
|
||||
let aspectRatio = (quality == .default || quality == .high) ? Constants.aspectRatio4x3 : Constants.aspectRatio16x9
|
||||
|
||||
ThumbnailView(url: url)
|
||||
.aspectRatio(aspectRatio, contentMode: .fill)
|
||||
.frame(width: geometry.size.width, height: geometry.size.height)
|
||||
.clipped()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ struct YatteeApp: App {
|
||||
.commands {
|
||||
SidebarCommands()
|
||||
|
||||
CommandGroup(replacing: .newItem, addition: {})
|
||||
CommandGroup(replacing: .newItem) {}
|
||||
|
||||
MenuCommands(model: Binding<MenuModel>(get: { MenuModel.shared }, set: { _ in }))
|
||||
}
|
||||
|
||||
@@ -487,3 +487,5 @@
|
||||
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "ایرادها و پیشنهادی خوب برای امکانات را میتوانید به GitHub issues tracker بفرستید. ";
|
||||
"Copy %@ link" = "پیوند %@ را کپی کنید";
|
||||
"Copy %@ link with time" = "پیوند %@ با مهرزمان کپی کنید";
|
||||
"Decreased opacity" = "کاهش تاری";
|
||||
"Decrease rate" = "کاهش نرخ";
|
||||
|
||||
564
Shared/fi.lproj/Localizable.strings
Normal file
564
Shared/fi.lproj/Localizable.strings
Normal file
@@ -0,0 +1,564 @@
|
||||
|
||||
|
||||
" subscribers" = " tilaajaa";
|
||||
"%@ Channel" = "%@ Kanava";
|
||||
"%@ subscribers" = "%@ tilaajaa";
|
||||
"%lld videos" = "%lld videota";
|
||||
"Accounts" = "Tilit";
|
||||
"Add Account" = "Lisää tili";
|
||||
"Add Location" = "Lisää Sijainti";
|
||||
"Add profile..." = "Lisää profiili...";
|
||||
"Add to %@" = "Lisää kohteeseen %@";
|
||||
"Add to Favorites" = "Lisää Suosikeihin";
|
||||
"Advanced" = "Edistynyt";
|
||||
"Always use AVPlayer for live videos" = "Käytä aina AVPlayeriä live videoille";
|
||||
"Anonymous" = "Anonyymi";
|
||||
"Badge" = "Merkki";
|
||||
"Backend" = "Backend";
|
||||
"Badge color" = "Merkin väri";
|
||||
"Based on system color scheme" = "Järjestelmän väriteeman mukainen";
|
||||
"Battery" = "Akku";
|
||||
"Blue" = "Sininen";
|
||||
"Buffering stream..." = "Puskuroidaan...";
|
||||
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "Virheilmoitukset ja hyvät kehitysideat voi lähettää GitHubin ongelmien seurantaan. ";
|
||||
"Cancel" = "Peruta";
|
||||
"Captions" = "Tekstitykset";
|
||||
"Categories to Skip" = "Luokat jotka ohitetaan";
|
||||
"Category" = "Luokka";
|
||||
"Charging" = "Ladattaessa";
|
||||
"Clear" = "Tyhjennä";
|
||||
"Clear All" = "Tyhjennä kaikki";
|
||||
"Clear Search History" = "Tyhjennä hakuhistoria";
|
||||
"Clear Search History..." = "Tyhjennä hakuhistoria...";
|
||||
"Close PiP when player is opened" = "Sulje Kuva kuvassa, kun soitin avataan";
|
||||
"Close PiP when starting playing other video" = "Sulje Kuva kuvassa, kun aloitetaan toisen videon toisto";
|
||||
"Close player when closing video" = "Sulje soitin, kun video suljetaan";
|
||||
"Close player when starting PiP" = "Sulje soitin, kun Kuva kuvassa aktivoidaan";
|
||||
"Close Video" = "Sulje video";
|
||||
"Close video after playing last in the queue" = "Sulje video, kun jonon viimeinen toistettu";
|
||||
"Comments" = "Kommentit";
|
||||
"Connected successfully (%@)" = "Yhdistetty onnistuneesti (%@)";
|
||||
"Connection failed" = "Yhteys epäonnistui";
|
||||
"Contact" = "Yhteystiedot";
|
||||
"Continue" = "Jatka";
|
||||
"Continue from %@" = "Jatka kohdasta %@";
|
||||
"Contributing" = "Osallistuminen";
|
||||
"Controls" = "Säätimet";
|
||||
"Copy %@ link" = "Kopioi %@ linkki";
|
||||
"Copy %@ link with time" = "Kopioi %@ linkki ja aika";
|
||||
"Could not load locations manifest" = "SIjaintiluetteloa ei voitu ladata";
|
||||
"Country" = "Maa";
|
||||
"Country Name or Code" = "Maan nimi tai koodi";
|
||||
"Create Playlist" = "Luo soittolista";
|
||||
"Current: %@\n%@" = "Nykyinen: %@\n%@";
|
||||
"Custom" = "Mukautettu";
|
||||
"Custom Locations" = "Mukautetut sijainnit";
|
||||
"Date" = "Päivämäärä";
|
||||
"Decrease rate" = "Vähennä nopeutta";
|
||||
"Decreased opacity" = "Vähennetty opasiteetti";
|
||||
"Delete" = "Poista";
|
||||
"Disabled" = "Pois käytöstä";
|
||||
"Discord Server" = "Discord-serveri";
|
||||
"Discussions take place in Discord and Matrix. It's a good spot for general questions." = "Keskusteluja käydään Matrixissa ja Discordissa. Se on hyvä paikka yleisiin kysymyksiin.";
|
||||
"Don't use public locations" = "Älä käytä julkisia sijainteja";
|
||||
"Donations" = "Lahjoitukset";
|
||||
"Done" = "Tehty";
|
||||
"Duration" = "Kestoaika";
|
||||
"Edit" = "Muokkaa";
|
||||
"Edit Playlist" = "Muokkaa soittolistaa";
|
||||
"Edit Quality Profile" = "Muokkaa laatuprofiilia";
|
||||
"Edit..." = "Muokkaa...";
|
||||
"Enable logging" = "Kytke loki käyttöön";
|
||||
"Enable Return YouTube Dislike" = "Palauta YouTube Dislike";
|
||||
"Enter fullscreen in landscape" = "Siirry koko näytön tilaan vaakasuunnassa";
|
||||
"Error" = "Virhe";
|
||||
"Error when accessing playlist" = "Virhe soittolistaa avatessa";
|
||||
"Favorites" = "Suosikit";
|
||||
"Find Other" = "Etsi muu";
|
||||
"Finding something to play..." = "Etsitään jotain toistettavaksi...";
|
||||
"Frontend URL" = "Etusivun URL";
|
||||
"Fullscreen size" = "Koko täydellä näytöllä";
|
||||
"High" = "Korkea";
|
||||
"Highest" = "Korkein";
|
||||
"Gaming" = "Pelaaminen";
|
||||
"Help" = "Apua";
|
||||
"History" = "Historia";
|
||||
"Honor orientation lock" = "Kunnioita näytön suunnan lukitusta";
|
||||
"Hour" = "Tunti";
|
||||
"I am lost" = "Olen eksyksissä";
|
||||
"I found a bug /" = "Löysin bugin";
|
||||
"I have a feature request" = "Minulla on ominaisuuspyyntö";
|
||||
"I like this app!" = "Tykkään tästä sovelluksesta!";
|
||||
"If you are reporting a bug, include all relevant details (especially: app version, used device and system version, steps to reproduce)." = "Jos raportoit virheestä, sisällytä kaikki asiaankuuluvat tiedot (erityisesti: sovellusversio, käytetty laite- ja järjestelmäversio, kuinka virheen voi toistaa).";
|
||||
"Increase rate" = "Lisää nopeutta";
|
||||
"Info" = "Info";
|
||||
"Instance of current account" = "Nykyisen tilin instanssi";
|
||||
"Interaction" = "Vuorovaikutus";
|
||||
"Interface" = "Käyttöliittymä";
|
||||
"Issues Tracker" = "Ongelmien seuranta";
|
||||
"Large" = "Suuri";
|
||||
"Large layout is not suitable for all devices and using it may cause controls not to fit on the screen." = "Suuri asettelu ei sovellu kaikille laitteille. Käyttämällä sitä, kaikki säätimet eivät välttämättä sovi näytölle.";
|
||||
"Loading..." = "Ladataan...";
|
||||
"Locations" = "Sijainnit";
|
||||
"Lock portrait mode" = "Lukitse muotokuvatila";
|
||||
"Long" = "Pitkä";
|
||||
"Low" = "Matala";
|
||||
"Low quality" = "Matala laatu";
|
||||
"Lowest" = "Matalin";
|
||||
"Mark video as watched after playing" = "Merkitse video katsotuksi toiston jälkeen";
|
||||
"Mark watched videos with" = "Merkitse katsotut videot";
|
||||
"Matrix Channel" = "Matrix-kanava";
|
||||
"Medium" = "Keskikoko";
|
||||
"Milestones" = "Virstanpylväitä";
|
||||
"Month" = "Kuukausi";
|
||||
"Music" = "Musiikki";
|
||||
"New Playlist" = "Uusi soittolista";
|
||||
"No description" = "Ei kuvausta";
|
||||
"No Playlists" = "Ei soittolistoja";
|
||||
"Normal" = "Normaali";
|
||||
"Not Playing" = "Ei toisteta";
|
||||
"Nothing" = "Ei mitään";
|
||||
"Only when signed in" = "Vain sisäänkirjautuneena";
|
||||
"Open Settings" = "Avaa asetukset";
|
||||
"Opening audio stream…" = "Avataan äänistreamia…";
|
||||
"Orientation" = "Suunta";
|
||||
"Outro" = "Outro";
|
||||
"Pause" = "Tauko";
|
||||
"Pause when entering background" = "Tauko, kun siirrytään taustalle";
|
||||
"Play All" = "Toista kaikki";
|
||||
"Play in PiP" = "Toista Kuva kuvassa";
|
||||
"Play Now" = "Toista nyt";
|
||||
"Playlist" = "Soittolista";
|
||||
"Playlists" = "Soittolistat";
|
||||
"Popular" = "Suositut";
|
||||
"Preferred Formats" = "Suositut formaatit";
|
||||
"Proxy videos" = "Videot välityspalvelimen kautta";
|
||||
"Public Locations" = "Julkiset sijainnit";
|
||||
"Quality" = "Laatu";
|
||||
"Quality Profile" = "Laatuprofiili";
|
||||
"Queue" = "Jono";
|
||||
"Queue is empty" = "Jono on tyhjä";
|
||||
"Rating" = "Arvosana";
|
||||
"Recents" = "Viimeaikaiset";
|
||||
"Red" = "Punainen";
|
||||
"Refresh" = "Päivitä";
|
||||
"Regular size" = "Tavallinen koko";
|
||||
"Regular Size" = "Tavallinen Koko";
|
||||
"Related" = "Liittyviä";
|
||||
"Relevance" = "Merkitys";
|
||||
"Remove from Favorites" = "Poista suosikeista";
|
||||
"Remove from history" = "Poista historiasta";
|
||||
"Remove from Playlist" = "Poista soittolistasta";
|
||||
"Replies" = "Vastaukset";
|
||||
"Reset" = "Nollaa";
|
||||
"Reset search filters" = "Nollaa hakusuodattimet";
|
||||
"Reset watched status when playing again" = "Nollaa katsottu-tila kun toistetaan uudelleen";
|
||||
"Resolution" = "Resoluutio";
|
||||
"Restart" = "Käynnistä uudelleen";
|
||||
"Restart the app to apply the settings above." = "Käynnistä sovellus uudelleen yllä olevien asetusten käyttämiseksi.";
|
||||
"Restart/Play next" = "Käynnistä uudelleen/Toista seuraava";
|
||||
"Restore default profiles..." = "Palauta oletusprofiilit...";
|
||||
"Rotate to portrait when exiting fullscreen" = "Käännä pystyasentoon kun poistutaan koko näytön tilasta";
|
||||
"Round corners" = "Pyöreät kulmat";
|
||||
"Save" = "Tallenna";
|
||||
"Save history of played videos" = "Tallenna toistettujen videoiden historia";
|
||||
"Save history of searches, channels and playlists" = "Tallenna hakujen, kanavien ja soittolistojen historia";
|
||||
"Search" = "Haku";
|
||||
"Search..." = "Haku...";
|
||||
"Sections" = "Osat";
|
||||
"Seek gesture sensitivity" = "Kelaus eleen herkkyys";
|
||||
"Seek gesture speed" = "Kelaus eleen nopeus";
|
||||
"Seek with horizontal swipe on video" = "Kelaa vaakasuuntaisella pyyhkäisyllä videossa";
|
||||
"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." = "Osiot jotka yleensä löytyvät videon alusta ja jotka sisältävät animaatioita, still-kuvia tai klippejä, joita on myös saman tekijän muissa videoissa.";
|
||||
"Select location closest to you:" = "Valitse sinua lähin sijainti:";
|
||||
"Settings" = "Asetukset";
|
||||
"Share %@ link" = "Jaa %@ linkki";
|
||||
"Share %@ link with time" = "Jaa %@ linkki ja aika";
|
||||
"Share..." = "Jaa...";
|
||||
"Short" = "Lyhyt";
|
||||
"Show account username" = "Näytä tilin käyttäjätunnus";
|
||||
"Show anonymous accounts" = "Näytä anonyymit tilit";
|
||||
"Show channel name" = "Näytä kanavan nimi";
|
||||
"Show history" = "Näytä historia";
|
||||
"Show keywords" = "Näytä avainsanat";
|
||||
"Show playback statistics" = "Näytä toiston statistiikka";
|
||||
"Show progress of watching on thumbnails" = "Näytä katselun edistyminen pikkukuvassa";
|
||||
"Show sidebar when space permits" = "Näytä sivupalkki, kun tila sallii";
|
||||
"Show video length" = "Näytä videon pituus";
|
||||
"Shuffle" = "Sekoita";
|
||||
"Shuffle All" = "Sekoita kaikki";
|
||||
"Sidebar" = "Sivupalkki";
|
||||
"Sign In Required" = "Kirjautuminen vaaditaan";
|
||||
"Small" = "Pieni";
|
||||
"Sort" = "Järjestä";
|
||||
"Sort: %@" = "Järjestä: %@";
|
||||
"Source" = "Lähde";
|
||||
"SponsorBlock API Instance" = "SponsorBlock API Instanssi";
|
||||
"Switch to other public location" = "Vaihda toiseen julkiseen sijaintiin";
|
||||
"System controls buttons" = "Järjestelmän ohjauspainikkeet";
|
||||
"System controls show buttons for %@" = "Järjestelmän säätimet näyttää painikkeet %@:lle";
|
||||
"This cannot be reverted" = "Tätä ei voi perua";
|
||||
"This cannot be reverted. You might need to switch between views or restart the app to see changes." = "Tätä ei voi perua. Joudut ehkä vaihtamaan näkymää tai uudelleen käynnistämään sovelluksen, jotta muutokset näkyvät.";
|
||||
"This will remove all your custom profiles and return their default values. This cannot be reverted." = "Tämä poistaa kaikki mukautetut profiilit ja palauttaa niiden oletusasetukset. Tätä ei voi perua.";
|
||||
"Thumbnails" = "Pikkukuvat";
|
||||
"Today" = "Tänään";
|
||||
"Trending" = "Trendaavat";
|
||||
"TV" = "TV";
|
||||
"Typically near or at the end of the video when the credits pop up and/or endcards are shown." = "Tyypillisesti lähellä videon loppua, jossa on lopputekstit ja/tai loppukortit.";
|
||||
"unknown" = "tuntematon";
|
||||
"Unsubscribe" = "Lopeta tilaus";
|
||||
"Upload date" = "Latauspäivä";
|
||||
"URL" = "URL";
|
||||
"Used to create links from videos, channels and playlists" = "Käytetään linkkien luomiseen videoista, kanavista ja soittolistoista";
|
||||
"Username" = "Käyttäjänimi";
|
||||
"Very Large" = "Erittäin suuri";
|
||||
"Views" = "Katselukerrat";
|
||||
"Watched" = "Katsottu";
|
||||
"Watched %@" = "Katsottu %@";
|
||||
"Watching now" = "Katsotaan juuri nyt";
|
||||
"Week" = "Viikko";
|
||||
"Welcome" = "Tervetuloa";
|
||||
"Wi-Fi" = "Wi-Fi";
|
||||
"Yattee %@ (build %@)" = "Yattee %@ (koontiversio %@)";
|
||||
"Year" = "Vuosi";
|
||||
"You can find information about using Yattee in the Wiki pages." = "Löydät tietoa Yatteen käytöstä Wiki-sivuilta.";
|
||||
"You have no Playlists" = "Sinulla ei ole soittolistoja";
|
||||
"You have no playlists\n\nTap on \"New Playlist\" to create one" = "Sinulla ei ole soittolistoja\n\nNapauta \"Uusi soittolista\" luodaksesi uuden";
|
||||
"You need to select an account\nto access %@ section" = "Sinun täytyy valita tili\npäästäksesi %@ osioon";
|
||||
"Public" = "Julkinen";
|
||||
"Unlisted" = "Listaamaton";
|
||||
"Now Playing" = "Toistossa nyt";
|
||||
"Current Location" = "Nykyinen sijainti";
|
||||
"Private" = "Yksityinen";
|
||||
"Playback queue is empty" = "Toistojono on tyhjä";
|
||||
"Add Channels, Playlists and Searches to Favorites using" = "Lisää kanavia, soittolistoja ja hakuja suosikkeihin käyttäen";
|
||||
"Make default" = "Tee oletus";
|
||||
"Visibility" = "Näkyvyys";
|
||||
"Current Playlist" = "Nykyinen soittolista";
|
||||
"Stream & Player" = "Striimi ja soitin";
|
||||
"Statistics" = "Statistiikka";
|
||||
"Hardware decoder" = "Laitteisto dekoodaaja";
|
||||
"Stream FPS" = "Striimin FPS";
|
||||
"Cached time" = "Puskuroitu aika";
|
||||
"Rate & Captions" = "Nopeus & tekstitykset";
|
||||
"Dropped frames" = "Jätetyt kehykset";
|
||||
"Any format" = "Mikä tahansa formaatti";
|
||||
"%@ formats" = "%@ formaattia";
|
||||
"Keep last played video in the queue after restart" = "Pidä viimeksi toistettu video jonossa uudelleen käynnistyksen jälkeen";
|
||||
"It can be changed later in settings. You can use your own locations too." = "Sitä voidaan muuttaa myöhemmin asetuksista. Voit käyttää myös omia sijainteja.";
|
||||
"Press and hold remote button to open captions and quality menus" = "Paina ja pidä kaukosäätimen painiketta avataksesi tekstitysten ja laadun valikot";
|
||||
"No comments" = "Ei kommentteja";
|
||||
"No chapters information available" = "Ei kappale tietoja saatavilla";
|
||||
"Open logs in Finder" = "Avaa lokit Finderissä";
|
||||
"Could not refresh Subscriptions" = "Tilauksia ei voitu päivittää";
|
||||
"Could not load streams" = "Striimejä ei voitu ladata";
|
||||
"Could not open video" = "Videota ei voitu avata";
|
||||
"Channel could not be found" = "Kanavaa ei löytynyt";
|
||||
"Could not extract channel information" = "Kanavan tietoja ei voitu hakea";
|
||||
"Could not extract SID from received cookies: %@" = "SID:tä ei voitu kaivaa vastaanotetuista evästeistä: %@";
|
||||
"Could not update your token." = "Valtuutustasi ei voitu päivittää.";
|
||||
"Could not refresh Trending" = "Trendaavia ei voitu päivittää";
|
||||
"This URL could not be opened" = "Tätä URL:ia ei voitu avata";
|
||||
"Could not open channel" = "Kanavaa ei voitu avata";
|
||||
"Could not refresh Popular" = "Suosittuja ei voitu päivittää";
|
||||
"Could not create share link" = "Jakolinkkiä ei voitu luoda";
|
||||
"Could not extract video ID" = "Video ID:tä ei voitu hakea";
|
||||
"This video could not be opened" = "Tätä videota ei voi avata";
|
||||
"Could not extract playlist ID" = "Soittolistan ID:tä ei voitu hakea";
|
||||
"Could not load video" = "Videota ei voitu ladata";
|
||||
"No locations available at the moment" = "Sijainteja ei ole saatavilla tällä hetkellä";
|
||||
"Could not refresh Playlists" = "Soittolistaa ei voitu päivittää";
|
||||
"If you want this app to be available in your language, join translation project." = "Jos haluat tämän sovelluksen olevan saatavilla kielelläsi, liity käännösprojektiin.";
|
||||
"Translations" = "Käännökset";
|
||||
"No documents" = "Ei dokumentteja";
|
||||
"Recent Documents" = "Viimeaikaiset dokumentit";
|
||||
"Home" = "Koti";
|
||||
"Share files from Finder on a Mac\nor iTunes on Windows" = "Jaa tiedostoja Macin Finderistä\ntai iTunesista Windowsissa";
|
||||
"Show Home" = "Näytä koti";
|
||||
"Show Open Videos quick actions" = "Näytä Avaa Videoita -pikatoiminnot";
|
||||
"Recent History" = "Viimeaikainen historia";
|
||||
"Show Favorites" = "Näytä suosikit";
|
||||
"Inspector visibility" = "Inspektorin näkyvyys";
|
||||
"Edit Favorites…" = "Muokkaa suosikkeja…";
|
||||
"Show Open Videos toolbar button" = "Näytä Avaa Videoita -painike työkalupalkissa";
|
||||
"Buttons labels" = "Painikkeiden nimikkeet";
|
||||
"Files" = "Tiedostot";
|
||||
"Show Documents" = "Näytä dokumentit";
|
||||
"Pages toolbar position" = "SIvujen työkalurivin positio";
|
||||
"Video Details" = "Videon tiedot";
|
||||
"Show Inspector" = "Näytä inspektori";
|
||||
"Open" = "Avaa";
|
||||
"Video actions buttons" = "Videotoimintojen painikkeet";
|
||||
"Pages buttons" = "Sivujen painikkeet";
|
||||
"URL to Open" = "Avattava URL";
|
||||
"Enter link to open" = "Syötä avattava linkki";
|
||||
"Could not open Files" = "Tiedostoja ei voitu avata";
|
||||
"Paste" = "Liitä";
|
||||
"Open Videos" = "Avaa videot";
|
||||
"Enter links to open, one per line" = "Syötä avattavat linkit, yksi per rivi";
|
||||
"Playback Mode" = "Toistotila";
|
||||
"Add" = "Lisää";
|
||||
"Hide" = "Piilota";
|
||||
"Always" = "Aina";
|
||||
"Only for local files and URLs" = "Vain paikallisille tiedostoille ja URL:lle";
|
||||
"Right" = "Oikea";
|
||||
"Channels" = "Kanavat";
|
||||
"Open Files" = "Avaa tiedostot";
|
||||
"Share" = "Jaa";
|
||||
"Show icons and text when space permits" = "Näytä kuvakkeet ja teksti, kun tila sallii";
|
||||
"Left" = "Vasen";
|
||||
"Format" = "Formaatti";
|
||||
"Driver" = "Ajuri";
|
||||
"Show only icons" = "Näytä vain kuvakkeet";
|
||||
"Center" = "Keskellä";
|
||||
"Documents" = "Dokumentit";
|
||||
"Audio" = "Audio";
|
||||
"File" = "Tiedosto";
|
||||
"Video" = "Video";
|
||||
"Codec" = "Kodekki";
|
||||
"Size" = "Koko";
|
||||
"FPS" = "FPS";
|
||||
"Sample Rate" = "Näytetaajuus";
|
||||
"Could not find any links to open in your clipboard" = "Leikepöydältä ei löytynyt yhtään avattavaa linkkiä";
|
||||
"Address" = "Osoite";
|
||||
"Remove…" = "Poista…";
|
||||
"Actions buttons" = "Toiminto-painikkeet";
|
||||
"Show sidebar" = "Näytä sivupalkki";
|
||||
"Locations Manifest" = "Sijaintien luettelo";
|
||||
"Remove Location" = "Poista sijainti";
|
||||
"Open Video" = "Avaa video";
|
||||
"Default Profile" = "Oletusprofiili";
|
||||
"Playback history is empty" = "Toistohistoria on tyhjä";
|
||||
"Copy%@link" = "Kopioi %@ linkki";
|
||||
"Share%@link" = "Jaa %@ linkki";
|
||||
"Are you sure you want to remove this document?" = "Oletko varma, että haluat poistaa tämän dokumentin?";
|
||||
"\"%@\" will be irreversibly removed from this device." = "\"%@\" poistetaan peruuttamattomasti tästä laitteesta.";
|
||||
"Could not delete document" = "Dokumenttia ei voitu poistaa";
|
||||
"Are you sure you want to remove %@ location?" = "Haluatko varmasti poistaa %@ sijainnin?";
|
||||
"Shorts" = "Shorts";
|
||||
"Verified" = "Tarkistettu";
|
||||
"Channel" = "Kanava";
|
||||
"Open expanded" = "Avaa laajennettuna";
|
||||
"Mark channel feed as unwatched" = "Merkitse kanavasyöte katsomattomaksi";
|
||||
"Mark channel feed as watched" = "Merkitse kanavasyöte katsotuksi";
|
||||
"Player Bar" = "Toistopalkki";
|
||||
"Short videos: visible" = "Shorts-videot: näkyvillä";
|
||||
"Short videos: hidden" = "Shorts-videot: piilotettu";
|
||||
"Play all unwatched" = "Toista kaikki katsomattomat";
|
||||
"Double tap gesture" = "Kaksoisnapautus ele";
|
||||
"Tap and hold channel thumbnail to open context menu with more actions" = "Napauta ja pidä kanavan pikkukuvaa avataksesi valikon, jossa lisää toimintoja";
|
||||
"Always show controls buttons" = "Näytä aina ohjauspainikkeet";
|
||||
"Single tap gesture" = "Yhden napautuksen ele";
|
||||
"Maximum width expanded" = "Suurin leveys laajennettuna";
|
||||
"Clear all" = "Tyhjennä kaikki";
|
||||
"Right click channel thumbnail to open context menu with more actions" = "Klikkaa kanavan pikkukuvaa hiiren oikealla avataksesi valikon, jossa lisää toimintoja";
|
||||
"Show unwatched feed badges" = "Näytä katsomattoman syötteen merkit";
|
||||
"Seeking" = "Kelaaminen";
|
||||
"Gesture: fowards" = "Ele: eteenpäin";
|
||||
"Controls Buttons" = "Ohjauspainikkeet";
|
||||
"System controls" = "Järjestelmän säätimet";
|
||||
"Controls button: backwards" = "Ohjauspainike: taaksepäin";
|
||||
"Controls button: forwards" = "Ohjauspainike: eteenpäin";
|
||||
"Gesture: backwards" = "Ele: taaksepäin";
|
||||
"Gesture settings control skipping interval for double tap gesture on left/right side of the player. Changing system controls settings requires restart." = "Ele asetukset ohjaavat skippaus väliä kaksoisnapautus eleelle soittimen vasemmalla/oikealla puolella. Järjestelmäsäätimien asetuksian muuttaminen vaatii uudelleenkäynnistyksen.";
|
||||
"Hide player" = "Piilota soitin";
|
||||
"Actions Buttons" = "Toiminto-painikkeet";
|
||||
"Play next item" = "Toista seuraava kohde";
|
||||
"Lock orientation" = "Lukitse näytön suunta";
|
||||
"Music Mode" = "Musiikki-tila";
|
||||
"Total size: %@" = "Koko: %@";
|
||||
"Open channels with description expanded" = "Avaa kanavat kuvaus on laajennettuna";
|
||||
"Cache" = "Välimuisti";
|
||||
"Subscribe/Unsubscribe" = "Tilaa/Lopeta tilaus";
|
||||
"Show cache status" = "Näytä välimuistin tila";
|
||||
"Maximum feed items" = "Syötteen kohteiden enimmäismäärä";
|
||||
"Are you sure you want to clear cache?" = "Haluatko varmasti tyhjentää välimuistin?";
|
||||
"Show Next in Queue" = "Näytä seuraava jonossa";
|
||||
"Show toggle watch status button" = "Näytä katsottu-tilan valitsin painike";
|
||||
"Next in Queue" = "Seuraavana jonossa";
|
||||
"List" = "Lista";
|
||||
"Cells" = "Solut";
|
||||
"Toggle size" = "Vaihda koko";
|
||||
"Toggle player" = "Valitse soitin";
|
||||
"Do nothing" = "Älä tee mitään";
|
||||
"Feed" = "Syöte";
|
||||
"Open channel" = "Avaa kanava";
|
||||
"Inspector" = "Inspektori";
|
||||
"Open video description expanded" = "Avaa videon kuvaus laajennettuna";
|
||||
"Mark all as unwatched" = "Merkitse kaikki katsomattomaksi";
|
||||
"Mark all as watched" = "Merkitse kaikki katsotuksi";
|
||||
"Queue - shuffled" = "Jono - sekoitettu";
|
||||
"Playback Settings" = "Toiston asetukset";
|
||||
"Replay" = "Katso uudelleen";
|
||||
"Fullscreen" = "Koko näyttö";
|
||||
"Lock" = "Lukitse";
|
||||
"Description" = "Kuvaus";
|
||||
"Loop one" = "Yksi video silmukkana";
|
||||
"Autoplay next" = "Toista seuraava automaattisesti";
|
||||
"Stream" = "Striimi";
|
||||
"Show scroll to top button in comments" = "Näytä vieritä ylös-painike kommenteissa";
|
||||
"Enter account credentials to connect..." = "Syötä tilin tunnistetiedot yhdistääksesi…";
|
||||
"Enter location address to connect..." = "Syötä sijainnin osoite yhdistääksesi…";
|
||||
"Seek" = "Kelaa";
|
||||
"Opened File" = "Avattu tiedosto";
|
||||
"File Extension" = "Tiedostopääte";
|
||||
"Opening file…" = "Tiedostoa avataan…";
|
||||
"Public account" = "Julkinen tili";
|
||||
"Close video and player on end" = "Sulje video ja soitin lopuksi";
|
||||
"Use system controls with AVPlayer" = "Käytä järjestelmän ohjaimia AVPlayerille";
|
||||
"Rotate when entering fullscreen on landscape video" = "Käännä kun siirrytään koko näytölle vaakasuuntaisessa videossa";
|
||||
"Landscape left" = "Vaakasuunta vasen";
|
||||
"Landscape right" = "Vaakasuunta oikea";
|
||||
"No rotation" = "Ei kääntöä";
|
||||
"Available" = "Saatavilla";
|
||||
"Startup section" = "Aloitusosio";
|
||||
"Home Settings" = "Koti asetukset";
|
||||
"Watched: hidden" = "Katsottu: piilotettu";
|
||||
"Watched: visible" = "Katsottu: näkyvillä";
|
||||
"No videos to show" = "Ei videoita näytettäväksi";
|
||||
"(watched hidden)" = "(katsotut piilotettu)";
|
||||
"(shorts hidden)" = "(shorts-videot piilotettu)";
|
||||
"Play Now in MPV" = "Toista nyt MPV:llä";
|
||||
"Disable filters" = "Poista suodattimet käytöstä";
|
||||
"Limit" = "Rajoita";
|
||||
"Are you sure you want to remove %@ from Favorites?" = "Haluatko poistaa %@:n suosikeista?";
|
||||
"Show video context menu options to force selected backend" = "Näytä videon kontekstivalikon valinnat pakottaaksesi valitun backendin";
|
||||
"Podcasts" = "Podcastit";
|
||||
"Releases" = "Julkaisut";
|
||||
"Add %@" = "Lisää %@";
|
||||
"Description preview" = "Kuvauksen esikatselu";
|
||||
"No preview" = "Ei esikatselua";
|
||||
"Open vertical chapters expanded" = "Avaa pystysuuntaiset kappaleet laajennettuna";
|
||||
"Chapters (if available)" = "Kappaleet (jos saatavilla)";
|
||||
"Import Settings..." = "Tuo asetukset…";
|
||||
"Export Settings" = "Vie asetukset";
|
||||
"Accounts passwords (unencrypted)" = "Tilien salasanat (salaamaton)";
|
||||
"Other" = "Muu";
|
||||
"Other data" = "Muu data";
|
||||
"Export..." = "Vie…";
|
||||
"Other data include last used playback preferences and listing options" = "Muu data sisältää viimeksi käytetyt toistoasetukset ja listaus vaihtoehdot";
|
||||
"Are you sure you want to export unencrypted passwords?" = "Haluatko varmasti viedä salaamattomat salasanat?";
|
||||
"Icon only" = "Vain kuvake";
|
||||
"Export" = "Vie";
|
||||
"File information" = "Tiedoston tiedot";
|
||||
"Build" = "Koontiversio";
|
||||
"Import" = "Tuo";
|
||||
"Platform" = "Alusta";
|
||||
"Action button labels" = "Toiminto -painikkeiden nimikkeet";
|
||||
"Icon and text" = "Kuvake ja teksti";
|
||||
"Password required to import" = "Tuonti vaatii salasanan";
|
||||
"Custom Location already exists" = "Mukautettu sijainti on jo olemassa";
|
||||
"Custom Location not selected for import" = "Mukautettua sijaintia ei ole valittu tuontia varten";
|
||||
"Account already exists" = "Tili on jo olemassa";
|
||||
"Password saved in import file" = "Salasana tallennettu tuontitiedostoon";
|
||||
"Export in progress..." = "Vienti meneillään…";
|
||||
"In progress..." = "Meneillään…";
|
||||
"10 seconds forwards/backwards" = "10 sekuntia eteen/taakse";
|
||||
"%@ Playlist" = "%@ Soittolista";
|
||||
"Add Location..." = "Lisää Sijainti..";
|
||||
"Accounts are not supported for the application of this instance" = "Tilejä ei tueta tämän instanssin käyttöön";
|
||||
"Add Account..." = "Lisää tili...";
|
||||
"Add Quality Profile" = "Lisää Laatuprofiili";
|
||||
"Add to Playlist..." = "Lisää Soittolistaan...";
|
||||
"Add to Playlist" = "Lisää Soittolistaan";
|
||||
"Clear History" = "Tyhjennä historia";
|
||||
"All" = "Kaikki";
|
||||
"Any" = "Mikä tahansa";
|
||||
"Apply to all" = "Käytä kaikkiin";
|
||||
"Are you sure you want to clear history of watched videos?" = "Haluatko varmasti tyhjentää katsottujen videoiden historian?";
|
||||
"Are you sure you want to clear search history?" = "Haluatko varmasti tyhjentää hakuhistorian?";
|
||||
"Are you sure you want to delete playlist?" = "Haluatko varmasti poistaa soittolistan?";
|
||||
"Are you sure you want to restore default quality profiles?" = "Haluatko varmasti palauttaa oletusarvoiset laatuprofiilit?";
|
||||
"Are you sure you want to unsubscribe from %@?" = "Haluatko varmasti poistaa tilauksen %@?";
|
||||
"Automatic" = "Automaattinen";
|
||||
"Autoplaying Next" = "Toistetaan automaattisesti seuraava";
|
||||
"Badge & Decreased opacity" = "Merkki & Vähentynyt opasiteetti";
|
||||
"Browsing" = "Selaaminen";
|
||||
"Button" = "Painike";
|
||||
"Cellular" = "Mobiiliverkko";
|
||||
"Chapters" = "Kappaleet";
|
||||
"Clear All Recents" = "Tyhjennä kaikki viimeaikaiset";
|
||||
"Clear the queue" = "Tyhjennä jono";
|
||||
"Close" = "Sulje";
|
||||
"Close PiP and open player when application enters foreground" = "Sulje kuva kuvassa ja avaa soitin, kun sovellus tulee etualalle";
|
||||
"LIVE" = "LIVE";
|
||||
"Loading streams…" = "Ladataan…";
|
||||
"Mark as watched" = "Merkitse katsotuksi";
|
||||
"Matrix Chat" = "Matrix Chat";
|
||||
"Medium quality" = "Keskimääräinen laatu";
|
||||
"Movies" = "Elokuvat";
|
||||
"MPV Documentation" = "MPV-dokumentaatio";
|
||||
"More info can be found in:" = "Lisätietoja löytyy:";
|
||||
"Name" = "Nimi";
|
||||
"Next" = "Seuraava";
|
||||
"No results" = "Ei tuloksia";
|
||||
"Not available" = "Ei saatavilla";
|
||||
"Password" = "Salasana";
|
||||
"Open \"Playlists\" tab to create new one" = "Avaa \"Soittolistat\" -välilehti luodaksesi uuden";
|
||||
"Opening %@ stream…" = "Avataan %@ streamia…";
|
||||
"Picture in Picture" = "Kuva kuvassa";
|
||||
"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." = "Osa videosta, joka edistää tuotetta tai palvelua, joka ei liity suoraan tekijään. Tekijä saa maksun tai korvauksen rahan tai ilmaisten tuotteiden muodossa.";
|
||||
"Pause when player is closed" = "Tauko, kun soitin suljetaan";
|
||||
"Play" = "Toista";
|
||||
"Play Last" = "Toista viimeinen";
|
||||
"Play Next" = "Toista seuraava";
|
||||
"Play Music" = "Toista musiikki";
|
||||
"Playback" = "Toisto";
|
||||
"Player" = "Soitin";
|
||||
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "Soittolista \"%@\" poistetaan\nToimintoa ei voi perua.";
|
||||
"Profiles" = "Profiilit";
|
||||
"Promoting a product or service that is directly related to the creator themselves. This usually includes merchandise or promotion of monetized platforms." = "Mainostaa tuotetta tai palvelua, joka liittyy suoraan tekijään. Tämä sisältää yleensä kaupankäyntialustojen tuotteita tai mainostamista.";
|
||||
"Highest quality" = "Korkein laatu";
|
||||
"I want to ask a question" = "Haluan esittää kysymyksen";
|
||||
"If you are interested what's coming in future updates, you can track project Milestones." = "Jos olet kiinnostunut siitä, mitä tulevissa päivityksissä tapahtuu, voit seurata projektin virstanpylväitä.";
|
||||
"Intro" = "Intro";
|
||||
"Just watched" = "Juuri katsottu";
|
||||
"Hide sidebar" = "Kätke sivupalkki";
|
||||
"Public Manifest" = "Julkinen luettelo";
|
||||
"Offtopic in Music Videos" = "Offtopic musiikkivideoissa";
|
||||
"Rate" = "Nopeus";
|
||||
"Remove" = "Poista";
|
||||
"Remove from the queue" = "Poista jonosta";
|
||||
"Search history is empty" = "Hakuhistoria on tyhjä";
|
||||
"Self-promotion" = "Itsensä mainostaminen";
|
||||
"Smaller" = "Pienempi";
|
||||
"Sponsor" = "Sponsori";
|
||||
"SponsorBlock" = "SponsoriBlock";
|
||||
"Explicit reminders to like, subscribe or interact with them on any paid or free platform(s) (e.g. click on a video)." = "Nimenomainen muistutus tykkätä, tilata tai olla vuorovaikutuksessa heidän kanssaan millä tahansa maksullisella tai ilmaisella alustalla (esim. napsauttamalla videota).";
|
||||
"Filter" = "Suodatin";
|
||||
"Filter: active" = "Suodatin: käytössä";
|
||||
"For videos which feature music as the primary content." = "Videoille, joissa musiikki on ensisijainen sisältö.";
|
||||
"Formats will be selected in order as listed.\nHLS is an adaptive format (resolution setting does not apply)." = "Formaatit valitaan listan mukaisessa järjestyksessä.\nHLS on adaptiivinen formaatti (resoluutioasetus ei sovellu).";
|
||||
"Subscriptions" = "Tilaukset";
|
||||
"Switch to public locations" = "Vaihda julkiseen sijaintiin";
|
||||
"Subscribe" = "Tilaa";
|
||||
"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." = "Se on kiva kuulla. On hauskaa tarjota sovelluksia, joita muut haluavat käyttää. Voit harkita lahjoittamista projektiin tai apua edistämällä uusia ominaisuuksia.";
|
||||
"Yattee" = "Yattee";
|
||||
"This information will be processed only on your device and used to connect you to the server in the specified country." = "Tämä tieto käsitellään ainoastaan laitteessasi ja sitä käytetään yhdistämään palvelimeen määrittelemässäsi maassa.";
|
||||
"Videos" = "Videot";
|
||||
"When partially watched video is played" = "Kun osittain katsottu video toistetaan";
|
||||
"Wiki" = "Wiki";
|
||||
"Playing Next" = "Toistetaan seuraavaksi";
|
||||
"You can switch between profiles in playback settings controls." = "Voit vaihtaa profiilien välillä toistoasetuksissa.";
|
||||
"Comments are disabled" = "Kommentit ovat poissa käytöstä";
|
||||
"For custom locations you can configure Frontend URL in Locations settings" = "Voit konfiguroida mukautetun sijainnin etusivun URL:n Sijaintien asetuksissa";
|
||||
"Share Logs..." = "Jaa lokit…";
|
||||
"Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "Soittolista on tyhjä\n\nNapauta ja pidä videota ja sitten\n”Lisää soittolistaan”";
|
||||
"Could not open playlist" = "Soittolistaa ei voitu avata";
|
||||
"Reload manifest" = "Uudelleen lataa luettelo";
|
||||
"Clear Queue before opening" = "Tyhjennä jono ennen avaamista";
|
||||
"Gesture settings control skipping interval for double click on left/right side of the player. Changing system controls settings requires restart." = "Ele asetukset ohjaavat skippaus väliä kaksoisklikkaukselle soittimen vasemmalla/oikealla puolella. Järjestelmäsäätimien asetuksian muuttaminen vaatii uudelleenkäynnistyksen.";
|
||||
"Gesture settings control skipping interval for remote arrow buttons (for 2nd generation Siri Remote or newer). Changing system controls settings requires restart." = "Ele asetukset ohjaavat skippaus väliä kaukosäätimen nuolinäppäimille (2. sukupolven Siri Remote, tai uudempi). Järjestelmäsäätimien asetuksian muuttaminen vaatii uudelleenkäynnistyksen.";
|
||||
"Close video" = "Sulje video";
|
||||
"Live Streams" = "Live striimit";
|
||||
"You need to create an instance and accounts\nto access %@ section" = "Sinun täytyy luoda instanssi ja tilejä\npäästäksesi %@ osioon";
|
||||
"You can use automatic profile selection based on current device status or switch it in video playback settings controls." = "Voit käyttää automaattista profiilivalintaa nykyisen laitteen tilan perusteella tai vaihtaa sitä videon toistoasetuksissa.";
|
||||
"Play Now in AVPlayer" = "Toista nyt AVPlayerillä";
|
||||
"Show channel avatars in videos lists" = "Näytä kanavien kuvakkeet video listoissa";
|
||||
"Show channel avatars in channels lists" = "Näytä kanavien kuvakkeet kanavalistoissa";
|
||||
"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" = "Älä jaa tätä tiedostoa kenenkään kanssa tai voit menettää pääsyn tileillesi. Jos et valitse salasanojen vientiä, sinua pyydetään antamaan ne tuonnin aikana";
|
||||
"Custom Location selected for import" = "Mukautettu sijainti valittu tuontia varten";
|
||||
"Your Accounts" = "Sinun tilisi";
|
||||
"Browse without account" = "Selaa ilman tiliä";
|
||||
"(watched and shorts hidden)" = "(katsotut ja shorts-videot piilotettu)";
|
||||
"Keep channels with unwatched videos on top of subscriptions list" = "Pidä kanavat, joilla katsomattomia videoita, tilauslistan yläosassa";
|
||||
@@ -4,7 +4,7 @@
|
||||
"Save history of searches, channels and playlists" = "検索、チャンネル、再生リストの履歴を保存";
|
||||
"Statistics" = "統計";
|
||||
"Apply to all" = "これをすべてに適用";
|
||||
"Reload manifest" = "マニフェストを再読込";
|
||||
"Reload manifest" = "定義ファイルを再読込";
|
||||
"Left" = "左";
|
||||
"Codec" = "コーデック";
|
||||
"Add profile..." = "プロファイルの追加...";
|
||||
@@ -15,8 +15,8 @@
|
||||
"%lld videos" = "%lld本の動画";
|
||||
"%@ Channel" = "%@ チャンネル";
|
||||
"%@ Playlist" = "%@ 再生リスト";
|
||||
"Add Location" = "場所を追加";
|
||||
"Add Location..." = "場所を追加...";
|
||||
"Add Location" = "インスタンスを追加";
|
||||
"Add Location..." = "インスタンスを追加...";
|
||||
"Advanced" = "高度";
|
||||
"Add to Favorites" = "お気に入りに追加";
|
||||
"Add to %@" = "%@に追加";
|
||||
@@ -43,13 +43,13 @@
|
||||
"Continue from %@" = "%@から続ける";
|
||||
"Comments" = "コメント";
|
||||
"Create Playlist" = "再生リストの作成";
|
||||
"Could not load locations manifest" = "場所のマニフェストが読み込めません";
|
||||
"Could not load locations manifest" = "インスタンスの定義ファイルを読み込めません";
|
||||
"Copy %@ link" = "%@ リンクをコピー";
|
||||
"Copy %@ link with time" = "%@ リンクを時間指定でコピー";
|
||||
"Current: %@\n%@" = "現在: %@\n%@";
|
||||
"Decreased opacity" = "透明化";
|
||||
"Delete" = "削除";
|
||||
"Custom Locations" = "場所の指定";
|
||||
"Custom Locations" = "インスタンスの指定";
|
||||
"Decrease rate" = "速度を下げる";
|
||||
"Done" = "完了";
|
||||
"Discord Server" = "Discord のサーバー";
|
||||
@@ -57,7 +57,7 @@
|
||||
"Edit" = "編集";
|
||||
"Edit Playlist" = "再生リストを編集";
|
||||
"Donations" = "寄付";
|
||||
"Don't use public locations" = "公開された場所を使用しない";
|
||||
"Don't use public locations" = "公開インスタンスを使用しない";
|
||||
"Enable logging" = "ログ記録を有効化";
|
||||
"Enable Return YouTube Dislike" = "低評価を表示(Return YouTube Dislike)";
|
||||
"Error" = "エラー";
|
||||
@@ -90,7 +90,7 @@
|
||||
"Loading streams…" = "ストリーム読込中…";
|
||||
"Lock portrait mode" = "縦モードをロック";
|
||||
"LIVE" = "ライブ";
|
||||
"Locations" = "場所";
|
||||
"Locations" = "インスタンス";
|
||||
|
||||
/* Video duration filter in search */
|
||||
"Long" = "長い";
|
||||
@@ -121,7 +121,7 @@
|
||||
"Play Music" = "音楽を再生";
|
||||
"Profiles" = "プロファイル";
|
||||
"Popular" = "人気";
|
||||
"Public Manifest" = "公開のマニフェスト";
|
||||
"Public Manifest" = "公開の定義ファイル";
|
||||
"Queue" = "再生キュー";
|
||||
"Red" = "赤";
|
||||
"Recents" = "最近";
|
||||
@@ -144,7 +144,7 @@
|
||||
"Seek with horizontal swipe on video" = "動画で水平スワイプでシーク";
|
||||
"Search" = "検索";
|
||||
"Search..." = "検索...";
|
||||
"Select location closest to you:" = "あなたの場所に近い場所を選択:";
|
||||
"Select location closest to you:" = "あなたに近い場所を選択します:";
|
||||
"Share %@ link" = "%@ リンクを共有";
|
||||
"Share %@ link with time" = "%@ リンク 時間指定で共有";
|
||||
"Show playback statistics" = "再生データの統計を表示";
|
||||
@@ -162,7 +162,7 @@
|
||||
|
||||
/* Subscriptions title */
|
||||
"Subscriptions" = "登録チャンネル";
|
||||
"Switch to other public location" = "ほかの公開された場所に切り替え";
|
||||
"Switch to other public location" = "ほかの公開インスタンスに変更";
|
||||
"This cannot be reverted" = "元に戻せません";
|
||||
"This cannot be reverted. You might need to switch between views or restart the app to see changes." = "元に戻せません。変更の確認には、表示を切り替えたり、アプリの再起動が必要なこともあります。";
|
||||
"Trending" = "急上昇";
|
||||
@@ -184,13 +184,13 @@
|
||||
"You have no playlists\n\nTap on \"New Playlist\" to create one" = "再生リストなし\n\n作成には「新規再生リスト」をタップ";
|
||||
"Private" = "非公開";
|
||||
"Unlisted" = "限定公開";
|
||||
"Current Location" = "現在の場所";
|
||||
"Current Location" = "現在のインスタンス";
|
||||
"You can switch between profiles in playback settings controls." = "再生設定の制御からプロファイルを切り替えできます。";
|
||||
"Add Channels, Playlists and Searches to Favorites using" = "チャンネル、再生リスト、検索をお気に入りにするには";
|
||||
"Stream FPS" = "ストリーム FPS";
|
||||
"Dropped frames" = "フレーム落ち";
|
||||
"Keep last played video in the queue after restart" = "再起動しても再生待ちの最後の動画を維持";
|
||||
"It can be changed later in settings. You can use your own locations too." = "設定は後で変更できます。場所の指定も可能です。";
|
||||
"It can be changed later in settings. You can use your own locations too." = "設定は後で変更できます。インスタンスの指定も可能です。";
|
||||
"Comments are disabled" = "コメント無効です";
|
||||
"Could not refresh Subscriptions" = "登録チャンネルを更新できません";
|
||||
"Could not load streams" = "ストリームを開けません";
|
||||
@@ -201,7 +201,7 @@
|
||||
"Could not load video" = "動画を読み込めません";
|
||||
"Translations" = "翻訳";
|
||||
"Could not refresh Playlists" = "再生リストを更新できません";
|
||||
"No locations available at the moment" = "現時点で利用可能な場所がありません";
|
||||
"No locations available at the moment" = "現時点で利用可能なインスタンスがありません";
|
||||
"Show Open Videos quick actions" = "動画を開くクイック操作を表示";
|
||||
"Show Documents" = "文書を表示";
|
||||
"Pages toolbar position" = "ページのツールバー位置";
|
||||
@@ -221,12 +221,12 @@
|
||||
"Audio" = "音声";
|
||||
"Actions buttons" = "操作ボタン";
|
||||
"Default Profile" = "標準のプロファイル";
|
||||
"Remove Location" = "場所を削除";
|
||||
"Locations Manifest" = "場所のマニフェスト";
|
||||
"Remove Location" = "インスタンスを削除";
|
||||
"Locations Manifest" = "インスタンスの定義ファイル";
|
||||
"Copy%@link" = "%@リンクをコピー";
|
||||
"Share%@link" = "%@リンクを共有";
|
||||
"\"%@\" will be irreversibly removed from this device." = "「%@」はこの端末から完全に削除されます。";
|
||||
"Are you sure you want to remove %@ location?" = "場所 %@ を削除しますか?";
|
||||
"Are you sure you want to remove %@ location?" = "インスタンス %@ を削除しますか?";
|
||||
"Live Streams" = "ライブ配信";
|
||||
"Mark channel feed as watched" = "チャンネルフィードを視聴済みにする";
|
||||
"Short videos: visible" = "ショート動画: 表示";
|
||||
@@ -526,10 +526,10 @@
|
||||
"Gesture settings control skipping interval for double tap gesture on left/right side of the player. Changing system controls settings requires restart." = "ジェスチャーの設定で、プレイヤーの左右をダブルタップした時のスキップ間隔を変更します。システム制御の設定を変更するには、再起動が必要です。";
|
||||
"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." = "作成者と直接関係のない製品やサービスを宣伝する部分。作成者は金銭や商品提供によって報酬を受け取ります。";
|
||||
"Press and hold remote button to open captions and quality menus" = "リモコンのボタンを長押しすると、字幕と品質のメニューが表示されます";
|
||||
"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)." = "有料/無料のプラットフォームかを問わず、いいね、登録などを明示的に操作を促す(例: 動画をクリック)。\n";
|
||||
"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)." = "有料/無料のプラットフォームかを問わず、いいね、登録などを明示的に操作を促す(例: 動画をクリック)。";
|
||||
"Proxy videos" = "動画閲覧にプロキシ使用";
|
||||
"Sections" = "表示するボタン";
|
||||
"System controls show buttons for %@" = "システム制御「%@」用のボタンを表示";
|
||||
@@ -610,14 +610,14 @@
|
||||
"File information" = "ファイル情報";
|
||||
"Platform" = "プラットフォーム";
|
||||
"Icon and text" = "アイコンと文字";
|
||||
"Custom Location not selected for import" = "指定の場所は取り込み用に選択されていません";
|
||||
"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" = "指定の場所は取り込み用に選択済み";
|
||||
"Custom Location selected for import" = "指定したインスタンスは取り込み用に選択済み";
|
||||
"Export" = "出力";
|
||||
"Build" = "ビルド";
|
||||
"Import" = "取り込み";
|
||||
@@ -628,4 +628,4 @@
|
||||
"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" = "指定の場所は既に存在します";
|
||||
"Custom Location already exists" = "指定したインスタンスは既に存在します";
|
||||
|
||||
@@ -10,33 +10,33 @@
|
||||
"Add Location" = "Добавить локацию";
|
||||
"Add profile..." = "Добавить профиль...";
|
||||
"Add to %@" = "Добавить к %@";
|
||||
"Add to Favorites" = "Добавить к избранному";
|
||||
"Add to Playlist" = "Добавить к плейлисту";
|
||||
"Add to Favorites" = "Добавить в избранное";
|
||||
"Add to Playlist" = "Добавить в плейлист";
|
||||
"Anonymous" = "Анонимный";
|
||||
|
||||
/* Video date filter in search
|
||||
Video duration filter in search */
|
||||
"Any" = "Любой";
|
||||
"Any" = "Любая";
|
||||
"Apply to all" = "Применить ко всем";
|
||||
"Are you sure you want to delete playlist?" = "Вы точно хотите удалить плейлист?";
|
||||
"Are you sure you want to unsubscribe from %@?" = "Вы точно хотите описаться от %@?";
|
||||
"Autoplaying Next" = "Автоматически проигрывать след. видео";
|
||||
"Backend" = "Бэкэнд";
|
||||
"Are you sure you want to unsubscribe from %@?" = "Вы точно хотите отписаться от %@?";
|
||||
"Autoplaying Next" = "Автоматически воспроизводится следующее";
|
||||
"Backend" = "Backend";
|
||||
"Blue" = "Синий";
|
||||
"Button" = "Кнопка";
|
||||
"Cancel" = "Отмена";
|
||||
"Captions" = "Субтитры";
|
||||
"Categories to Skip" = "Категории для пропуска";
|
||||
"Cellular" = "Через мобильный интернет";
|
||||
"Cellular" = "Сотовая связь";
|
||||
"Charging" = "Зарядка";
|
||||
"Clear All Recents" = "Очистить все последние записи";
|
||||
"Clear All Recents" = "Очистить всё последнее";
|
||||
"Close" = "Закрыть";
|
||||
"Close PiP when player is opened" = "Закрыть К-в-К, когда плеер открыт";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Date" = "Дата";
|
||||
"Decrease rate" = "Снижение уровня";
|
||||
"Decreased opacity" = "Уменьшение непрозрачности";
|
||||
"Date" = "По дате";
|
||||
"Decrease rate" = "Снизить скорость";
|
||||
"Decreased opacity" = "Прозрачностью";
|
||||
"Delete" = "Удалить";
|
||||
"Donations" = "Донаты";
|
||||
"Done" = "Применить";
|
||||
@@ -44,14 +44,14 @@
|
||||
"Edit Playlist" = "Редактировать плейлист";
|
||||
"Edit Quality Profile" = "Редактировать профиль качества";
|
||||
"Edit..." = "Редактировать...";
|
||||
"Enable Return YouTube Dislike" = "Включить дизлайки";
|
||||
"Enable Return YouTube Dislike" = "Включить Return YouTube Dislike";
|
||||
"Error" = "Ошибка";
|
||||
"Error when accessing playlist" = "Ошибка при доступе к плейлисту";
|
||||
"Favorites" = "Избранное";
|
||||
"For videos which feature music as the primary content." = "Для видео, в которых музыка используется в качестве основного контента.";
|
||||
"Highest quality" = "Высшее качество";
|
||||
"For videos which feature music as the primary content." = "Для видео, основным содержанием которых является музыка.";
|
||||
"Highest quality" = "Наивысшее качество";
|
||||
"History" = "История";
|
||||
"Honor orientation lock" = "Фиксация ориентации Honor";
|
||||
"Honor orientation lock" = "Учитывать блокировку ориентации";
|
||||
"Locations" = "Локации";
|
||||
"More info can be found in:" = "Более подробную информацию можно найти в:";
|
||||
"Movies" = "Фильмы";
|
||||
@@ -70,20 +70,20 @@
|
||||
"Play Next" = "Играть следующее";
|
||||
"Preferred Formats" = "Предпочитаемые форматы";
|
||||
"Profiles" = "Профили";
|
||||
"Proxy videos" = "Проксировать видео";
|
||||
"Related" = "Связанный";
|
||||
"Proxy videos" = "Использовать прокси для видео";
|
||||
"Related" = "Похожие";
|
||||
"Share..." = "Поделиться...";
|
||||
|
||||
/* Video duration filter in search */
|
||||
"Short" = "Короткое";
|
||||
"Show account username" = "Показать никнэйм аккаунта";
|
||||
"Short" = "Короткая";
|
||||
"Show account username" = "Показать имя пользователя аккаунта";
|
||||
"Show anonymous accounts" = "Показать анонимные аккаунты";
|
||||
"Show channel name" = "Показать имя канала";
|
||||
"Show keywords" = "Показать ключевые слова";
|
||||
"Show playback statistics" = "Показать статистику просмотра";
|
||||
"Show sidebar when space permits" = "Показать боковую панель, когда позволяет пространство";
|
||||
"Show video length" = "Показать длину видео";
|
||||
"Shuffle" = "Переместить";
|
||||
"Shuffle" = "Перемешать";
|
||||
"Sign In Required" = "Требуется войти";
|
||||
|
||||
/* Player controls layout size */
|
||||
@@ -93,11 +93,11 @@
|
||||
/* Selected video was played on given date */
|
||||
"Watched %@" = "Просмотренные %@";
|
||||
"Wi-Fi" = "Wi-Fi";
|
||||
"You have no playlists\n\nTap on \"New Playlist\" to create one" = "У вас нет списков воспроизведения\n\nНажмите на \"Новый плейлист\", чтобы создать его";
|
||||
"You have no playlists\n\nTap on \"New Playlist\" to create one" = "У вас нет плейлистов\n\nНажмите на \"Новый плейлист\", чтобы создать один";
|
||||
"Could not refresh Subscriptions" = "Не удалось обновить подписки";
|
||||
"This video could not be opened" = "Это видео не удалось открыть";
|
||||
"Translations" = "Переводы";
|
||||
"Show Open Videos quick actions" = "Показать быстродействие открытия видео";
|
||||
"Show Open Videos quick actions" = "Показать быстрые действия при открытии видео";
|
||||
"Recent History" = "Недавняя история";
|
||||
"Files" = "Файлы";
|
||||
"Show Documents" = "Показать документы";
|
||||
@@ -115,14 +115,14 @@
|
||||
"Open channel" = "Открыть канал";
|
||||
"Inspector" = "Инспектор";
|
||||
"Open video description expanded" = "Открыть расширенное описание видео";
|
||||
" subscribers" = " подписчики";
|
||||
" subscribers" = " подписчиков";
|
||||
"%@ Channel" = "%@ Канал";
|
||||
"%@ Playlist" = "%@ Плейлист";
|
||||
"10 seconds forwards/backwards" = "10 секунд вперёд/назад";
|
||||
"Accounts are not supported for the application of this instance" = "Аккаунты не поддерживаются для приложения на этом инстансе";
|
||||
"Add Location..." = "Добавить локацию...";
|
||||
"Accounts are not supported for the application of this instance" = "Аккаунты не поддерживаются приложением для этого инстанса";
|
||||
"Add Location..." = "Добавить локацию..";
|
||||
"Add Quality Profile" = "Добавить профиль качества";
|
||||
"Add to Playlist..." = "Добавить к плейлисту...";
|
||||
"Add to Playlist..." = "Добавить в плейлист...";
|
||||
"Advanced" = "Расширенные";
|
||||
|
||||
/* Trending category, section containing all kinds of videos */
|
||||
@@ -130,37 +130,37 @@
|
||||
"Always use AVPlayer for live videos" = "Всегда использовать AVPlayer для прямых трансляций";
|
||||
"Are you sure you want to clear search history?" = "Вы точно хотите очистить историю поиска?";
|
||||
"Are you sure you want to clear history of watched videos?" = "Вы точно хотите очистить историю просмотренных видео?";
|
||||
"Are you sure you want to restore default quality profiles?" = "Вы точно хотите восстановить настройки по умолчанию для профиля качества?";
|
||||
"Automatic" = "Автоматически";
|
||||
"Badge" = "Оценка";
|
||||
"Badge & Decreased opacity" = "Оценка и уменьшенная непрозрачность";
|
||||
"Badge color" = "Цвет оценки";
|
||||
"Are you sure you want to restore default quality profiles?" = "Вы точно хотите восстановить изначальные профили качества?";
|
||||
"Automatic" = "Автоматический";
|
||||
"Badge" = "Значком";
|
||||
"Badge & Decreased opacity" = "Значком и прозрачностью";
|
||||
"Badge color" = "Цвет значка";
|
||||
"Based on system color scheme" = "Как в системе";
|
||||
"Battery" = "Батарея";
|
||||
"Browsing" = "В браузере";
|
||||
"Buffering stream..." = "Буферизация прямой трансляции...";
|
||||
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "Баги и новые идеи можно отправить на трекер проблем на GitHub. ";
|
||||
"Browsing" = "Навигация";
|
||||
"Buffering stream..." = "Буферизация потока...";
|
||||
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "Об ошибках и предложениях сообщайте на странице проекта в GitHub во вкладке Issues. ";
|
||||
"Category" = "Категория";
|
||||
"Chapters" = "Главы";
|
||||
"Clear" = "Очистить";
|
||||
"Clear All" = "Очистить всё";
|
||||
"Clear History" = "Очистить историю";
|
||||
"Close PiP and open player when application enters foreground" = "Закрыть К-в-К и открыть плеер, когда приложение не в спящем режиме";
|
||||
"Close PiP and open player when application enters foreground" = "Закрыть К-в-К и открыть плеер, когда приложение на переднем плане";
|
||||
"Clear Search History" = "Очистить историю поиска";
|
||||
"Show Open Videos toolbar button" = "Кнопка \"Показать открытые видео\" на панели инструментов";
|
||||
"Buttons labels" = "Ярлыки кнопок";
|
||||
"Show Open Videos toolbar button" = "Показать кнопку \"Открыть видео\" на панели инструментов";
|
||||
"Buttons labels" = "Надписи на кнопках";
|
||||
"Rotate to portrait when exiting fullscreen" = "Поворачивать в портретное положение при выходе из полноэкранного режима";
|
||||
"Round corners" = "Закругленные углы";
|
||||
"Save" = "Сохранить";
|
||||
"Save history of played videos" = "Сохранить историю проигранных видео";
|
||||
"Save history of searches, channels and playlists" = "Сохранение истории поиска, каналов и плейлистов";
|
||||
"Save history of searches, channels and playlists" = "Сохранить истории поиска, каналов и плейлистов";
|
||||
"Search" = "Поиск";
|
||||
"Search history is empty" = "История поиска пуста";
|
||||
"Search..." = "Поиск...";
|
||||
"Sections" = "Разделы";
|
||||
"Seek gesture sensitivity" = "Поиск чувствительности к жестам";
|
||||
"Seek gesture speed" = "Поиск скорости жеста";
|
||||
"Seek with horizontal swipe on video" = "Поиск с помощью горизонтального свайпа по видео";
|
||||
"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:" = "Выберите ближайшее к вам местоположение:";
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
"Share %@ link" = "Поделиться %@ ссылкой";
|
||||
"Show history" = "Показать историю";
|
||||
"Show progress of watching on thumbnails" = "Показать прогресс просмотра на миниатюрах";
|
||||
"Shuffle All" = "Переместить всё";
|
||||
"Shuffle All" = "Перемешать всё";
|
||||
"Sidebar" = "Боковая панель";
|
||||
"Sort" = "Сортировать";
|
||||
|
||||
@@ -181,25 +181,25 @@
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Sponsor" = "Спонсорская реклама";
|
||||
"Source" = "Исходный код";
|
||||
"SponsorBlock API Instance" = "Истанс SponsorBlock API";
|
||||
"Source" = "Источник";
|
||||
"SponsorBlock API Instance" = "Инстанс SponsorBlock API";
|
||||
"Subscribe" = "Подписаться";
|
||||
|
||||
/* Subscriptions title */
|
||||
"Subscriptions" = "Подписчики";
|
||||
"Subscriptions" = "Подписки";
|
||||
"Switch to other public location" = "Переключиться на другую публичную локацию";
|
||||
"This cannot be reverted" = "Это не может быть отменено";
|
||||
"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. You might need to switch between views or restart the app to see changes." = "Это не может быть отменено. Возможно, вам потребуется переключаться между представлениями или перезапускать приложение, чтобы увидеть изменения.";
|
||||
"This cannot be reverted" = "Это нельзя потом отменить";
|
||||
"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. You might need to switch between views or restart the app to see changes." = "Это нельзя потом отменить. Возможно, вам потребуется переключиться между представлениями или перезапустить приложение, чтобы увидеть изменения.";
|
||||
"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." = "Это удалит все ваши пользовательские профили и вернет их значения по умолчанию. Это не может быть отменено.";
|
||||
"This will remove all your custom profiles and return their default values. This cannot be reverted." = "Это удалит все ваши пользовательские профили и вернет их значения по умолчанию. Это нельзя потом отменить.";
|
||||
"Thumbnails" = "Миниатюры";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Today" = "Сегодня";
|
||||
"Today" = "За сегодня";
|
||||
"Trending" = "Тренды";
|
||||
|
||||
/* Player controls layout size for TV */
|
||||
@@ -216,60 +216,60 @@
|
||||
"Very Large" = "Очень большой";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Views" = "Просмотры";
|
||||
"Views" = "По просмотрам";
|
||||
"Watched" = "Просмотренные";
|
||||
|
||||
/* Selected video is being played */
|
||||
"Watching now" = "Смотреть сейчас";
|
||||
"Watching now" = "Смотрим сейчас";
|
||||
"Yattee %@ (build %@)" = "Yattee %@ (сборка %@)";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Week" = "Неделя";
|
||||
"Week" = "За эту неделю";
|
||||
"Welcome" = "Добро пожаловать";
|
||||
"Wiki" = "Вики";
|
||||
"When partially watched video is played" = "При воспроизведении частично просмотренного видео";
|
||||
"Yattee" = "Yattee";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Year" = "Год";
|
||||
"Year" = "За этот год";
|
||||
"You can find information about using Yattee in the Wiki pages." = "Вы можете найти информацию об использовании Yattee на страницах вики.";
|
||||
"You can use automatic profile selection based on current device status or switch it in video playback settings controls." = "Вы можете использовать автоматический выбор профиля на основе текущего состояния устройства или переключить его в элементах управления настройками воспроизведения видео.";
|
||||
"You need to create an instance and accounts\nto access %@ section" = "Вам нужно создать экземпляр и учетные\nзаписи для доступа к разделу %@";
|
||||
"You can use automatic profile selection based on current device status or switch it in video playback settings controls." = "Вы можете использовать автоматический выбор профиля на основе текущего состояния устройства или переключить его в настройками воспроизведения видео.";
|
||||
"You need to create an instance and accounts\nto access %@ section" = "Вам нужно создать инстанс и аккаунты\nдля доступа к %@ разделу";
|
||||
"You have no Playlists" = "У вас нет плейлистов";
|
||||
"You need to select an account\nto access %@ section" = "Вам нужно выбрать учетную\nзапись для доступа к разделу %@";
|
||||
"You need to select an account\nto access %@ section" = "Вам нужно выбрать аккаунт\nдля доступа к %@ разделу";
|
||||
|
||||
|
||||
"Public" = "Публично";
|
||||
"Public" = "Публичный";
|
||||
"Now Playing" = "Сейчас играет";
|
||||
"Unlisted" = "По ссылке";
|
||||
"Current Location" = "Текущая локация";
|
||||
"Private" = "Лично";
|
||||
"SponsorBlock" = "СпонсорБлок";
|
||||
"Private" = "Личный";
|
||||
"SponsorBlock" = "SponsorBlock";
|
||||
"Playback queue is empty" = "Очередь воспроизведения пуста";
|
||||
"Playing Next" = "Играет дальше";
|
||||
"You can switch between profiles in playback settings controls." = "Вы можете переключаться между профилями в элементах управления настройками воспроизведения.";
|
||||
"You can switch between profiles in playback settings controls." = "Вы можете переключаться между профилями в настройках воспроизведения видео.";
|
||||
"Add Channels, Playlists and Searches to Favorites using" = "Добавить каналы, плейлисты и результаты поиска в избранное с помощью";
|
||||
"Stream & Player" = "Прямая трансляция и плеер";
|
||||
"Stream & Player" = "Стрим и плеер";
|
||||
"Make default" = "Сделать по умолчанию";
|
||||
"Statistics" = "Статистика";
|
||||
"Visibility" = "Видимость";
|
||||
"Current Playlist" = "Текущий плейлист";
|
||||
"Hardware decoder" = "Аппаратный декодер";
|
||||
"Stream FPS" = "К/с прямой трансляции";
|
||||
"Stream FPS" = "К/с потока";
|
||||
"Cached time" = "Кэшированное время";
|
||||
"Rate & Captions" = "Оценка и субтитры";
|
||||
"Rate & Captions" = "Скорость и субтитры";
|
||||
"Dropped frames" = "Пропущенные кадры";
|
||||
"Keep last played video in the queue after restart" = "Сохранить последнее воспроизведенное видео в очереди после перезапуска";
|
||||
"Any format" = "Любой формат";
|
||||
"%@ formats" = "%@ форматы";
|
||||
"Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "Список воспроизведения пуст\n\nНажмите и удерживайте видео, а затем\n\"Добавить в список воспроизведения\"";
|
||||
"Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "Плейлист пуст\n\nНажмите и удерживайте на видео, а затем\n\"Добавить в плейлист\"";
|
||||
"It can be changed later in settings. You can use your own locations too." = "Это можно изменить позже в настройках. Вы также можете использовать свои собственные локации.";
|
||||
"Comments are disabled" = "Комментарии отключены";
|
||||
"Press and hold remote button to open captions and quality menus" = "Нажмите и удерживайте кнопку дистанционного управления, чтобы открыть титры и меню качества";
|
||||
"Press and hold remote button to open captions and quality menus" = "Нажмите и удерживайте кнопку дистанционного управления, чтобы открыть субтитры и меню качества";
|
||||
"No comments" = "Комментариев нет";
|
||||
"No chapters information available" = "Информация о главах недоступна";
|
||||
"Share Logs..." = "Поделиться логами…";
|
||||
"Could not load streams" = "Не удалось загрузить прямые трансляции";
|
||||
"Could not load streams" = "Не удалось загрузить потоки";
|
||||
"Channel could not be found" = "Не удалось найти канал";
|
||||
"Could not open video" = "Не удалось открыть видео";
|
||||
"Could not extract channel information" = "Не удалось извлечь информацию о канале";
|
||||
@@ -277,9 +277,9 @@
|
||||
"Could not update your token." = "Не удалось обновить ваш токен.";
|
||||
"Could not refresh Trending" = "Не удалось обновить тренды";
|
||||
"This URL could not be opened" = "Этот URL-адрес не удалось открыть";
|
||||
"For custom locations you can configure Frontend URL in Locations settings" = "Для пользовательских местоположений вы можете настроить URL-адрес интерфейса в настройках местоположений";
|
||||
"For custom locations you can configure Frontend URL in Locations settings" = "Для пользовательских локаций вы можете настроить Frontend URL в настройках Локации";
|
||||
"Could not open channel" = "Не удалось открыть канал";
|
||||
"Could not refresh Popular" = "Не удалось обновить вкладку \"Популярность\"";
|
||||
"Could not refresh Popular" = "Не удалось обновить вкладку \"Популярное\"";
|
||||
"Could not create share link" = "Не удалось создать ссылку для общего доступа";
|
||||
"Could not extract playlist ID" = "Не удалось извлечь идентификатор плейлиста";
|
||||
"Could not open playlist" = "Не удалось открыть плейлист";
|
||||
@@ -289,24 +289,24 @@
|
||||
"Could not refresh Playlists" = "Не удалось обновить плейлисты";
|
||||
"If you want this app to be available in your language, join translation project." = "Если вы хотите, чтобы это приложение было доступно на вашем языке, присоединяйтесь к проекту перевода.";
|
||||
"No documents" = "Нет документов";
|
||||
"Recent Documents" = "Последние документы";
|
||||
"Recent Documents" = "Недавние документы";
|
||||
"Home" = "Дом";
|
||||
"Show Home" = "Показать дом";
|
||||
"Share files from Finder on a Mac\nor iTunes on Windows" = "Делитесь файлами из Finder на Mac\nили iTunes на Windows";
|
||||
"Show Favorites" = "Показать избранное";
|
||||
"Inspector visibility" = "Видимость инспектора";
|
||||
"Edit Favorites…" = "Редактирование избранного…";
|
||||
"Edit Favorites…" = "Редактировать избранное…";
|
||||
"Close PiP when starting playing other video" = "Закрыть К-в-К, когда воспроизводится другое видео";
|
||||
"Close player when closing video" = "Закрыть плеер, когда закрывается видео";
|
||||
"Close player when closing video" = "Закрыть плеер при закрытии видео";
|
||||
"Close player when starting PiP" = "Закрыть плеер, когда запущен К-в-К";
|
||||
"Close video after playing last in the queue" = "Закрыть видео после проигрывания последнего в очереди";
|
||||
"Close video after playing last in the queue" = "Закрыть видео после проигрывания очереди";
|
||||
"Comments" = "Комментарии";
|
||||
"Connected successfully (%@)" = "Подключение завершено (%@)";
|
||||
"Contact" = "Контакт";
|
||||
"Connection failed" = "Подключение провалено";
|
||||
"Connected successfully (%@)" = "Подключение успешно (%@)";
|
||||
"Contact" = "Обратная связь";
|
||||
"Connection failed" = "Подключение не удалось";
|
||||
"Continue" = "Продолжить";
|
||||
"Continue from %@" = "Продолжить с %@";
|
||||
"Contributing" = "Контрибуция";
|
||||
"Contributing" = "Внести свой вклад";
|
||||
"Controls" = "Управления";
|
||||
"Copy %@ link" = "Копировать %@ ссылку";
|
||||
"Copy %@ link with time" = "Копировать %@ ссылку со временем";
|
||||
@@ -319,37 +319,37 @@
|
||||
/* Locations settings, custom instance is selected as current */
|
||||
"Custom" = "Пользовательские";
|
||||
"Custom Locations" = "Пользовательские локации";
|
||||
"Disabled" = "Отключить";
|
||||
"Discord Server" = "Сервер на Discord";
|
||||
"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" = "Не использовать публичные локации";
|
||||
"Duration" = "Продолжительность";
|
||||
"Enable logging" = "Включить логирование";
|
||||
"Enable logging" = "Включить ведение журнала";
|
||||
"Enter fullscreen in landscape" = "Войти в полноэкранный режим в альбомной ориентации";
|
||||
"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)." = "Явные напоминания о необходимости поставить лайк, подписаться или взаимодействовать с автором на любой платной или бесплатной платформе (платформах) (например, нажать на видео).";
|
||||
"Filter" = "Фильтр";
|
||||
"Filter: active" = "Фильтр: активен";
|
||||
"Finding something to play..." = "Ищу другие видео...";
|
||||
"Formats will be selected in order as listed.\nHLS is an adaptive format (resolution setting does not apply)." = "Форматы будут выбраны в том порядке, как указано в списке.\nHLS - это адаптивный формат (настройка разрешения не применяется).";
|
||||
"Formats will be selected in order as listed.\nHLS is an adaptive format (resolution setting does not apply)." = "Форматы будут выбраны в порядке, указанном в списке.\nHLS - это адаптивный формат (настройка разрешения не применяется).";
|
||||
"Find Other" = "Найти другое";
|
||||
"Frontend URL" = "URL инстанса";
|
||||
"Fullscreen size" = "Размер видео в полноэкранном";
|
||||
"Frontend URL" = "Frontend URL";
|
||||
"Fullscreen size" = "Полноэкранный размер";
|
||||
"Gaming" = "Игры";
|
||||
"Help" = "Помощь";
|
||||
"Hide sidebar" = "Скрыть боковую панель";
|
||||
"Highest" = "Высшее";
|
||||
"Highest" = "Наивысшая";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Hour" = "Час";
|
||||
"Hour" = "За последний час";
|
||||
"I am lost" = "Я заблудился";
|
||||
"I found a bug /" = "Я нашёл баг /";
|
||||
"High" = "Высокое";
|
||||
"I have a feature request" = "Я придумал новую функцию";
|
||||
"I found a bug /" = "Я нашёл ошибку /";
|
||||
"High" = "Высокая";
|
||||
"I have a feature request" = "У меня есть предложение";
|
||||
"I like this app!" = "Мне нравится это приложение!";
|
||||
"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)." = "Если вы сообщаете об ошибке, укажите все соответствующие сведения (особенно: версию приложения, используемое устройство и версию системы, как пришли к ошибке).";
|
||||
"If you are interested what's coming in future updates, you can track project Milestones." = "Если вам интересно, что будет в будущих обновлениях, вы можете отслеживать этапы проекта.";
|
||||
"Increase rate" = "Увеличение скорости";
|
||||
"If you are reporting a bug, include all relevant details (especially: app version, used device and system version, steps to reproduce)." = "Если вы сообщаете об ошибке, укажите все необходимые сведения (особенно: версию приложения, используемое устройство, версию операционной системы, а также шаги для воспроизведения этой ошибки).";
|
||||
"If you are interested what's coming in future updates, you can track project Milestones." = "Если вам интересно, что будет в будущих обновлениях, вы можете следить за вехами (milestones) проекта на его странице GitHub.";
|
||||
"Increase rate" = "Увеличить скорость";
|
||||
"Instance of current account" = "Инстанс текущего аккаунта";
|
||||
"Interface" = "Интерфейс";
|
||||
"Info" = "Информация";
|
||||
@@ -361,57 +361,57 @@
|
||||
"Large" = "Большой";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Intro" = "Интро";
|
||||
"Issues Tracker" = "Трекер ошибок";
|
||||
"Large layout is not suitable for all devices and using it may cause controls not to fit on the screen." = "Большой лайаут подходит не для всех устройств, и ее использование может привести к тому, что элементы управления не поместятся на экране.";
|
||||
"Intro" = "Заставка";
|
||||
"Issues Tracker" = "Отслеживание ошибок";
|
||||
"Large layout is not suitable for all devices and using it may cause controls not to fit on the screen." = "Большой размер не подходит для всех устройств, и его использование может привести к тому, что элементы управления не поместятся на экране.";
|
||||
|
||||
/* Selected video has just finished playing */
|
||||
"Just watched" = "Просто наблюдал";
|
||||
"Just watched" = "Только что посмотрел";
|
||||
"LIVE" = "ПРЯМАЯ ТРАНСЛЯЦИЯ";
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Loading streams…" = "Загрузка прямой трансляции…";
|
||||
"Loading streams…" = "Загрузка потока…";
|
||||
"Loading..." = "Загрузка...";
|
||||
"Lock portrait mode" = "Блокировка портретного режима";
|
||||
"Low" = "Низкое";
|
||||
"Lock portrait mode" = "Блокировать портретный режим";
|
||||
"Low" = "Низкая";
|
||||
"Low quality" = "Низкое качество";
|
||||
|
||||
/* Video duration filter in search */
|
||||
"Long" = "Длинное";
|
||||
"Lowest" = "Низшее";
|
||||
"Mark as watched" = "Оцените видео";
|
||||
"Mark video as watched after playing" = "Оцените видео после просмотра";
|
||||
"Mark watched videos with" = "Оцените видео с";
|
||||
"Matrix Channel" = "Канал на Matrix";
|
||||
"Matrix Chat" = "Чат на Matrix";
|
||||
"Long" = "Длинная";
|
||||
"Lowest" = "Наименьшая";
|
||||
"Mark as watched" = "Отметить как просмотренное";
|
||||
"Mark video as watched after playing" = "Отметить видео как просмотренное после воспроизведения";
|
||||
"Mark watched videos with" = "Отметить просмотренные видео";
|
||||
"Matrix Channel" = "Matrix канал";
|
||||
"Matrix Chat" = "Matrix чат";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Medium" = "Среднее";
|
||||
"Medium" = "Средний";
|
||||
"Medium quality" = "Среднее качество";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Month" = "Месяц";
|
||||
"Milestones" = "Этапы проекта";
|
||||
"Month" = "За этот месяц";
|
||||
"Milestones" = "Вехи (Milestones)";
|
||||
"Next" = "Далее";
|
||||
"No Playlists" = "Без плейлистов";
|
||||
"No description" = "Без описания";
|
||||
"No results" = "Без результатов";
|
||||
"Nothing" = "Ничего";
|
||||
"Normal" = "Обычное";
|
||||
"No Playlists" = "Нет плейлистов";
|
||||
"No description" = "Нет описания";
|
||||
"No results" = "Нет результатов";
|
||||
"Nothing" = "Ничем";
|
||||
"Normal" = "Обычная";
|
||||
"Not available" = "Нет доступа";
|
||||
"Not Playing" = "Нет просмотров";
|
||||
"Not Playing" = "Не воспроизводится";
|
||||
"Only when signed in" = "Только после входа в";
|
||||
"Open \"Playlists\" tab to create new one" = "Открыть вкладку \"Плейлисты\", чтобы создать новый";
|
||||
"Open Settings" = "Отрыть настройки";
|
||||
"Open \"Playlists\" tab to create new one" = "Откройте вкладку \"Плейлисты\", чтобы создать новый";
|
||||
"Open Settings" = "Открыть настройки";
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Opening %@ stream…" = "Открытие %@ прямой трансляции…";
|
||||
"Opening audio stream…" = "Открытие прямой трансляции аудио…";
|
||||
"Opening %@ stream…" = "Открытие %@ потока…";
|
||||
"Opening audio stream…" = "Открытие аудиопотока…";
|
||||
"Orientation" = "Ориентация";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Outro" = "Оутро";
|
||||
"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." = "Часть видеоролика, рекламирующего продукт или услугу, не имеющие прямого отношения к создателю. Создатель получит оплату или компенсацию в виде денег или бесплатных продуктов.";
|
||||
"Outro" = "Концовка";
|
||||
"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." = "Часть видеоролика, рекламирующего продукт или услугу, не имеющие прямого отношения к автору. Автор получит оплату или компенсацию в виде денег или бесплатных продуктов.";
|
||||
"Pause when player is closed" = "Пауза при закрытии плеера";
|
||||
"Picture in Picture" = "Картинка-в-Картинке";
|
||||
"Play" = "Играть";
|
||||
@@ -422,36 +422,36 @@
|
||||
"Player" = "Плеер";
|
||||
"Playlist" = "Плейлист";
|
||||
"Playlists" = "Плейлисты";
|
||||
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "Список воспроизведения \"%@\" будет удален.\nЭтого не изменить.";
|
||||
"Popular" = "Популярность";
|
||||
"Promoting a product or service that is directly related to the creator themselves. This usually includes merchandise or promotion of monetized platforms." = "Продвижение продукта или услуги, которые непосредственно связаны с самим создателем. Обычно это включает в себя товары или продвижение монетизированных платформ.";
|
||||
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "Плейлист \"%@\" будет удалён.\nНавсегда.";
|
||||
"Popular" = "Популярное";
|
||||
"Promoting a product or service that is directly related to the creator themselves. This usually includes merchandise or promotion of monetized platforms." = "Продвижение продукта или сервис, которые непосредственно связаны с самим создателем. Обычно это связано с продажей товаров или продвижением подписочной платформы.";
|
||||
"Public Manifest" = "Публичный манифест";
|
||||
"Quality" = "Качество";
|
||||
"Public Locations" = "Публичные локации";
|
||||
"Queue" = "Очередь";
|
||||
"Quality Profile" = "Профиль качества";
|
||||
"Queue is empty" = "Очередь пуста";
|
||||
"Rate" = "Оценить";
|
||||
"Rate" = "Скорость";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Rating" = "Рейтинг";
|
||||
"Rating" = "По рейтингу";
|
||||
"Recents" = "Недавние";
|
||||
"Regular size" = "Обычный размер";
|
||||
"Red" = "Красный";
|
||||
"Refresh" = "Обновить";
|
||||
"Regular Size" = "Обычный Размер";
|
||||
"Remove" = "Стереть";
|
||||
"Remove from Favorites" = "Стереть из избранного";
|
||||
"Remove from history" = "Стереть из истории";
|
||||
"Remove from Playlist" = "Стереть из плейлиста";
|
||||
"Remove" = "Удалить";
|
||||
"Remove from Favorites" = "Удалить из избранного";
|
||||
"Remove from history" = "Удалить из истории";
|
||||
"Remove from Playlist" = "Удалить из плейлиста";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Relevance" = "Актуальность";
|
||||
"Remove from the queue" = "Стереть из очереди";
|
||||
"Relevance" = "По релевантности";
|
||||
"Remove from the queue" = "Удалить из очереди";
|
||||
"Replies" = "Ответы";
|
||||
"Reset search filters" = "Поисковые фильтры по умолчанию";
|
||||
"Reset search filters" = "Сбросить фильтры поиска";
|
||||
"Reset" = "По умолчанию";
|
||||
"Reset watched status when playing again" = "Статус просмотра при повторном воспроизведении по умолчанию";
|
||||
"Reset watched status when playing again" = "Сбросить состояние просмотра при повторном воспроизведении";
|
||||
"Restart" = "Перезапустить";
|
||||
"Resolution" = "Разрешение";
|
||||
"Restart the app to apply the settings above." = "Перезапустите приложение, чтобы применить выбранные настройки.";
|
||||
@@ -466,72 +466,72 @@
|
||||
"\"%@\" will be irreversibly removed from this device." = "\"%@\" будет необратимо удален с этого устройства.";
|
||||
"Could not delete document" = "Не удалось удалить документ";
|
||||
"Open Video" = "Открыть Видео";
|
||||
"Are you sure you want to remove %@ location?" = "Вы уверены, что хотите удалить локацию %@ ?";
|
||||
"Are you sure you want to remove %@ location?" = "Вы уверены, что хотите удалить %@ локацию?";
|
||||
"Live Streams" = "Прямые Трансляции";
|
||||
"Shorts" = "Короткие видео";
|
||||
"Verified" = "Проверенный";
|
||||
"Channel" = "Канал";
|
||||
"Mark channel feed as unwatched" = "Пометить канал как не просматриваемый";
|
||||
"Mark channel feed as unwatched" = "Пометить канал как не просмотренный";
|
||||
"Mark channel feed as watched" = "Пометить канал как просмотренный";
|
||||
"Open expanded" = "Открыть расширенный";
|
||||
"Open expanded" = "Открыть расширенным";
|
||||
"Short videos: visible" = "Короткие видео: показать";
|
||||
"Player Bar" = "Панель плеера";
|
||||
"Short videos: hidden" = "Короткие видео: скрыть";
|
||||
"Double tap gesture" = "Жест двойного касания";
|
||||
"Tap and hold channel thumbnail to open context menu with more actions" = "Нажмите и удерживайте миниатюру канала, чтобы открыть контекстное меню с дополнительными действиями";
|
||||
"Always show controls buttons" = "Всегда показывать кнопки управления";
|
||||
"Single tap gesture" = "Жест \"однократное нажатие\"";
|
||||
"Single tap gesture" = "Жест однократного касания";
|
||||
"Maximum width expanded" = "Максимальная ширина в полноэкранном режиме";
|
||||
"Clear all" = "Очистить весь кэш";
|
||||
"Right click channel thumbnail to open context menu with more actions" = "Щелчок правой кнопкой мыши на миниатюре канала открывает контекстное меню с дополнительными действиями";
|
||||
"Show unwatched feed badges" = "Показать значки непросмотренных каналов";
|
||||
"Seeking" = "Искать";
|
||||
"Seeking" = "Прокрутка";
|
||||
"Gesture: fowards" = "Жест: вперед";
|
||||
"Controls Buttons" = "Кнопки управления";
|
||||
"System controls" = "Системные средства управления";
|
||||
"Controls button: backwards" = "Кнопка управления: назад";
|
||||
"Controls button: forwards" = "Кнопка управления: вперед";
|
||||
"Gesture: backwards" = "Жест: назад";
|
||||
"Gesture settings control skipping interval for double tap gesture on left/right side of the player. Changing system controls settings requires restart." = "Настройки жестов управляют интервалом пропуска жеста двойного касания левой/правой стороны плеера. Изменение настроек управления системой требует перезагрузки.";
|
||||
"Gesture settings control skipping interval for double tap gesture on left/right side of the player. Changing system controls settings requires restart." = "Настройки жестов управляют интервалом пропуска жеста двойного касания левой/правой стороны плеера. Изменение настройки системного управления требует перезагрузки.";
|
||||
"Hide player" = "Скрыть плеер";
|
||||
"Gesture settings control skipping interval for double click on left/right side of the player. Changing system controls settings requires restart." = "Настройки жестов управляют интервалом пропуска двойного щелчка левой/правой стороной проигрывателя. Изменение настроек управления системой требует перезагрузки.";
|
||||
"Gesture settings control skipping interval for remote arrow buttons (for 2nd generation Siri Remote or newer). Changing system controls settings requires restart." = "Настройки жестов управляют интервалом пропуска кнопок-стрелок пульта ДУ (для пульта Siri Remote 2-го поколения или новее). Изменение настроек управления системой требует перезагрузки.";
|
||||
"Gesture settings control skipping interval for double click on left/right side of the player. Changing system controls settings requires restart." = "Настройки жестов управляют интервалом пропуска двойного щелчка левой/правой стороной проигрывателя. Изменение настройки системного управления требует перезагрузки.";
|
||||
"Gesture settings control skipping interval for remote arrow buttons (for 2nd generation Siri Remote or newer). Changing system controls settings requires restart." = "Настройки жестов управляют интервалом пропуска кнопок-стрелок пульта ДУ (для пульта Siri Remote 2-го поколения или новее). Изменение настройки системного управления требует перезагрузки.";
|
||||
"Close Video" = "Закрыть Видео";
|
||||
"Open channels with description expanded" = "Открытые каналы с расширенным описанием";
|
||||
"Open channels with description expanded" = "Открывать каналы с расширенным описанием";
|
||||
"Show Next in Queue" = "Показать следующее в очереди";
|
||||
"Subscribe/Unsubscribe" = "Подписаться/Отписаться";
|
||||
"Maximum feed items" = "Максимальное количество объектов в ленте";
|
||||
"Are you sure you want to clear cache?" = "Вы уверены, что хотите очистить кэш?";
|
||||
"Show cache status" = "Показать статус кэша";
|
||||
"Show toggle watch status button" = "Показать кнопку переключения состояния часов";
|
||||
"Show toggle watch status button" = "Показать кнопку переключения статуса просмотра";
|
||||
"Next in Queue" = "Следующий в очереди";
|
||||
"List" = "Список";
|
||||
"Cells" = "Клетки";
|
||||
"Toggle size" = "Тогл размера";
|
||||
"Toggle player" = "Тогл плеера";
|
||||
"Toggle size" = "Размер переключателя";
|
||||
"Toggle player" = "Переключить плеер";
|
||||
"Do nothing" = "Ничего не делать";
|
||||
"Feed" = "Лента";
|
||||
"Mark all as watched" = "Пометить все как просмотренное";
|
||||
"Mark all as unwatched" = "Пометить все как непросмотренное";
|
||||
"Queue - shuffled" = "Очередь - перемещена";
|
||||
"Rotate when entering fullscreen on landscape video" = "Поворот при переходе в полноэкранный режим на видео с ландшафтом";
|
||||
"Landscape left" = "Ландшафт слева";
|
||||
"Landscape right" = "Ландшафт справа";
|
||||
"No rotation" = "Нет вращения";
|
||||
"Mark all as watched" = "Пометить всё как просмотренное";
|
||||
"Mark all as unwatched" = "Пометить всё как непросмотренное";
|
||||
"Queue - shuffled" = "Очередь - перемешанная";
|
||||
"Rotate when entering fullscreen on landscape video" = "Поворачивать при переходе в полноэкранный режим в альбомной ориентации";
|
||||
"Landscape left" = "Альбомная ориентация слева";
|
||||
"Landscape right" = "Альбомная ориентация справа";
|
||||
"No rotation" = "Без вращений";
|
||||
"Available" = "Доступно";
|
||||
"Startup section" = "Раздел ввода в эксплуатацию";
|
||||
"Startup section" = "Начальный раздел";
|
||||
"Watched: hidden" = "Просмотренное: скрыто";
|
||||
"Home Settings" = "Настройки дома";
|
||||
"(watched and shorts hidden)" = "(просмотрено и короткие видео скрыты)";
|
||||
"Watched: visible" = "Просморенные: показаны";
|
||||
"(watched and shorts hidden)" = "(просмотренное и короткие видео скрыты)";
|
||||
"Watched: visible" = "Просмотренные: показаны";
|
||||
"No videos to show" = "Нет видео для показа";
|
||||
"(shorts hidden)" = "(короткие видео скрыты)";
|
||||
"Limit" = "Лимит";
|
||||
"(watched hidden)" = "(просмотренные скрыты)";
|
||||
"Disable filters" = "Отключить фильтры";
|
||||
"Are you sure you want to remove %@ from Favorites?" = "Вы уверены, что хотите удалить %@ из избранного?";
|
||||
"Keep channels with unwatched videos on top of subscriptions list" = "Сохранять каналы с непросмотренными видеороликами в верхней части списка подписок";
|
||||
"Show video context menu options to force selected backend" = "Показывать опции контекстного меню видео для принудительного выбора бэкенда";
|
||||
"Keep channels with unwatched videos on top of subscriptions list" = "Держать каналы с непросмотренными видео в верхней части списка подписок";
|
||||
"Show video context menu options to force selected backend" = "Показать опции контекстного меню видео для принудительного выбора backend";
|
||||
"Play Now in MPV" = "Играть сейчас в MPV";
|
||||
"Play Now in AVPlayer" = "Играть сейчас в AVPlayer";
|
||||
"Show channel avatars in videos lists" = "Показывать аватары каналов в списках видео";
|
||||
@@ -539,17 +539,17 @@
|
||||
"Fullscreen" = "Полный экран";
|
||||
"Playback Settings" = "Настройки воспроизведения";
|
||||
"Lock" = "Заблокировать";
|
||||
"Replay" = "Воспроизвести";
|
||||
"Replay" = "Повторить";
|
||||
"Description" = "Описание";
|
||||
"Loop one" = "Повторить одно";
|
||||
"Loop one" = "Зациклить видео";
|
||||
"Close video" = "Закрыть видео";
|
||||
"Autoplay next" = "Автоплей следующего";
|
||||
"Autoplay next" = "Авто-очередь";
|
||||
"Stream" = "Прямая трансляция";
|
||||
"Show scroll to top button in comments" = "Показать кнопку прокрутки к верху в комментариях";
|
||||
"Enter account credentials to connect..." = "Введите данные аккаунта для подключения...";
|
||||
"Opened File" = "Открытие файла";
|
||||
"Seek" = "Искать следующее/предыдущее";
|
||||
"Enter location address to connect..." = "Введите адрес местоположения для подключения...";
|
||||
"Opened File" = "Открытый файл";
|
||||
"Seek" = "Перемотать видео вперёд/назад";
|
||||
"Enter location address to connect..." = "Введите адрес локации для подключения...";
|
||||
"Show Inspector" = "Показать инспектора";
|
||||
"Clear Queue before opening" = "Очистить очередь до открытия";
|
||||
"URL to Open" = "URL-адрес для открытия";
|
||||
@@ -581,7 +581,7 @@
|
||||
"Documents" = "Документы";
|
||||
"Video" = "Видео-файл";
|
||||
"Sample Rate" = "Частота дискретизации";
|
||||
"Could not find any links to open in your clipboard" = "Не удалось найти никаких ссылок для открытия в вашем буфере обмена";
|
||||
"Could not find any links to open in your clipboard" = "Не удалось найти никаких ссылок для открытия из вашего буфера обмена";
|
||||
"Audio" = "Аудио-файл";
|
||||
"FPS" = "К/с";
|
||||
"Address" = "Адрес";
|
||||
@@ -590,15 +590,42 @@
|
||||
"Remove…" = "Удалить…";
|
||||
"Actions buttons" = "Кнопки действия";
|
||||
"Show sidebar" = "Показать боковую панель";
|
||||
"Browse without account" = "Искать без аккаунта";
|
||||
"Opening file…" = "Отрытие файла…";
|
||||
"Browse without account" = "Смотреть без аккаунта";
|
||||
"Opening file…" = "Открытие файла…";
|
||||
"Public account" = "Публичный аккаунт";
|
||||
"Your Accounts" = "Ваши аккаунты";
|
||||
"Close video and player on end" = "Закрыть видео и плеер в конце";
|
||||
"Use system controls with AVPlayer" = "Использование системных элементов управления с помощью AVPlayer";
|
||||
"Use system controls with AVPlayer" = "Использовать системных элементы управления с помощью AVPlayer";
|
||||
"File Extension" = "Расширение файла";
|
||||
"No preview" = "Без предварительного просмотра";
|
||||
"Description preview" = "Предварительный просмотр описания";
|
||||
"Podcasts" = "Подкасты";
|
||||
"Releases" = "Релизы";
|
||||
"Add %@" = "Добавить %@";
|
||||
"Import Settings..." = "Импортировать настройки...";
|
||||
"Export Settings" = "Экспортировать настройки";
|
||||
"Accounts passwords (unencrypted)" = "Пароли аккаунтов (не зашифрованные)";
|
||||
"Other" = "Другое";
|
||||
"Other data" = "Другие данные";
|
||||
"Export..." = "Экспортировать…";
|
||||
"Export" = "Экспорт";
|
||||
"Platform" = "Платформа";
|
||||
"Import" = "Импорт";
|
||||
"Icon only" = "Только иконка";
|
||||
"Icon and text" = "Иконка и текст";
|
||||
"File information" = "Информация о файле";
|
||||
"Account already exists" = "Аккаунт уже существует";
|
||||
"Chapters (if available)" = "Главы (если доступны)";
|
||||
"Password saved in import file" = "Пароль сохранён в файле импорта";
|
||||
"Password required to import" = "Для импорта требуется пароль";
|
||||
"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" = "Не передавайте этот файл никому, иначе вы можете потерять доступ к своим аккаунтам. Если вы не выберете экспорт паролей, вас попросят предоставить их при импорте";
|
||||
"Build" = "Сборка";
|
||||
"Action button labels" = "Надписи кнопок действия";
|
||||
"Custom Location already exists" = "Пользовательская локация уже существует";
|
||||
"Custom Location selected for import" = "Пользовательская локация выбрана для импорта";
|
||||
"Custom Location not selected for import" = "Пользовательская локация не выбрана для импорта";
|
||||
"Export in progress..." = "Экспортируем...";
|
||||
"In progress..." = "Выполняется…";
|
||||
"Open vertical chapters expanded" = "Открывать вертикальные главы развернутыми";
|
||||
|
||||
@@ -5,30 +5,30 @@
|
||||
"Continue" = "Продовжити";
|
||||
|
||||
/* Locations settings, custom instance is selected as current */
|
||||
"Custom" = "Своє";
|
||||
" subscribers" = " підписники";
|
||||
"Custom" = "Користувальницькі";
|
||||
" subscribers" = " підписників";
|
||||
"%@ Channel" = "%@ Канал";
|
||||
"%@ Playlist" = "%@ Плейлист";
|
||||
"%@ subscribers" = "%@ підписників";
|
||||
"%lld videos" = "%lld відео";
|
||||
"10 seconds forwards/backwards" = "Перемотати 10 секунд";
|
||||
"10 seconds forwards/backwards" = "10 секунд вперед/назад";
|
||||
"Accounts" = "Акаунти";
|
||||
"Accounts are not supported for the application of this instance" = "Акаунти не підтримуються для цього екземпляру";
|
||||
"Accounts are not supported for the application of this instance" = "Акаунти не підтримуються програмою для цього інстанса";
|
||||
"Add Account" = "Додати акаунт";
|
||||
"Add Account..." = "Додати акаунт...";
|
||||
"Add Location" = "Нова локація (API)";
|
||||
"Add Location..." = "Додати локацію...";
|
||||
"Add Location" = "Додати локацію (API)";
|
||||
"Add Location..." = "Додати локацію..";
|
||||
"Add profile..." = "Додати профіль...";
|
||||
"Add Quality Profile" = "Додати профіль якості";
|
||||
"Add to %@" = "Додати до %@";
|
||||
"Add to Favorites" = "Додати в обране";
|
||||
"Add to Favorites" = "Додати в улюблене";
|
||||
"Add to Playlist" = "Додати в плейлист";
|
||||
"Add to Playlist..." = "Додати в плейлист...";
|
||||
"Advanced" = "Розширені";
|
||||
|
||||
/* Trending category, section containing all kinds of videos */
|
||||
"All" = "Все";
|
||||
"Anonymous" = "Анонімно";
|
||||
"All" = "Всі";
|
||||
"Anonymous" = "Анонімний";
|
||||
|
||||
/* Video date filter in search
|
||||
Video duration filter in search */
|
||||
@@ -37,46 +37,46 @@
|
||||
"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?" = "Ви впевнені, що бажаєте відновити стандартні профілі якості?";
|
||||
"Automatic" = "Автоматично";
|
||||
"Automatic" = "Автоматичний";
|
||||
"Autoplaying Next" = "Автовідтворення наступного";
|
||||
"Backend" = "Бекенд";
|
||||
"Backend" = "Backend";
|
||||
"Badge color" = "Колір значка";
|
||||
"Based on system color scheme" = "На основі системної кольорової гами";
|
||||
"Battery" = "Заряд";
|
||||
"Blue" = "Блакитний";
|
||||
"Browsing" = "Перегляд";
|
||||
"Based on system color scheme" = "Як в системі";
|
||||
"Battery" = "Батарея";
|
||||
"Blue" = "Синій";
|
||||
"Browsing" = "Навігація";
|
||||
"Buffering stream..." = "Буферизація потоку..";
|
||||
"Button" = "Кнопка";
|
||||
"Cancel" = "Скасування";
|
||||
"Cancel" = "Скасувати";
|
||||
"Captions" = "Субтитри";
|
||||
"Continue from %@" = "Продовжити з %@";
|
||||
"Contributing" = "Внесок";
|
||||
"Could not load locations manifest" = "Не вдається загрузити маніфест локацій";
|
||||
"Could not load locations manifest" = "Не вдалося завантажити маніфест локацій";
|
||||
"Country" = "Країна";
|
||||
"For videos which feature music as the primary content." = "Для відеороликів, основним змістом яких є музика.";
|
||||
"Formats will be selected in order as listed.\nHLS is an adaptive format (resolution setting does not apply)." = "Формати будуть вибиратися в порядку, як зазначено в списку. \nHLS - адаптивний формат (налаштування роздільної здатності не застосовується).";
|
||||
"Frontend URL" = "URL-адреса інтерфейсу";
|
||||
"Hide sidebar" = "Сховати сайдбар";
|
||||
"For videos which feature music as the primary content." = "Для відео, основним змістом яких є музика.";
|
||||
"Formats will be selected in order as listed.\nHLS is an adaptive format (resolution setting does not apply)." = "Формати будуть обрані в порядку, зазначеному в списку.\nHLS - адаптивний формат (налаштування роздільної здатності не застосовується).";
|
||||
"Frontend URL" = "Frontend URL";
|
||||
"Hide sidebar" = "Сховати бічну панель";
|
||||
"High" = "Висока";
|
||||
"Highest" = "Найвища";
|
||||
"Highest quality" = "Найвища якість";
|
||||
"History" = "Історія";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Hour" = "Година";
|
||||
"Hour" = "За останню годину";
|
||||
"I am lost" = "Я загубився";
|
||||
"I found a bug /" = "Я знайшов баг /";
|
||||
"I have a feature request" = "В мене є пропозиція";
|
||||
"I like this app!" = "Мені подобається цей застосунок!";
|
||||
"I have a feature request" = "У мене є пропозиція";
|
||||
"I like this app!" = "Мені подобається ця програма!";
|
||||
"I want to ask a question" = "Хочу задати питання";
|
||||
"If you are interested what's coming in future updates, you can track project Milestones." = "Якщо вам цікаво, що буде в наступних оновленнях, ви можете відстежувати етапи проєкту.";
|
||||
"Increase rate" = "Підвищити якість";
|
||||
"Info" = "Інфо";
|
||||
"Instance of current account" = "Экземпляр поточного акаунта";
|
||||
"Picture in Picture" = "Картинка в картинці";
|
||||
"If you are interested what's coming in future updates, you can track project Milestones." = "Якщо вам цікаво, що буде в наступних оновленнях, ви можете стежити за віхами (milestones) проекту на його сторінці GitHub.";
|
||||
"Increase rate" = "Збільшити швидкість";
|
||||
"Info" = "Інфомація";
|
||||
"Instance of current account" = "Інстанс поточного акаунта";
|
||||
"Picture in Picture" = "Картинка-в-картинці";
|
||||
"Play" = "Грати";
|
||||
"Play All" = "Грати все";
|
||||
"Play in PiP" = "Картинка в картинці";
|
||||
"Play in PiP" = "Грати в К-в-К";
|
||||
"Play Last" = "Грати останнє";
|
||||
"Play Music" = "Грати музику";
|
||||
"Play Next" = "Грати наступне";
|
||||
@@ -84,36 +84,36 @@
|
||||
"Playback" = "Відтворення";
|
||||
"Player" = "Плеєр";
|
||||
"Playlist" = "Плейлист";
|
||||
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "Плейлист \"%@\" буде видалений. \nЦе не можна буде скасувати.";
|
||||
"Playlist \"%@\" will be deleted.\nIt cannot be reverted." = "Плейлист \"%@\" буде видалений.\nЦе не можна буде скасувати.";
|
||||
"Playlists" = "Плейлисти";
|
||||
"Popular" = "Популярне";
|
||||
"Preferred Formats" = "Пріорітетні формати";
|
||||
"Preferred Formats" = "Бажані формати";
|
||||
"Profiles" = "Профілі";
|
||||
"Proxy videos" = "Використовувати проксі";
|
||||
"Public Locations" = "Публічні API";
|
||||
"Public Locations" = "Публічні API (локації)";
|
||||
"Public Manifest" = "Публічний маніфест";
|
||||
"Quality" = "Якість";
|
||||
"Quality Profile" = "Профіль якості";
|
||||
"Queue" = "Черга";
|
||||
"Queue is empty" = "Черга порожня";
|
||||
"Rate" = "Якість";
|
||||
"Rate" = "Швидкість";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Rating" = "Рейтинг";
|
||||
"Rating" = "По рейтингу";
|
||||
"Recents" = "Недавні";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Relevance" = "Відповідність";
|
||||
"Relevance" = "По релевантності";
|
||||
"Remove" = "Видалити";
|
||||
"Remove from Favorites" = "Видалити з улюблених";
|
||||
"Remove from history" = "Відалити з історії";
|
||||
"Remove from history" = "Видалити з історії";
|
||||
"Remove from Playlist" = "Видалити з плейлиста";
|
||||
"Remove from the queue" = "Видалити з черги";
|
||||
"Replies" = "Відповіді";
|
||||
"Thumbnails" = "Мініатюри";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Today" = "Сьогодні";
|
||||
"Today" = "За сьогодні";
|
||||
"Trending" = "Тренди";
|
||||
|
||||
/* Player controls layout size for TV */
|
||||
@@ -121,16 +121,16 @@
|
||||
"Typically near or at the end of the video when the credits pop up and/or endcards are shown." = "Як правило, в кінці відео, коли з'являються титри.";
|
||||
"unknown" = "невідомо";
|
||||
"Unsubscribe" = "Відписатися";
|
||||
"Upload date" = "Загрузити дату";
|
||||
"Upload date" = "Дата завантаження";
|
||||
"URL" = "URL";
|
||||
"Username" = "Імя користувача";
|
||||
"Username" = "Ім'я користувача";
|
||||
|
||||
/* Player controls layout size */
|
||||
"Very Large" = "Дуже великі";
|
||||
"Videos" = "Відео";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Views" = "Перегляди";
|
||||
"Views" = "По переглядам";
|
||||
"Watched" = "Переглянуто";
|
||||
|
||||
/* Selected video was played on given date */
|
||||
@@ -140,24 +140,24 @@
|
||||
"Watching now" = "Дивлюся зараз";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Week" = "Тиждень";
|
||||
"Welcome" = "Привіт";
|
||||
"Week" = "За тиждень";
|
||||
"Welcome" = "Ласкаво просимо";
|
||||
"Wi-Fi" = "Wi-Fi";
|
||||
"Wiki" = "Вікі";
|
||||
"Yattee %@ (build %@)" = "Yattee %@ (збірка %@)";
|
||||
"You have no Playlists" = "У вас немає плейлистів";
|
||||
"You have no playlists\n\nTap on \"New Playlist\" to create one" = "У вас немає плейлистів\n\nНатісніть \"Новий плейлист\" для створення";
|
||||
"You need to create an instance and accounts\nto access %@ section" = "Необхідно створити екземляри і аккаунти\nдля доступу до %@";
|
||||
"You need to select an account\nto access %@ section" = "Потрібно вибрати аккаунт\nдля доступу до %@";
|
||||
"You need to create an instance and accounts\nto access %@ section" = "Необхідно створити інстанс та акаунти\nдля доступу до %@ розділу";
|
||||
"You need to select an account\nto access %@ section" = "Потрібно вибрати акаунт\nдля доступу до %@ розділу";
|
||||
|
||||
|
||||
"Public" = "Публічний";
|
||||
"Unlisted" = "Прихований";
|
||||
"Unlisted" = "За посиланням";
|
||||
"Now Playing" = "Зараз грає";
|
||||
"Current Location" = "Поточний API (локація)";
|
||||
"Private" = "Видимість плейлиста";
|
||||
"Private" = "Приватний";
|
||||
"Playback queue is empty" = "Черга перегляду порожня";
|
||||
"Playing Next" = "Далі";
|
||||
"Playing Next" = "Грає далі";
|
||||
"You can switch between profiles in playback settings controls." = "Ви можете змінювати профіль під час перегляду.";
|
||||
"Make default" = "Зробити стандартним";
|
||||
"Visibility" = "Видимість";
|
||||
@@ -165,16 +165,16 @@
|
||||
"Stream & Player" = "Трансляція і відеоплеєр";
|
||||
"Hardware decoder" = "Апаратний декодер";
|
||||
"Stream FPS" = "FPS трансляції";
|
||||
"Rate & Captions" = "Якість і субтитри";
|
||||
"Rate & Captions" = "Швидкість і субтитри";
|
||||
"Translations" = "Переклади";
|
||||
"Could not open playlist" = "Не вдалося відкрити плейлист";
|
||||
"Could not extract video ID" = "Не вдалося отримати ID відео";
|
||||
"Always use AVPlayer for live videos" = "Використовуйте AVPlayer для live відео";
|
||||
"Always use AVPlayer for live videos" = "Завжди використовувати AVPlayer для прямих ефірів";
|
||||
"Are you sure you want to clear history of watched videos?" = "Ви впевнені, що хочете очистити історію переглядів?";
|
||||
"Country Name or Code" = "Назва або код країни";
|
||||
|
||||
/* Video sort order in search */
|
||||
"Date" = "Дата";
|
||||
"Date" = "По Даті";
|
||||
"Discord Server" = "Discord сервер";
|
||||
"Are you sure you want to unsubscribe from %@?" = "Ви впевнені, що хочете відписатися від %@?";
|
||||
"Bugs and great feature ideas can be sent to the GitHub issues tracker. " = "Баги та ідеї можна надсилати на GitHub Issues. ";
|
||||
@@ -182,32 +182,32 @@
|
||||
"Done" = "Готово";
|
||||
"Create Playlist" = "Створити плейлист";
|
||||
"Current: %@\n%@" = "Зараз: %@\n%@";
|
||||
"Custom Locations" = "Свої локації";
|
||||
"Custom Locations" = "Користувальницькі локації";
|
||||
"Copy %@ link with time" = "Копіювати %@ посилання з часом";
|
||||
"Decrease rate" = "Знизити рейт";
|
||||
"Decreased opacity" = "Зменшена непрозорість";
|
||||
"Decrease rate" = "Знизити швидкість";
|
||||
"Decreased opacity" = "Прозорістю";
|
||||
"Delete" = "Видалити";
|
||||
"Disabled" = "Вимкнено";
|
||||
"Discussions take place in Discord and Matrix. It's a good spot for general questions." = "Дискусії відбуваються в Discord та Matrix. Це гарні місця для загальних питань.";
|
||||
"Don't use public locations" = "Не використовуйте публічні локації";
|
||||
"Don't use public locations" = "Не використовувати публічні локації";
|
||||
"Donations" = "Донати";
|
||||
"Duration" = "Тривалість";
|
||||
"Gaming" = "Ігри";
|
||||
"Fullscreen size" = "На весь екран";
|
||||
"Fullscreen size" = "Повноекранний розмір";
|
||||
"Help" = "Допомога";
|
||||
"Related" = "Схожі";
|
||||
"Honor orientation lock" = "Блокування орієнтації";
|
||||
"If you are reporting a bug, include all relevant details (especially: app version, used device and system version, steps to reproduce)." = "Якщо ви повідомляєте про помилку, вказуйте всі відповідні деталі (особливо: версію застосунку, використовуваний пристрій, версію системи і кроки для відтворення).";
|
||||
"Promoting a product or service that is directly related to the creator themselves. This usually includes merchandise or promotion of monetized platforms." = "Просування продукту або послуги, які безпосередньо пов'язані з самим автором. Зазвичай це стосується товарів або просування монетизованих платформ.";
|
||||
"Honor orientation lock" = "Враховувати блокування орієнтації";
|
||||
"If you are reporting a bug, include all relevant details (especially: app version, used device and system version, steps to reproduce)." = "Якщо ви повідомляєте про баг, вказуйте всі відповідні деталі (особливо: версію застосунку, використовуваний пристрій, версію системи і кроки для відтворення).";
|
||||
"Promoting a product or service that is directly related to the creator themselves. This usually includes merchandise or promotion of monetized platforms." = "Просування продукту або послуги, які безпосередньо пов'язані з самим автором. Зазвичай це стосується товарів або просування підписочної платформи.";
|
||||
"Red" = "Червоний";
|
||||
"Refresh" = "Поновити";
|
||||
"Refresh" = "Оновити";
|
||||
"Regular size" = "Звичайний розмір";
|
||||
"Regular Size" = "Звичайний розмір";
|
||||
"Used to create links from videos, channels and playlists" = "Використовується для створення посилань на відео, канали ті плейлисти";
|
||||
"Regular Size" = "Звичайний Розмір";
|
||||
"Used to create links from videos, channels and playlists" = "Використовується для створення посилань на відео, канали та плейлисти";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Year" = "Рік";
|
||||
"You can find information about using Yattee in the Wiki pages." = "Додаткову інформацію про Yattee можна знайти на Вікі-сторінках.";
|
||||
"Year" = "За рік";
|
||||
"You can find information about using Yattee in the Wiki pages." = "Додаткову інформацію про Yattee можна знайти на просторах Вікі.";
|
||||
"You can use automatic profile selection based on current device status or switch it in video playback settings controls." = "Ви можете використовувати автоматичний вибір профілю якості на основі поточного стану пристрою або перемикати його в налаштуваннях відтворення відео.";
|
||||
"When partially watched video is played" = "При відтворенні частково переглянутого відео";
|
||||
"Yattee" = "Yattee";
|
||||
@@ -215,11 +215,11 @@
|
||||
"Statistics" = "Статистика";
|
||||
"Could not create share link" = "Не вдалося створити посилання";
|
||||
"Dropped frames" = "Втрата кадрів";
|
||||
"Badge" = "Значок";
|
||||
"Badge & Decreased opacity" = "Значок та зменшення непрозорості";
|
||||
"Badge" = "Значком";
|
||||
"Badge & Decreased opacity" = "Значком та прозорістю";
|
||||
"Categories to Skip" = "Категорії для пропуску";
|
||||
"Category" = "Категорія";
|
||||
"Cellular" = "Сотовий звязок";
|
||||
"Cellular" = "Сотовий зв'язок";
|
||||
"Chapters" = "Розділи";
|
||||
"Charging" = "Зарядка";
|
||||
"Clear" = "Очистити";
|
||||
@@ -229,20 +229,20 @@
|
||||
"Clear Search History" = "Очистити історію пошуку";
|
||||
"Clear Search History..." = "Очистити історію пошуку...";
|
||||
"Clear the queue" = "Очистити чергу";
|
||||
"Close PiP and open player when application enters foreground" = "Закрийте PiP і відкрийте плеєр, коли застосунок відкриється";
|
||||
"Close player when closing video" = "Закрийте плеєр, коли зупините відео";
|
||||
"Close player when starting PiP" = "Закрийте плеєр при старті PiP";
|
||||
"Close PiP and open player when application enters foreground" = "Закрити К-в-К і відкрити плеєр, коли застосунок на передньому плані";
|
||||
"Close player when closing video" = "Закрити плеєр при закритті відео";
|
||||
"Close player when starting PiP" = "Закрити плеєр при старті К-в-К";
|
||||
"Close Video" = "Закрити відео";
|
||||
"Close video after playing last in the queue" = "Закрити відео після завершення останнього відео в черзі";
|
||||
"Close video after playing last in the queue" = "Закрити відео після програвання черги";
|
||||
"Comments" = "Коментарі";
|
||||
"Contact" = "Контакт";
|
||||
"Contact" = "Зворотній зв'язок";
|
||||
"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)." = "Прямі нагадування залишити лайк, підписатися або взаємодіяти з автором на будь-якій платній чи безкоштовній платформі (платформах) (наприклад, натиснути на відео).";
|
||||
"Favorites" = "Улюблене";
|
||||
"Filter" = "ФІльтер";
|
||||
"Filter: active" = "Фільтер: активний";
|
||||
"Filter" = "Фільтр";
|
||||
"Filter: active" = "Фільтр: активний";
|
||||
"Find Other" = "Найти інше";
|
||||
"Finding something to play..." = "Знайти, у що пограти...";
|
||||
"Finding something to play..." = "Шукаю що відтворити...";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Interaction" = "Взаємодія";
|
||||
@@ -268,21 +268,21 @@
|
||||
"Lowest" = "Найнища";
|
||||
"Mark as watched" = "Позначити як переглянуте";
|
||||
"Mark video as watched after playing" = "Помітити відео як переглянуте після перегляду";
|
||||
"Mark watched videos with" = "Відмітити переглянуті відео з";
|
||||
"Mark watched videos with" = "Відмітити переглянуті відео";
|
||||
"Matrix Channel" = "Канал Matrix";
|
||||
"Matrix Chat" = "Чат Matrix";
|
||||
"Medium quality" = "Середня якість";
|
||||
"Milestones" = "Етапи";
|
||||
"Milestones" = "Віхи (Milestones)";
|
||||
|
||||
/* Video date filter in search */
|
||||
"Month" = "Місяці";
|
||||
"Month" = "За останній місяць";
|
||||
"More info can be found in:" = "Більше інформації можна знайти за посиланням:";
|
||||
"Movies" = "Фільми";
|
||||
"MPV Documentation" = "Документація MPV";
|
||||
"Music" = "Музика";
|
||||
"Name" = "Імʼя";
|
||||
"Name" = "Ім'я";
|
||||
"New Playlist" = "Новий плейлист";
|
||||
"Next" = "Наступне";
|
||||
"Next" = "Далі";
|
||||
"No description" = "Без опису";
|
||||
"No Playlists" = "Нема плейлистів";
|
||||
"No results" = "Без результатів";
|
||||
@@ -292,19 +292,19 @@
|
||||
"Nothing" = "Нічого";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Offtopic in Music Videos" = "Офтоп в музичних кліпах";
|
||||
"Offtopic in Music Videos" = "Не по темі в музичних кліпах";
|
||||
"Only when signed in" = "Тільки після авторизації";
|
||||
"Open \"Playlists\" tab to create new one" = "Відкрийте розділ \"Плейлисти\" для створення нового";
|
||||
"Open \"Playlists\" tab to create new one" = "Відкрити розділ \"Плейлисти\" для створення нового";
|
||||
"Open Settings" = "Відрити налаштування";
|
||||
|
||||
/* Loading stream OSD */
|
||||
"Opening %@ stream…" = "Запуск трансляції %@…";
|
||||
"Opening %@ stream…" = "Запуск %@ ефіру…";
|
||||
"Opening audio stream…" = "Запуск аудіо трансляції…";
|
||||
"Orientation" = "Орієнтація";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Outro" = "Кінцівка";
|
||||
"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." = "Частина відеоролика, що рекламує товар або послугу, не пов'язану безпосередньо з каналом. Власник каналу отримає оплату або безкоштовної продукції.";
|
||||
"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." = "Частина відеоролика, що рекламує товар або послугу, не пов'язану безпосередньо з автором. Власник каналу отримає оплату або безкоштовну продукції.";
|
||||
"Password" = "Пароль";
|
||||
"Pause" = "Пауза";
|
||||
"Pause when entering background" = "Пауза при переключенні на фоновий режим";
|
||||
@@ -315,7 +315,7 @@
|
||||
"Restart" = "Перезавантажити";
|
||||
"Restart/Play next" = "Перезапустити/Відтворити далі";
|
||||
"Restore default profiles..." = "Відновити стандартні профілі...";
|
||||
"Rotate to portrait when exiting fullscreen" = "Перехід до портретного режиму при виході з полноекранного режиму";
|
||||
"Rotate to portrait when exiting fullscreen" = "Перехід до портретного режиму при виході з повноекранного режиму";
|
||||
"Round corners" = "Закруглення кутів";
|
||||
"Save" = "Зберегти";
|
||||
"Save history of played videos" = "Зберегти історію переглянутих відео";
|
||||
@@ -326,24 +326,24 @@
|
||||
"Sections" = "Розділи";
|
||||
"Seek gesture sensitivity" = "Чутливість жестів";
|
||||
"Seek gesture speed" = "Швидкість жестів";
|
||||
"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." = "Сегменти, які зазвичай знаходяться на початку відео, що включають анімацію, стоп-кадр або кліп, які також можна побачити в інших відео того ж каналу.";
|
||||
"Select location closest to you:" = "Виберіть найблищу локацію:";
|
||||
|
||||
/* SponsorBlock category name */
|
||||
"Self-promotion" = "Самореклама";
|
||||
"Settings" = "Налаштування";
|
||||
"Share %@ link" = "Поділитися посиланням %@";
|
||||
"Share %@ link" = "Поділитися %@ посиланням";
|
||||
"Share..." = "Поділитися...";
|
||||
|
||||
/* Video duration filter in search */
|
||||
"Short" = "Короткі";
|
||||
"Show history" = "Показувати історію";
|
||||
"Show keywords" = "Показувати ключові слова";
|
||||
"Show playback statistics" = "Показувати статистику переглядів";
|
||||
"Show progress of watching on thumbnails" = "Показувати прогрес перегляду на мініатюрі";
|
||||
"Show sidebar when space permits" = "Показувати бокову панель, якщо вистачає простору";
|
||||
"Show video length" = "Показувати тривалість відео";
|
||||
"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" = "Бокова панель";
|
||||
@@ -360,23 +360,23 @@
|
||||
/* SponsorBlock category name */
|
||||
"Sponsor" = "Спонсор";
|
||||
"SponsorBlock" = "SponsorBlock";
|
||||
"SponsorBlock API Instance" = "Екземпляр API SponsorBlock";
|
||||
"SponsorBlock API Instance" = "Інстанс SponsorBlock API";
|
||||
"Subscribe" = "Підписатися";
|
||||
|
||||
/* Subscriptions title */
|
||||
"Subscriptions" = "Підписки";
|
||||
"Switch to other public location" = "Переключитися на іншу публічну локацію";
|
||||
"Switch to public locations" = "Переключитися на публічні локації";
|
||||
"System controls show buttons for %@" = "На елементах керування системою відображаються кнопки %@";
|
||||
"System controls show buttons for %@" = "На системних елементах керування відображаються кнопки %@";
|
||||
"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." = "Це призведе до видалення всіх ваших користувацьких профілів і повернення їхніх значень до стандартних. Це не може бути скасовано.";
|
||||
"This will remove all your custom profiles and return their default values. This cannot be reverted." = "Це призведе до видалення всіх ваших користувацьких профілів і повернення їхніх значень до стандартних. Це не можна буде скасувати.";
|
||||
"Cached time" = "Час кешування";
|
||||
"Any format" = "Будь-який формат";
|
||||
"%@ formats" = "%@ формати";
|
||||
"Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "Плейлист порожній\n\nНатисніть і утримуйте кнопку на відео, а потім натисніть на\n\"Додати до плейлиста\"";
|
||||
"Playlist is empty\n\nTap and hold on a video and then \n\"Add to Playlist\"" = "Плейлист порожній\n\nНатисніть і утримуйте на відео, а потім \n\"Додати до плейлиста\"";
|
||||
"Press and hold remote button to open captions and quality menus" = "Натисніть і утримуйте кнопку пульта, щоб відкрити меню субтитрів і якості";
|
||||
"Comments are disabled" = "Коментування вимкнуто";
|
||||
"Comments are disabled" = "Коментарі вимкнені";
|
||||
"No comments" = "Коментарі відсутні";
|
||||
"No chapters information available" = "Інформація про епізоди відсутня";
|
||||
"Share Logs..." = "Поділитися логами…";
|
||||
@@ -388,19 +388,19 @@
|
||||
"Could not update your token." = "Не вдалося оновити ваш токен.";
|
||||
"Could not refresh Trending" = "Не вдалося оновити тренди";
|
||||
"For custom locations you can configure Frontend URL in Locations settings" = "Для користувацьких локацій ви можете налаштувати Frontend URL в налаштуваннях локацій";
|
||||
"Connected successfully (%@)" = "Успішно підключено (%@)";
|
||||
"Close PiP when player is opened" = "Закрийте PiP, поки плеєр відкритий";
|
||||
"Close PiP when starting playing other video" = "Закрийте PiP, коли починаєте перегляд іншого відео";
|
||||
"Connected successfully (%@)" = "Підключено успішно (%@)";
|
||||
"Close PiP when player is opened" = "Закрити К-в-К, поки плеєр відкритий";
|
||||
"Close PiP when starting playing other video" = "Закрити К-в-К, коли відтворюється інше відео";
|
||||
"Connection failed" = "Помилка при підключенні";
|
||||
"Enable logging" = "Ввімкнути запис логів";
|
||||
"Enable logging" = "Увімкнути ведення журналу";
|
||||
"Edit" = "Редагувати";
|
||||
"Edit Playlist" = "Редагувати плейлист";
|
||||
"Edit Quality Profile" = "Редагувати профіль якості";
|
||||
"Edit..." = "Редагувати...";
|
||||
"Error" = "Помилка";
|
||||
"Large layout is not suitable for all devices and using it may cause controls not to fit on the screen." = "Великий розмір підходить не для всіх пристроїв і його використання може призвести до того, що елементи керування не будуть поміщатися на екрані.";
|
||||
"Enable Return YouTube Dislike" = "Ввімкнути повернення дизлайку YouTube";
|
||||
"Enter fullscreen in landscape" = "Увімкнути повноекранний режим в горизонтальному положенні";
|
||||
"Enable Return YouTube Dislike" = "Увімкнути Return YouTube Dislike";
|
||||
"Enter fullscreen in landscape" = "Увійти в повноекранний режим в альбомній орієнтації";
|
||||
"Interface" = "Інтерфейс";
|
||||
|
||||
/* Video duration filter in search */
|
||||
@@ -408,15 +408,15 @@
|
||||
|
||||
/* Player controls layout size */
|
||||
"Medium" = "Середній";
|
||||
"Share %@ link with time" = "Поділитися посиланням %@ з часом";
|
||||
"Share %@ link with time" = "Поділитися %@ посиланням з часом";
|
||||
"Reset watched status when playing again" = "Скинути статус перегляду при повторному відкритті";
|
||||
"Show account username" = "Відображати імʼя акаунту";
|
||||
"Restart the app to apply the settings above." = "Перезапустіть застосунок, щоб застосувати нові налаштування.";
|
||||
"Show anonymous accounts" = "Показувати анонімні акаунти";
|
||||
"Show channel name" = "Показувати назву каналу";
|
||||
"Show account username" = "Відображати ім'я акаунту";
|
||||
"Restart the app to apply the settings above." = "Перезапустіть програму, щоб застосувати нові налаштування.";
|
||||
"Show anonymous accounts" = "Відображати анонімні акаунти";
|
||||
"Show channel name" = "Відображати назву каналу";
|
||||
"Sign In Required" = "Необхідно увійти в систему";
|
||||
"It can be changed later in settings. You can use your own locations too." = "Пізніше це можна змінити в налаштуваннях. Ви також можете використовувати власні локації.";
|
||||
"System controls buttons" = "Кнопки керування системою";
|
||||
"System controls buttons" = "Системні кнопки керування";
|
||||
"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. You might need to switch between views or restart the app to see changes." = "Це не можна буде скасувати. Можливо, вам доведеться перемкнутися між режимами перегляду або перезапустити застосунок, щоб побачити зміни.";
|
||||
"Keep last played video in the queue after restart" = "Залишати останнє проглянуте відео в черзі після перезапуску";
|
||||
@@ -429,18 +429,18 @@
|
||||
"This video could not be opened" = "Не вдалося відкрити відео";
|
||||
"Could not load video" = "Не вдалося завантажити відео";
|
||||
"No locations available at the moment" = "Зараз немає доступних API (локацій)";
|
||||
"Could not refresh Playlists" = "Не вдалося поновити плейлисти";
|
||||
"Could not refresh Playlists" = "Не вдалося оновити плейлисти";
|
||||
"If you want this app to be available in your language, join translation project." = "Ви можете змінити або створити свій переклад на сторінці проєкту.";
|
||||
"No documents" = "Немає документів";
|
||||
"Are you sure you want to remove this document?" = "Ви впевнені, що бажаєте видалити цей документ?";
|
||||
"Recent Documents" = "Нещодавні документи";
|
||||
"Recent History" = "Останнє з історії";
|
||||
"Show Open Videos quick actions" = "Показати швидкі дії з відкритими відео";
|
||||
"Show Favorites" = "Показати вибране";
|
||||
"Show Favorites" = "Показати улюблене";
|
||||
"Home" = "Головна";
|
||||
"Share files from Finder on a Mac\nor iTunes on Windows" = "Обмін файлами з Finder на Mac\nабо iTunes на Windows";
|
||||
"Show Home" = "Показати головну";
|
||||
"URL to Open" = "Відкрити посилання";
|
||||
"URL to Open" = "Посилання для відкриття";
|
||||
"Enter link to open" = "Введіть посилання для відкриття";
|
||||
"Video" = "Відео";
|
||||
"Sample Rate" = "Частота дискретизації";
|
||||
@@ -448,7 +448,7 @@
|
||||
"Buttons labels" = "Написи на кнопках";
|
||||
"Files" = "Файли";
|
||||
"Video Details" = "Детальніше про відео";
|
||||
"Show Inspector" = "Показати інспектор";
|
||||
"Show Inspector" = "Показати інспектора";
|
||||
"Reload manifest" = "Перезавантажити маніфест";
|
||||
"Clear Queue before opening" = "Очищати чергу перед відкриттям";
|
||||
"Open" = "Відкрити";
|
||||
@@ -479,7 +479,7 @@
|
||||
"Playback history is empty" = "Історія перегляду відсутня";
|
||||
"Address" = "Адреса";
|
||||
"Actions buttons" = "Кнопки дій";
|
||||
"Show sidebar" = "Показ сайдбару";
|
||||
"Show sidebar" = "Показати бокову панель";
|
||||
"Locations Manifest" = "Маніфест локації";
|
||||
"Remove Location" = "Видалити локацію";
|
||||
"Open Video" = "Відкрити відео";
|
||||
@@ -494,15 +494,15 @@
|
||||
"Right" = "Праворуч";
|
||||
"File" = "Файл";
|
||||
"Show only icons" = "Показувати тільки іконки";
|
||||
"Edit Favorites…" = "Редагувати обране…";
|
||||
"Edit Favorites…" = "Редагувати улюблене…";
|
||||
"\"%@\" will be irreversibly removed from this device." = "\"%@\" буде безповоротно видалено з цього пристрою.";
|
||||
"Could not delete document" = "Не вдалося видалити документ";
|
||||
"Are you sure you want to remove %@ location?" = "Ви впевнені, що хочете видалити локацію %@?";
|
||||
"Are you sure you want to remove %@ location?" = "Ви впевнені, що хочете видалити %@ локацію?";
|
||||
"Live Streams" = "Наживо";
|
||||
"Shorts" = "Shorts";
|
||||
"Verified" = "Перевірений";
|
||||
"Channel" = "Канал";
|
||||
"Open expanded" = "Відкрито розширено";
|
||||
"Open expanded" = "Відкрити розширенним";
|
||||
"Mark channel feed as unwatched" = "Позначити стрiчку каналу не переглянутою";
|
||||
"Mark channel feed as watched" = "Позначити стрiчку каналу переглянутою";
|
||||
"Short videos: visible" = "Короткi вiдео: виднi";
|
||||
@@ -517,10 +517,10 @@
|
||||
"Clear all" = "Зачистити все";
|
||||
"Right click channel thumbnail to open context menu with more actions" = "Клацніть правою кнопкою миші на мініатюрі каналу, щоб відкрити контекстне меню з іншими діями";
|
||||
"Show unwatched feed badges" = "Показати бейджики непроглянутих стрічок";
|
||||
"Seeking" = "У пошуках";
|
||||
"Seeking" = "Прокрутка";
|
||||
"Gesture: fowards" = "Жест: вперед";
|
||||
"Controls Buttons" = "Кнопки керування";
|
||||
"System controls" = "Керування системою";
|
||||
"System controls" = "Системні елементи керування";
|
||||
"Controls button: backwards" = "Кнопка керування: назад";
|
||||
"Controls button: forwards" = "Кнопка керування: вперед";
|
||||
"Gesture: backwards" = "Жест: назад";
|
||||
@@ -552,18 +552,80 @@
|
||||
"Open channel" = "Відкрити канал";
|
||||
"Inspector" = "Інспектор";
|
||||
"Open video description expanded" = "Відкрити опис відео розширено";
|
||||
"Mark all as unwatched" = "Позначити всі не переклянутими";
|
||||
"Mark all as unwatched" = "Позначити всі не переглянутими";
|
||||
"Mark all as watched" = "Позначити всі переглянутими";
|
||||
"Queue - shuffled" = "Черга - перемішана";
|
||||
"Playback Settings" = "Налаштування відтворення";
|
||||
"Replay" = "Повтор";
|
||||
"Fullscreen" = "Повний екран";
|
||||
"Lock" = "Замок";
|
||||
"Lock" = "Заблокувати";
|
||||
"Description" = "Опис";
|
||||
"Loop one" = "Цикл один";
|
||||
"Loop one" = "Зациклити відео";
|
||||
"Autoplay next" = "Автовідтворення далі";
|
||||
"Stream" = "Потік";
|
||||
"Enter account credentials to connect..." = "Введіть облікові дані для з'єднання...";
|
||||
"Seek" = "Шукати";
|
||||
"Seek" = "Перемотати відео вперед/назад";
|
||||
"Show scroll to top button in comments" = "Показати кнопку прокрутки вгору в коментарях";
|
||||
"Enter location address to connect..." = "Введіть адресу розташування для з'єднання...";
|
||||
"Enter location address to connect..." = "Введіть адресу локації для з'єднання...";
|
||||
"Import Settings..." = "Імпортувати налаштування...";
|
||||
"Export Settings" = "Експортувати налаштування";
|
||||
"Accounts passwords (unencrypted)" = "Паролі акаунтів (не зашифровані)";
|
||||
"Other" = "Інше";
|
||||
"Other data" = "Інші дані";
|
||||
"Other data include last used playback preferences and listing options" = "Інші дані містять у собі налаштування останнього відтворення та параметри списку";
|
||||
"File information" = "Інформація про файл";
|
||||
"Build" = "Збірка";
|
||||
"Import" = "Імпорт";
|
||||
"Action button labels" = "Написи кнопок дій";
|
||||
"Icon and text" = "Іконка і текст";
|
||||
"Platform" = "Платформа";
|
||||
"Password required to import" = "Для імпорту потрібен пароль";
|
||||
"Custom Location not selected for import" = "Користувацька локація не обрана для імпорту";
|
||||
"Custom Location already exists" = "Користувацька локація вже існує";
|
||||
"Custom Location selected for import" = "Користувацька локація обрана для імпорту";
|
||||
"Account already exists" = "Акаунт уже існує";
|
||||
"Password saved in import file" = "Пароль збережений у файлі імпорту";
|
||||
"Export in progress..." = "Експорт у процесі...";
|
||||
"In progress..." = "У процесі…";
|
||||
"Play Now in AVPlayer" = "Грати зараз в AVPlayer";
|
||||
"Opening file…" = "Відкриваю файл…";
|
||||
"Show channel avatars in videos lists" = "Показати аватари каналів у списках відео";
|
||||
"Keep channels with unwatched videos on top of subscriptions list" = "Тримати канали з непроглянутими відео у верхній частині списку підписок";
|
||||
"Show video context menu options to force selected backend" = "Показати опції контекстного меню відео для примусового вибору backend";
|
||||
"Play Now in MPV" = "Грати зараз в MPV";
|
||||
"Description preview" = "Попередній перегляд опису";
|
||||
"No preview" = "Без попереднього перегляду";
|
||||
"Open vertical chapters expanded" = "Відкривати вертикальні розділи розгорнутими";
|
||||
"Chapters (if available)" = "Розділи (якщо доступні)";
|
||||
"Opened File" = "Відкритий файл";
|
||||
"File Extension" = "Розширення файлу";
|
||||
"Close video and player on end" = "Закрити відео і плеєр в кінці";
|
||||
"Public account" = "Публічний акаунт";
|
||||
"Browse without account" = "Дивитися без акаунта";
|
||||
"Landscape left" = "Альбомна орієнтація зліва";
|
||||
"Landscape right" = "Альбомна орієнтація праворуч";
|
||||
"Use system controls with AVPlayer" = "Використовувати системні елементи керування за допомогою AVPlayer";
|
||||
"Your Accounts" = "Ваші акаунти";
|
||||
"Rotate when entering fullscreen on landscape video" = "Повертати під час переходу в повноекранний режим в альбомній орієнтації";
|
||||
"No rotation" = "Без поворотів";
|
||||
"Show channel avatars in channels lists" = "Показувати аватари каналів у списках каналів";
|
||||
"Export..." = "Експортувати…";
|
||||
"Are you sure you want to export unencrypted passwords?" = "Ви впевнені, що хочете експортувати не зашифровані паролі?";
|
||||
"Icon only" = "Тільки іконка";
|
||||
"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" = "Не передавайте цей файл нікому, інакше ви можете втратити доступ до своїх акаунтів. Якщо ви не виберете експорт паролів, вам буде запропоновано ввести їх під час імпорту";
|
||||
"Export" = "Експорт";
|
||||
"Available" = "Доступно";
|
||||
"Startup section" = "Початковий розділ";
|
||||
"Home Settings" = "Налаштування головної";
|
||||
"Watched: hidden" = "Переглянуті: сховані";
|
||||
"Watched: visible" = "Переглянуті: показані";
|
||||
"(watched and shorts hidden)" = "(переглянуті та shorts сховані)";
|
||||
"Disable filters" = "Вимкнути фільтри";
|
||||
"No videos to show" = "Немає відео для показу";
|
||||
"(watched hidden)" = "(переглянуті сховані)";
|
||||
"(shorts hidden)" = "(shorts сховані)";
|
||||
"Limit" = "Ліміт";
|
||||
"Are you sure you want to remove %@ from Favorites?" = "Ви впевнені, що хочете видалити %@ з улюбленого?";
|
||||
"Podcasts" = "Подкасти";
|
||||
"Releases" = "Релізи";
|
||||
"Add %@" = "Додати %@";
|
||||
|
||||
@@ -72,8 +72,6 @@
|
||||
3703206627D2BB35007A0CB8 /* PINCache in Frameworks */ = {isa = PBXBuildFile; productRef = 3703206527D2BB35007A0CB8 /* PINCache */; };
|
||||
3703206827D2BB45007A0CB8 /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = 3703206727D2BB45007A0CB8 /* Defaults */; };
|
||||
3703206A27D2BB49007A0CB8 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 3703206927D2BB49007A0CB8 /* Alamofire */; };
|
||||
3704BDFF2ABF260C00370FF7 /* MPVKit in Frameworks */ = {isa = PBXBuildFile; productRef = 3704BDFE2ABF260C00370FF7 /* MPVKit */; };
|
||||
3704BE012ABF263E00370FF7 /* MPVKit in Frameworks */ = {isa = PBXBuildFile; productRef = 3704BE002ABF263E00370FF7 /* MPVKit */; };
|
||||
3705B180267B4DFB00704544 /* TrendingCountry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B17F267B4DFB00704544 /* TrendingCountry.swift */; };
|
||||
3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B181267B4E4900704544 /* TrendingCategory.swift */; };
|
||||
3705B183267B4E4900704544 /* TrendingCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3705B181267B4E4900704544 /* TrendingCategory.swift */; };
|
||||
@@ -621,6 +619,9 @@
|
||||
3797104928D3D10600D5F53C /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3797104828D3D10600D5F53C /* SDWebImageSwiftUI */; };
|
||||
3797104B28D3D18800D5F53C /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3797104A28D3D18800D5F53C /* SDWebImageSwiftUI */; };
|
||||
3797104D28D3D19100D5F53C /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 3797104C28D3D19100D5F53C /* SDWebImageSwiftUI */; };
|
||||
3797665B2C79FA6900C10DBD /* MPVKit in Frameworks */ = {isa = PBXBuildFile; productRef = 3797665A2C79FA6900C10DBD /* MPVKit */; };
|
||||
3797665D2C79FA7500C10DBD /* MPVKit in Frameworks */ = {isa = PBXBuildFile; productRef = 3797665C2C79FA7500C10DBD /* MPVKit */; };
|
||||
3797665F2C79FA7D00C10DBD /* MPVKit in Frameworks */ = {isa = PBXBuildFile; productRef = 3797665E2C79FA7D00C10DBD /* MPVKit */; };
|
||||
3797757D268922D100DD52A8 /* Siesta in Frameworks */ = {isa = PBXBuildFile; productRef = 3797757C268922D100DD52A8 /* Siesta */; };
|
||||
37977583268922F600DD52A8 /* InvidiousAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37977582268922F600DD52A8 /* InvidiousAPI.swift */; };
|
||||
37977584268922F600DD52A8 /* InvidiousAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37977582268922F600DD52A8 /* InvidiousAPI.swift */; };
|
||||
@@ -1082,7 +1083,6 @@
|
||||
E27568B92BFAAC2000BDF0AF /* LanguageCodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27568B82BFAAC2000BDF0AF /* LanguageCodes.swift */; };
|
||||
E27568BA2BFAAC2000BDF0AF /* LanguageCodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27568B82BFAAC2000BDF0AF /* LanguageCodes.swift */; };
|
||||
E27568BB2BFAAC2000BDF0AF /* LanguageCodes.swift in Sources */ = {isa = PBXBuildFile; fileRef = E27568B82BFAAC2000BDF0AF /* LanguageCodes.swift */; };
|
||||
FA97174C2A494700001FF53D /* MPVKit in Frameworks */ = {isa = PBXBuildFile; productRef = FA97174B2A494700001FF53D /* MPVKit */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -1597,9 +1597,9 @@
|
||||
37BADCA52699FB72009BE4FB /* Alamofire in Frameworks */,
|
||||
377FC7D5267A080300A6BBAF /* SwiftyJSON in Frameworks */,
|
||||
3797104928D3D10600D5F53C /* SDWebImageSwiftUI in Frameworks */,
|
||||
FA97174C2A494700001FF53D /* MPVKit in Frameworks */,
|
||||
37BD07B92698AB2E003EBB87 /* Siesta in Frameworks */,
|
||||
37FB284D2722099E00A57617 /* SDWebImageWebPCoder in Frameworks */,
|
||||
3797665B2C79FA6900C10DBD /* MPVKit in Frameworks */,
|
||||
37CF8B8428535E4F00B71E37 /* SDWebImage in Frameworks */,
|
||||
37C7367A2AC33010007630E1 /* SwiftUIIntrospect in Frameworks */,
|
||||
);
|
||||
@@ -1624,7 +1624,7 @@
|
||||
375B8AB728B583BD00397B31 /* KeychainAccess in Frameworks */,
|
||||
3703205E27D2BB12007A0CB8 /* SDWebImageWebPCoder in Frameworks */,
|
||||
37CF8B8628535E5A00B71E37 /* SDWebImage in Frameworks */,
|
||||
3704BDFF2ABF260C00370FF7 /* MPVKit in Frameworks */,
|
||||
3797665D2C79FA7500C10DBD /* MPVKit in Frameworks */,
|
||||
3703205C27D2BAF3007A0CB8 /* SwiftyJSON in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1670,7 +1670,7 @@
|
||||
372915E42687E33E00F5A35B /* Defaults in Frameworks */,
|
||||
3772003B27E8EEC800CB2475 /* libbz2.tbd in Frameworks */,
|
||||
37BADCA9269A570B009BE4FB /* Alamofire in Frameworks */,
|
||||
3704BE012ABF263E00370FF7 /* MPVKit in Frameworks */,
|
||||
3797665F2C79FA7D00C10DBD /* MPVKit in Frameworks */,
|
||||
37D4B19D2671817900C925CA /* SwiftyJSON in Frameworks */,
|
||||
3797757D268922D100DD52A8 /* Siesta in Frameworks */,
|
||||
);
|
||||
@@ -2584,8 +2584,8 @@
|
||||
377F9F73294403770043F856 /* Cache */,
|
||||
371AC0AB294D1A490085989E /* CachedAsyncImage */,
|
||||
379325D429A265A300181CF1 /* Logging */,
|
||||
FA97174B2A494700001FF53D /* MPVKit */,
|
||||
37C736792AC33010007630E1 /* SwiftUIIntrospect */,
|
||||
3797665A2C79FA6900C10DBD /* MPVKit */,
|
||||
);
|
||||
productName = "Yattee (iOS)";
|
||||
productReference = 37D4B0C92671614900C925CA /* Yattee.app */;
|
||||
@@ -2623,8 +2623,8 @@
|
||||
374D11E62943C56300CB4350 /* Cache */,
|
||||
371AC0B1294D1C230085989E /* CachedAsyncImage */,
|
||||
379325D629A265AE00181CF1 /* Logging */,
|
||||
3704BDFE2ABF260C00370FF7 /* MPVKit */,
|
||||
37C736772AC32B28007630E1 /* SwiftUIIntrospect */,
|
||||
3797665C2C79FA7500C10DBD /* MPVKit */,
|
||||
);
|
||||
productName = "Yattee (macOS)";
|
||||
productReference = 37D4B0CF2671614900C925CA /* Yattee.app */;
|
||||
@@ -2702,7 +2702,7 @@
|
||||
377F9F75294403880043F856 /* Cache */,
|
||||
371AC0B3294D1C290085989E /* CachedAsyncImage */,
|
||||
379325D829A265B500181CF1 /* Logging */,
|
||||
3704BE002ABF263E00370FF7 /* MPVKit */,
|
||||
3797665E2C79FA7D00C10DBD /* MPVKit */,
|
||||
);
|
||||
productName = Yattee;
|
||||
productReference = 37D4B158267164AE00C925CA /* Yattee.app */;
|
||||
@@ -2734,7 +2734,7 @@
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1500;
|
||||
LastUpgradeCheck = 1500;
|
||||
LastUpgradeCheck = 1600;
|
||||
TargetAttributes = {
|
||||
37095E7E291DC85400301883 = {
|
||||
CreatedOnToolsVersion = 14.1;
|
||||
@@ -2822,7 +2822,7 @@
|
||||
374D11E52943C56300CB4350 /* XCRemoteSwiftPackageReference "Cache" */,
|
||||
371AC0AA294D1A490085989E /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */,
|
||||
379325D329A265A300181CF1 /* XCRemoteSwiftPackageReference "swift-log" */,
|
||||
FA97174A2A494700001FF53D /* XCRemoteSwiftPackageReference "MPVKit" */,
|
||||
379766592C79FA6900C10DBD /* XCRemoteSwiftPackageReference "MPVKit" */,
|
||||
);
|
||||
productRefGroup = 37D4B0CA2671614900C925CA /* Products */;
|
||||
projectDirPath = "";
|
||||
@@ -4103,7 +4103,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee";
|
||||
@@ -4134,7 +4134,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
||||
@@ -4165,7 +4165,7 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
@@ -4185,7 +4185,7 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
@@ -4342,14 +4342,13 @@
|
||||
37D4B0ED2671614900C925CA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
|
||||
CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
@@ -4395,14 +4394,13 @@
|
||||
37D4B0EE2671614900C925CA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1";
|
||||
@@ -4454,7 +4452,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@@ -4493,7 +4491,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
@@ -4526,9 +4524,8 @@
|
||||
37D4B0F32671614900C925CA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4550,9 +4547,8 @@
|
||||
37D4B0F42671614900C925CA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4575,10 +4571,9 @@
|
||||
37D4B0F62671614900C925CA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4600,10 +4595,9 @@
|
||||
37D4B0F72671614900C925CA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4629,7 +4623,7 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -4669,7 +4663,7 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
"DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -4708,9 +4702,8 @@
|
||||
37D4B17E267164B000C925CA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -4732,9 +4725,8 @@
|
||||
37D4B17F267164B000C925CA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 187;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -4968,6 +4960,14 @@
|
||||
minimumVersion = 2.1.0;
|
||||
};
|
||||
};
|
||||
379766592C79FA6900C10DBD /* XCRemoteSwiftPackageReference "MPVKit" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/cxfksword/MPVKit";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 0.38.0;
|
||||
};
|
||||
};
|
||||
3797757B268922D100DD52A8 /* XCRemoteSwiftPackageReference "siesta" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/bustoutsolutions/siesta";
|
||||
@@ -5040,14 +5040,6 @@
|
||||
minimumVersion = 0.3.0;
|
||||
};
|
||||
};
|
||||
FA97174A2A494700001FF53D /* XCRemoteSwiftPackageReference "MPVKit" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/cxfksword/MPVKit.git";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 0.38.0;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
@@ -5086,16 +5078,6 @@
|
||||
package = 37BADCA32699FB72009BE4FB /* XCRemoteSwiftPackageReference "Alamofire" */;
|
||||
productName = Alamofire;
|
||||
};
|
||||
3704BDFE2ABF260C00370FF7 /* MPVKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = FA97174A2A494700001FF53D /* XCRemoteSwiftPackageReference "MPVKit" */;
|
||||
productName = MPVKit;
|
||||
};
|
||||
3704BE002ABF263E00370FF7 /* MPVKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = FA97174A2A494700001FF53D /* XCRemoteSwiftPackageReference "MPVKit" */;
|
||||
productName = MPVKit;
|
||||
};
|
||||
371AC0AB294D1A490085989E /* CachedAsyncImage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 371AC0AA294D1A490085989E /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */;
|
||||
@@ -5246,6 +5228,21 @@
|
||||
package = 3797104728D3D10600D5F53C /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */;
|
||||
productName = SDWebImageSwiftUI;
|
||||
};
|
||||
3797665A2C79FA6900C10DBD /* MPVKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 379766592C79FA6900C10DBD /* XCRemoteSwiftPackageReference "MPVKit" */;
|
||||
productName = MPVKit;
|
||||
};
|
||||
3797665C2C79FA7500C10DBD /* MPVKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 379766592C79FA6900C10DBD /* XCRemoteSwiftPackageReference "MPVKit" */;
|
||||
productName = MPVKit;
|
||||
};
|
||||
3797665E2C79FA7D00C10DBD /* MPVKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 379766592C79FA6900C10DBD /* XCRemoteSwiftPackageReference "MPVKit" */;
|
||||
productName = MPVKit;
|
||||
};
|
||||
3797757C268922D100DD52A8 /* Siesta */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 3797757B268922D100DD52A8 /* XCRemoteSwiftPackageReference "siesta" */;
|
||||
@@ -5331,11 +5328,6 @@
|
||||
package = 37FB285227220D8400A57617 /* XCRemoteSwiftPackageReference "SDWebImagePINPlugin" */;
|
||||
productName = SDWebImagePINPlugin;
|
||||
};
|
||||
FA97174B2A494700001FF53D /* MPVKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = FA97174A2A494700001FF53D /* XCRemoteSwiftPackageReference "MPVKit" */;
|
||||
productName = MPVKit;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
||||
/* Begin XCVersionGroup section */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "9899ef48b3ee49eae175e25421b8330438e40c30a266d96473b299a6ab7c4188",
|
||||
"originHash" : "1f99971d9d21cffe56d0033bc5c38e9fcd5ff46ca5f7d19c76f5ba0a268ce4b6",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "activelabel.swift",
|
||||
@@ -25,7 +25,7 @@
|
||||
"location" : "https://github.com/hyperoslo/Cache.git",
|
||||
"state" : {
|
||||
"branch" : "master",
|
||||
"revision" : "dff9930c559aa2d1f7ed818d490d30c8852f57a6"
|
||||
"revision" : "d2e8f5a53c601b43371fdc90277d7f64b0e89a25"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -58,7 +58,7 @@
|
||||
{
|
||||
"identity" : "mpvkit",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/cxfksword/MPVKit.git",
|
||||
"location" : "https://github.com/cxfksword/MPVKit",
|
||||
"state" : {
|
||||
"revision" : "f646e4b625e9c8a2ff22a7e0bb5557306300be5d",
|
||||
"version" : "0.38.0"
|
||||
@@ -105,8 +105,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/SDWebImage/SDWebImage",
|
||||
"state" : {
|
||||
"revision" : "be0bcd7823ce56629948491f2eaeaa19979514f7",
|
||||
"version" : "5.19.4"
|
||||
"revision" : "8a1be70a625683bc04d6903e2935bf23f3c6d609",
|
||||
"version" : "5.19.7"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
LastUpgradeVersion = "1600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
LastUpgradeVersion = "1600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
LastUpgradeVersion = "1600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
LastUpgradeVersion = "1600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
LastUpgradeVersion = "1600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
LastUpgradeVersion = "1600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1500"
|
||||
LastUpgradeVersion = "1600"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -65,9 +65,11 @@ public class OrientationTracker {
|
||||
guard newDeviceOrientation != self.currentDeviceOrientation else { return }
|
||||
self.currentDeviceOrientation = newDeviceOrientation
|
||||
|
||||
NotificationCenter.default.post(name: Self.deviceOrientationChangedNotification,
|
||||
object: nil,
|
||||
userInfo: nil)
|
||||
NotificationCenter.default.post(
|
||||
name: Self.deviceOrientationChangedNotification,
|
||||
object: nil,
|
||||
userInfo: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import SwiftUI
|
||||
struct ShareSheet: UIViewControllerRepresentable {
|
||||
typealias Callback = (_ activityType: UIActivity.ActivityType?,
|
||||
_ completed: Bool,
|
||||
_ returnedItems: [Any]?,
|
||||
_ returnedItems: [Any],
|
||||
_ error: Error?) -> Void
|
||||
|
||||
let activityItems: [Any]
|
||||
@@ -19,7 +19,10 @@ struct ShareSheet: UIViewControllerRepresentable {
|
||||
)
|
||||
|
||||
controller.excludedActivityTypes = excludedActivityTypes
|
||||
controller.completionWithItemsHandler = callback
|
||||
|
||||
controller.completionWithItemsHandler = { activityType, completed, returnedItems, error in
|
||||
callback?(activityType, completed, returnedItems ?? [], error)
|
||||
}
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
@@ -38,10 +38,12 @@ final class VideoLayer: CAOpenGLLayer {
|
||||
glGetIntegerv(GLenum(GL_DRAW_FRAMEBUFFER_BINDING), &i)
|
||||
|
||||
if client.mpvGL != nil {
|
||||
var data = mpv_opengl_fbo(fbo: Int32(i),
|
||||
w: Int32(bounds.size.width),
|
||||
h: Int32(bounds.size.height),
|
||||
internal_format: 0)
|
||||
var data = mpv_opengl_fbo(
|
||||
fbo: Int32(i),
|
||||
w: Int32(bounds.size.width),
|
||||
h: Int32(bounds.size.height),
|
||||
internal_format: 0
|
||||
)
|
||||
var params: [mpv_render_param] = [
|
||||
mpv_render_param(type: MPV_RENDER_PARAM_OPENGL_FBO, data: &data),
|
||||
mpv_render_param(type: MPV_RENDER_PARAM_FLIP_Y, data: &flip),
|
||||
@@ -106,8 +108,10 @@ final class VideoLayer: CAOpenGLLayer {
|
||||
let displayId = UInt32(NSScreen.main?.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as! Int)
|
||||
|
||||
CVDisplayLinkCreateWithCGDisplay(displayId, &client.link)
|
||||
CVDisplayLinkSetOutputCallback(client.link!, displayLinkCallback,
|
||||
UnsafeMutableRawPointer(Unmanaged.passUnretained(client.layer).toOpaque()))
|
||||
CVDisplayLinkSetOutputCallback(
|
||||
client.link!, displayLinkCallback,
|
||||
UnsafeMutableRawPointer(Unmanaged.passUnretained(client.layer).toOpaque())
|
||||
)
|
||||
CVDisplayLinkStart(client.link!)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ struct NowPlayingView: View {
|
||||
var inInfoViewController = false
|
||||
|
||||
@State private var repliesID: Comment.ID?
|
||||
@State private var availableWidth = 0.0
|
||||
|
||||
@FetchRequest(sortDescriptors: [.init(key: "watchedAt", ascending: false)])
|
||||
var watches: FetchedResults<Watch>
|
||||
@@ -109,7 +110,7 @@ struct NowPlayingView: View {
|
||||
} else {
|
||||
Section {
|
||||
ForEach(comments.all) { comment in
|
||||
CommentView(comment: comment, repliesID: $repliesID)
|
||||
CommentView(comment: comment, repliesID: $repliesID, availableWidth: availableWidth)
|
||||
}
|
||||
if comments.nextPageAvailable {
|
||||
Text("Scroll to load more...")
|
||||
@@ -120,6 +121,12 @@ struct NowPlayingView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
.background(GeometryReader { geometry in
|
||||
Color.clear
|
||||
.onAppear {
|
||||
self.availableWidth = Double(geometry.size.width)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user