Skip to content

Commit 057b67c

Browse files
authored
Refactor camera player UI and remove legacy WebRTC views (#4277)
1 parent daa4a05 commit 057b67c

12 files changed

+121
-561
lines changed

HomeAssistant.xcodeproj/project.pbxproj

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,6 @@
613613
420FE84B2B556BB100878E06 /* CarPlayActionsTemplate+Build.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420FE84A2B556BB100878E06 /* CarPlayActionsTemplate+Build.swift */; };
614614
420FE84E2B556CE500878E06 /* CarPlayEntitiesListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420FE84D2B556CE500878E06 /* CarPlayEntitiesListViewModel.swift */; };
615615
420FE8502B556F7500878E06 /* CarPlayEntitiesListTemplate+Build.swift in Sources */ = {isa = PBXBuildFile; fileRef = 420FE84F2B556F7500878E06 /* CarPlayEntitiesListTemplate+Build.swift */; };
616-
4210CCD92F150CDD00B71FB9 /* WebRTCPlayerVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4210CCD82F150CDD00B71FB9 /* WebRTCPlayerVideoView.swift */; };
617-
4210CCDB2F150CDD00B71FB9 /* WebRTCPlayerViewControls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4210CCDA2F150CDD00B71FB9 /* WebRTCPlayerViewControls.swift */; };
618-
4210CCDD2F150CDE00B71FB9 /* WebRTCPlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4210CCDC2F150CDE00B71FB9 /* WebRTCPlayerViewController.swift */; };
619616
4210CCEB2F152AD000B71FB9 /* CameraPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4210CCEA2F152AD000B71FB9 /* CameraPlayerView.swift */; };
620617
4210CCEF2F152ED800B71FB9 /* CameraStreamHLSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4210CCEE2F152ED800B71FB9 /* CameraStreamHLSView.swift */; };
621618
4210CCF32F1532C400B71FB9 /* CameraMJPEGPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4210CCF22F1532C400B71FB9 /* CameraMJPEGPlayerView.swift */; };
@@ -2308,9 +2305,6 @@
23082305
420FE84A2B556BB100878E06 /* CarPlayActionsTemplate+Build.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarPlayActionsTemplate+Build.swift"; sourceTree = "<group>"; };
23092306
420FE84D2B556CE500878E06 /* CarPlayEntitiesListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarPlayEntitiesListViewModel.swift; sourceTree = "<group>"; };
23102307
420FE84F2B556F7500878E06 /* CarPlayEntitiesListTemplate+Build.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarPlayEntitiesListTemplate+Build.swift"; sourceTree = "<group>"; };
2311-
4210CCD82F150CDD00B71FB9 /* WebRTCPlayerVideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRTCPlayerVideoView.swift; sourceTree = "<group>"; };
2312-
4210CCDA2F150CDD00B71FB9 /* WebRTCPlayerViewControls.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRTCPlayerViewControls.swift; sourceTree = "<group>"; };
2313-
4210CCDC2F150CDE00B71FB9 /* WebRTCPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebRTCPlayerViewController.swift; sourceTree = "<group>"; };
23142308
4210CCEA2F152AD000B71FB9 /* CameraPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPlayerView.swift; sourceTree = "<group>"; };
23152309
4210CCEE2F152ED800B71FB9 /* CameraStreamHLSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraStreamHLSView.swift; sourceTree = "<group>"; };
23162310
4210CCF22F1532C400B71FB9 /* CameraMJPEGPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraMJPEGPlayerView.swift; sourceTree = "<group>"; };
@@ -4781,9 +4775,6 @@
47814775
42DC44352E1C0791001046C1 /* WebRTCVideoPlayerViewControls.swift */,
47824776
425390D82E05B41900E24EDD /* WebRTCVideoPlayerViewController.swift */,
47834777
425390D92E05B41900E24EDD /* WebRTCViewPlayerViewModel.swift */,
4784-
4210CCD82F150CDD00B71FB9 /* WebRTCPlayerVideoView.swift */,
4785-
4210CCDA2F150CDD00B71FB9 /* WebRTCPlayerViewControls.swift */,
4786-
4210CCDC2F150CDE00B71FB9 /* WebRTCPlayerViewController.swift */,
47874778
);
47884779
path = WebRTC;
47894780
sourceTree = "<group>";
@@ -9382,11 +9373,9 @@
93829373
429858882EB13FD300E33710 /* WebViewControllerOverlayedViewTags.swift in Sources */,
93839374
B641BC1F1E2097EF002CCBC1 /* AboutView.swift in Sources */,
93849375
42E95C592CA46AD50010ECE3 /* ShareActivityView.swift in Sources */,
9385-
4210CCD92F150CDD00B71FB9 /* WebRTCPlayerVideoView.swift in Sources */,
93869376
420A80992E9D14C800D30A6B /* OnboardingPermissionsNavigationViewModel.swift in Sources */,
93879377
4201FD932F0E73C900C3EF1C /* CameraCardViewModel.swift in Sources */,
93889378
4206FFB62DAD58520087626C /* WebViewGestureHandler.swift in Sources */,
9389-
4210CCDB2F150CDD00B71FB9 /* WebRTCPlayerViewControls.swift in Sources */,
93909379
B675ECC3221BB0E600C65D31 /* SearchPushRow.swift in Sources */,
93919380
424A49E02EC5FD3E00524586 /* OpenInBrowser.swift in Sources */,
93929381
11C05F2D254919210031D038 /* AccountInitialsImage.swift in Sources */,
@@ -9423,7 +9412,6 @@
94239412
4210CCF32F1532C400B71FB9 /* CameraMJPEGPlayerView.swift in Sources */,
94249413
42B129512F056DAC00B957AF /* EntityMoreInfoDialogView.swift in Sources */,
94259414
42266B112B740E4C00E94A71 /* BarcodeScannerView.swift in Sources */,
9426-
4210CCDD2F150CDE00B71FB9 /* WebRTCPlayerViewController.swift in Sources */,
94279415
42FCCFE32B9B1B610057783F /* BarcodeScannerCameraView.swift in Sources */,
94289416
42BF8DB42EC4E73700DCB7E7 /* ConnectionSettingsView.swift in Sources */,
94299417
42BF8DB52EC4E73700DCB7E7 /* ConnectionSettingsViewModel.swift in Sources */,

