mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 18:25:21 +00:00
Prevent Bluetooth alerts from competing with sheets
This commit is contained in:
@@ -6,6 +6,18 @@ import UIKit
|
|||||||
import AppKit
|
import AppKit
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ContentPeopleSheetModalPresentationState {
|
||||||
|
var isImagePreviewPresented = false
|
||||||
|
var isVerificationSheetPresented = false
|
||||||
|
var isMediaPickerPresented = false
|
||||||
|
|
||||||
|
var hasPresentation: Bool {
|
||||||
|
isImagePreviewPresented
|
||||||
|
|| isVerificationSheetPresented
|
||||||
|
|| isMediaPickerPresented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ContentPeopleSheetView: View {
|
struct ContentPeopleSheetView: View {
|
||||||
@EnvironmentObject private var appChromeModel: AppChromeModel
|
@EnvironmentObject private var appChromeModel: AppChromeModel
|
||||||
@EnvironmentObject private var privateConversationModel: PrivateConversationModel
|
@EnvironmentObject private var privateConversationModel: PrivateConversationModel
|
||||||
@@ -24,6 +36,7 @@ struct ContentPeopleSheetView: View {
|
|||||||
var isTextFieldFocused: FocusState<Bool>.Binding
|
var isTextFieldFocused: FocusState<Bool>.Binding
|
||||||
@ObservedObject var voiceRecordingVM: VoiceRecordingViewModel
|
@ObservedObject var voiceRecordingVM: VoiceRecordingViewModel
|
||||||
@Binding var autocompleteDebounceTimer: Timer?
|
@Binding var autocompleteDebounceTimer: Timer?
|
||||||
|
@State private var showVerifySheet = false
|
||||||
@ThemedPalette private var palette
|
@ThemedPalette private var palette
|
||||||
|
|
||||||
let headerHeight: CGFloat
|
let headerHeight: CGFloat
|
||||||
@@ -37,14 +50,17 @@ struct ContentPeopleSheetView: View {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private var hasModalPresentation: Bool {
|
private var hasModalPresentation: Bool {
|
||||||
if imagePreviewURL != nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
return showImagePicker
|
let isMediaPickerPresented = showImagePicker
|
||||||
#else
|
#else
|
||||||
return showMacImagePicker
|
let isMediaPickerPresented = showMacImagePicker
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return ContentPeopleSheetModalPresentationState(
|
||||||
|
isImagePreviewPresented: imagePreviewURL != nil,
|
||||||
|
isVerificationSheetPresented: showVerifySheet,
|
||||||
|
isMediaPickerPresented: isMediaPickerPresented
|
||||||
|
).hasPresentation
|
||||||
}
|
}
|
||||||
|
|
||||||
private var bluetoothAlertBinding: Binding<Bool> {
|
private var bluetoothAlertBinding: Binding<Bool> {
|
||||||
@@ -108,7 +124,8 @@ struct ContentPeopleSheetView: View {
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ContentPeopleListView(
|
ContentPeopleListView(
|
||||||
showSidebar: $showSidebar
|
showSidebar: $showSidebar,
|
||||||
|
showVerifySheet: $showVerifySheet
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,8 +254,7 @@ private struct ContentPeopleListView: View {
|
|||||||
@ThemedPalette private var palette
|
@ThemedPalette private var palette
|
||||||
|
|
||||||
@Binding var showSidebar: Bool
|
@Binding var showSidebar: Bool
|
||||||
|
@Binding var showVerifySheet: Bool
|
||||||
@State private var showVerifySheet = false
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
|
|||||||
@@ -14,6 +14,30 @@ import AppKit
|
|||||||
#endif
|
#endif
|
||||||
import BitFoundation
|
import BitFoundation
|
||||||
|
|
||||||
|
struct ContentRootModalPresentationState {
|
||||||
|
var isPeopleSheetPresented = false
|
||||||
|
var isAppInfoPresented = false
|
||||||
|
var isFingerprintPresented = false
|
||||||
|
var isLocationChannelsSheetPresented = false
|
||||||
|
var isNoticesSheetPresented = false
|
||||||
|
var isImagePreviewPresented = false
|
||||||
|
var isVerificationSheetPresented = false
|
||||||
|
var isVoiceAlertPresented = false
|
||||||
|
var isMediaPickerPresented = false
|
||||||
|
|
||||||
|
var hasPresentation: Bool {
|
||||||
|
isPeopleSheetPresented
|
||||||
|
|| isAppInfoPresented
|
||||||
|
|| isFingerprintPresented
|
||||||
|
|| isLocationChannelsSheetPresented
|
||||||
|
|| isNoticesSheetPresented
|
||||||
|
|| isImagePreviewPresented
|
||||||
|
|| isVerificationSheetPresented
|
||||||
|
|| isVoiceAlertPresented
|
||||||
|
|| isMediaPickerPresented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// On macOS 14+, disables the default system focus ring on TextFields.
|
/// On macOS 14+, disables the default system focus ring on TextFields.
|
||||||
/// On earlier macOS versions and on iOS this is a no-op.
|
/// On earlier macOS versions and on iOS this is a no-op.
|
||||||
struct FocusEffectDisabledModifier: ViewModifier {
|
struct FocusEffectDisabledModifier: ViewModifier {
|
||||||
@@ -77,19 +101,23 @@ struct ContentView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var hasRootModalPresentation: Bool {
|
private var hasRootModalPresentation: Bool {
|
||||||
if isPeopleSheetPresented
|
|
||||||
|| appChromeModel.isAppInfoPresented
|
|
||||||
|| appChromeModel.showingFingerprintFor != nil
|
|
||||||
|| imagePreviewURL != nil
|
|
||||||
|| showVerifySheet
|
|
||||||
|| voiceRecordingVM.showAlert {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
return showImagePicker
|
let isMediaPickerPresented = showImagePicker
|
||||||
#else
|
#else
|
||||||
return showMacImagePicker
|
let isMediaPickerPresented = showMacImagePicker
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return ContentRootModalPresentationState(
|
||||||
|
isPeopleSheetPresented: isPeopleSheetPresented,
|
||||||
|
isAppInfoPresented: appChromeModel.isAppInfoPresented,
|
||||||
|
isFingerprintPresented: appChromeModel.showingFingerprintFor != nil,
|
||||||
|
isLocationChannelsSheetPresented: appChromeModel.isLocationChannelsSheetPresented,
|
||||||
|
isNoticesSheetPresented: appChromeModel.isNoticesSheetPresented,
|
||||||
|
isImagePreviewPresented: imagePreviewURL != nil,
|
||||||
|
isVerificationSheetPresented: showVerifySheet,
|
||||||
|
isVoiceAlertPresented: voiceRecordingVM.showAlert,
|
||||||
|
isMediaPickerPresented: isMediaPickerPresented
|
||||||
|
).hasPresentation
|
||||||
}
|
}
|
||||||
|
|
||||||
private var rootBluetoothAlertBinding: Binding<Bool> {
|
private var rootBluetoothAlertBinding: Binding<Bool> {
|
||||||
|
|||||||
@@ -551,6 +551,31 @@ struct ViewSmokeTests {
|
|||||||
#expect(featureModels.privateConversationModel.selectedHeaderState?.headerPeerID == peerID)
|
#expect(featureModels.privateConversationModel.selectedHeaderState?.headerPeerID == peerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test("Root Bluetooth alert waits for location and notices sheets")
|
||||||
|
func rootBluetoothAlertGuard_includesHeaderSheets() {
|
||||||
|
#expect(!ContentRootModalPresentationState().hasPresentation)
|
||||||
|
#expect(
|
||||||
|
ContentRootModalPresentationState(
|
||||||
|
isLocationChannelsSheetPresented: true
|
||||||
|
).hasPresentation
|
||||||
|
)
|
||||||
|
#expect(
|
||||||
|
ContentRootModalPresentationState(
|
||||||
|
isNoticesSheetPresented: true
|
||||||
|
).hasPresentation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test("People-sheet Bluetooth alert waits for local verification sheet")
|
||||||
|
func peopleSheetBluetoothAlertGuard_includesVerificationSheet() {
|
||||||
|
#expect(!ContentPeopleSheetModalPresentationState().hasPresentation)
|
||||||
|
#expect(
|
||||||
|
ContentPeopleSheetModalPresentationState(
|
||||||
|
isVerificationSheetPresented: true
|
||||||
|
).hasPresentation
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
func geohashAndTextMessageViews_renderCoreBranches() {
|
func geohashAndTextMessageViews_renderCoreBranches() {
|
||||||
let (viewModel, _, _) = makeSmokeViewModel()
|
let (viewModel, _, _) = makeSmokeViewModel()
|
||||||
|
|||||||
Reference in New Issue
Block a user