From 7ed3cbddc7410c2db9e8e40ed08a977e6a949170 Mon Sep 17 00:00:00 2001 From: Hiroshi Horie <548776+hiroshihorie@users.noreply.github.com> Date: Mon, 11 Mar 2024 14:15:11 +0900 Subject: [PATCH] implement --- .../Layouts/ParticipantLayout.swift | 2 +- .../Prebuilt/ConnectView.swift | 2 +- .../Prebuilt/VideoConferenceView.swift | 2 +- .../Scopes/ComponentsScope.swift | 14 ++- Sources/LiveKitComponents/UIPreference.swift | 94 ++++++++++--------- .../Views/LocalCameraPreview.swift | 2 +- .../ConnectionQualityIndicatorView.swift | 2 +- .../ParticipantInformationView.swift | 2 +- .../Views/Participant/ParticipantView.swift | 2 +- .../Views/Room/ControlsView.swift | 2 +- .../Views/Room/LocalCameraVideoView.swift | 2 +- .../TrackPublication/VideoTrackView.swift | 2 +- 12 files changed, 71 insertions(+), 57 deletions(-) diff --git a/Sources/LiveKitComponents/Layouts/ParticipantLayout.swift b/Sources/LiveKitComponents/Layouts/ParticipantLayout.swift index f60b570..8ee5923 100644 --- a/Sources/LiveKitComponents/Layouts/ParticipantLayout.swift +++ b/Sources/LiveKitComponents/Layouts/ParticipantLayout.swift @@ -17,7 +17,7 @@ import SwiftUI struct ParticipantLayout: View where Data.Element: Identifiable, Data.Index: Hashable { - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference private let data: Data private let spacing: CGFloat? diff --git a/Sources/LiveKitComponents/Prebuilt/ConnectView.swift b/Sources/LiveKitComponents/Prebuilt/ConnectView.swift index 31af977..2d124cf 100644 --- a/Sources/LiveKitComponents/Prebuilt/ConnectView.swift +++ b/Sources/LiveKitComponents/Prebuilt/ConnectView.swift @@ -19,7 +19,7 @@ import SwiftUI public struct ConnectView: View { @EnvironmentObject var room: Room - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference @AppStorage("url") var url: String = "" @AppStorage("token") var token: String = "" diff --git a/Sources/LiveKitComponents/Prebuilt/VideoConferenceView.swift b/Sources/LiveKitComponents/Prebuilt/VideoConferenceView.swift index a8ad5cc..a79bc22 100644 --- a/Sources/LiveKitComponents/Prebuilt/VideoConferenceView.swift +++ b/Sources/LiveKitComponents/Prebuilt/VideoConferenceView.swift @@ -18,8 +18,8 @@ import LiveKit import SwiftUI public struct VideoConferenceView: View { - @EnvironmentObject var ui: UIPreference @EnvironmentObject var room: Room + @Environment(\.uiPreference) var ui: UIPreference public init() {} diff --git a/Sources/LiveKitComponents/Scopes/ComponentsScope.swift b/Sources/LiveKitComponents/Scopes/ComponentsScope.swift index 7179247..bd200b6 100644 --- a/Sources/LiveKitComponents/Scopes/ComponentsScope.swift +++ b/Sources/LiveKitComponents/Scopes/ComponentsScope.swift @@ -17,6 +17,18 @@ import LiveKit import SwiftUI +public struct LiveKitComponentsEnvironmentKey: EnvironmentKey { + // This is the default value that SwiftUI will fallback to if you don't pass the object + public static var defaultValue: UIPreference = .init() +} + +public extension EnvironmentValues { + var uiPreference: UIPreference { + get { self[LiveKitComponentsEnvironmentKey.self] } + set { self[LiveKitComponentsEnvironmentKey.self] = newValue } + } +} + public struct ComponentsScope: View { var content: () -> Content let preference: UIPreference @@ -30,6 +42,6 @@ public struct ComponentsScope: View { public var body: some View { content() - .environmentObject(preference) + .environment(\.uiPreference, preference) } } diff --git a/Sources/LiveKitComponents/UIPreference.swift b/Sources/LiveKitComponents/UIPreference.swift index c2aece8..f1a61da 100644 --- a/Sources/LiveKitComponents/UIPreference.swift +++ b/Sources/LiveKitComponents/UIPreference.swift @@ -33,87 +33,89 @@ open class UIPreference: ObservableObject { /// Spacing between ``ParticipantView``s. var participantViewSpacing: CGFloat { 8 } + public init() {} + /// Placeholder view when the video is disabled or not available. - public func videoDisabledView(geometry: GeometryProxy) -> some View { - Image(systemName: "video.slash") - .resizable() - .aspectRatio(contentMode: .fit) - .foregroundColor(Color(.lightGray)) - .frame(width: min(geometry.size.width, geometry.size.height) * 0.3) - .frame( - maxWidth: .infinity, - maxHeight: .infinity - ) + public func videoDisabledView(geometry: GeometryProxy) -> AnyView { + AnyView( + Image(systemName: "video.slash") + .resizable() + .aspectRatio(contentMode: .fit) + .foregroundColor(Color(.lightGray)) + .frame(width: min(geometry.size.width, geometry.size.height) * 0.3) + .frame( + maxWidth: .infinity, + maxHeight: .infinity + )) } - func micEnabledView() -> some View { - Image(systemName: "mic.fill") - .foregroundColor(.orange) + func micEnabledView() -> AnyView { + AnyView(Image(systemName: "mic.fill") + .foregroundColor(.orange)) } /// Placeholder view when the microphone is disabled or not available. - func micDisabledView() -> some View { - Image(systemName: "mic.slash.fill") - .foregroundColor(.red) + open func micDisabledView() -> AnyView { + AnyView(Image(systemName: "mic.slash.fill") + .foregroundColor(.red)) } - func enableVideoView() -> some View { - Image(systemName: "video.slash.fill") + open func enableVideoView() -> AnyView { + AnyView(Image(systemName: "video.slash.fill")) } - func disableVideoView() -> some View { - Image(systemName: "video.fill") - .foregroundColor(.green) + func disableVideoView() -> AnyView { + AnyView(Image(systemName: "video.fill") + .foregroundColor(.green)) } - func enableMicrophoneView() -> some View { - Image(systemName: "mic.slash.fill") + open func enableMicrophoneView() -> AnyView { + AnyView(Image(systemName: "mic.slash.fill")) } - func disableMicrophoneView() -> some View { - Image(systemName: "mic.fill") - .foregroundColor(.orange) + func disableMicrophoneView() -> AnyView { + AnyView(Image(systemName: "mic.fill") + .foregroundColor(.orange)) } - func disconnectView() -> some View { - Image(systemName: "xmark.circle.fill") - .foregroundColor(.red) + func disconnectView() -> AnyView { + AnyView(Image(systemName: "xmark.circle.fill") + .foregroundColor(.red)) } - func textFieldContainer(_ childView: () -> some View, label: () -> some View) -> some View { - VStack(alignment: .leading, spacing: 10.0) { + func textFieldContainer(_ childView: () -> some View, label: () -> some View) -> AnyView { + AnyView(VStack(alignment: .leading, spacing: 10.0) { label() - childView() .padding() .overlay(RoundedRectangle(cornerRadius: 10.0) .strokeBorder(Color.white.opacity(0.3), style: StrokeStyle(lineWidth: 1.0))) - } + }) } - func textField(for text: Binding, type _: TextFieldType) -> some View { - TextField("", text: text) + func textField(for text: Binding, type _: TextFieldType) -> AnyView { + AnyView(TextField("", text: text) .textFieldStyle(PlainTextFieldStyle()) .disableAutocorrection(true) - // TODO: add iOS unique view modifiers - #if os(iOS) - .autocapitalization(.none) - // .keyboardType(type.toiOSType()) - #endif + // TODO: add iOS unique view modifiers + #if os(iOS) + .autocapitalization(.none) + // .keyboardType(type.toiOSType()) + #endif) } - func button(_ action: @escaping () -> Void, label: () -> some View) -> some View { - Button(action: action, label: label) + func button(_ action: @escaping () -> Void, label: () -> some View) -> AnyView { + AnyView(Button(action: action, label: label)) } - func connectionQualityIndicatorBuilder(connectionQuality: ConnectionQuality) -> some View { + func connectionQualityIndicatorBuilder(connectionQuality: ConnectionQuality) -> AnyView { if case .excellent = connectionQuality { - return Image(systemName: "wifi").foregroundColor(.green) + return AnyView(Image(systemName: "wifi").foregroundColor(.green)) } else if case .good = connectionQuality { - return Image(systemName: "wifi").foregroundColor(Color.orange) + return AnyView(Image(systemName: "wifi").foregroundColor(Color.orange)) } - return Image(systemName: "wifi.exclamationmark").foregroundColor(Color.red) + return AnyView(Image(systemName: "wifi.exclamationmark").foregroundColor(Color.red)) } } diff --git a/Sources/LiveKitComponents/Views/LocalCameraPreview.swift b/Sources/LiveKitComponents/Views/LocalCameraPreview.swift index cd0f5e2..b6ea2d8 100644 --- a/Sources/LiveKitComponents/Views/LocalCameraPreview.swift +++ b/Sources/LiveKitComponents/Views/LocalCameraPreview.swift @@ -18,7 +18,7 @@ import LiveKit import SwiftUI public struct LocalCameraPreview: View { - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference let localVideoTrack: LocalVideoTrack diff --git a/Sources/LiveKitComponents/Views/Participant/ConnectionQualityIndicatorView.swift b/Sources/LiveKitComponents/Views/Participant/ConnectionQualityIndicatorView.swift index 7dec7da..53449e5 100644 --- a/Sources/LiveKitComponents/Views/Participant/ConnectionQualityIndicatorView.swift +++ b/Sources/LiveKitComponents/Views/Participant/ConnectionQualityIndicatorView.swift @@ -19,7 +19,7 @@ import SwiftUI public struct ConnectionQualityIndicatorView: View { @EnvironmentObject var participant: Participant - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference public var body: some View { ui.connectionQualityIndicatorBuilder(connectionQuality: participant.connectionQuality) diff --git a/Sources/LiveKitComponents/Views/Participant/ParticipantInformationView.swift b/Sources/LiveKitComponents/Views/Participant/ParticipantInformationView.swift index 8729f70..a92c25e 100644 --- a/Sources/LiveKitComponents/Views/Participant/ParticipantInformationView.swift +++ b/Sources/LiveKitComponents/Views/Participant/ParticipantInformationView.swift @@ -19,7 +19,7 @@ import SwiftUI public struct ParticipantInformationView: View { @EnvironmentObject var participant: Participant - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference public var body: some View { HStack(spacing: ui.paddingSmall) { diff --git a/Sources/LiveKitComponents/Views/Participant/ParticipantView.swift b/Sources/LiveKitComponents/Views/Participant/ParticipantView.swift index 82e8fdf..c63d77e 100644 --- a/Sources/LiveKitComponents/Views/Participant/ParticipantView.swift +++ b/Sources/LiveKitComponents/Views/Participant/ParticipantView.swift @@ -19,7 +19,7 @@ import SwiftUI public struct ParticipantView: View { @EnvironmentObject var participant: Participant - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference let showInformation: Bool diff --git a/Sources/LiveKitComponents/Views/Room/ControlsView.swift b/Sources/LiveKitComponents/Views/Room/ControlsView.swift index 8959d88..d3a42b8 100644 --- a/Sources/LiveKitComponents/Views/Room/ControlsView.swift +++ b/Sources/LiveKitComponents/Views/Room/ControlsView.swift @@ -17,7 +17,7 @@ import SwiftUI public struct ControlsView: View { - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference public var body: some View { CameraToggleButton { diff --git a/Sources/LiveKitComponents/Views/Room/LocalCameraVideoView.swift b/Sources/LiveKitComponents/Views/Room/LocalCameraVideoView.swift index d326cb3..e055933 100644 --- a/Sources/LiveKitComponents/Views/Room/LocalCameraVideoView.swift +++ b/Sources/LiveKitComponents/Views/Room/LocalCameraVideoView.swift @@ -19,7 +19,7 @@ import SwiftUI public struct LocalCameraVideoView: View { @EnvironmentObject var room: Room - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference public init() {} diff --git a/Sources/LiveKitComponents/Views/TrackPublication/VideoTrackView.swift b/Sources/LiveKitComponents/Views/TrackPublication/VideoTrackView.swift index e1ac06c..be24e28 100644 --- a/Sources/LiveKitComponents/Views/TrackPublication/VideoTrackView.swift +++ b/Sources/LiveKitComponents/Views/TrackPublication/VideoTrackView.swift @@ -19,7 +19,7 @@ import SwiftUI public struct VideoTrackView: View { @EnvironmentObject var trackReference: TrackReference - @EnvironmentObject var ui: UIPreference + @Environment(\.uiPreference) var ui: UIPreference var layoutMode: VideoView.LayoutMode = .fill var mirrorMode: VideoView.MirrorMode = .auto