Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@types/node": "^26.2.0",
"@types/react": "^19.2.18",
"@types/react-dom": "^19.2.4",
"oxlint": "^1.78.0",
"oxlint": "1.80.0",
"postcss": "^8.5.26",
"tailwindcss": "^4.3.3",
"typescript": "^6.0.3"
Expand Down
25 changes: 20 additions & 5 deletions ios/App/ChatListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ struct ChatListView: View {
ForEach(searchHits) { hit in
Button {
Task {
if let chat = await session.open(hit) { path.append(chat) }
if let chat = await session.open(hit) {
Haptics.selection()
path.append(chat)
}
}
} label: {
SearchHitRow(hit: hit)
Expand Down Expand Up @@ -154,10 +157,14 @@ struct ChatListView: View {
return
}
searching = true
defer {
if query == expected { searching = false }
}
try? await Task.sleep(for: .milliseconds(250))
guard !Task.isCancelled, query == expected else { return }
searchHits = await session.search(expected)
searching = false
let hits = await session.search(expected)
guard !Task.isCancelled, query == expected else { return }
searchHits = hits
}
}
}
Expand Down Expand Up @@ -228,6 +235,7 @@ struct ChatListView: View {
.buttonStyle(.plain)
}
Button {
Haptics.selection()
showingNewGroup = true
} label: {
GroupTile(room: nil)
Expand Down Expand Up @@ -280,18 +288,25 @@ struct ChatListView: View {
.frame(height: 52)
.glassCapsule()
} else {
UpdatesPill(updates: session.state.updates) { showingUpdates = true }
UpdatesPill(updates: session.state.updates) {
Haptics.selection()
showingUpdates = true
}
.frame(height: 52)

GlassButton(systemImage: "magnifyingglass", size: 48, weight: .semibold) {
Haptics.selection()
searchOpen = true
searchFocused = true
}
.accessibilityLabel("Search")

GlassButton(systemImage: "square.and.pencil", size: 48, weight: .medium) {
Task {
if let bot = await session.createBot() { path.append(Chat.bot(bot)) }
if let bot = await session.createBot() {
Haptics.success()
path.append(Chat.bot(bot))
}
}
}
.accessibilityLabel("New bot")
Expand Down
8 changes: 7 additions & 1 deletion ios/App/ChatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,7 @@ struct MessageRow: View {
HStack(spacing: 6) {
ForEach(reactionGroups(reactions), id: \.emoji) { group in
Button("\(group.emoji) \(group.count)") {
Haptics.selection()
Task { await session.react(to: message, in: chat.threadId, emoji: group.emoji) }
}
.font(.system(size: 13))
Expand Down Expand Up @@ -784,7 +785,10 @@ struct MessageRow: View {
}
.contextMenu {
ForEach(Self.reactionChoices, id: \.self) { emoji in
Button(emoji) { Task { await session.react(to: message, in: chat.threadId, emoji: emoji) } }
Button(emoji) {
Haptics.selection()
Task { await session.react(to: message, in: chat.threadId, emoji: emoji) }
}
}
if message.role == .user, message.kind == .text, case let .bot(bot) = chat {
Divider()
Expand Down Expand Up @@ -1063,6 +1067,7 @@ struct CardView: View {
HStack(spacing: 8) {
ForEach(card.options, id: \.self) { option in
Button {
Haptics.selection()
answering = true
Task {
await session.answer(chat: chat, card: card, choice: option)
Expand Down Expand Up @@ -1091,6 +1096,7 @@ struct CardView: View {
// never a string invented here.
if card.allowKey != nil, let allow = allowChoice, case let .bot(bot) = chat {
Button("Always allow this tool") {
Haptics.selection()
answering = true
Task {
await session.alwaysAllow(bot: bot, card: card)
Expand Down
1 change: 1 addition & 0 deletions ios/App/Island.swift
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ struct NeedsYouIsland: View {
HStack(spacing: 8) {
ForEach(card.options, id: \.self) { option in
Button {
Haptics.selection()
answering = true
Task {
await session.answer(chat: shown.chat, card: card, choice: option)
Expand Down
2 changes: 2 additions & 0 deletions ios/App/NewGroupSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ struct NewGroupSheet: View {
ForEach(bots) { bot in
Button {
if members.contains(bot.id) { members.remove(bot.id) } else { members.insert(bot.id) }
Haptics.selection()
} label: {
HStack(spacing: 12) {
BotAvatarView(bot: bot, size: 36, state: .idle, animated: false)
Expand Down Expand Up @@ -59,6 +60,7 @@ struct NewGroupSheet: View {
// it defaults) follows the first bot you picked
let ordered = bots.map(\.id).filter(members.contains)
if let room = await session.createRoom(name: name, memberIds: ordered) {
Haptics.success()
created(room)
}
creating = false
Expand Down
1 change: 1 addition & 0 deletions ios/App/UpdatesSheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ private struct UpdateRow: View {
HStack(spacing: 8) {
ForEach(card.options, id: \.self) { option in
Button {
Haptics.selection()
answering = true
Task {
await session.answer(chat: update.chat, card: card, choice: option)
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"zod": "4.4.3"
},
"devDependencies": {
"@oxlint/plugins": "1.78.0",
"@oxlint/plugins": "1.80.0",
"@tailwindcss/vite": "^4.1.11",
"@types/node": "^26.2.0",
"@types/react": "^19.1.9",
Expand All @@ -101,7 +101,7 @@
"electron-builder": "^26.15.3",
"electron-updater": "^6.8.9",
"esbuild": "^0.28.2",
"oxlint": "1.78.0",
"oxlint": "1.80.0",
"tailwindcss": "^4.1.11",
"typebox": "1.3.7",
"typescript": "^5.8.3",
Expand Down
Loading
Loading