|
@@ -4,7 +4,7 @@ struct ChatInputCard: View {
|
|
|
@ObservedObject var viewModel: HomeViewModel
|
|
@ObservedObject var viewModel: HomeViewModel
|
|
|
|
|
|
|
|
private let inputSectionHeight: CGFloat = AppTheme.chatInputHeight - AppTheme.chatInputToolbarHeight
|
|
private let inputSectionHeight: CGFloat = AppTheme.chatInputHeight - AppTheme.chatInputToolbarHeight
|
|
|
- private let actionButtonSize: CGFloat = 30
|
|
|
|
|
|
|
+ private let actionButtonSize: CGFloat = 32
|
|
|
|
|
|
|
|
var body: some View {
|
|
var body: some View {
|
|
|
VStack(spacing: 0) {
|
|
VStack(spacing: 0) {
|
|
@@ -16,7 +16,7 @@ struct ChatInputCard: View {
|
|
|
.padding(.horizontal, 16)
|
|
.padding(.horizontal, 16)
|
|
|
.frame(height: inputSectionHeight)
|
|
.frame(height: inputSectionHeight)
|
|
|
|
|
|
|
|
- HStack(spacing: 6) {
|
|
|
|
|
|
|
+ HStack(spacing: 8) {
|
|
|
Button(action: {}) {
|
|
Button(action: {}) {
|
|
|
Image(systemName: "plus")
|
|
Image(systemName: "plus")
|
|
|
.font(.system(size: 17, weight: .regular))
|
|
.font(.system(size: 17, weight: .regular))
|
|
@@ -28,13 +28,14 @@ struct ChatInputCard: View {
|
|
|
|
|
|
|
|
Spacer(minLength: 0)
|
|
Spacer(minLength: 0)
|
|
|
|
|
|
|
|
- modelMenu
|
|
|
|
|
|
|
+ ModelSelectorMenu(viewModel: viewModel)
|
|
|
|
|
|
|
|
voiceButton
|
|
voiceButton
|
|
|
|
|
|
|
|
sendButton
|
|
sendButton
|
|
|
}
|
|
}
|
|
|
.padding(.horizontal, 12)
|
|
.padding(.horizontal, 12)
|
|
|
|
|
+ .padding(.bottom, 8)
|
|
|
.frame(height: AppTheme.chatInputToolbarHeight)
|
|
.frame(height: AppTheme.chatInputToolbarHeight)
|
|
|
}
|
|
}
|
|
|
.frame(maxWidth: .infinity)
|
|
.frame(maxWidth: .infinity)
|
|
@@ -50,40 +51,20 @@ struct ChatInputCard: View {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private var modelMenu: some View {
|
|
|
|
|
- Menu {
|
|
|
|
|
- ForEach(viewModel.availableModels, id: \.self) { model in
|
|
|
|
|
- Button(model) {
|
|
|
|
|
- viewModel.selectedModel = model
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- } label: {
|
|
|
|
|
- HStack(spacing: 4) {
|
|
|
|
|
- Text(viewModel.selectedModel)
|
|
|
|
|
- .font(.system(size: 13, weight: .medium))
|
|
|
|
|
- .foregroundStyle(AppTheme.textPrimary)
|
|
|
|
|
- Image(systemName: "chevron.down")
|
|
|
|
|
- .font(.system(size: 9, weight: .semibold))
|
|
|
|
|
- .foregroundStyle(AppTheme.textSecondary)
|
|
|
|
|
- }
|
|
|
|
|
- .padding(.horizontal, 10)
|
|
|
|
|
- .padding(.vertical, 6)
|
|
|
|
|
- .background(
|
|
|
|
|
- RoundedRectangle(cornerRadius: 8, style: .continuous)
|
|
|
|
|
- .fill(Color.white)
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- .menuStyle(.borderlessButton)
|
|
|
|
|
- .fixedSize()
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
private var voiceButton: some View {
|
|
private var voiceButton: some View {
|
|
|
Button(action: {}) {
|
|
Button(action: {}) {
|
|
|
Image(systemName: "waveform")
|
|
Image(systemName: "waveform")
|
|
|
- .font(.system(size: 12, weight: .medium))
|
|
|
|
|
- .foregroundStyle(AppTheme.textSecondary)
|
|
|
|
|
|
|
+ .font(.system(size: 13, weight: .medium))
|
|
|
|
|
+ .foregroundStyle(AppTheme.textPrimary.opacity(0.72))
|
|
|
.frame(width: actionButtonSize, height: actionButtonSize)
|
|
.frame(width: actionButtonSize, height: actionButtonSize)
|
|
|
- .background(Circle().fill(Color.white))
|
|
|
|
|
|
|
+ .background(
|
|
|
|
|
+ Circle()
|
|
|
|
|
+ .fill(Color.white)
|
|
|
|
|
+ )
|
|
|
|
|
+ .overlay(
|
|
|
|
|
+ Circle()
|
|
|
|
|
+ .stroke(AppTheme.chatActionButtonBorder, lineWidth: 1)
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|
|
|
.buttonStyle(.plain)
|
|
.buttonStyle(.plain)
|
|
|
.accessibilityLabel("Voice input")
|
|
.accessibilityLabel("Voice input")
|
|
@@ -92,10 +73,13 @@ struct ChatInputCard: View {
|
|
|
private var sendButton: some View {
|
|
private var sendButton: some View {
|
|
|
Button(action: {}) {
|
|
Button(action: {}) {
|
|
|
Image(systemName: "arrow.up")
|
|
Image(systemName: "arrow.up")
|
|
|
- .font(.system(size: 15, weight: .bold))
|
|
|
|
|
|
|
+ .font(.system(size: 14, weight: .bold))
|
|
|
.foregroundStyle(.white)
|
|
.foregroundStyle(.white)
|
|
|
.frame(width: actionButtonSize, height: actionButtonSize)
|
|
.frame(width: actionButtonSize, height: actionButtonSize)
|
|
|
- .background(Circle().fill(AppTheme.accent))
|
|
|
|
|
|
|
+ .background(
|
|
|
|
|
+ Circle()
|
|
|
|
|
+ .fill(AppTheme.chatSendButtonBackground)
|
|
|
|
|
+ )
|
|
|
}
|
|
}
|
|
|
.buttonStyle(.plain)
|
|
.buttonStyle(.plain)
|
|
|
.accessibilityLabel("Send message")
|
|
.accessibilityLabel("Send message")
|