Skip to content

Commit

Permalink
Adjust mic button to open up space for more chat items
Browse files Browse the repository at this point in the history
  • Loading branch information
bgoncal committed Jun 25, 2024
1 parent 29a4aaf commit e3ae385
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 59 deletions.
3 changes: 2 additions & 1 deletion Sources/App/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"app_intents.widget_action.actions_parameter_configuration" = "Which actions?";
"assist.error.pipelines_response" = "Failed to obtain Assist pipelines, please check your pipelines configuration.";
"assist.pipelines_picker.title" = "Assist Pipelines";
"assist.watch.mic_button.title" = "Tap to ";
"cancel_label" = "Cancel";
"carPlay.action.intro.item.body" = "Tap to continue on your iPhone";
"carPlay.action.intro.item.title" = "Create your first action";
Expand Down Expand Up @@ -854,4 +855,4 @@ Home Assistant is free and open source home automation software with a focus on
"widgets.open_page.description" = "Open a frontend page in Home Assistant.";
"widgets.open_page.not_configured" = "No Pages Available";
"widgets.open_page.title" = "Open Page";
"yes_label" = "Yes";
"yes_label" = "Yes";
10 changes: 6 additions & 4 deletions Sources/Extensions/Watch/Assist/Views/ChatBubbleView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ struct ChatBubbleView: View {

var body: some View {
Text(item.content)
.padding(8)
.padding(.horizontal, 8)
.padding(4)
.padding(.horizontal, 4)
.background(backgroundForChatItemType(item.itemType))
.roundedCorner(10, corners: roundedCornersForChatItemType(item.itemType))
.roundedCorner(6, corners: roundedCornersForChatItemType(item.itemType))
.foregroundColor(.white)
.frame(maxWidth: .infinity, alignment: alignmentForChatItemType(item.itemType))
.listRowBackground(Color.clear)
Expand Down Expand Up @@ -61,11 +61,13 @@ struct ChatBubbleView: View {
}

#Preview {
List {
LazyVStack(spacing: 8) {
ChatBubbleView(item: .init(content: "Hello world", itemType: .input))
.background(.red)
ChatBubbleView(item: .init(content: "Hello world", itemType: .output))
ChatBubbleView(item: .init(content: "Hello world", itemType: .info))
ChatBubbleView(item: .init(content: "Hello world", itemType: .input))
ChatBubbleView(item: .init(content: "Hello world", itemType: .output))
}
.background(.green)
}
104 changes: 50 additions & 54 deletions Sources/Extensions/Watch/Assist/WatchAssistView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@ struct WatchAssistView: View {

var body: some View {
ZStack(alignment: .bottom) {
micButton
chatList
stateView
inlineLoading
}
.animation(.easeInOut, value: viewModel.state)
/* Double tap for watchOS 11
.handGestureShortcut(.primaryAction)
*/
.onTapGesture {
viewModel.assist(assistService)
}
.modify {
if #available(watchOS 10, *) {
$0.toolbar {
Expand All @@ -47,9 +55,7 @@ struct WatchAssistView: View {
// TODO: On watchOS 10 this can be replaced by '.sensoryFeedback' modifier
let currentDevice = WKInterfaceDevice.current()
switch newValue {
case .recording:
currentDevice.play(.start)
case .waitingForPipelineResponse:
case .recording, .waitingForPipelineResponse:
currentDevice.play(.start)
default:
break
Expand Down Expand Up @@ -121,7 +127,7 @@ struct WatchAssistView: View {
Text(String(firstPipelineNameChar))
} else {
// When watchS below 10, this item has more space available
Text(String(firstPipelineName))
Text(firstPipelineName)
}
Image(systemName: "chevron.down")
.font(.system(size: 8))
Expand All @@ -142,31 +148,22 @@ struct WatchAssistView: View {

@ViewBuilder
private var micButton: some View {
if viewModel.state != .loading {
Button {
viewModel.assist(assistService)
} label: {
if viewModel.showChatLoader {
micButtonProgressView
} else {
micImage
}
if ![.loading, .recording].contains(viewModel.state), !viewModel.showChatLoader {
HStack {
Text(L10n.Assist.Watch.MicButton.title)
Image(systemName: "mic.fill")
}
/* Double tap for watchOS 11
.handGestureShortcut(.primaryAction)
*/
.buttonStyle(.plain)
.ignoresSafeArea()
.padding(.horizontal, Spaces.two)
.padding(.top, Spaces.one)
.padding(.bottom, -Spaces.two)
.disabled(viewModel.showChatLoader)
.modify {
if #available(watchOS 10, *) {
$0.background(.thinMaterial)
} else {
$0.background(.black.opacity(0.5))
}
.font(.system(size: 11))
.foregroundStyle(.gray)
.offset(y: 22)
}
}

@ViewBuilder
private var inlineLoading: some View {
if ![.loading, .recording].contains(viewModel.state) {
if viewModel.showChatLoader {
micButtonProgressView
}
}
}
Expand All @@ -178,17 +175,15 @@ struct WatchAssistView: View {
.frame(maxWidth: .infinity, alignment: .center)
.progressViewStyle(.linear)
.frame(height: 40)
}

private var micImage: some View {
Image(uiImage: MaterialDesignIcons.microphoneIcon.image(
ofSize: .init(width: 24, height: 24),
color: .white
))
.frame(maxWidth: .infinity)
.padding()
.background(Color.asset(Asset.Colors.haPrimary))
.clipShape(RoundedRectangle(cornerRadius: 25))
.padding(Spaces.half)
.modify {
if #available(watchOS 10, *) {
$0.background(.regularMaterial)
} else {
$0.background(.black.opacity(0.3))
}
}
.clipShape(Circle())
}

@ViewBuilder
Expand Down Expand Up @@ -226,26 +221,27 @@ struct WatchAssistView: View {

private var chatList: some View {
ScrollViewReader { proxy in
List {
ForEach(viewModel.chatItems, id: \.id) { item in
ChatBubbleView(item: item)
}
if viewModel.chatItems.isEmpty {
emptyState
ScrollView {
// Using LazyVStack instead of List to avoid List minimum row height
LazyVStack(spacing: Spaces.one) {
ForEach(viewModel.chatItems, id: \.id) { item in
ChatBubbleView(item: item)
}
if viewModel.chatItems.isEmpty {
emptyState
}
}
}
.frame(maxHeight: .infinity)
.animation(.easeInOut, value: viewModel.chatItems)
.onChange(of: viewModel.chatItems) { _ in
if let lastItem = viewModel.chatItems.last {
proxy.scrollTo(lastItem.id, anchor: .bottom)
.frame(maxHeight: .infinity)
.padding(.horizontal)
.animation(.easeInOut, value: viewModel.chatItems)
.onChange(of: viewModel.chatItems) { _ in
if let lastItem = viewModel.chatItems.last {
proxy.scrollTo(lastItem.id, anchor: .bottom)
}
}
}
}
.frame(maxHeight: .infinity)
.safeAreaInset(edge: .bottom) {
micButton
}
}

private var emptyState: some View {
Expand Down
6 changes: 6 additions & 0 deletions Sources/Shared/Resources/Swiftgen/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ public enum L10n {
/// Assist Pipelines
public static var title: String { return L10n.tr("Localizable", "assist.pipelines_picker.title") }
}
public enum Watch {
public enum MicButton {
/// Tap to
public static var title: String { return L10n.tr("Localizable", "assist.watch.mic_button.title") }
}
}
}

public enum CarPlay {
Expand Down

0 comments on commit e3ae385

Please sign in to comment.