Compare commits

..

6 Commits

Author SHA1 Message Date
Arkadiusz Fal
1fe8a32fb8 Bump build number to 182 2024-05-16 19:09:12 +02:00
Arkadiusz Fal
5a0c1bbae3 Update CHANGELOG 2024-05-16 19:07:50 +02:00
Arkadiusz Fal
4ce9dc6729 Fix build issues 2024-05-16 19:05:00 +02:00
Arkadiusz Fal
b783db30b6 Update dependencies 2024-05-16 19:01:02 +02:00
Arkadiusz Fal
7741e531f4 Swiftformat fixes 2024-05-16 19:01:02 +02:00
Arkadiusz Fal
4b21cd48e3 Merge pull request #669 from yattee/revert-652-seek-gesture
Revert "small delay before vertical scrubbing is possible"
2024-05-16 19:00:30 +02:00
39 changed files with 237 additions and 185 deletions

View File

@@ -1,10 +1,25 @@
## Build 181 ## Build 181
* History Setting: hide the recent activity in the sidebar or limit the number of items shown (by @rickykresslein) * Don't show related in sidebar when disabled in settings by @stonerl in https://github.com/yattee/yattee/pull/635
* Fix issues with empty comments (by @stonerl) * Handle audio session interrupts by other media by @stonerl in https://github.com/yattee/yattee/pull/640
* Improved Invidious comments (by @stonerl) * Only show Queue header in sidebar view by @stonerl in https://github.com/yattee/yattee/pull/642
* Downgrade MPVKit to 0.36.0-1 due to issues with WebVTT subtitles * SponsorBlock Improvements by @stonerl in https://github.com/yattee/yattee/pull/639
* Chapter title on jump by @stonerl in https://github.com/yattee/yattee/pull/655
* Restart finished video by @stonerl in https://github.com/yattee/yattee/pull/646
* SponsorBlock jump to end instead of pausing by @stonerl in https://github.com/yattee/yattee/pull/648
* Call correct class of SDImageAWebPCoder by @stonerl in https://github.com/yattee/yattee/pull/664
* Fix handling and displaying captions by @stonerl in https://github.com/yattee/yattee/pull/636
* Advanced settings: make number fields .numPad by @stonerl in https://github.com/yattee/yattee/pull/661
* Preserve time on stream change by @stonerl in https://github.com/yattee/yattee/pull/651
* Switch to previous backend when leaving PiP by @stonerl in https://github.com/yattee/yattee/pull/641
* Handle deep links by @timonus in https://github.com/yattee/yattee/pull/645
* Music Mode: don't bindPlayerToLayer when entering foreground by @stonerl in https://github.com/yattee/yattee/pull/644
* Allow user to disable thumbnails and jump to current chapter in horizontal view by @stonerl in https://github.com/yattee/yattee/pull/665
* Rework qualitiy settings by @stonerl in https://github.com/yattee/yattee/pull/650
* HLS: set target bitrate / AVPlayer: higher resolution by @stonerl in https://github.com/yattee/yattee/pull/667
* Fix #619: Remove ports from shared YouTube links by @0x000C in https://github.com/yattee/yattee/pull/627
* XCode enable IDEPreferLogStreaming by @stonerl in https://github.com/yattee/yattee/pull/638
* Updated localizations * Updated localizations
* Updated dependencies * Upgraded dependencies
## Previous builds ## Previous builds
* Add skip, play/pause, and fullscreen shortcuts to macOS player (by @rickykresslein) * Add skip, play/pause, and fullscreen shortcuts to macOS player (by @rickykresslein)
@@ -16,6 +31,10 @@
* Added Controls setting "Action button labels" icon or icon and text * Added Controls setting "Action button labels" icon or icon and text
* Added Advanced setting for MPV: "deinterlace" * Added Advanced setting for MPV: "deinterlace"
* Add help text to all header buttons (by @rickykresslein) * Add help text to all header buttons (by @rickykresslein)
* History Setting: hide the recent activity in the sidebar or limit the number of items shown (by @rickykresslein)
* Fix issues with empty comments (by @stonerl)
* Improved Invidious comments (by @stonerl)
* Downgrade MPVKit to 0.36.0-1 due to issues with WebVTT subtitles
* Add Chinese (Traditional) localization (by @rexcsk) * Add Chinese (Traditional) localization (by @rexcsk)
* Localization fixes * Localization fixes
* Updated localizations * Updated localizations

View File

