Fix button appearance in dark mode. Add the heard text the UI below the buttons. Convert to MacOS Roman character set so words like "resume" appear with the correct accents on the GS.

This commit is contained in:
Jeremy Rand 2022-01-18 22:51:28 -05:00
parent dc3db26243
commit 72a49275a9
7 changed files with 195 additions and 41 deletions

View File

@ -0,0 +1,29 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "205",
"green" : "97",
"red" : "0"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "253",
"green" : "224",
"red" : "188"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "60",
"green" : "60",
"red" : "60"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "0.700",
"blue" : "255",
"green" : "255",
"red" : "255"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "119",
"green" : "119",
"red" : "119"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -7,12 +7,6 @@
import SwiftUI import SwiftUI
extension Color {
static let defaultBlue = Color(red: 0, green: 97 / 255.0, blue: 205 / 255.0)
static let paleBlue = Color(red: 188 / 255.0, green: 224 / 255.0, blue: 253 / 255.0)
static let paleWhite = Color(white: 1, opacity: 179 / 255.0)
}
struct GSButtonStyle : ButtonStyle { struct GSButtonStyle : ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View { func makeBody(configuration: Self.Configuration) -> some View {
GSButtonStyleView(configuration: configuration) GSButtonStyleView(configuration: configuration)
@ -23,6 +17,7 @@ private extension GSButtonStyle {
struct GSButtonStyleView: View { struct GSButtonStyleView: View {
// tracks if the button is enabled or not // tracks if the button is enabled or not
@Environment(\.isEnabled) var isEnabled @Environment(\.isEnabled) var isEnabled
@Environment(\.colorScheme) var colorScheme
// tracks the pressed state // tracks the pressed state
let configuration: GSButtonStyle.Configuration let configuration: GSButtonStyle.Configuration
@ -31,8 +26,8 @@ private extension GSButtonStyle {
.lineLimit(nil) .lineLimit(nil)
.padding() .padding()
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.background(isEnabled ? Color.defaultBlue : Color.paleBlue) .background(isEnabled ? Color("ButtonColor") : Color("InactiveButtonColor"))
.foregroundColor(isEnabled ? .white : .paleWhite) .foregroundColor(isEnabled ? Color("ButtonTextColor") : Color("InactiveButtonTextColor"))
.font(.subheadline) .font(.subheadline)
.clipShape(Capsule()) .clipShape(Capsule())
.opacity(configuration.isPressed ? 0.8 : 1.0) .opacity(configuration.isPressed ? 0.8 : 1.0)
@ -47,30 +42,37 @@ struct GSView: View {
var body: some View { var body: some View {
VStack { VStack {
Button(speechForwarder.connected ? VStack {
"\(Image(systemName: "desktopcomputer.trianglebadge.exclamationmark")) Disconnect from \(ipAddress)" : Button(speechForwarder.connected ?
"\(Image(systemName: "desktopcomputer.and.arrow.down")) Connect to \(ipAddress)") { "\(Image(systemName: "desktopcomputer.trianglebadge.exclamationmark")) Disconnect from \(ipAddress)" :
if (speechForwarder.connected) { "\(Image(systemName: "desktopcomputer.and.arrow.down")) Connect to \(ipAddress)") {
speechForwarder.disconnect() if (speechForwarder.connected) {
} else { speechForwarder.disconnect()
speechForwarder.connect(destination: ipAddress) } else {
speechForwarder.connect(destination: ipAddress)
}
} }
.disabled(false)
.buttonStyle(GSButtonStyle())
Button(speechForwarder.listening ?
"\(Image(systemName: "ear.trianglebadge.exclamationmark")) Stop Listening" :
"\(Image(systemName: "ear.and.waveform")) Listen and Send Text") {
speechForwarder.listen()
}
.disabled(!speechForwarder.connected)
.buttonStyle(GSButtonStyle())
} }
.disabled(false) .fixedSize(horizontal: true, vertical: false)
.buttonStyle(GSButtonStyle()) .navigationBarTitle(ipAddress)
Button(speechForwarder.listening ?
"\(Image(systemName: "ear.trianglebadge.exclamationmark")) Stop Listening" :
"\(Image(systemName: "ear.and.waveform")) Listen and Send Text") {
speechForwarder.listen()
}
.disabled(!speechForwarder.connected)
.buttonStyle(GSButtonStyle())
Spacer()
} }
.fixedSize(horizontal: true, vertical: false)
.navigationBarTitle(ipAddress) Text(speechForwarder.textHeard)
.truncationMode(.head)
.lineLimit(15)
.padding()
Spacer()
} }
init(ipAddress : String) { init(ipAddress : String) {

View File

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0</string> <string>1.0</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>358</string> <string>378</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string> <string>public.app-category.utilities</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>

View File

@ -12,7 +12,7 @@ import Speech
class SpeechForwarder : ObservableObject { class SpeechForwarder : ObservableObject {
@Published var listening = false @Published var listening = false
@Published var connected = false @Published var connected = false
private var textHeard = "" @Published var textHeard = ""
let LISTEN_STATE_MSG = 1 let LISTEN_STATE_MSG = 1
let LISTEN_TEXT_MSG = 2 let LISTEN_TEXT_MSG = 2
@ -20,7 +20,7 @@ class SpeechForwarder : ObservableObject {
let port = 19026 let port = 19026
private var client: TCPClient? private var client: TCPClient?
private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))! private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: Locale.preferredLanguages[0]))!
private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest? private var recognitionRequest: SFSpeechAudioBufferRecognitionRequest?
@ -144,15 +144,24 @@ class SpeechForwarder : ObservableObject {
if (stringToSend.count > 0) { if (stringToSend.count > 0) {
// TODO - Handle strings to send that are longer than 64K (doubt that would happen though) // TODO - Handle strings to send that are longer than 64K (doubt that would happen though)
// TODO - Try to convert encoding from utf8 to something the GS can understand. let nsEnc = CFStringConvertEncodingToNSStringEncoding(CFStringEncoding(CFStringBuiltInEncodings.macRoman.rawValue))
switch (client.send(data: pack("<hh\(stringToSend.count)s", [LISTEN_TEXT_MSG, stringToSend.count, stringToSend]))) { let encoding = String.Encoding(rawValue: nsEnc) // String.Encoding
case .success: if let bytes = stringToSend.data(using: encoding) {
self.textHeard = latestText switch (client.send(data: pack("<hh", [LISTEN_TEXT_MSG, bytes.count]))) {
logger.debug("Sent text \"\(stringToSend)\"") case .success:
break switch (client.send(data: bytes)) {
case .failure(let error): case .success:
self.listening = false self.textHeard = latestText
logger.error("Failed to send text: \(String(describing: error))") logger.debug("Sent text \"\(stringToSend)\"")
break
case .failure(let error):
self.listening = false
logger.error("Failed to send text: \(String(describing: error))")
}
case .failure(let error):
self.listening = false
logger.error("Failed to send text: \(String(describing: error))")
}
} }
} }
} }