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>
This commit is contained in:
@@ -388,7 +388,7 @@
|
|||||||
5053ACA72A56DF3B00851AE3 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5053ACA62A56DF3B00851AE3 /* DeveloperSettingsView.swift */; };
|
5053ACA72A56DF3B00851AE3 /* DeveloperSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5053ACA62A56DF3B00851AE3 /* DeveloperSettingsView.swift */; };
|
||||||
50A16FFB2AA6C06600DFEC1F /* DamusAVPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */; };
|
50A16FFB2AA6C06600DFEC1F /* DamusAVPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */; };
|
||||||
50A16FFD2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.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 */; };
|
50A50A8D29A09E1C00C01BE7 /* RequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A50A8C29A09E1C00C01BE7 /* RequestTests.swift */; };
|
||||||
50A60D142A28BEEE00186190 /* RelayLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A60D132A28BEEE00186190 /* RelayLog.swift */; };
|
50A60D142A28BEEE00186190 /* RelayLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A60D132A28BEEE00186190 /* RelayLog.swift */; };
|
||||||
50B5685329F97CB400A23243 /* CredentialHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50B5685229F97CB400A23243 /* CredentialHandler.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 */; };
|
D73E5ED72C6A97F4007EB227 /* MutinyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C7389B62B9E692E00781E0A /* MutinyButton.swift */; };
|
||||||
D73E5ED82C6A97F4007EB227 /* DamusVideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A2929DDF54400516EAC /* DamusVideoPlayer.swift */; };
|
D73E5ED82C6A97F4007EB227 /* DamusVideoPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A2929DDF54400516EAC /* DamusVideoPlayer.swift */; };
|
||||||
D73E5ED92C6A97F4007EB227 /* DamusVideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.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 */; };
|
D73E5EDB2C6A97F4007EB227 /* DamusAVPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */; };
|
||||||
D73E5EDC2C6A97F4007EB227 /* ReactionsSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C15C7142A55DE7A00D0A0DB /* ReactionsSettingsView.swift */; };
|
D73E5EDC2C6A97F4007EB227 /* ReactionsSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C15C7142A55DE7A00D0A0DB /* ReactionsSettingsView.swift */; };
|
||||||
D73E5EDD2C6A97F4007EB227 /* NotificationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C1A9A1C29DDCF9B00516EAC /* NotificationSettingsView.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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
50B5685229F97CB400A23243 /* CredentialHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CredentialHandler.swift; sourceTree = "<group>"; };
|
||||||
@@ -2294,7 +2294,7 @@
|
|||||||
children = (
|
children = (
|
||||||
4C1A9A2929DDF54400516EAC /* DamusVideoPlayer.swift */,
|
4C1A9A2929DDF54400516EAC /* DamusVideoPlayer.swift */,
|
||||||
50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift */,
|
50A16FFC2AA7525700DFEC1F /* DamusVideoPlayerViewModel.swift */,
|
||||||
50A16FFE2AA76A0900DFEC1F /* VideoController.swift */,
|
50A16FFE2AA76A0900DFEC1F /* DamusVideoCoordinator.swift */,
|
||||||
50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */,
|
50A16FFA2AA6C06600DFEC1F /* DamusAVPlayerView.swift */,
|
||||||
);
|
);
|
||||||
path = Video;
|
path = Video;
|
||||||
@@ -3899,7 +3899,7 @@
|
|||||||
5C14C29F2BBBA5C600079FD2 /* RelayNipList.swift in Sources */,
|
5C14C29F2BBBA5C600079FD2 /* RelayNipList.swift in Sources */,
|
||||||
D78DB85B2C20FE5000F0AB12 /* VectorMath.swift in Sources */,
|
D78DB85B2C20FE5000F0AB12 /* VectorMath.swift in Sources */,
|
||||||
D7CB5D3E2B116DAD00AD4105 /* NotificationsManager.swift in Sources */,
|
D7CB5D3E2B116DAD00AD4105 /* NotificationsManager.swift in Sources */,
|
||||||
50A16FFF2AA76A0900DFEC1F /* VideoController.swift in Sources */,
|
50A16FFF2AA76A0900DFEC1F /* DamusVideoCoordinator.swift in Sources */,
|
||||||
F7908E97298B1FDF00AB113A /* NIPURLBuilder.swift in Sources */,
|
F7908E97298B1FDF00AB113A /* NIPURLBuilder.swift in Sources */,
|
||||||
4C285C8228385570008A31F1 /* CarouselView.swift in Sources */,
|
4C285C8228385570008A31F1 /* CarouselView.swift in Sources */,
|
||||||
3A3040F129A8FF97008A0F29 /* LocalizationUtil.swift in Sources */,
|
3A3040F129A8FF97008A0F29 /* LocalizationUtil.swift in Sources */,
|
||||||
@@ -4452,7 +4452,7 @@
|
|||||||
D73E5ED72C6A97F4007EB227 /* MutinyButton.swift in Sources */,
|
D73E5ED72C6A97F4007EB227 /* MutinyButton.swift in Sources */,
|
||||||
D73E5ED82C6A97F4007EB227 /* DamusVideoPlayer.swift in Sources */,
|
D73E5ED82C6A97F4007EB227 /* DamusVideoPlayer.swift in Sources */,
|
||||||
D73E5ED92C6A97F4007EB227 /* DamusVideoPlayerViewModel.swift in Sources */,
|
D73E5ED92C6A97F4007EB227 /* DamusVideoPlayerViewModel.swift in Sources */,
|
||||||
D73E5EDA2C6A97F4007EB227 /* VideoController.swift in Sources */,
|
D73E5EDA2C6A97F4007EB227 /* DamusVideoCoordinator.swift in Sources */,
|
||||||
D73E5EDB2C6A97F4007EB227 /* DamusAVPlayerView.swift in Sources */,
|
D73E5EDB2C6A97F4007EB227 /* DamusAVPlayerView.swift in Sources */,
|
||||||
D73E5EDC2C6A97F4007EB227 /* ReactionsSettingsView.swift in Sources */,
|
D73E5EDC2C6A97F4007EB227 /* ReactionsSettingsView.swift in Sources */,
|
||||||
D73E5EDD2C6A97F4007EB227 /* NotificationSettingsView.swift in Sources */,
|
D73E5EDD2C6A97F4007EB227 /* NotificationSettingsView.swift in Sources */,
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ struct ImageCarousel<Content: View>: View {
|
|||||||
model.open_sheet = true
|
model.open_sheet = true
|
||||||
}
|
}
|
||||||
case .video(let url):
|
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
|
.onChange(of: model.video_size) { size in
|
||||||
guard let size else { return }
|
guard let size else { return }
|
||||||
|
|
||||||
@@ -257,14 +257,14 @@ struct ImageCarousel<Content: View>: View {
|
|||||||
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
|
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
|
||||||
.fullScreenCover(isPresented: $model.open_sheet) {
|
.fullScreenCover(isPresented: $model.open_sheet) {
|
||||||
if let content {
|
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
|
content({ // Dismiss closure
|
||||||
model.open_sheet = false
|
model.open_sheet = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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)
|
.frame(height: height)
|
||||||
|
|||||||
@@ -686,7 +686,7 @@ struct ContentView: View {
|
|||||||
wallet: WalletModel(settings: settings),
|
wallet: WalletModel(settings: settings),
|
||||||
nav: self.navigationCoordinator,
|
nav: self.navigationCoordinator,
|
||||||
music: MusicController(onChange: music_changed),
|
music: MusicController(onChange: music_changed),
|
||||||
video: VideoController(),
|
video: DamusVideoCoordinator(),
|
||||||
ndb: ndb,
|
ndb: ndb,
|
||||||
quote_reposts: .init(our_pubkey: pubkey),
|
quote_reposts: .init(our_pubkey: pubkey),
|
||||||
emoji_provider: DefaultEmojiProvider(showAllVariations: true)
|
emoji_provider: DefaultEmojiProvider(showAllVariations: true)
|
||||||
|
|||||||
@@ -34,13 +34,13 @@ class DamusState: HeadlessDamusState {
|
|||||||
let wallet: WalletModel
|
let wallet: WalletModel
|
||||||
let nav: NavigationCoordinator
|
let nav: NavigationCoordinator
|
||||||
let music: MusicController?
|
let music: MusicController?
|
||||||
let video: VideoController
|
let video: DamusVideoCoordinator
|
||||||
let ndb: Ndb
|
let ndb: Ndb
|
||||||
var purple: DamusPurple
|
var purple: DamusPurple
|
||||||
var push_notification_client: PushNotificationClient
|
var push_notification_client: PushNotificationClient
|
||||||
let emoji_provider: EmojiProvider
|
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.pool = pool
|
||||||
self.keypair = keypair
|
self.keypair = keypair
|
||||||
self.likes = likes
|
self.likes = likes
|
||||||
@@ -141,7 +141,7 @@ class DamusState: HeadlessDamusState {
|
|||||||
wallet: WalletModel(settings: settings),
|
wallet: WalletModel(settings: settings),
|
||||||
nav: navigationCoordinator,
|
nav: navigationCoordinator,
|
||||||
music: MusicController(onChange: { _ in }),
|
music: MusicController(onChange: { _ in }),
|
||||||
video: VideoController(),
|
video: DamusVideoCoordinator(),
|
||||||
ndb: ndb,
|
ndb: ndb,
|
||||||
quote_reposts: .init(our_pubkey: pubkey),
|
quote_reposts: .init(our_pubkey: pubkey),
|
||||||
emoji_provider: DefaultEmojiProvider(showAllVariations: true)
|
emoji_provider: DefaultEmojiProvider(showAllVariations: true)
|
||||||
@@ -209,7 +209,7 @@ class DamusState: HeadlessDamusState {
|
|||||||
wallet: WalletModel(settings: UserSettingsStore()),
|
wallet: WalletModel(settings: UserSettingsStore()),
|
||||||
nav: NavigationCoordinator(),
|
nav: NavigationCoordinator(),
|
||||||
music: nil,
|
music: nil,
|
||||||
video: VideoController(),
|
video: DamusVideoCoordinator(),
|
||||||
ndb: .empty,
|
ndb: .empty,
|
||||||
quote_reposts: .init(our_pubkey: empty_pub),
|
quote_reposts: .init(our_pubkey: empty_pub),
|
||||||
emoji_provider: DefaultEmojiProvider(showAllVariations: true)
|
emoji_provider: DefaultEmojiProvider(showAllVariations: true)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct FullScreenCarouselView<Content: View>: View {
|
struct FullScreenCarouselView<Content: View>: View {
|
||||||
let video_controller: VideoController
|
let video_coordinator: DamusVideoCoordinator
|
||||||
let urls: [MediaUrl]
|
let urls: [MediaUrl]
|
||||||
|
|
||||||
@Environment(\.presentationMode) var presentationMode
|
@Environment(\.presentationMode) var presentationMode
|
||||||
@@ -19,8 +19,8 @@ struct FullScreenCarouselView<Content: View>: View {
|
|||||||
@Binding var selectedIndex: Int
|
@Binding var selectedIndex: Int
|
||||||
let content: (() -> Content)?
|
let content: (() -> Content)?
|
||||||
|
|
||||||
init(video_controller: VideoController, urls: [MediaUrl], showMenu: Bool = true, settings: UserSettingsStore, selectedIndex: Binding<Int>, @ViewBuilder content: @escaping () -> Content) {
|
init(video_coordinator: DamusVideoCoordinator, urls: [MediaUrl], showMenu: Bool = true, settings: UserSettingsStore, selectedIndex: Binding<Int>, @ViewBuilder content: @escaping () -> Content) {
|
||||||
self.video_controller = video_controller
|
self.video_coordinator = video_coordinator
|
||||||
self.urls = urls
|
self.urls = urls
|
||||||
self._showMenu = State(initialValue: showMenu)
|
self._showMenu = State(initialValue: showMenu)
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
@@ -28,8 +28,8 @@ struct FullScreenCarouselView<Content: View>: View {
|
|||||||
self.content = content
|
self.content = content
|
||||||
}
|
}
|
||||||
|
|
||||||
init(video_controller: VideoController, urls: [MediaUrl], showMenu: Bool = true, settings: UserSettingsStore, selectedIndex: Binding<Int>) {
|
init(video_coordinator: DamusVideoCoordinator, urls: [MediaUrl], showMenu: Bool = true, settings: UserSettingsStore, selectedIndex: Binding<Int>) {
|
||||||
self.video_controller = video_controller
|
self.video_coordinator = video_coordinator
|
||||||
self.urls = urls
|
self.urls = urls
|
||||||
self._showMenu = State(initialValue: showMenu)
|
self._showMenu = State(initialValue: showMenu)
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
@@ -59,7 +59,7 @@ struct FullScreenCarouselView<Content: View>: View {
|
|||||||
ForEach(urls.indices, id: \.self) { index in
|
ForEach(urls.indices, id: \.self) { index in
|
||||||
VStack {
|
VStack {
|
||||||
if case .video = urls[safe: index] {
|
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
|
.clipped() // SwiftUI hack from https://stackoverflow.com/a/74401288 to make playback controls show up within the TabView
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.padding(.top, Theme.safeAreaInsets?.top)
|
.padding(.top, Theme.safeAreaInsets?.top)
|
||||||
@@ -71,7 +71,7 @@ struct FullScreenCarouselView<Content: View>: View {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ZoomableScrollView {
|
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)
|
.aspectRatio(contentMode: .fit)
|
||||||
.padding(.top, Theme.safeAreaInsets?.top)
|
.padding(.top, Theme.safeAreaInsets?.top)
|
||||||
.padding(.bottom, Theme.safeAreaInsets?.bottom)
|
.padding(.bottom, Theme.safeAreaInsets?.bottom)
|
||||||
@@ -148,7 +148,7 @@ fileprivate struct FullScreenCarouselPreviewView<Content: View>: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var body: some 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?()
|
self.custom_content?()
|
||||||
}
|
}
|
||||||
.environmentObject(OrientationTracker())
|
.environmentObject(OrientationTracker())
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import Kingfisher
|
|||||||
|
|
||||||
|
|
||||||
struct ImageContainerView: View {
|
struct ImageContainerView: View {
|
||||||
let video_controller: VideoController
|
let video_coordinator: DamusVideoCoordinator
|
||||||
let url: MediaUrl
|
let url: MediaUrl
|
||||||
let settings: UserSettingsStore
|
let settings: UserSettingsStore
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ struct ImageContainerView: View {
|
|||||||
case .image(let url):
|
case .image(let url):
|
||||||
Img(url: url)
|
Img(url: url)
|
||||||
case .video(let 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 {
|
static var previews: some View {
|
||||||
@State var imageDict: [URL: UIImage] = [:]
|
@State var imageDict: [URL: UIImage] = [:]
|
||||||
Group {
|
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")
|
.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")
|
.previewDisplayName("Video")
|
||||||
}
|
}
|
||||||
.environmentObject(OrientationTracker())
|
.environmentObject(OrientationTracker())
|
||||||
|
|||||||
53
damus/Views/Video/DamusVideoCoordinator.swift
Normal file
53
damus/Views/Video/DamusVideoCoordinator.swift
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,7 @@ struct DamusVideoPlayer: View {
|
|||||||
let visibility_tracking_method: VisibilityTrackingMethod
|
let visibility_tracking_method: VisibilityTrackingMethod
|
||||||
@State var isVisible: Bool = false
|
@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
|
self.url = url
|
||||||
let mute: Bool?
|
let mute: Bool?
|
||||||
if case .full = style {
|
if case .full = style {
|
||||||
@@ -33,7 +33,7 @@ struct DamusVideoPlayer: View {
|
|||||||
else {
|
else {
|
||||||
mute = nil
|
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.visibility_tracking_method = visibility_tracking_method
|
||||||
self.style = style
|
self.style = style
|
||||||
}
|
}
|
||||||
@@ -166,11 +166,11 @@ struct DamusVideoPlayer: View {
|
|||||||
struct DamusVideoPlayer_Previews: PreviewProvider {
|
struct DamusVideoPlayer_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
Group {
|
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())
|
.environmentObject(OrientationTracker())
|
||||||
.previewDisplayName("Full video player")
|
.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())
|
.environmentObject(OrientationTracker())
|
||||||
.previewDisplayName("Preview video player")
|
.previewDisplayName("Preview video player")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ final class DamusVideoPlayerViewModel: ObservableObject {
|
|||||||
private let url: URL
|
private let url: URL
|
||||||
private let player_item: AVPlayerItem
|
private let player_item: AVPlayerItem
|
||||||
let player: AVPlayer
|
let player: AVPlayer
|
||||||
fileprivate let controller: VideoController
|
fileprivate let coordinator: DamusVideoCoordinator
|
||||||
let player_view_controller = AVPlayerViewController()
|
let player_view_controller = AVPlayerViewController()
|
||||||
let id = UUID()
|
let id = UUID()
|
||||||
|
|
||||||
@@ -47,28 +47,28 @@ final class DamusVideoPlayerViewModel: ObservableObject {
|
|||||||
didSet {
|
didSet {
|
||||||
if is_scrolled_into_view && !oldValue {
|
if is_scrolled_into_view && !oldValue {
|
||||||
// we have just scrolled from out of view into view
|
// 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 {
|
} else if !is_scrolled_into_view && oldValue {
|
||||||
// we have just scrolled from in view to out of view
|
// we have just scrolled from in view to out of view
|
||||||
if controller.focused_model_id == id {
|
if coordinator.focused_model_id == id {
|
||||||
controller.focused_model_id = nil
|
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
|
self.url = url
|
||||||
player_item = AVPlayerItem(url: url)
|
player_item = AVPlayerItem(url: url)
|
||||||
player = AVPlayer(playerItem: player_item)
|
player = AVPlayer(playerItem: player_item)
|
||||||
self.controller = controller
|
self.coordinator = coordinator
|
||||||
_video_size = video_size
|
_video_size = video_size
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
await load()
|
await load()
|
||||||
}
|
}
|
||||||
|
|
||||||
is_muted = mute ?? controller.should_mute_video(url: url)
|
is_muted = mute ?? coordinator.should_mute_video(url: url)
|
||||||
player.isMuted = is_muted
|
player.isMuted = is_muted
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(
|
NotificationCenter.default.addObserver(
|
||||||
@@ -78,7 +78,7 @@ final class DamusVideoPlayerViewModel: ObservableObject {
|
|||||||
object: player_item
|
object: player_item
|
||||||
)
|
)
|
||||||
|
|
||||||
controller.$focused_model_id
|
coordinator.$focused_model_id
|
||||||
.sink { [weak self] model_id in
|
.sink { [weak self] model_id in
|
||||||
model_id == self?.id ? self?.player.play() : self?.player.pause()
|
model_id == self?.id ? self?.player.play() : self?.player.pause()
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ final class DamusVideoPlayerViewModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func load() async {
|
private func load() async {
|
||||||
if let meta = controller.metadata(for: url) {
|
if let meta = coordinator.metadata(for: url) {
|
||||||
has_audio = meta.has_audio
|
has_audio = meta.has_audio
|
||||||
video_size = meta.size
|
video_size = meta.size
|
||||||
} else {
|
} else {
|
||||||
@@ -124,7 +124,7 @@ final class DamusVideoPlayerViewModel: ObservableObject {
|
|||||||
func did_tap_mute_button() {
|
func did_tap_mute_button() {
|
||||||
is_muted.toggle()
|
is_muted.toggle()
|
||||||
player.isMuted = is_muted
|
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) {
|
func set_view_is_visible(_ is_visible: Bool) {
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user