diff --git a/Model/Player/Backends/MPVBackend.swift b/Model/Player/Backends/MPVBackend.swift index 73bf76ce..e85850ac 100644 --- a/Model/Player/Backends/MPVBackend.swift +++ b/Model/Player/Backends/MPVBackend.swift @@ -129,7 +129,7 @@ final class MPVBackend: PlayerBackend { ) { self.model = model self.controls = controls - self.playerTime = playerTime ?? PlayerTimeModel.shared + self.playerTime = playerTime ?? PlayerTimeModel.shared self.networkState = networkState clientTimer = .init(interval: .seconds(Self.timeUpdateInterval), mode: .infinite) { [weak self] _ in diff --git a/Model/Player/Backends/MPVClient.swift b/Model/Player/Backends/MPVClient.swift index da260a47..9bca1818 100644 --- a/Model/Player/Backends/MPVClient.swift +++ b/Model/Player/Backends/MPVClient.swift @@ -274,7 +274,7 @@ final class MPVClient: ObservableObject { let height = [self.backend.model.playerSize.height, self.backend.model.playerSize.width / aspectRatio].min()! var insets = 0.0 #if os(iOS) - insets = OrientationTracker.shared.currentInterfaceOrientation.isPortrait ? SafeArea.insets.bottom : 0 + insets = OrientationTracker.shared.currentInterfaceOrientation.isPortrait ? SafeArea.insets.bottom : 0 #endif let offsetY = self.backend.model.playingFullScreen ? ((self.backend.model.playerSize.height / 2.0) - ((height + insets) / 2)) : 0 self.glView?.frame = CGRect(x: 0, y: offsetY, width: roundedWidth, height: height) diff --git a/Shared/Player/ChapterView.swift b/Shared/Player/ChapterView.swift index cb7b5921..b6baca04 100644 --- a/Shared/Player/ChapterView.swift +++ b/Shared/Player/ChapterView.swift @@ -45,13 +45,13 @@ struct ChapterView: View { ProgressView() } .indicator(.activity) -#if os(tvOS) + #if os(tvOS) .frame(width: thumbnailWidth, height: 140) .mask(RoundedRectangle(cornerRadius: 12)) -#else + #else .frame(width: thumbnailWidth, height: 60) .mask(RoundedRectangle(cornerRadius: 6)) -#endif + #endif } } diff --git a/Shared/Player/Controls/OSD/Seek.swift b/Shared/Player/Controls/OSD/Seek.swift index 875f440c..cbd16f7d 100644 --- a/Shared/Player/Controls/OSD/Seek.swift +++ b/Shared/Player/Controls/OSD/Seek.swift @@ -64,22 +64,18 @@ struct Seek: View { } } } - #if os(tvOS) - .frame(minWidth: 250, minHeight: 100) - .padding(30) - #endif .frame(maxWidth: playerControlsLayout.seekOSDWidth) - .padding(2) - .modifier(ControlBackgroundModifier()) - .clipShape(RoundedRectangle(cornerRadius: 3)) - .foregroundColor(.primary) + #if os(tvOS) + .padding(30) + #else + .padding(2) + .modifier(ControlBackgroundModifier()) + .clipShape(RoundedRectangle(cornerRadius: 3)) + #endif + + .foregroundColor(.primary) } - #if os(tvOS) - .fixedSize() - .buttonStyle(.card) - #else .buttonStyle(.plain) - #endif .opacity(visible || YatteeApp.isForPreviews ? 1 : 0) } diff --git a/Shared/Player/Controls/PlayerControls.swift b/Shared/Player/Controls/PlayerControls.swift index 16132343..f48f6e10 100644 --- a/Shared/Player/Controls/PlayerControls.swift +++ b/Shared/Player/Controls/PlayerControls.swift @@ -49,7 +49,6 @@ struct PlayerControls: View { .transition(.opacity) .frame(maxWidth: .infinity, alignment: .topLeading) #if os(tvOS) - .offset(x: 10, y: 10) .focused($focusedField, equals: .seekOSD) .onChange(of: player.seek.lastSeekTime) { _ in if !model.presentingControls { @@ -161,7 +160,6 @@ struct PlayerControls: View { #endif } }.opacity(model.presentingControls && !model.presentingOverlays ? 1 : 0) - } } .frame(maxWidth: .infinity) @@ -313,7 +311,7 @@ struct PlayerControls: View { } private var settingsButton: some View { - button("settings", systemImage: "gearshape", active: model.presentingControlsOverlay) { + button("settings", systemImage: "gearshape") { withAnimation(Self.animation) { model.presentingControlsOverlay.toggle() } diff --git a/Shared/Player/Controls/TVControls.swift b/Shared/Player/Controls/TVControls.swift index da122fa8..d648ef6f 100644 --- a/Shared/Player/Controls/TVControls.swift +++ b/Shared/Player/Controls/TVControls.swift @@ -32,8 +32,11 @@ struct TVControls: UIViewRepresentable { let controls = UIHostingController(rootView: PlayerControls(player: player, thumbnails: thumbnails)) controls.view.frame = .init( - origin: .zero, - size: .init(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height) + origin: .init(x: SafeArea.insets.left, y: SafeArea.insets.top), + size: .init( + width: UIScreen.main.bounds.width - SafeArea.horizontalInsets, + height: UIScreen.main.bounds.height - SafeArea.verticalInset + ) ) controlsArea.addSubview(controls.view) diff --git a/Shared/Player/VideoPlayerView.swift b/Shared/Player/VideoPlayerView.swift index c40dbd35..99f30e04 100644 --- a/Shared/Player/VideoPlayerView.swift +++ b/Shared/Player/VideoPlayerView.swift @@ -461,6 +461,7 @@ struct VideoPlayerView: View { struct VideoPlayerView_Previews: PreviewProvider { static var previews: some View { VideoPlayerView() + .environmentObject(SeekModel()) .injectFixtureEnvironmentObjects() } } diff --git a/iOS/SafeArea.swift b/Shared/SafeArea.swift similarity index 72% rename from iOS/SafeArea.swift rename to Shared/SafeArea.swift index 2d4fb42f..2cbb8b5a 100644 --- a/iOS/SafeArea.swift +++ b/Shared/SafeArea.swift @@ -8,6 +8,14 @@ struct SafeArea { return keyWindow?.safeAreaInsets ?? .init() } + static var verticalInset: Double { + insets.top + insets.bottom + } + + static var horizontalInsets: Double { + insets.left + insets.right + } + static var scene: UIWindowScene? { UIApplication.shared.connectedScenes .filter { $0.activationState == .foregroundActive } diff --git a/Shared/Videos/VideoBanner.swift b/Shared/Videos/VideoBanner.swift index 478f0026..5d938f92 100644 --- a/Shared/Videos/VideoBanner.swift +++ b/Shared/Videos/VideoBanner.swift @@ -79,13 +79,13 @@ struct VideoBanner: View { } placeholder: { Rectangle().foregroundColor(Color("PlaceholderColor")) } -#if os(tvOS) - .frame(width: thumbnailWidth, height: 140) - .mask(RoundedRectangle(cornerRadius: 12)) -#else - .frame(width: thumbnailWidth, height: 60) - .mask(RoundedRectangle(cornerRadius: 6)) -#endif + #if os(tvOS) + .frame(width: thumbnailWidth, height: 140) + .mask(RoundedRectangle(cornerRadius: 12)) + #else + .frame(width: thumbnailWidth, height: 60) + .mask(RoundedRectangle(cornerRadius: 6)) + #endif } else { WebImage(url: url) .resizable() @@ -93,13 +93,13 @@ struct VideoBanner: View { ProgressView() } .indicator(.activity) -#if os(tvOS) + #if os(tvOS) .frame(width: thumbnailWidth, height: 140) .mask(RoundedRectangle(cornerRadius: 12)) -#else + #else .frame(width: thumbnailWidth, height: 60) .mask(RoundedRectangle(cornerRadius: 6)) -#endif + #endif } } diff --git a/Shared/Videos/VideoCell.swift b/Shared/Videos/VideoCell.swift index 8ff9d58d..8236f4ea 100644 --- a/Shared/Videos/VideoCell.swift +++ b/Shared/Videos/VideoCell.swift @@ -428,9 +428,9 @@ struct VideoCell: View { } placeholder: { Rectangle().foregroundColor(Color("PlaceholderColor")) } -#if os(tvOS) - .frame(minHeight: 320) -#endif + #if os(tvOS) + .frame(minHeight: 320) + #endif } else { WebImage(url: url) .resizable() @@ -443,9 +443,9 @@ struct VideoCell: View { thumbnails.insertUnloadable(url) } -#if os(tvOS) + #if os(tvOS) .frame(minHeight: 320) -#endif + #endif } } .mask(RoundedRectangle(cornerRadius: thumbnailRoundingCornerRadius)) diff --git a/Shared/Views/ChannelCell.swift b/Shared/Views/ChannelCell.swift index e55f4178..7243ccfb 100644 --- a/Shared/Views/ChannelCell.swift +++ b/Shared/Views/ChannelCell.swift @@ -38,7 +38,7 @@ struct ChannelCell: View { } .foregroundColor(.secondary) if #available(iOS 15, macOS 12, *) { - AsyncImage(url: channel.thumbnailURL) { image in + AsyncImage(url: channel.thumbnailURL) { image in image .resizable() } placeholder: { diff --git a/Shared/Views/ChannelPlaylistCell.swift b/Shared/Views/ChannelPlaylistCell.swift index 076b9bf6..a442f6a7 100644 --- a/Shared/Views/ChannelPlaylistCell.swift +++ b/Shared/Views/ChannelPlaylistCell.swift @@ -38,7 +38,7 @@ struct ChannelPlaylistCell: View { .foregroundColor(.secondary) if #available(iOS 15, macOS 12, *) { - AsyncImage(url: playlist.thumbnailURL) { image in + AsyncImage(url: playlist.thumbnailURL) { image in image .resizable() } placeholder: { diff --git a/Yattee.xcodeproj/project.pbxproj b/Yattee.xcodeproj/project.pbxproj index 537c6e32..d4116054 100644 --- a/Yattee.xcodeproj/project.pbxproj +++ b/Yattee.xcodeproj/project.pbxproj @@ -215,6 +215,7 @@ 37319F0627103F94004ECCD0 /* PlayerQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37319F0427103F94004ECCD0 /* PlayerQueue.swift */; }; 37319F0727103F94004ECCD0 /* PlayerQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37319F0427103F94004ECCD0 /* PlayerQueue.swift */; }; 3732BFD028B83763009F3F4D /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 3732BFCF28B83763009F3F4D /* KeychainAccess */; }; + 3732C9FD28C012E600E7DCAF /* SafeArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37ECED55289FE166002BC2C9 /* SafeArea.swift */; }; 3736A1FE286BB72300C9E5EE /* libavdevice.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3736A1EF286BB72300C9E5EE /* libavdevice.xcframework */; }; 3736A1FF286BB72300C9E5EE /* libavdevice.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3736A1EF286BB72300C9E5EE /* libavdevice.xcframework */; }; 3736A200286BB72300C9E5EE /* libuchardet.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3736A1F0286BB72300C9E5EE /* libuchardet.xcframework */; }; @@ -1901,7 +1902,6 @@ 37B4E802277D0A72004BF56A /* AppDelegate.swift */, 37B4E804277D0AB4004BF56A /* Orientation.swift */, 379B0252287A1CDF001015B5 /* OrientationTracker.swift */, - 37ECED55289FE166002BC2C9 /* SafeArea.swift */, 3784B23A272894DA00B09468 /* ShareSheet.swift */, 3749BF9227ADA142000480FF /* BridgingHeader.h */, 37992DC726CC50BC003D4C27 /* Info.plist */, @@ -2022,6 +2022,7 @@ 3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */, 3729037D2739E47400EA99F6 /* MenuCommands.swift */, 37B7958F2771DAE0001CF27B /* OpenURLHandler.swift */, + 37ECED55289FE166002BC2C9 /* SafeArea.swift */, 3700155E271B12DD0049C794 /* SiestaConfiguration.swift */, 37FFC43F272734C3009FFD26 /* Throttle.swift */, 378FFBC328660172009E3FBE /* URLParser.swift */, @@ -3327,6 +3328,7 @@ 376B2E0926F920D600B1D64D /* SignInRequiredView.swift in Sources */, 378FFBC628660172009E3FBE /* URLParser.swift in Sources */, 37141671267A8ACC006CA35D /* TrendingView.swift in Sources */, + 3732C9FD28C012E600E7DCAF /* SafeArea.swift in Sources */, 37C3A24727235DA70087A57A /* ChannelPlaylist.swift in Sources */, 3788AC2926F6840700F6BAA9 /* FavoriteItemView.swift in Sources */, 37319F0727103F94004ECCD0 /* PlayerQueue.swift in Sources */,