ios: some iPad fixes
This commit is contained in:
@@ -5,10 +5,18 @@ import SwiftUI
|
||||
import UniformTypeIdentifiers
|
||||
import UIKit
|
||||
|
||||
enum SybilWorkspaceNavigationLeadingControl {
|
||||
case back
|
||||
case hidden
|
||||
case showSidebar
|
||||
}
|
||||
|
||||
struct SybilWorkspaceView: View {
|
||||
@Bindable var viewModel: SybilViewModel
|
||||
var composerFocusRequest: Int = 0
|
||||
var usesCustomChatNavigation: Bool = false
|
||||
var usesCustomWorkspaceNavigation: Bool = true
|
||||
var navigationLeadingControl: SybilWorkspaceNavigationLeadingControl = .back
|
||||
var onShowSidebar: (() -> Void)? = nil
|
||||
var onRequestNewChat: (() -> Void)? = nil
|
||||
@FocusState private var composerFocused: Bool
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@@ -26,7 +34,7 @@ struct SybilWorkspaceView: View {
|
||||
@State private var newChatSwipeDidTriggerHaptic = false
|
||||
@State private var newChatSwipeFeedbackGenerator: UIImpactFeedbackGenerator?
|
||||
|
||||
private let customChatNavigationContentInset: CGFloat = 96
|
||||
private let customWorkspaceNavigationContentInset: CGFloat = 96
|
||||
|
||||
private var isSettingsSelected: Bool {
|
||||
if case .settings = viewModel.selectedItem {
|
||||
@@ -39,8 +47,8 @@ struct SybilWorkspaceView: View {
|
||||
viewModel.errorMessage != nil
|
||||
}
|
||||
|
||||
private var showsCustomChatNavigation: Bool {
|
||||
usesCustomChatNavigation && !isSettingsSelected && !viewModel.isSearchMode
|
||||
private var showsCustomWorkspaceNavigation: Bool {
|
||||
usesCustomWorkspaceNavigation && !isSettingsSelected
|
||||
}
|
||||
|
||||
private var transcriptScrollContextID: String {
|
||||
@@ -93,12 +101,12 @@ struct SybilWorkspaceView: View {
|
||||
}
|
||||
.offset(x: newChatSwipeCompletionOffset)
|
||||
.background(SybilTheme.background)
|
||||
.navigationTitle(showsCustomChatNavigation ? "" : viewModel.selectedTitle)
|
||||
.navigationTitle(showsCustomWorkspaceNavigation ? "" : viewModel.selectedTitle)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbarRole(.editor)
|
||||
.toolbar(showsCustomChatNavigation ? .hidden : .visible, for: .navigationBar)
|
||||
.toolbar(showsCustomWorkspaceNavigation ? .hidden : .visible, for: .navigationBar)
|
||||
.toolbar {
|
||||
if !isSettingsSelected && !showsCustomChatNavigation {
|
||||
if !isSettingsSelected && !showsCustomWorkspaceNavigation {
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
if viewModel.isSearchMode {
|
||||
searchModeChip
|
||||
@@ -124,10 +132,10 @@ struct SybilWorkspaceView: View {
|
||||
ZStack(alignment: .top) {
|
||||
workspaceContentStack
|
||||
|
||||
if showsCustomChatNavigation {
|
||||
SybilChatCharacterBackdrop(isBusy: viewModel.isSending)
|
||||
if showsCustomWorkspaceNavigation {
|
||||
SybilWorkspaceCharacterBackdrop(isBusy: viewModel.isSending)
|
||||
.allowsHitTesting(false)
|
||||
customChatNavigationBar
|
||||
customWorkspaceNavigationBar
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,7 +157,8 @@ struct SybilWorkspaceView: View {
|
||||
search: viewModel.selectedSearch,
|
||||
isLoading: viewModel.isLoadingSelection,
|
||||
isRunning: viewModel.isSending,
|
||||
isStartingChat: viewModel.isCreatingSearchChat
|
||||
isStartingChat: viewModel.isCreatingSearchChat,
|
||||
topContentInset: showsCustomWorkspaceNavigation ? customWorkspaceNavigationContentInset : 0
|
||||
) {
|
||||
Task {
|
||||
await viewModel.startChatFromSelectedSearch()
|
||||
@@ -160,7 +169,7 @@ struct SybilWorkspaceView: View {
|
||||
messages: viewModel.displayedMessages,
|
||||
isLoading: viewModel.isLoadingSelection,
|
||||
isSending: viewModel.isSending,
|
||||
topContentInset: showsCustomChatNavigation ? customChatNavigationContentInset : 0
|
||||
topContentInset: showsCustomWorkspaceNavigation ? customWorkspaceNavigationContentInset : 0
|
||||
)
|
||||
.id(transcriptScrollContextID)
|
||||
}
|
||||
@@ -193,15 +202,9 @@ struct SybilWorkspaceView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private var customChatNavigationBar: some View {
|
||||
private var customWorkspaceNavigationBar: some View {
|
||||
HStack(spacing: 14) {
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
SybilNavigationIcon(systemImage: "chevron.left")
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.accessibilityLabel("Back")
|
||||
workspaceNavigationLeadingControl
|
||||
|
||||
Text(viewModel.selectedTitle)
|
||||
.font(.sybil(size: 16, weight: .semibold))
|
||||
@@ -211,7 +214,7 @@ struct SybilWorkspaceView: View {
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.multilineTextAlignment(.leading)
|
||||
|
||||
providerModelNavigationMenu
|
||||
workspaceNavigationTrailingControl
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.top, 10)
|
||||
@@ -222,6 +225,32 @@ struct SybilWorkspaceView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var workspaceNavigationLeadingControl: some View {
|
||||
switch navigationLeadingControl {
|
||||
case .back:
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
SybilNavigationIcon(systemImage: "chevron.left")
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.accessibilityLabel("Back")
|
||||
|
||||
case .showSidebar:
|
||||
Button {
|
||||
onShowSidebar?()
|
||||
} label: {
|
||||
SybilNavigationIcon(systemImage: "sidebar.left")
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.accessibilityLabel("Show sidebar")
|
||||
|
||||
case .hidden:
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
|
||||
private func beginNewChatSwipe(containerWidth: CGFloat) {
|
||||
let update = {
|
||||
newChatSwipeContainerWidth = max(containerWidth, 1)
|
||||
@@ -367,6 +396,22 @@ struct SybilWorkspaceView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var workspaceNavigationTrailingControl: some View {
|
||||
if viewModel.isSearchMode {
|
||||
searchModeNavigationLabel
|
||||
} else {
|
||||
providerModelNavigationMenu
|
||||
}
|
||||
}
|
||||
|
||||
private var searchModeNavigationLabel: some View {
|
||||
Label("Search", systemImage: "globe")
|
||||
.font(.sybil(.caption, weight: .medium))
|
||||
.foregroundStyle(SybilTheme.accent)
|
||||
.lineLimit(1)
|
||||
}
|
||||
|
||||
private func providerModelMenu<Label: View>(@ViewBuilder label: @escaping () -> Label) -> some View {
|
||||
Menu {
|
||||
providerModelMenuItems
|
||||
@@ -983,7 +1028,7 @@ private struct SybilNavigationFadeBackground: View {
|
||||
}
|
||||
}
|
||||
|
||||
private struct SybilChatCharacterBackdrop: View {
|
||||
private struct SybilWorkspaceCharacterBackdrop: View {
|
||||
var isBusy: Bool
|
||||
|
||||
var body: some View {
|
||||
|
||||
Reference in New Issue
Block a user