Create Wristivo iPhone and Apple Watch foundation
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import RemoteCore
|
||||
|
||||
extension RemoteCommand {
|
||||
var title: String {
|
||||
switch self {
|
||||
case .up: "Up"
|
||||
case .down: "Down"
|
||||
case .left: "Left"
|
||||
case .right: "Right"
|
||||
case .select: "Select"
|
||||
case .back: "Back"
|
||||
case .home: "Home"
|
||||
case .playPause: "Play / pause"
|
||||
case .volumeUp: "Volume up"
|
||||
case .volumeDown: "Volume down"
|
||||
case .mute: "Mute"
|
||||
}
|
||||
}
|
||||
|
||||
var symbol: String {
|
||||
switch self {
|
||||
case .up: "chevron.up"
|
||||
case .down: "chevron.down"
|
||||
case .left: "chevron.left"
|
||||
case .right: "chevron.right"
|
||||
case .select: "checkmark"
|
||||
case .back: "arrow.uturn.backward"
|
||||
case .home: "house"
|
||||
case .playPause: "playpause"
|
||||
case .volumeUp: "speaker.plus"
|
||||
case .volumeDown: "speaker.minus"
|
||||
case .mute: "speaker.slash"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import SwiftUI
|
||||
import RemoteCore
|
||||
|
||||
struct WatchRemoteDemoView: View {
|
||||
@State private var lastCommand = "No TV connected"
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(spacing: 8) {
|
||||
Text("Wristivo").font(.headline)
|
||||
Text("DEMO").font(.caption2).foregroundStyle(.secondary)
|
||||
commandButton(.up)
|
||||
HStack(spacing: 4) {
|
||||
commandButton(.left)
|
||||
commandButton(.select)
|
||||
commandButton(.right)
|
||||
}
|
||||
commandButton(.down)
|
||||
Text(lastCommand).font(.caption2)
|
||||
HStack(spacing: 4) {
|
||||
commandButton(.back)
|
||||
commandButton(.home)
|
||||
}
|
||||
Text("Wrist gestures are coming in the hardware prototype.")
|
||||
.font(.footnote).foregroundStyle(.secondary)
|
||||
}.padding(.horizontal, 4)
|
||||
}.tint(.teal)
|
||||
}
|
||||
|
||||
private func commandButton(_ command: RemoteCommand) -> some View {
|
||||
Button { lastCommand = "Demo: \(command.title)" } label: {
|
||||
Image(systemName: command.symbol).frame(minWidth: 24, minHeight: 30)
|
||||
}
|
||||
.buttonStyle(.bordered)
|
||||
.accessibilityLabel(command.title)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct WristivoWatchApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup { WatchRemoteDemoView() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import SwiftUI
|
||||
import RemoteCore
|
||||
|
||||
/// Foundation UI: intentionally never opens a TV connection.
|
||||
struct RemoteDemoView: View {
|
||||
@State private var lastCommand = "Try a button below"
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
ScrollView {
|
||||
VStack(spacing: 24) {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Label("Demo mode", systemImage: "play.rectangle")
|
||||
.font(.headline)
|
||||
Text("Explore your remote. No television is connected.")
|
||||
Text("Pairing and wrist movement recognition are still in development.")
|
||||
.font(.footnote).foregroundStyle(.secondary)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding().background(.thinMaterial, in: RoundedRectangle(cornerRadius: 20))
|
||||
|
||||
VStack(spacing: 12) {
|
||||
commandButton(.up)
|
||||
HStack(spacing: 16) {
|
||||
commandButton(.left)
|
||||
commandButton(.select)
|
||||
commandButton(.right)
|
||||
}
|
||||
commandButton(.down)
|
||||
}
|
||||
Text(lastCommand).font(.callout).accessibilityIdentifier("demo.lastCommand")
|
||||
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 12) {
|
||||
ForEach([RemoteCommand.back, .home, .volumeDown, .volumeUp, .mute, .playPause], id: \.rawValue) { command in
|
||||
Button { record(command) } label: {
|
||||
Label(command.title, systemImage: command.symbol)
|
||||
.frame(maxWidth: .infinity, minHeight: 44)
|
||||
}.buttonStyle(.bordered)
|
||||
}
|
||||
}
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Made for a lighter touch").font(.headline)
|
||||
Text("The planned watch remote translates deliberate wrist movements into directional presses. Your iPhone will relay commands to a paired TV on your home network.")
|
||||
Text("Gesture control will require an active watch session and a reachable iPhone.")
|
||||
.foregroundStyle(.secondary)
|
||||
}.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
.padding().frame(maxWidth: 560)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
.navigationTitle("Wristivo")
|
||||
.tint(.teal)
|
||||
}
|
||||
}
|
||||
|
||||
private func commandButton(_ command: RemoteCommand) -> some View {
|
||||
Button { record(command) } label: {
|
||||
Image(systemName: command.symbol)
|
||||
.font(.title2).frame(width: 64, height: 56)
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.accessibilityLabel(command.title)
|
||||
}
|
||||
|
||||
private func record(_ command: RemoteCommand) {
|
||||
lastCommand = "Demo: \(command.title)"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct WristivoApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup { RemoteDemoView() }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user