damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit 290152c8595a542596a6262d178dcd910a5944d7
parent c4ee52fdac589a2b3a90a75dbb171ba30d6b4fba
Author: Daniel D’Aquino <daniel@daquino.me>
Date:   Fri, 18 Oct 2024 12:46:11 -0700

Rename VideoController to DamusVideoCoordinator

This commit renames this class to better represent what it does.

This reduces some of the term overloading between this class and other video
controller classes/structs. (Such as AVPlayerController)

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>

Diffstat:
Mdamus.xcodeproj/project.pbxproj | 12++++++------
Mdamus/Components/ImageCarousel.swift | 6+++---
Mdamus/ContentView.swift | 2+-
Mdamus/Models/DamusState.swift | 8++++----
Mdamus/Views/Images/FullScreenCarouselView.swift | 16++++++++--------
Mdamus/Views/Images/ImageContainerView.swift | 8++++----
Adamus/Views/Video/DamusVideoCoordinator.swift | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdamus/Views/Video/DamusVideoPlayer.swift | 8++++----
Mdamus/Views/Video/DamusVideoPlayerViewModel.swift | 20++++++++++----------
Ddamus/Views/Video/VideoController.swift | 44--------------------------------------------
10 files changed, 93 insertions(+), 84 deletions(-)

diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj @@ -388,7 +388,7 @@ 5053ACA72A56DF3B00851AE3 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5053ACA62A56DF3B00851AE3 /* DeveloperSettingsView.swift */; }; 50A16FFB2AA6C06600DFEC1F /* DamusAVPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */; }; 50A16FFD2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift */; }; - 50A16FFF2AA76A0900DFEC1F /* VideoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFE2AA76A0900DFEC1F /* VideoController.swift */; }; + 50A16FFF2AA76A0900DFEC1F /* DamusVideoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFE2AA76A0900DFEC1F /* DamusVideoCoordinator.swift */; }; 50A50A8D29A09E1C00C01BE7 /* RequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A50A8C29A09E1C00C01BE7 /* RequestTests.swift */; }; 50A60D142A28BEEE00186190 /* RelayLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A60D132A28BEEE00186190 /* RelayLog.swift */; }; 50B5685329F97CB400A23243 /* CredentialHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B5685229F97CB400A23243 /* CredentialHandler.swift */; }; @@ -784,7 +784,7 @@ D73E5ED72C6A97F4007EB227 /* MutinyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7389B62B9E692E00781E0A /* MutinyButton.swift */; }; D73E5ED82C6A97F4007EB227 /* DamusVideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A2929DDF54400516EAC /* DamusVideoPlayer.swift */; }; D73E5ED92C6A97F4007EB227 /* DamusVideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift */; }; - D73E5EDA2C6A97F4007EB227 /* VideoController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFE2AA76A0900DFEC1F /* VideoController.swift */; }; + D73E5EDA2C6A97F4007EB227 /* DamusVideoCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFE2AA76A0900DFEC1F /* DamusVideoCoordinator.swift */; }; D73E5EDB2C6A97F4007EB227 /* DamusAVPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */; }; D73E5EDC2C6A97F4007EB227 /* ReactionsSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C15C7142A55DE7A00D0A0DB /* ReactionsSettingsView.swift */; }; D73E5EDD2C6A97F4007EB227 /* NotificationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A1C29DDCF9B00516EAC /* NotificationSettingsView.swift */; }; @@ -1832,7 +1832,7 @@ 5053ACA62A56DF3B00851AE3 /* DeveloperSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettingsView.swift; sourceTree = "<group>"; }; 50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusAVPlayerView.swift; sourceTree = "<group>"; }; 50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusVideoPlayerViewModel.swift; sourceTree = "<group>"; }; - 50A16FFE2AA76A0900DFEC1F /* VideoController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoController.swift; sourceTree = "<group>"; }; + 50A16FFE2AA76A0900DFEC1F /* DamusVideoCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusVideoCoordinator.swift; sourceTree = "<group>"; }; 50A50A8C29A09E1C00C01BE7 /* RequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestTests.swift; sourceTree = "<group>"; }; 50A60D132A28BEEE00186190 /* RelayLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayLog.swift; sourceTree = "<group>"; }; 50B5685229F97CB400A23243 /* CredentialHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CredentialHandler.swift; sourceTree = "<group>"; }; @@ -2294,7 +2294,7 @@ children = ( 4C1A9A2929DDF54400516EAC /* DamusVideoPlayer.swift */, 50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift */, - 50A16FFE2AA76A0900DFEC1F /* VideoController.swift */, + 50A16FFE2AA76A0900DFEC1F /* DamusVideoCoordinator.swift */, 50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */, ); path = Video; @@ -3899,7 +3899,7 @@ 5C14C29F2BBBA5C600079FD2 /* RelayNipList.swift in Sources */, D78DB85B2C20FE5000F0AB12 /* VectorMath.swift in Sources */, D7CB5D3E2B116DAD00AD4105 /* NotificationsManager.swift in Sources */, - 50A16FFF2AA76A0900DFEC1F /* VideoController.swift in Sources */, + 50A16FFF2AA76A0900DFEC1F /* DamusVideoCoordinator.swift in Sources */, F7908E97298B1FDF00AB113A /* NIPURLBuilder.swift in Sources */, 4C285C8228385570008A31F1 /* CarouselView.swift in Sources */, 3A3040F129A8FF97008A0F29 /* LocalizationUtil.swift in Sources */, @@ -4452,7 +4452,7 @@ D73E5ED72C6A97F4007EB227 /* MutinyButton.swift in Sources */, D73E5ED82C6A97F4007EB227 /* DamusVideoPlayer.swift in Sources */, D73E5ED92C6A97F4007EB227 /* DamusVideoPlayerViewModel.swift in Sources */, - D73E5EDA2C6A97F4007EB227 /* VideoController.swift in Sources */, + D73E5EDA2C6A97F4007EB227 /* DamusVideoCoordinator.swift in Sources */, D73E5EDB2C6A97F4007EB227 /* DamusAVPlayerView.swift in Sources */, D73E5EDC2C6A97F4007EB227 /* ReactionsSettingsView.swift in Sources */, D73E5EDD2C6A97F4007EB227 /* NotificationSettingsView.swift in Sources */, diff --git a/damus/Components/ImageCarousel.swift b/damus/Components/ImageCarousel.swift @@ -186,7 +186,7 @@ struct ImageCarousel<Content: View>: View { model.open_sheet = true } case .video(let url): - DamusVideoPlayer(url: url, video_size: $model.video_size, controller: state.video, style: .preview(on_tap: { model.open_sheet = true })) + DamusVideoPlayer(url: url, video_size: $model.video_size, coordinator: state.video, style: .preview(on_tap: { model.open_sheet = true })) .onChange(of: model.video_size) { size in guard let size else { return } @@ -257,14 +257,14 @@ struct ImageCarousel<Content: View>: View { .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) .fullScreenCover(isPresented: $model.open_sheet) { if let content { - FullScreenCarouselView<Content>(video_controller: state.video, urls: urls, settings: state.settings, selectedIndex: $model.selectedIndex) { + FullScreenCarouselView<Content>(video_coordinator: state.video, urls: urls, settings: state.settings, selectedIndex: $model.selectedIndex) { content({ // Dismiss closure model.open_sheet = false }) } } else { - FullScreenCarouselView<AnyView>(video_controller: state.video, urls: urls, settings: state.settings, selectedIndex: $model.selectedIndex) + FullScreenCarouselView<AnyView>(video_coordinator: state.video, urls: urls, settings: state.settings, selectedIndex: $model.selectedIndex) } } .frame(height: height) diff --git a/damus/ContentView.swift b/damus/ContentView.swift @@ -686,7 +686,7 @@ struct ContentView: View { wallet: WalletModel(settings: settings), nav: self.navigationCoordinator, music: MusicController(onChange: music_changed), - video: VideoController(), + video: DamusVideoCoordinator(), ndb: ndb, quote_reposts: .init(our_pubkey: pubkey), emoji_provider: DefaultEmojiProvider(showAllVariations: true) diff --git a/damus/Models/DamusState.swift b/damus/Models/DamusState.swift @@ -34,13 +34,13 @@ class DamusState: HeadlessDamusState { let wallet: WalletModel let nav: NavigationCoordinator let music: MusicController? - let video: VideoController + let video: DamusVideoCoordinator let ndb: Ndb var purple: DamusPurple var push_notification_client: PushNotificationClient let emoji_provider: EmojiProvider - init(pool: RelayPool, keypair: Keypair, likes: EventCounter, boosts: EventCounter, contacts: Contacts, mutelist_manager: MutelistManager, profiles: Profiles, dms: DirectMessagesModel, previews: PreviewCache, zaps: Zaps, lnurls: LNUrls, settings: UserSettingsStore, relay_filters: RelayFilters, relay_model_cache: RelayModelCache, drafts: Drafts, events: EventCache, bookmarks: BookmarksManager, postbox: PostBox, bootstrap_relays: [RelayURL], replies: ReplyCounter, wallet: WalletModel, nav: NavigationCoordinator, music: MusicController?, video: VideoController, ndb: Ndb, purple: DamusPurple? = nil, quote_reposts: EventCounter, emoji_provider: EmojiProvider) { + init(pool: RelayPool, keypair: Keypair, likes: EventCounter, boosts: EventCounter, contacts: Contacts, mutelist_manager: MutelistManager, profiles: Profiles, dms: DirectMessagesModel, previews: PreviewCache, zaps: Zaps, lnurls: LNUrls, settings: UserSettingsStore, relay_filters: RelayFilters, relay_model_cache: RelayModelCache, drafts: Drafts, events: EventCache, bookmarks: BookmarksManager, postbox: PostBox, bootstrap_relays: [RelayURL], replies: ReplyCounter, wallet: WalletModel, nav: NavigationCoordinator, music: MusicController?, video: DamusVideoCoordinator, ndb: Ndb, purple: DamusPurple? = nil, quote_reposts: EventCounter, emoji_provider: EmojiProvider) { self.pool = pool self.keypair = keypair self.likes = likes @@ -141,7 +141,7 @@ class DamusState: HeadlessDamusState { wallet: WalletModel(settings: settings), nav: navigationCoordinator, music: MusicController(onChange: { _ in }), - video: VideoController(), + video: DamusVideoCoordinator(), ndb: ndb, quote_reposts: .init(our_pubkey: pubkey), emoji_provider: DefaultEmojiProvider(showAllVariations: true) @@ -209,7 +209,7 @@ class DamusState: HeadlessDamusState { wallet: WalletModel(settings: UserSettingsStore()), nav: NavigationCoordinator(), music: nil, - video: VideoController(), + video: DamusVideoCoordinator(), ndb: .empty, quote_reposts: .init(our_pubkey: empty_pub), emoji_provider: DefaultEmojiProvider(showAllVariations: true) diff --git a/damus/Views/Images/FullScreenCarouselView.swift b/damus/Views/Images/FullScreenCarouselView.swift @@ -8,7 +8,7 @@ import SwiftUI struct FullScreenCarouselView<Content: View>: View { - let video_controller: VideoController + let video_coordinator: DamusVideoCoordinator let urls: [MediaUrl] @Environment(\.presentationMode) var presentationMode @@ -19,8 +19,8 @@ struct FullScreenCarouselView<Content: View>: View { @Binding var selectedIndex: Int let content: (() -> Content)? - init(video_controller: VideoController, urls: [MediaUrl], showMenu: Bool = true, settings: UserSettingsStore, selectedIndex: Binding<Int>, @ViewBuilder content: @escaping () -> Content) { - self.video_controller = video_controller + init(video_coordinator: DamusVideoCoordinator, urls: [MediaUrl], showMenu: Bool = true, settings: UserSettingsStore, selectedIndex: Binding<Int>, @ViewBuilder content: @escaping () -> Content) { + self.video_coordinator = video_coordinator self.urls = urls self._showMenu = State(initialValue: showMenu) self.settings = settings @@ -28,8 +28,8 @@ struct FullScreenCarouselView<Content: View>: View { self.content = content } - init(video_controller: VideoController, urls: [MediaUrl], showMenu: Bool = true, settings: UserSettingsStore, selectedIndex: Binding<Int>) { - self.video_controller = video_controller + init(video_coordinator: DamusVideoCoordinator, urls: [MediaUrl], showMenu: Bool = true, settings: UserSettingsStore, selectedIndex: Binding<Int>) { + self.video_coordinator = video_coordinator self.urls = urls self._showMenu = State(initialValue: showMenu) self.settings = settings @@ -59,7 +59,7 @@ struct FullScreenCarouselView<Content: View>: View { ForEach(urls.indices, id: \.self) { index in VStack { if case .video = urls[safe: index] { - ImageContainerView(video_controller: video_controller, url: urls[index], settings: settings, imageDict: $imageDict) + ImageContainerView(video_coordinator: video_coordinator, url: urls[index], settings: settings, imageDict: $imageDict) .clipped() // SwiftUI hack from https://stackoverflow.com/a/74401288 to make playback controls show up within the TabView .aspectRatio(contentMode: .fit) .padding(.top, Theme.safeAreaInsets?.top) @@ -71,7 +71,7 @@ struct FullScreenCarouselView<Content: View>: View { } else { ZoomableScrollView { - ImageContainerView(video_controller: video_controller, url: urls[index], settings: settings, imageDict: $imageDict) + ImageContainerView(video_coordinator: video_coordinator, url: urls[index], settings: settings, imageDict: $imageDict) .aspectRatio(contentMode: .fit) .padding(.top, Theme.safeAreaInsets?.top) .padding(.bottom, Theme.safeAreaInsets?.bottom) @@ -148,7 +148,7 @@ fileprivate struct FullScreenCarouselPreviewView<Content: View>: View { } var body: some View { - FullScreenCarouselView(video_controller: test_damus_state.video, urls: [test_video_url, url], settings: test_damus_state.settings, selectedIndex: $selectedIndex) { + FullScreenCarouselView(video_coordinator: test_damus_state.video, urls: [test_video_url, url], settings: test_damus_state.settings, selectedIndex: $selectedIndex) { self.custom_content?() } .environmentObject(OrientationTracker()) diff --git a/damus/Views/Images/ImageContainerView.swift b/damus/Views/Images/ImageContainerView.swift @@ -10,7 +10,7 @@ import Kingfisher struct ImageContainerView: View { - let video_controller: VideoController + let video_coordinator: DamusVideoCoordinator let url: MediaUrl let settings: UserSettingsStore @@ -51,7 +51,7 @@ struct ImageContainerView: View { case .image(let url): Img(url: url) case .video(let url): - DamusVideoPlayer(url: url, video_size: .constant(nil), controller: video_controller, style: .full, visibility_tracking_method: .generic) + DamusVideoPlayer(url: url, video_size: .constant(nil), coordinator: video_coordinator, style: .full, visibility_tracking_method: .generic) } } } @@ -64,9 +64,9 @@ struct ImageContainerView_Previews: PreviewProvider { static var previews: some View { @State var imageDict: [URL: UIImage] = [:] Group { - ImageContainerView(video_controller: test_damus_state.video, url: .image(test_image_url), settings: test_damus_state.settings, imageDict: $imageDict) + ImageContainerView(video_coordinator: test_damus_state.video, url: .image(test_image_url), settings: test_damus_state.settings, imageDict: $imageDict) .previewDisplayName("Image") - ImageContainerView(video_controller: test_damus_state.video, url: .video(test_video_url), settings: test_damus_state.settings, imageDict: $imageDict) + ImageContainerView(video_coordinator: test_damus_state.video, url: .video(test_video_url), settings: test_damus_state.settings, imageDict: $imageDict) .previewDisplayName("Video") } .environmentObject(OrientationTracker()) diff --git a/damus/Views/Video/DamusVideoCoordinator.swift b/damus/Views/Video/DamusVideoCoordinator.swift @@ -0,0 +1,53 @@ +// +// DamusVideoCoordinator.swift +// damus +// +// Created by Bryan Montz on 9/3/23. +// + +import Combine +import Foundation + +struct VideoMetadata { + let has_audio: Bool + let size: CGSize +} + +/// DamusVideoCoordinator is responsible for coordinating the various video players in the damus app. +/// The goals of this object are to: +/// - ensure some video playing states (such as mute state) are consistent across different video player view instances of the same video +/// - ensure only one video is playing at a time +/// - Provide global video playback controls to control the currently playing video +/// +/// This is used as a singleton object (one per DamusState), which gets passed around to video players, which can then interact with the coordinator to ensure an app-wide coherent experience +/// +/// A good analogy here is that video players and their models/states are like individual car drivers, and this coordinator is like a traffic control person that ensures cars don't crash each other. +final class DamusVideoCoordinator: ObservableObject { + private var mute_states: [URL: Bool] = [:] + private var metadatas: [URL: VideoMetadata] = [:] + + @Published var focused_model_id: UUID? + + func toggle_should_mute_video(url: URL) { + let state = mute_states[url] ?? true + mute_states[url] = !state + + objectWillChange.send() + } + + func should_mute_video(url: URL) -> Bool { + mute_states[url] ?? true + } + + func set_metadata(_ metadata: VideoMetadata, url: URL) { + metadatas[url] = metadata + } + + func metadata(for url: URL) -> VideoMetadata? { + metadatas[url] + } + + func size_for_url(_ url: URL) -> CGSize? { + metadatas[url]?.size + } +} diff --git a/damus/Views/Video/DamusVideoPlayer.swift b/damus/Views/Video/DamusVideoPlayer.swift @@ -24,7 +24,7 @@ struct DamusVideoPlayer: View { let visibility_tracking_method: VisibilityTrackingMethod @State var isVisible: Bool = false - init(url: URL, video_size: Binding<CGSize?>, controller: VideoController, style: Style, visibility_tracking_method: VisibilityTrackingMethod = .y_scroll) { + init(url: URL, video_size: Binding<CGSize?>, coordinator: DamusVideoCoordinator, style: Style, visibility_tracking_method: VisibilityTrackingMethod = .y_scroll) { self.url = url let mute: Bool? if case .full = style { @@ -33,7 +33,7 @@ struct DamusVideoPlayer: View { else { mute = nil } - _model = StateObject(wrappedValue: DamusVideoPlayerViewModel(url: url, video_size: video_size, controller: controller, mute: mute)) + _model = StateObject(wrappedValue: DamusVideoPlayerViewModel(url: url, video_size: video_size, coordinator: coordinator, mute: mute)) self.visibility_tracking_method = visibility_tracking_method self.style = style } @@ -166,11 +166,11 @@ struct DamusVideoPlayer: View { struct DamusVideoPlayer_Previews: PreviewProvider { static var previews: some View { Group { - DamusVideoPlayer(url: URL(string: "http://cdn.jb55.com/s/zaps-build.mp4")!, video_size: .constant(nil), controller: VideoController(), style: .full) + DamusVideoPlayer(url: URL(string: "http://cdn.jb55.com/s/zaps-build.mp4")!, video_size: .constant(nil), coordinator: DamusVideoCoordinator(), style: .full) .environmentObject(OrientationTracker()) .previewDisplayName("Full video player") - DamusVideoPlayer(url: URL(string: "http://cdn.jb55.com/s/zaps-build.mp4")!, video_size: .constant(nil), controller: VideoController(), style: .preview(on_tap: nil)) + DamusVideoPlayer(url: URL(string: "http://cdn.jb55.com/s/zaps-build.mp4")!, video_size: .constant(nil), coordinator: DamusVideoCoordinator(), style: .preview(on_tap: nil)) .environmentObject(OrientationTracker()) .previewDisplayName("Preview video player") } diff --git a/damus/Views/Video/DamusVideoPlayerViewModel.swift b/damus/Views/Video/DamusVideoPlayerViewModel.swift @@ -28,7 +28,7 @@ final class DamusVideoPlayerViewModel: ObservableObject { private let url: URL private let player_item: AVPlayerItem let player: AVPlayer - fileprivate let controller: VideoController + fileprivate let coordinator: DamusVideoCoordinator let player_view_controller = AVPlayerViewController() let id = UUID() @@ -47,28 +47,28 @@ final class DamusVideoPlayerViewModel: ObservableObject { didSet { if is_scrolled_into_view && !oldValue { // we have just scrolled from out of view into view - controller.focused_model_id = id + coordinator.focused_model_id = id } else if !is_scrolled_into_view && oldValue { // we have just scrolled from in view to out of view - if controller.focused_model_id == id { - controller.focused_model_id = nil + if coordinator.focused_model_id == id { + coordinator.focused_model_id = nil } } } } - init(url: URL, video_size: Binding<CGSize?>, controller: VideoController, mute: Bool? = nil) { + init(url: URL, video_size: Binding<CGSize?>, coordinator: DamusVideoCoordinator, mute: Bool? = nil) { self.url = url player_item = AVPlayerItem(url: url) player = AVPlayer(playerItem: player_item) - self.controller = controller + self.coordinator = coordinator _video_size = video_size Task { await load() } - is_muted = mute ?? controller.should_mute_video(url: url) + is_muted = mute ?? coordinator.should_mute_video(url: url) player.isMuted = is_muted NotificationCenter.default.addObserver( @@ -78,7 +78,7 @@ final class DamusVideoPlayerViewModel: ObservableObject { object: player_item ) - controller.$focused_model_id + coordinator.$focused_model_id .sink { [weak self] model_id in model_id == self?.id ? self?.player.play() : self?.player.pause() } @@ -111,7 +111,7 @@ final class DamusVideoPlayerViewModel: ObservableObject { } private func load() async { - if let meta = controller.metadata(for: url) { + if let meta = coordinator.metadata(for: url) { has_audio = meta.has_audio video_size = meta.size } else { @@ -124,7 +124,7 @@ final class DamusVideoPlayerViewModel: ObservableObject { func did_tap_mute_button() { is_muted.toggle() player.isMuted = is_muted - controller.toggle_should_mute_video(url: url) + coordinator.toggle_should_mute_video(url: url) } func set_view_is_visible(_ is_visible: Bool) { diff --git a/damus/Views/Video/VideoController.swift b/damus/Views/Video/VideoController.swift @@ -1,44 +0,0 @@ -// -// VideoController.swift -// damus -// -// Created by Bryan Montz on 9/3/23. -// - -import Combine -import Foundation - -struct VideoMetadata { - let has_audio: Bool - let size: CGSize -} - -final class VideoController: ObservableObject { - private var mute_states: [URL: Bool] = [:] - private var metadatas: [URL: VideoMetadata] = [:] - - @Published var focused_model_id: UUID? - - func toggle_should_mute_video(url: URL) { - let state = mute_states[url] ?? true - mute_states[url] = !state - - objectWillChange.send() - } - - func should_mute_video(url: URL) -> Bool { - mute_states[url] ?? true - } - - func set_metadata(_ metadata: VideoMetadata, url: URL) { - metadatas[url] = metadata - } - - func metadata(for url: URL) -> VideoMetadata? { - metadatas[url] - } - - func size_for_url(_ url: URL) -> CGSize? { - metadatas[url]?.size - } -}