Preserve Assistant navigation state
This commit is contained in:
1 parent
5641a28841
commit
e36f470917
8 files changed
+61
-17
No files matched your search
@@ -418,7 +418,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
LM_SKIP_METADATA_EXTRACTION = YES;
|
||||
MARKETING_VERSION = 0.1.1;
|
||||
MARKETING_VERSION = 0.1.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
@@ -449,7 +449,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
LM_SKIP_METADATA_EXTRACTION = YES;
|
||||
MARKETING_VERSION = 0.1.1;
|
||||
MARKETING_VERSION = 0.1.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.akinokaede.termind;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
|
||||
@@ -39,7 +39,7 @@ struct TermindCommands: Commands {
|
||||
app.connect(in: window)
|
||||
}
|
||||
.keyboardShortcut("t")
|
||||
Button("New Chat") { window?.openAssistant() }
|
||||
Button("New Chat") { window?.openNewAssistantChat() }
|
||||
.keyboardShortcut("t", modifiers: [.command, .option])
|
||||
|
||||
Divider()
|
||||
|
||||
@@ -59,7 +59,7 @@ final class AppCommandRegistry {
|
||||
guard let host = app.hostLibrary.host(id) else { return }
|
||||
app.open(host, as: target, in: window)
|
||||
case .newChat:
|
||||
window.openAssistant()
|
||||
window.openNewAssistantChat()
|
||||
case .newHost:
|
||||
window.openHostEditor(host: nil)
|
||||
case .showAssistant:
|
||||
|
||||
@@ -11,7 +11,7 @@ struct AssistantSidebarView: View {
|
||||
Divider()
|
||||
HStack(spacing: Metrics.Space.s) {
|
||||
Button {
|
||||
window.openAssistant()
|
||||
window.openNewAssistantChat()
|
||||
} label: {
|
||||
Label("New Chat", systemImage: "plus.bubble")
|
||||
.frame(
|
||||
@@ -532,7 +532,7 @@ struct AssistantView: View {
|
||||
} else if let conversation = window.assistantLibrary.selectedConversation {
|
||||
ConversationView(
|
||||
conversation: conversation,
|
||||
onNewChat: { window.selectAssistant() }
|
||||
onNewChat: { window.openNewAssistantChat() }
|
||||
)
|
||||
.background(.background)
|
||||
} else {
|
||||
|
||||
@@ -368,7 +368,7 @@ struct TabBarView: View {
|
||||
// Same order as the File menu, so the two lists of the same four
|
||||
// verbs cannot be read as two different lists.
|
||||
Button("Connect") { app.connect(in: window) }
|
||||
Button("New Chat") { window.openAssistant() }
|
||||
Button("New Chat") { window.openNewAssistantChat() }
|
||||
Button("New Host") { window.openHostEditor(host: nil) }
|
||||
|
||||
let recents = app.hostLibrary.recents(limit: 5)
|
||||
|
||||
@@ -765,7 +765,7 @@ struct WelcomeView: View {
|
||||
HStack(spacing: Metrics.Space.l) {
|
||||
Button("Connect") { app.connect(in: window) }
|
||||
Button("Batch Startup") { app.batchStartup(in: window) }
|
||||
Button("New Chat") { window.openAssistant() }
|
||||
Button("New Chat") { window.openNewAssistantChat() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -393,13 +393,15 @@ final class WindowModel {
|
||||
selectedTopLevelTab = .vault
|
||||
}
|
||||
|
||||
func selectAssistant(_ id: ConversationModel.ID? = nil) {
|
||||
/// Enters the Assistant without changing its in-memory navigation state:
|
||||
/// the current conversation, New Chat, and Archive are all left untouched.
|
||||
func selectAssistant() {
|
||||
selectedTopLevelTab = .assistant
|
||||
}
|
||||
|
||||
func selectAssistant(_ id: ConversationModel.ID) {
|
||||
isAssistantArchivePresented = false
|
||||
if let id {
|
||||
assistantLibrary.select(id)
|
||||
} else {
|
||||
assistantLibrary.selectNewConversation()
|
||||
}
|
||||
assistantLibrary.select(id)
|
||||
selectedTopLevelTab = .assistant
|
||||
}
|
||||
|
||||
@@ -652,7 +654,7 @@ final class WindowModel {
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func openAssistant() -> ConversationModel {
|
||||
func openNewAssistantChat() -> ConversationModel {
|
||||
isAssistantArchivePresented = false
|
||||
let conversation = assistantLibrary.selectNewConversation()
|
||||
selectedTopLevelTab = .assistant
|
||||
|
||||
@@ -202,7 +202,49 @@ struct WindowStateTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
func assistantDefaultsToNewChatEvenWhenHistoryExists() {
|
||||
func enteringAssistantKeepsTheVolatileConversationSelection() {
|
||||
let conversation = ConversationModel()
|
||||
let library = AssistantLibraryModel(store: AssistantConversationStore(
|
||||
conversations: [conversation]
|
||||
))
|
||||
let window = WindowModel(assistantLibrary: library)
|
||||
|
||||
window.selectAssistant(conversation.id)
|
||||
window.selectVault()
|
||||
window.selectAssistant()
|
||||
|
||||
#expect(window.selectedTopLevelTab == .assistant)
|
||||
#expect(window.assistantLibrary.selectedConversation === conversation)
|
||||
|
||||
let draft = window.openNewAssistantChat()
|
||||
#expect(window.assistantLibrary.selectedConversation == nil)
|
||||
#expect(draft === window.assistantLibrary.draftConversation)
|
||||
|
||||
window.selectVault()
|
||||
window.selectAssistant()
|
||||
#expect(window.assistantLibrary.selectedConversation == nil)
|
||||
#expect(draft === window.assistantLibrary.draftConversation)
|
||||
}
|
||||
|
||||
@Test
|
||||
func enteringAssistantKeepsTheVolatileArchiveDestination() {
|
||||
let conversation = ConversationModel()
|
||||
let library = AssistantLibraryModel(store: AssistantConversationStore(
|
||||
conversations: [conversation]
|
||||
))
|
||||
let window = WindowModel(assistantLibrary: library)
|
||||
|
||||
window.selectAssistant(conversation.id)
|
||||
window.showAssistantArchive()
|
||||
window.selectVault()
|
||||
window.selectAssistant()
|
||||
|
||||
#expect(window.isAssistantArchivePresented)
|
||||
#expect(window.assistantLibrary.selectedConversation === conversation)
|
||||
}
|
||||
|
||||
@Test
|
||||
func assistantStartsOnNewChatWhenNoVolatileSelectionExists() {
|
||||
let previousID = UUID()
|
||||
let library = AssistantLibraryModel()
|
||||
library.restore([
|
||||
@@ -225,7 +267,7 @@ struct WindowStateTests {
|
||||
@Test
|
||||
func newChatJoinsHistoryOnlyAfterItsFirstSend() {
|
||||
let window = WindowModel()
|
||||
let draft = window.openAssistant()
|
||||
let draft = window.openNewAssistantChat()
|
||||
|
||||
#expect(window.assistantLibrary.selectedConversation == nil)
|
||||
#expect(window.assistantLibrary.conversations.isEmpty)
|
||||
|
||||
Reference in new issue
Block a user