Sources/App/Cameras/CameraPlayer/CameraMJPEGPlayerView.swift

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,34 +34,6 @@ struct CameraMJPEGPlayerView: View {
3434
.ignoresSafeArea()
3535
}
3636

37-
// Overlay controls
38-
VStack {
39-
HStack {
40-
if let cameraName {
41-
Text(cameraName)
42-
.font(.headline)
43-
.foregroundStyle(.white)
44-
.padding(.horizontal)
45-
.padding(.vertical, 8)
46-
.background(.ultraThinMaterial)
47-
.clipShape(Capsule())
48-
}
49-
Spacer()
50-
Button {
51-
dismiss()
52-
} label: {
53-
Image(systemSymbol: .xmark)
54-
.font(.body.weight(.semibold))
55-
.foregroundStyle(.white)
56-
.padding(12)
57-
.background(.ultraThinMaterial)
58-
.clipShape(Circle())
59-
}
60-
}
61-
.padding()
62-
Spacer()
63-
}
64-
6537
if isLoading {
6638
ProgressView()
6739
.progressViewStyle(.circular)

Sources/App/Cameras/CameraPlayer/CameraPlayerView.swift

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1+
import GRDB
12
import Shared
23
import SwiftUI
34

45
/// A camera player view that automatically falls back from WebRTC to HLS to MJPEG
56
/// when a streaming method is not supported.
67
@available(iOS 16.0, *)
78
struct CameraPlayerView: View {
9+
@Environment(\.dismiss) private var dismiss
810
private let server: Server
911
private let cameraEntityId: String
1012
private let cameraName: String?
1113

1214
@State private var playerType: PlayerType = .webRTC
15+
@State private var appEntity: HAAppEntity?
16+
@State private var name: String?
17+
@State private var controlsVisible = true
1318

1419
enum PlayerType {
1520
case webRTC
@@ -24,13 +29,75 @@ struct CameraPlayerView: View {
2429
}
2530

2631
var body: some View {
32+
ZStack(alignment: .topLeading) {
33+
NavigationStack {
34+
content
35+
.toolbar {
36+
ToolbarItem(placement: .primaryAction) {
37+
if controlsVisible {
38+
CloseButton {
39+
dismiss()
40+
}
41+
}
42+
}
43+
}
44+
.modify { view in
45+
if #available(iOS 18.0, *) {
46+
view.toolbarVisibility(controlsVisible ? .automatic : .hidden, for: .navigationBar)
47+
} else {
48+
view
49+
}
50+
}
51+
}
52+
.frame(maxWidth: .infinity, maxHeight: .infinity)
53+
nameBadge
54+
}
55+
.onAppear {
56+
appEntity = HAAppEntity.entity(id: cameraEntityId, serverId: server.identifier.rawValue)
57+
name = appEntity?.registryTitle ?? appEntity?.name ?? cameraName
58+
}
59+
.statusBarHidden(true)
60+
.modify { view in
61+
if #available(iOS 16.0, *) {
62+
view.persistentSystemOverlays(.hidden)
63+
} else {
64+
view
65+
}
66+
}
67+
}
68+
69+
@ViewBuilder
70+
private var nameBadge: some View {
71+
if let name, controlsVisible {
72+
Text(name)
73+
.font(.headline)
74+
.padding(.horizontal, DesignSystem.Spaces.two)
75+
.padding(.vertical, DesignSystem.Spaces.one)
76+
.modify { view in
77+
if #available(iOS 26.0, *) {
78+
view
79+
.glassEffect(.regular.interactive(), in: .capsule)
80+
} else {
81+
view
82+
.background(.regularMaterial)
83+
.clipShape(.capsule)
84+
}
85+
}
86+
.frame(maxWidth: .infinity, alignment: .leading)
87+
.padding(.leading, DesignSystem.Spaces.two)
88+
.padding(.top, DesignSystem.Spaces.one)
89+
}
90+
}
91+
92+
private var content: some View {
2793
Group {
2894
switch playerType {
2995
case .webRTC:
3096
WebRTCVideoPlayerView(
3197
server: server,
3298
cameraEntityId: cameraEntityId,
3399
cameraName: cameraName,
100+
controlsVisible: $controlsVisible,
34101
onWebRTCUnsupported: {
35102
fallbackToHLS()
36103
}

Sources/App/Cameras/CameraPlayer/CameraStreamHLSView.swift

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,34 +38,6 @@ struct CameraStreamHLSView: View {
3838
.edgesIgnoringSafeArea(.all)
3939
}
4040

41-
// Overlay controls
42-
VStack {
43-
HStack {
44-
if let cameraName {
45-
Text(cameraName)
46-
.font(.headline)
47-
.foregroundStyle(.white)
48-
.padding(.horizontal)
49-
.padding(.vertical, 8)
50-
.background(.ultraThinMaterial)
51-
.clipShape(Capsule())
52-
}
53-
Spacer()
54-
Button {
55-
dismiss()
56-
} label: {
57-
Image(systemSymbol: .xmark)
58-
.font(.body.weight(.semibold))
59-
.foregroundStyle(.white)
60-
.padding(12)
61-
.background(.ultraThinMaterial)
62-
.clipShape(Circle())
63-
}
64-
}
65-
.padding()
66-
Spacer()
67-
}
68-
6941
if isLoading {
7042
ProgressView()
7143
.progressViewStyle(.circular)

0 commit comments

Comments
 (0)