@@ -17,13 +17,13 @@ extension String {
var outputText = self var outputText = self
results.reversed().forEach { match in for match in results.reversed() {
(1 ..< match.numberOfRanges).reversed().forEach { rangeIndex in for rangeIndex in (1 ..< match.numberOfRanges).reversed() {
let matchingGroup: String = (self as NSString).substring(with: match.range(at: rangeIndex)) let matchingGroup: String = (self as NSString).substring(with: match.range(at: rangeIndex))
let rangeBounds = match.range(at: rangeIndex) let rangeBounds = match.range(at: rangeIndex)
guard let range = Range(rangeBounds, in: self) else { guard let range = Range(rangeBounds, in: self) else {
return continue
} }
let replacement = replacementStringClosure(matchingGroup) ?? matchingGroup let replacement = replacementStringClosure(matchingGroup) ?? matchingGroup

View File

@@ -4,11 +4,11 @@ extension URL {
func byReplacingYatteeProtocol(with urlProtocol: String = "https") -> URL! { func byReplacingYatteeProtocol(with urlProtocol: String = "https") -> URL! {
var urlAbsoluteString = absoluteString var urlAbsoluteString = absoluteString
guard urlAbsoluteString.hasPrefix(Constants.yatteeProtocol) else { guard urlAbsoluteString.hasPrefix(Strings.yatteeProtocol) else {
return self return self
} }
urlAbsoluteString = String(urlAbsoluteString.dropFirst(Constants.yatteeProtocol.count)) urlAbsoluteString = String(urlAbsoluteString.dropFirst(Strings.yatteeProtocol.count))
if absoluteString.contains("://") { if absoluteString.contains("://") {
return URL(string: urlAbsoluteString) return URL(string: urlAbsoluteString)
} }

View File

@@ -57,17 +57,17 @@ GEM
artifactory (3.0.17) artifactory (3.0.17)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.3.0) aws-eventstream (1.3.0)
aws-partitions (1.906.0) aws-partitions (1.929.0)
aws-sdk-core (3.191.6) aws-sdk-core (3.196.1)
aws-eventstream (~> 1, >= 1.3.0) aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0) aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8) aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1) jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.78.0) aws-sdk-kms (1.81.0)
aws-sdk-core (~> 3, >= 3.191.0) aws-sdk-core (~> 3, >= 3.193.0)
aws-sigv4 (~> 1.1) aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.146.1) aws-sdk-s3 (1.151.0)
aws-sdk-core (~> 3, >= 3.191.0) aws-sdk-core (~> 3, >= 3.194.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8) aws-sigv4 (~> 1.8)
aws-sigv4 (1.8.0) aws-sigv4 (1.8.0)
@@ -157,27 +157,28 @@ GEM
domain_name (~> 0.5) domain_name (~> 0.5)
httpclient (2.8.3) httpclient (2.8.3)
jmespath (1.6.2) jmespath (1.6.2)
json (2.7.1) json (2.7.2)
jwt (2.8.1) jwt (2.8.1)
base64 base64
mini_magick (4.12.0) mini_magick (4.12.0)
mini_mime (1.1.5) mini_mime (1.1.5)
multi_json (1.15.0) multi_json (1.15.0)
multipart-post (2.4.0) multipart-post (2.4.1)
nanaimo (0.3.0) nanaimo (0.3.0)
naturally (2.2.1) naturally (2.2.1)
nkf (0.2.0) nkf (0.2.0)
optparse (0.4.0) optparse (0.5.0)
os (1.1.4) os (1.1.4)
plist (3.7.1) plist (3.7.1)
public_suffix (5.0.5) public_suffix (5.0.5)
rake (13.2.0) rake (13.2.1)
representable (3.2.0) representable (3.2.0)
declarative (< 0.1.0) declarative (< 0.1.0)
trailblazer-option (>= 0.1.1, < 0.2.0) trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0) uber (< 0.2.0)
retriable (3.1.2) retriable (3.1.2)
rexml (3.2.6) rexml (3.2.8)
strscan (>= 3.0.9)
rouge (2.0.7) rouge (2.0.7)
ruby2_keywords (0.0.5) ruby2_keywords (0.0.5)
rubyzip (2.3.2) rubyzip (2.3.2)
@@ -190,6 +191,7 @@ GEM
simctl (1.6.10) simctl (1.6.10)
CFPropertyList CFPropertyList
naturally naturally
strscan (3.1.0)
terminal-notifier (2.0.0) terminal-notifier (2.0.0)
terminal-table (3.0.2) terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3) unicode-display_width (>= 1.1.1, < 3)

View File

@@ -66,7 +66,7 @@ protocol VideosAPI {
failureHandler: ((RequestError) -> Void)?, failureHandler: ((RequestError) -> Void)?,
completionHandler: @escaping (PlayerQueueItem) -> Void completionHandler: @escaping (PlayerQueueItem) -> Void
) )
func shareURL(_ item: ContentItem, frontendURL: String?, time: CMTime?) -> URL? func shareURL(_ item: ContentItem, frontendURLString: String?, time: CMTime?) -> URL?
func comments(_ id: Video.ID, page: String?) -> Resource? func comments(_ id: Video.ID, page: String?) -> Resource?
} }
@@ -111,8 +111,9 @@ extension VideosAPI {
func shareURL(_ item: ContentItem, frontendURLString: String? = nil, time: CMTime? = nil) -> URL? { func shareURL(_ item: ContentItem, frontendURLString: String? = nil, time: CMTime? = nil) -> URL? {
var urlComponents: URLComponents? var urlComponents: URLComponents?
if let frontendURLString, if let frontendURLString,
let frontendURL = URL(string: frontendURLString) { let frontendURL = URL(string: frontendURLString)
urlComponents = URLComponents(URL: frontendURL, resolvingAgainstBaseURL: false) {
urlComponents = URLComponents(url: frontendURL, resolvingAgainstBaseURL: false)
} else if let instanceComponents = account?.instance?.urlComponents { } else if let instanceComponents = account?.instance?.urlComponents {
urlComponents = instanceComponents urlComponents = instanceComponents
} }

View File

@@ -22,7 +22,7 @@ struct BrowsingSettingsGroupImporter {
} }
if let favorites = json["favorites"].array { if let favorites = json["favorites"].array {
favorites.forEach { favoriteJSON in for favoriteJSON in favorites {
if let jsonString = favoriteJSON.rawString(options: []), if let jsonString = favoriteJSON.rawString(options: []),
let item = FavoriteItem.bridge.deserialize(jsonString) let item = FavoriteItem.bridge.deserialize(jsonString)
{ {
@@ -32,7 +32,7 @@ struct BrowsingSettingsGroupImporter {
} }
if let widgetsFavorites = json["widgetsSettings"].array { if let widgetsFavorites = json["widgetsSettings"].array {
widgetsFavorites.forEach { widgetJSON in for widgetJSON in widgetsFavorites {
let dict = widgetJSON.dictionaryValue.mapValues { json in json.stringValue } let dict = widgetJSON.dictionaryValue.mapValues { json in json.stringValue }
if let item = WidgetSettingsBridge().deserialize(dict) { if let item = WidgetSettingsBridge().deserialize(dict) {
FavoritesModel.shared.updateWidgetSettings(item) FavoritesModel.shared.updateWidgetSettings(item)

View File

@@ -56,7 +56,7 @@ struct LocationsSettingsGroupImporter {
} }
if let accounts = json["accounts"].array { if let accounts = json["accounts"].array {
accounts.forEach { accountJSON in for accountJSON in accounts {
let dict = accountJSON.dictionaryValue.mapValues { json in json.stringValue } let dict = accountJSON.dictionaryValue.mapValues { json in json.stringValue }
if let account = AccountsBridge().deserialize(dict), if let account = AccountsBridge().deserialize(dict),
includedAccountsIDs.contains(account.id) includedAccountsIDs.contains(account.id)

View File

@@ -26,7 +26,7 @@ struct QualitySettingsGroupImporter {
} }
if let qualityProfiles = json["qualityProfiles"].array { if let qualityProfiles = json["qualityProfiles"].array {
qualityProfiles.forEach { qualityProfileJSON in for qualityProfileJSON in qualityProfiles {
let dict = qualityProfileJSON.dictionaryValue.mapValues { json in json.stringValue } let dict = qualityProfileJSON.dictionaryValue.mapValues { json in json.stringValue }
if let item = QualityProfileBridge().deserialize(dict) { if let item = QualityProfileBridge().deserialize(dict) {
QualityProfilesModel.shared.update(item, item) QualityProfilesModel.shared.update(item, item)

View File

@@ -6,7 +6,7 @@ struct RecentlyOpenedImporter {
func performImport() { func performImport() {
if let recentlyOpened = json["recentlyOpened"].array { if let recentlyOpened = json["recentlyOpened"].array {
recentlyOpened.forEach { recentlyOpenedJSON in for recentlyOpenedJSON in recentlyOpened {
let dict = recentlyOpenedJSON.dictionaryValue.mapValues { json in json.stringValue } let dict = recentlyOpenedJSON.dictionaryValue.mapValues { json in json.stringValue }
if let item = RecentItemBridge().deserialize(dict) { if let item = RecentItemBridge().deserialize(dict) {
RecentsModel.shared.add(item) RecentsModel.shared.add(item)

View File

@@ -147,7 +147,7 @@ struct OpenVideosModel {
if prepending { if prepending {
videos.reverse() videos.reverse()
} }
videos.forEach { video in for video in videos {
player.enqueueVideo(video, play: false, prepending: prepending, loadDetails: false) player.enqueueVideo(video, play: false, prepending: prepending, loadDetails: false)
} }
} }

View File

@@ -625,6 +625,7 @@ final class MPVBackend: PlayerBackend {
} }
} }
#if !os(macOS)
@objc func handleAudioSessionInterruption(_ notification: Notification) { @objc func handleAudioSessionInterruption(_ notification: Notification) {
logger.info("Audio session interruption received.") logger.info("Audio session interruption received.")
@@ -651,4 +652,5 @@ final class MPVBackend: PlayerBackend {
deinit { deinit {
NotificationCenter.default.removeObserver(self, name: AVAudioSession.interruptionNotification, object: nil) NotificationCenter.default.removeObserver(self, name: AVAudioSession.interruptionNotification, object: nil)
} }
#endif
} }

View File

@@ -60,21 +60,21 @@ class Stream: Equatable, Hashable, Identifiable {
var bitrate: Int { var bitrate: Int {
switch self { switch self {
case .hd2160p60, .hd2160p50, .hd2160p48, .hd2160p30: case .hd2160p60, .hd2160p50, .hd2160p48, .hd2160p30:
return 56000000 // 56 Mbit/s return 56_000_000 // 56 Mbit/s
case .hd1440p60, .hd1440p50, .hd1440p48, .hd1440p30: case .hd1440p60, .hd1440p50, .hd1440p48, .hd1440p30:
return 24000000 // 24 Mbit/s return 24_000_000 // 24 Mbit/s
case .hd1080p60, .hd1080p50, .hd1080p48, .hd1080p30: case .hd1080p60, .hd1080p50, .hd1080p48, .hd1080p30:
return 12000000 // 12 Mbit/s return 12_000_000 // 12 Mbit/s
case .hd720p60, .hd720p50, .hd720p48, .hd720p30: case .hd720p60, .hd720p50, .hd720p48, .hd720p30:
return 9500000 // 9.5 Mbit/s return 9_500_000 // 9.5 Mbit/s
case .sd480p30: case .sd480p30:
return 4000000 // 4 Mbit/s return 4_000_000 // 4 Mbit/s
case .sd360p30: case .sd360p30:
return 1500000 // 1.5 Mbit/s return 1_500_000 // 1.5 Mbit/s
case .sd240p30: case .sd240p30:
return 1000000 // 1 Mbit/s return 1_000_000 // 1 Mbit/s
case .sd144p30: case .sd144p30:
return 600000 // 0.6 Mbit/s return 600_000 // 0.6 Mbit/s
case .unknown: case .unknown:
return 0 return 0
} }

View File

@@ -114,7 +114,7 @@ struct URLBookmarkModel {
func refreshAll() { func refreshAll() {
logger.info("refreshing all bookmarks") logger.info("refreshing all bookmarks")
allURLs.forEach { url in for url in allURLs {
if loadBookmark(url) != nil { if loadBookmark(url) != nil {
logger.info("bookmark for \(url) exists") logger.info("bookmark for \(url) exists")
} else { } else {

View File

@@ -57,7 +57,7 @@ final class URLParserTests: XCTestCase {
] ]
func testUrlsParsing() throws { func testUrlsParsing() throws {
Self.urls.forEach { urlString in for urlString in Self.urls {
let url = URL(string: urlString)! let url = URL(string: urlString)!
let parser = URLParser(url: url) let parser = URLParser(url: url)
XCTAssertEqual(parser.destination, .fileURL) XCTAssertEqual(parser.destination, .fileURL)
@@ -66,7 +66,7 @@ final class URLParserTests: XCTestCase {
} }
func testVideosParsing() throws { func testVideosParsing() throws {
Self.videos.forEach { url, id in for (url, id) in Self.videos {
let parser = URLParser(url: URL(string: url)!) let parser = URLParser(url: URL(string: url)!)
XCTAssertEqual(parser.destination, .video) XCTAssertEqual(parser.destination, .video)
XCTAssertEqual(parser.videoID, id) XCTAssertEqual(parser.videoID, id)
@@ -74,7 +74,7 @@ final class URLParserTests: XCTestCase {
} }
func testChannelsByNameParsing() throws { func testChannelsByNameParsing() throws {
Self.channelsByName.forEach { url, name in for (url, name) in Self.channelsByName {
let parser = URLParser(url: URL(string: url)!) let parser = URLParser(url: URL(string: url)!)
XCTAssertEqual(parser.destination, .channel) XCTAssertEqual(parser.destination, .channel)
XCTAssertEqual(parser.channelName, name) XCTAssertEqual(parser.channelName, name)
@@ -83,7 +83,7 @@ final class URLParserTests: XCTestCase {
} }
func testChannelsByIdParsing() throws { func testChannelsByIdParsing() throws {
Self.channelsByID.forEach { url, id in for (url, id) in Self.channelsByID {
let parser = URLParser(url: URL(string: url)!) let parser = URLParser(url: URL(string: url)!)
XCTAssertEqual(parser.destination, .channel) XCTAssertEqual(parser.destination, .channel)
XCTAssertEqual(parser.channelID, id) XCTAssertEqual(parser.channelID, id)
@@ -92,7 +92,7 @@ final class URLParserTests: XCTestCase {
} }
func testUsersParsing() throws { func testUsersParsing() throws {
Self.users.forEach { url, user in for (url, user) in Self.users {
let parser = URLParser(url: URL(string: url)!) let parser = URLParser(url: URL(string: url)!)
XCTAssertEqual(parser.destination, .channel) XCTAssertEqual(parser.destination, .channel)
XCTAssertNil(parser.channelID) XCTAssertNil(parser.channelID)
@@ -102,7 +102,7 @@ final class URLParserTests: XCTestCase {
} }
func testPlaylistsParsing() throws { func testPlaylistsParsing() throws {
Self.playlists.forEach { url, id in for (url, id) in Self.playlists {
let parser = URLParser(url: URL(string: url)!) let parser = URLParser(url: URL(string: url)!)
XCTAssertEqual(parser.destination, .playlist) XCTAssertEqual(parser.destination, .playlist)
XCTAssertEqual(parser.playlistID, id) XCTAssertEqual(parser.playlistID, id)
@@ -110,7 +110,7 @@ final class URLParserTests: XCTestCase {
} }
func testSearchesParsing() throws { func testSearchesParsing() throws {
Self.searches.forEach { url, query in for (url, query) in Self.searches {
let parser = URLParser(url: URL(string: url)!) let parser = URLParser(url: URL(string: url)!)
XCTAssertEqual(parser.destination, .search) XCTAssertEqual(parser.destination, .search)
XCTAssertEqual(parser.searchQuery, query) XCTAssertEqual(parser.searchQuery, query)
@@ -127,7 +127,7 @@ final class URLParserTests: XCTestCase {
"watch?v=IUTGFQpKaPU&t=30s": 30 "watch?v=IUTGFQpKaPU&t=30s": 30
] ]
samples.forEach { url, time in for (url, time) in samples {
XCTAssertEqual( XCTAssertEqual(
URLParser(url: URL(string: url)!).time, URLParser(url: URL(string: url)!).time,
time time

View File

@@ -53,7 +53,6 @@ struct ChannelPlaylistCell: View {
Text("\(playlist.videosCount ?? playlist.videos.count) videos") Text("\(playlist.videosCount ?? playlist.videos.count) videos")
.foregroundColor(.secondary) .foregroundColor(.secondary)
.frame(height: 20) .frame(height: 20)
} }
} }

View File

@@ -3,7 +3,6 @@ import Foundation
import SwiftUI import SwiftUI
enum Constants { enum Constants {
static let yatteeProtocol = "yattee://"
static let overlayAnimation = Animation.linear(duration: 0.2) static let overlayAnimation = Animation.linear(duration: 0.2)
static var isAppleTV: Bool { static var isAppleTV: Bool {
@@ -98,6 +97,20 @@ enum Constants {
#endif #endif
} }
static var defaultNavigationStyle: NavigationStyle {
#if os(macOS)
return .sidebar
#elseif os(iOS)
if isIPad {
return .sidebar
} else {
return .tab
}
#else
return .tab
#endif
}
static func seekIcon(_ type: String, _ interval: TimeInterval) -> String { static func seekIcon(_ type: String, _ interval: TimeInterval) -> String {
let interval = Int(interval) let interval = Int(interval)
let allVersions = [10, 15, 30, 45, 60, 75, 90] let allVersions = [10, 15, 30, 45, 60, 75, 90]

View File

@@ -81,7 +81,6 @@ struct FavoriteItemView: View {
} }
} }
.contentShape(Rectangle()) .contentShape(Rectangle())
.onAppear { .onAppear {
if item.section == .history { if item.section == .history {
reloadVisibleWatches() reloadVisibleWatches()
@@ -165,7 +164,7 @@ struct FavoriteItemView: View {
.prefix(favoritesModel.limit(item)) .prefix(favoritesModel.limit(item))
) )
let last = watches.last let last = watches.last
watches.forEach { watch in for watch in watches {
player.loadHistoryVideoDetails(watch) { player.loadHistoryVideoDetails(watch) {
guard let video = player.historyVideo(watch.videoID), itemVisible(.init(video: video)) else { return } guard let video = player.historyVideo(watch.videoID), itemVisible(.init(video: video)) else { return }
visibleWatches.append(watch) visibleWatches.append(watch)

View File

@@ -4,8 +4,6 @@ import Siesta
struct OpenURLHandler { struct OpenURLHandler {
static var firstHandle = true static var firstHandle = true
static let yatteeProtocol = "yattee://"
var accounts: AccountsModel { .shared } var accounts: AccountsModel { .shared }
var navigation: NavigationModel { .shared } var navigation: NavigationModel { .shared }
var recents: RecentsModel { .shared } var recents: RecentsModel { .shared }

View File

@@ -142,7 +142,6 @@ struct PlaybackSettings: View {
} }
.animation(nil, value: player.activeBackend) .animation(nil, value: player.activeBackend)
.frame(alignment: .topLeading) .frame(alignment: .topLeading)
.ignoresSafeArea(.all, edges: .bottom) .ignoresSafeArea(.all, edges: .bottom)
.backport .backport
.playbackSettingsPresentationDetents() .playbackSettingsPresentationDetents()
@@ -235,7 +234,6 @@ struct PlaybackSettings: View {
#if os(iOS) #if os(iOS)
.padding(12) .padding(12)
.frame(width: 40, height: 40) .frame(width: 40, height: 40)
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(Color.accentColor, lineWidth: 1)) .background(RoundedRectangle(cornerRadius: 4).strokeBorder(Color.accentColor, lineWidth: 1))
.contentShape(Rectangle()) .contentShape(Rectangle())
#endif #endif
@@ -261,7 +259,6 @@ struct PlaybackSettings: View {
#if os(iOS) #if os(iOS)
.padding(12) .padding(12)
.frame(width: 40, height: 40) .frame(width: 40, height: 40)
.background(RoundedRectangle(cornerRadius: 4).strokeBorder(Color.accentColor, lineWidth: 1)) .background(RoundedRectangle(cornerRadius: 4).strokeBorder(Color.accentColor, lineWidth: 1))
.contentShape(Rectangle()) .contentShape(Rectangle())
#endif #endif

View File

@@ -57,7 +57,6 @@ import SwiftUI
} }
.indicator(.activity) .indicator(.activity)
.frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight) .frame(width: Self.thumbnailWidth, height: Self.thumbnailHeight)
.mask(RoundedRectangle(cornerRadius: 6)) .mask(RoundedRectangle(cornerRadius: 6))
} }

View File

@@ -80,7 +80,7 @@ struct ChaptersView: View {
} }
#if !os(tvOS) #if !os(tvOS)
private func chapterViews(for chaptersToShow: ArraySlice<Chapter>, opacity: Double = 1.0, clickable: Bool = true, scrollViewProxy: ScrollViewProxy? = nil) -> some View { private func chapterViews(for chaptersToShow: ArraySlice<Chapter>, opacity: Double = 1.0, clickable: Bool = true, scrollViewProxy _: ScrollViewProxy? = nil) -> some View {
ForEach(Array(chaptersToShow.indices), id: \.self) { index in ForEach(Array(chaptersToShow.indices), id: \.self) { index in
let chapter = chaptersToShow[index] let chapter = chaptersToShow[index]
ChapterView(chapter: chapter, chapterIndex: index, showThumbnail: showThumbnails) ChapterView(chapter: chapter, chapterIndex: index, showThumbnail: showThumbnails)

View File

@@ -88,7 +88,7 @@ struct VideoDescription: View {
var formattedString: AttributedString { var formattedString: AttributedString {
var attrString = AttributedString(description) var attrString = AttributedString(description)
let words = description.unicodeScalars.split(whereSeparator: separators.contains).map(String.init) let words = description.unicodeScalars.split(whereSeparator: separators.contains).map(String.init)
words.forEach { word in for word in words {
if word.hasPrefix("https://") || word.hasPrefix("http://"), let url = URL(string: String(word)) { if word.hasPrefix("https://") || word.hasPrefix("http://"), let url = URL(string: String(word)) {
if let range = attrString.range(of: word) { if let range = attrString.range(of: word) {
attrString[range].link = url attrString[range].link = url

View File

@@ -263,7 +263,6 @@ struct VideoPlayerView: View {
#else #else
GeometryReader { geometry in GeometryReader { geometry in
player.playerBackendView player.playerBackendView
.modifier( .modifier(
VideoPlayerSizeModifier( VideoPlayerSizeModifier(
geometry: geometry, geometry: geometry,

View File

@@ -198,7 +198,7 @@ struct PlaylistFormView: View {
} }
} }
#else #else
Button(self.visibility.name) { Button(visibility.name) {
self.visibility = self.visibility.next() self.visibility = self.visibility.next()
} }
.contextMenu { .contextMenu {

View File

@@ -196,7 +196,7 @@ struct HistorySettings: View {
private func counterButtons(for _value: Binding<Int>) -> some View { private func counterButtons(for _value: Binding<Int>) -> some View {
var value: Binding<Int> { var value: Binding<Int> {
Binding( Binding(
get: { return _value.wrappedValue }, get: { _value.wrappedValue },
set: { set: {
if $0 < 1 { if $0 < 1 {
_value.wrappedValue = 1 _value.wrappedValue = 1

View File

@@ -261,7 +261,6 @@ struct PlayerControlsSettings: View {
TextField("Duration", text: value) TextField("Duration", text: value)
.frame(width: textFieldWidth, alignment: .trailing) .frame(width: textFieldWidth, alignment: .trailing)
.multilineTextAlignment(.center) .multilineTextAlignment(.center)
.labelsHidden() .labelsHidden()
#if !os(macOS) #if !os(macOS)
.keyboardType(.numberPad) .keyboardType(.numberPad)

View File

@@ -48,7 +48,6 @@ struct QualityProfileForm: View {
.onAppear(perform: initializeForm) .onAppear(perform: initializeForm)
.onChange(of: backend, perform: { _ in backendChanged(self.backend); updateActiveFormats(); validate() }) .onChange(of: backend, perform: { _ in backendChanged(self.backend); updateActiveFormats(); validate() })
.onChange(of: name, perform: { _ in validate() }) .onChange(of: name, perform: { _ in validate() })
.onChange(of: resolution, perform: { _ in validate() }) .onChange(of: resolution, perform: { _ in validate() })
.onChange(of: orderedFormats, perform: { _ in validate() }) .onChange(of: orderedFormats, perform: { _ in validate() })

View File

@@ -1,6 +1,7 @@
import Defaults import Defaults
import Foundation import Foundation
import SwiftUI import SwiftUI
struct SettingsView: View { struct SettingsView: View {
static let matrixURL = URL(string: "https://tinyurl.com/matrix-yattee")! static let matrixURL = URL(string: "https://tinyurl.com/matrix-yattee")!
static let discordURL = URL(string: "https://yattee.stream/discord")! static let discordURL = URL(string: "https://yattee.stream/discord")!

View File

@@ -1,6 +1,8 @@
import Defaults import Defaults
import SwiftUI import SwiftUI
import UIKit #if canImport(UIKit)
import UIKit
#endif
struct SponsorBlockSettings: View { struct SponsorBlockSettings: View {
@ObservedObject private var settings = SettingsModel.shared @ObservedObject private var settings = SettingsModel.shared
@@ -55,6 +57,8 @@ struct SponsorBlockSettings: View {
Section(header: SettingsHeader(text: "Categories to Skip".localized())) { Section(header: SettingsHeader(text: "Categories to Skip".localized())) {
categoryRows categoryRows
} }
#if os(iOS)
colorSection colorSection
Button { Button {
@@ -73,6 +77,7 @@ struct SponsorBlockSettings: View {
Text("Restore Default Colors …") Text("Restore Default Colors …")
.foregroundColor(.red) .foregroundColor(.red)
} }
#endif
Section(footer: categoriesDetails) { Section(footer: categoriesDetails) {
EmptyView() EmptyView()
@@ -80,6 +85,7 @@ struct SponsorBlockSettings: View {
} }
} }
#if os(iOS)
private var colorSection: some View { private var colorSection: some View {
Section(header: SettingsHeader(text: "Colors for Categories")) { Section(header: SettingsHeader(text: "Colors for Categories")) {
ForEach(SponsorBlockAPI.categories, id: \.self) { category in ForEach(SponsorBlockAPI.categories, id: \.self) { category in
@@ -95,6 +101,7 @@ struct SponsorBlockSettings: View {
} }
} }
} }
#endif
private var categoryRows: some View { private var categoryRows: some View {
ForEach(SponsorBlockAPI.categories, id: \.self) { category in ForEach(SponsorBlockAPI.categories, id: \.self) { category in
@@ -145,6 +152,7 @@ struct SponsorBlockSettings: View {
return Color("AppRedColor") // Fallback color if no match found return Color("AppRedColor") // Fallback color if no match found
} }
#if canImport(UIKit)
private func setColor(_ color: Color, for category: String) { private func setColor(_ color: Color, for category: String) {
let uiColor = UIColor(color) let uiColor = UIColor(color)
@@ -164,6 +172,7 @@ struct SponsorBlockSettings: View {
let rgbValue = (r << 16) | (g << 8) | b let rgbValue = (r << 16) | (g << 8) | b
sponsorBlockColors[category] = String(format: "#%06x", rgbValue) sponsorBlockColors[category] = String(format: "#%06x", rgbValue)
} }
#endif
private func resetColors() { private func resetColors() {
sponsorBlockColors = SponsorBlockColors.dictionary sponsorBlockColors = SponsorBlockColors.dictionary

3
Shared/Strings.swift Normal file
View File

@@ -0,0 +1,3 @@
enum Strings {
static let yatteeProtocol = "yattee://"
}

View File

@@ -176,7 +176,7 @@ struct URLParser {
private func removePrefixes(_ value: String, _ prefixes: [String]) -> String { private func removePrefixes(_ value: String, _ prefixes: [String]) -> String {
var value = value var value = value
prefixes.forEach { prefix in for prefix in prefixes {
if value.hasPrefix(prefix) { if value.hasPrefix(prefix) {
value.removeFirst(prefix.count) value.removeFirst(prefix.count)
} }

View File

@@ -77,7 +77,7 @@ struct ShareButton<LabelView: View>: View {
private var youtubeActions: some View { private var youtubeActions: some View {
Group { Group {
if let url = accounts.api.shareURL(contentItem, frontendURL: "https://www.youtube.com") { if let url = accounts.api.shareURL(contentItem, frontendURLString: "https://www.youtube.com") {
Button(labelForShareURL("YouTube")) { Button(labelForShareURL("YouTube")) {
shareAction(url) shareAction(url)
} }
@@ -87,7 +87,7 @@ struct ShareButton<LabelView: View>: View {
shareAction( shareAction(
accounts.api.shareURL( accounts.api.shareURL(
contentItem, contentItem,
frontendURL: "https://www.youtube.com", frontendURLString: "https://www.youtube.com",
time: player.backend.currentTime time: player.backend.currentTime
)! )!
) )

View File

@@ -26,7 +26,7 @@ extension UIView {
} }
private func viewsInHierarchy<ViewType: UIView>(views: inout [ViewType]) { private func viewsInHierarchy<ViewType: UIView>(views: inout [ViewType]) {
subviews.forEach { eachSubView in for eachSubView in subviews {
if let matchingView = eachSubView as? ViewType { if let matchingView = eachSubView as? ViewType {
views.append(matchingView) views.append(matchingView)
} }

View File

@@ -82,7 +82,6 @@
3709528A29283E14001ECA40 /* NoDocumentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3709528929283E14001ECA40 /* NoDocumentsView.swift */; }; 3709528A29283E14001ECA40 /* NoDocumentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3709528929283E14001ECA40 /* NoDocumentsView.swift */; };
37095E82291DC85400301883 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37095E81291DC85400301883 /* ShareViewController.swift */; }; 37095E82291DC85400301883 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37095E81291DC85400301883 /* ShareViewController.swift */; };
37095E89291DC85400301883 /* Open in Yattee.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 37095E7F291DC85400301883 /* Open in Yattee.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 37095E89291DC85400301883 /* Open in Yattee.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 37095E7F291DC85400301883 /* Open in Yattee.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
37095E8D291DD5DA00301883 /* URLBookmarkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37F5E8B5291BE9D0006C15F5 /* URLBookmarkModel.swift */; };
370B79C9286279810045DB77 /* NSObject+Swizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370B79C8286279810045DB77 /* NSObject+Swizzle.swift */; }; 370B79C9286279810045DB77 /* NSObject+Swizzle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370B79C8286279810045DB77 /* NSObject+Swizzle.swift */; };
370B79CC286279BA0045DB77 /* UIViewController+HideHomeIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370B79CB286279BA0045DB77 /* UIViewController+HideHomeIndicator.swift */; }; 370B79CC286279BA0045DB77 /* UIViewController+HideHomeIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370B79CB286279BA0045DB77 /* UIViewController+HideHomeIndicator.swift */; };
370E990A2A1EA8C500D144E9 /* WatchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370E99092A1EA8C500D144E9 /* WatchModel.swift */; }; 370E990A2A1EA8C500D144E9 /* WatchModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370E99092A1EA8C500D144E9 /* WatchModel.swift */; };
@@ -378,6 +377,12 @@
3761ABFD26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */; }; 3761ABFD26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */; };
3761ABFE26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */; }; 3761ABFE26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */; };
3761ABFF26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */; }; 3761ABFF26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */; };
3762C46D2BF66CDD008E50B8 /* EnvironmentValues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */; };
3762C4772BF66F04008E50B8 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3762C4762BF66F04008E50B8 /* Strings.swift */; };
3762C4782BF66F04008E50B8 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3762C4762BF66F04008E50B8 /* Strings.swift */; };
3762C4792BF66F04008E50B8 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3762C4762BF66F04008E50B8 /* Strings.swift */; };
3762C47A2BF66F04008E50B8 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3762C4762BF66F04008E50B8 /* Strings.swift */; };
3762C47D2BF66FF7008E50B8 /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = 3762C47C2BF66FF7008E50B8 /* Defaults */; };
3763495126DFF59D00B9A393 /* AppSidebarRecents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3763495026DFF59D00B9A393 /* AppSidebarRecents.swift */; }; 3763495126DFF59D00B9A393 /* AppSidebarRecents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3763495026DFF59D00B9A393 /* AppSidebarRecents.swift */; };
3763495226DFF59D00B9A393 /* AppSidebarRecents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3763495026DFF59D00B9A393 /* AppSidebarRecents.swift */; }; 3763495226DFF59D00B9A393 /* AppSidebarRecents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3763495026DFF59D00B9A393 /* AppSidebarRecents.swift */; };
37635FE4291EA6CF00C11E79 /* AccentButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37635FE3291EA6CF00C11E79 /* AccentButton.swift */; }; 37635FE4291EA6CF00C11E79 /* AccentButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37635FE3291EA6CF00C11E79 /* AccentButton.swift */; };
@@ -1059,8 +1064,6 @@
37FD77002932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD76FF2932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift */; }; 37FD77002932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD76FF2932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift */; };
37FD77012932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD76FF2932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift */; }; 37FD77012932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD76FF2932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift */; };
37FD77022932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD76FF2932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift */; }; 37FD77022932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD76FF2932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift */; };
37FD77032932C5EC00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD76FF2932C4DA00D91A5F /* URL+ByReplacingYatteeProtocol.swift */; };
37FD77042932C5FC00D91A5F /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754B01428B7F84D009717C8 /* Constants.swift */; };
37FEF11327EFD8580033912F /* PlaceholderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FEF11227EFD8580033912F /* PlaceholderCell.swift */; }; 37FEF11327EFD8580033912F /* PlaceholderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FEF11227EFD8580033912F /* PlaceholderCell.swift */; };
37FEF11427EFD8580033912F /* PlaceholderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FEF11227EFD8580033912F /* PlaceholderCell.swift */; }; 37FEF11427EFD8580033912F /* PlaceholderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FEF11227EFD8580033912F /* PlaceholderCell.swift */; };
37FEF11527EFD8580033912F /* PlaceholderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FEF11227EFD8580033912F /* PlaceholderCell.swift */; }; 37FEF11527EFD8580033912F /* PlaceholderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FEF11227EFD8580033912F /* PlaceholderCell.swift */; };
@@ -1265,6 +1268,7 @@
375EC971289F2ABF00751258 /* MultiselectRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiselectRow.swift; sourceTree = "<group>"; }; 375EC971289F2ABF00751258 /* MultiselectRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiselectRow.swift; sourceTree = "<group>"; };
375F740F289DC35A00747050 /* PlayerBackendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerBackendView.swift; sourceTree = "<group>"; }; 375F740F289DC35A00747050 /* PlayerBackendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerBackendView.swift; sourceTree = "<group>"; };
3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnvironmentValues.swift; sourceTree = "<group>"; }; 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnvironmentValues.swift; sourceTree = "<group>"; };
3762C4762BF66F04008E50B8 /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = "<group>"; };
3763495026DFF59D00B9A393 /* AppSidebarRecents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSidebarRecents.swift; sourceTree = "<group>"; }; 3763495026DFF59D00B9A393 /* AppSidebarRecents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSidebarRecents.swift; sourceTree = "<group>"; };
37635FE3291EA6CF00C11E79 /* AccentButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccentButton.swift; sourceTree = "<group>"; }; 37635FE3291EA6CF00C11E79 /* AccentButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccentButton.swift; sourceTree = "<group>"; };
3763C988290C7A50004D3B5F /* OpenVideosView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVideosView.swift; sourceTree = "<group>"; }; 3763C988290C7A50004D3B5F /* OpenVideosView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVideosView.swift; sourceTree = "<group>"; };
@@ -1542,6 +1546,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
3762C47D2BF66FF7008E50B8 /* Defaults in Frameworks */,
378CC2E32B669489006309F4 /* Logging in Frameworks */, 378CC2E32B669489006309F4 /* Logging in Frameworks */,
377F9F85294417FA0043F856 /* SwiftyJSON in Frameworks */, 377F9F85294417FA0043F856 /* SwiftyJSON in Frameworks */,
377F9F83294417B40043F856 /* Cache in Frameworks */, 377F9F83294417B40043F856 /* Cache in Frameworks */,
@@ -2276,6 +2281,7 @@
371AAE2726CEBF4700901972 /* Videos */, 371AAE2726CEBF4700901972 /* Videos */,
371AAE2826CEC7D900901972 /* Views */, 371AAE2826CEC7D900901972 /* Views */,
3754B01428B7F84D009717C8 /* Constants.swift */, 3754B01428B7F84D009717C8 /* Constants.swift */,
3762C4762BF66F04008E50B8 /* Strings.swift */,
375168D52700FAFF008F96A6 /* Debounce.swift */, 375168D52700FAFF008F96A6 /* Debounce.swift */,
372915E52687E3B900F5A35B /* Defaults.swift */, 372915E52687E3B900F5A35B /* Defaults.swift */,
37D2E0D328B67EFC00F64D52 /* Delay.swift */, 37D2E0D328B67EFC00F64D52 /* Delay.swift */,
@@ -2501,6 +2507,7 @@
377F9F82294417B40043F856 /* Cache */, 377F9F82294417B40043F856 /* Cache */,
377F9F84294417FA0043F856 /* SwiftyJSON */, 377F9F84294417FA0043F856 /* SwiftyJSON */,
378CC2E22B669489006309F4 /* Logging */, 378CC2E22B669489006309F4 /* Logging */,
3762C47C2BF66FF7008E50B8 /* Defaults */,
); );
productName = "Open in Yattee"; productName = "Open in Yattee";
productReference = 37095E7F291DC85400301883 /* Open in Yattee.appex */; productReference = 37095E7F291DC85400301883 /* Open in Yattee.appex */;
@@ -3000,10 +3007,9 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
3738535729451E0C00D2D0CB /* BookmarksCacheModel.swift in Sources */, 3738535729451E0C00D2D0CB /* BookmarksCacheModel.swift in Sources */,
37FD77042932C5FC00D91A5F /* Constants.swift in Sources */, 3762C46D2BF66CDD008E50B8 /* EnvironmentValues.swift in Sources */,
37095E82291DC85400301883 /* ShareViewController.swift in Sources */, 37095E82291DC85400301883 /* ShareViewController.swift in Sources */,
37FD77032932C5EC00D91A5F /* URL+ByReplacingYatteeProtocol.swift in Sources */, 3762C47A2BF66F04008E50B8 /* Strings.swift in Sources */,
37095E8D291DD5DA00301883 /* URLBookmarkModel.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -3330,6 +3336,7 @@
37D4B0E42671614900C925CA /* YatteeApp.swift in Sources */, 37D4B0E42671614900C925CA /* YatteeApp.swift in Sources */,
37C3A241272359900087A57A /* Double+Format.swift in Sources */, 37C3A241272359900087A57A /* Double+Format.swift in Sources */,
3784CDE227772EE40055BBF2 /* Watch.swift in Sources */, 3784CDE227772EE40055BBF2 /* Watch.swift in Sources */,
3762C4772BF66F04008E50B8 /* Strings.swift in Sources */,
37FB285E272225E800A57617 /* ContentItemView.swift in Sources */, 37FB285E272225E800A57617 /* ContentItemView.swift in Sources */,
3797758B2689345500DD52A8 /* Store.swift in Sources */, 3797758B2689345500DD52A8 /* Store.swift in Sources */,
3773B80D2ADC076800B5FEF3 /* FramePreferenceKey.swift in Sources */, 3773B80D2ADC076800B5FEF3 /* FramePreferenceKey.swift in Sources */,
@@ -3401,6 +3408,7 @@
37192D5828B179D60012EEDD /* ChaptersView.swift in Sources */, 37192D5828B179D60012EEDD /* ChaptersView.swift in Sources */,
37E75CCC2B6AEB01003A6237 /* RecentlyOpenedExporter.swift in Sources */, 37E75CCC2B6AEB01003A6237 /* RecentlyOpenedExporter.swift in Sources */,
3784CDE327772EE40055BBF2 /* Watch.swift in Sources */, 3784CDE327772EE40055BBF2 /* Watch.swift in Sources */,
3762C4782BF66F04008E50B8 /* Strings.swift in Sources */,
371AC0B7294D1D6E0085989E /* PlayingIndicatorView.swift in Sources */, 371AC0B7294D1D6E0085989E /* PlayingIndicatorView.swift in Sources */,
3773B8182ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift in Sources */, 3773B8182ADC081300B5FEF3 /* VisualEffectBlur-macOS.swift in Sources */,
37E80F3D287B107F00561799 /* VideoDetailsOverlay.swift in Sources */, 37E80F3D287B107F00561799 /* VideoDetailsOverlay.swift in Sources */,
@@ -3826,6 +3834,7 @@
37769250294630110055EC18 /* ChannelAvatarView.swift in Sources */, 37769250294630110055EC18 /* ChannelAvatarView.swift in Sources */,
37030FFD27B0398000ECDDAA /* MPVClient.swift in Sources */, 37030FFD27B0398000ECDDAA /* MPVClient.swift in Sources */,
378E9C4229455A5800B2D696 /* ChannelsView.swift in Sources */, 378E9C4229455A5800B2D696 /* ChannelsView.swift in Sources */,
3762C4792BF66F04008E50B8 /* Strings.swift in Sources */,
37192D5928B179D60012EEDD /* ChaptersView.swift in Sources */, 37192D5928B179D60012EEDD /* ChaptersView.swift in Sources */,
37B767DD2677C3CA0098BAA8 /* PlayerModel.swift in Sources */, 37B767DD2677C3CA0098BAA8 /* PlayerModel.swift in Sources */,
373CFAF12697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */, 373CFAF12697A78B003CB2C6 /* AddToPlaylistView.swift in Sources */,
@@ -4062,7 +4071,7 @@
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements"; CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist"; INFOPLIST_FILE = "Open in Yattee/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee"; INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee";
@@ -4093,7 +4102,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "Open in Yattee/Info.plist"; INFOPLIST_FILE = "Open in Yattee/Info.plist";
@@ -4124,7 +4133,7 @@
buildSettings = { buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
@@ -4144,7 +4153,7 @@
buildSettings = { buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
@@ -4308,7 +4317,7 @@
CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements"; CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements";
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1", "DEBUG=1",
@@ -4361,7 +4370,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ; "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1"; GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1";
@@ -4413,7 +4422,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
ENABLE_APP_SANDBOX = YES; ENABLE_APP_SANDBOX = YES;
ENABLE_HARDENED_RUNTIME = YES; ENABLE_HARDENED_RUNTIME = YES;
@@ -4452,7 +4461,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
"DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ; "DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ;
ENABLE_APP_SANDBOX = YES; ENABLE_APP_SANDBOX = YES;
@@ -4487,7 +4496,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@@ -4511,7 +4520,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@@ -4537,7 +4546,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@@ -4562,7 +4571,7 @@
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
@@ -4588,7 +4597,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -4628,7 +4637,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual; CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
"DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ; "DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -4669,7 +4678,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@@ -4693,7 +4702,7 @@
buildSettings = { buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 181; CURRENT_PROJECT_VERSION = 182;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@@ -5003,7 +5012,7 @@
isa = XCRemoteSwiftPackageReference; isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/cxfksword/MPVKit.git"; repositoryURL = "https://github.com/cxfksword/MPVKit.git";
requirement = { requirement = {
kind = upToNextMinorVersion; kind = upToNextMajorVersion;
minimumVersion = 0.38.0; minimumVersion = 0.38.0;
}; };
}; };
@@ -5110,6 +5119,11 @@
package = 375B8AAF28B57F4200397B31 /* XCRemoteSwiftPackageReference "KeychainAccess" */; package = 375B8AAF28B57F4200397B31 /* XCRemoteSwiftPackageReference "KeychainAccess" */;
productName = KeychainAccess; productName = KeychainAccess;
}; };
3762C47C2BF66FF7008E50B8 /* Defaults */ = {
isa = XCSwiftPackageProductDependency;
package = 372915E22687E33E00F5A35B /* XCRemoteSwiftPackageReference "Defaults" */;
productName = Defaults;
};
3765917B27237D21009F956E /* PINCache */ = { 3765917B27237D21009F956E /* PINCache */ = {
isa = XCSwiftPackageProductDependency; isa = XCSwiftPackageProductDependency;
package = 3765917827237D07009F956E /* XCRemoteSwiftPackageReference "PINCache" */; package = 3765917827237D07009F956E /* XCRemoteSwiftPackageReference "PINCache" */;

View File

@@ -70,7 +70,7 @@
"location" : "https://github.com/pinterest/PINCache", "location" : "https://github.com/pinterest/PINCache",
"state" : { "state" : {
"branch" : "master", "branch" : "master",
"revision" : "f856226e8bee58d75cb6be1707ae0cb2f5801150" "revision" : "2fb85948463292c2e824148cf17dc62a4c217a94"
} }
}, },
{ {
@@ -78,8 +78,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/pinterest/PINOperation.git", "location" : "https://github.com/pinterest/PINOperation.git",
"state" : { "state" : {
"revision" : "40504c156a68b20f98f7ddc73a115cbb7893be25", "revision" : "a74f978733bdaf982758bfa23d70a189f4b4c1b6",
"version" : "1.2.2" "version" : "1.2.3"
} }
}, },
{ {
@@ -105,8 +105,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/SDWebImage/SDWebImage", "location" : "https://github.com/SDWebImage/SDWebImage",
"state" : { "state" : {
"revision" : "f6afa0132961d593f07970d84e2d8b588c29ea04", "revision" : "5642d1ffe3dbe628592443bd14154e31929727b4",
"version" : "5.19.1" "version" : "5.19.2"
} }
}, },
{ {
@@ -182,5 +182,5 @@
} }
} }
], ],
"version" : 3 "version" : 2
} }

View File

@@ -20,9 +20,9 @@ final class AppDelegate: UIResponder, UIApplicationDelegate {
return true return true
} }
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { func application(_: UIApplication, open url: URL, options _: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if url.scheme == "yattee" { if url.scheme == "yattee" {
OpenURLHandler.handle(url) OpenURLHandler(navigationStyle: Constants.defaultNavigationStyle).handle(url)
return true return true
} }
return false return false

View File

@@ -153,7 +153,6 @@ struct InstancesSettings: View {
} }
} }
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.onAppear { .onAppear {
selectedInstanceID = instances.first?.id selectedInstanceID = instances.first?.id
frontendURL = selectedInstanceFrontendURL frontendURL = selectedInstanceFrontendURL

View File

@@ -31,7 +31,7 @@ struct VerticalScrollingFixWrapper<Content>: View where Content: View {
} }
var body: some View { var body: some View {
VerticalScrollingFixViewRepresentable(content: self.content()) VerticalScrollingFixViewRepresentable(content: content())
} }
} }