Skip to content

Commit f5308ad

Browse files
committed
Support toast namespace
1 parent 4ebacf8 commit f5308ad

File tree

8 files changed

+89
-34
lines changed

8 files changed

+89
-34
lines changed

Core/Sources/HostApp/AccountSettings/ChatModelManagement/ChatModelEdit.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import AIModel
2+
import Toast
23
import ComposableArchitecture
34
import Dependencies
45
import Keychain
@@ -40,7 +41,12 @@ struct ChatModelEdit: ReducerProtocol {
4041
case baseURLSelection(BaseURLSelection.Action)
4142
}
4243

43-
@Dependency(\.toast) var toast
44+
var toast: (String, ToastType) -> Void {
45+
@Dependency(\.namespacedToast) var toast
46+
return {
47+
toast($0, $1, "ChatModelEdit")
48+
}
49+
}
4450
@Dependency(\.apiKeyKeychain) var keychain
4551

4652
var body: some ReducerProtocol<State, Action> {

Core/Sources/HostApp/AccountSettings/ChatModelManagement/ChatModelEditView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ struct ChatModelEditView: View {
7171
store.send(.appear)
7272
}
7373
.fixedSize(horizontal: false, vertical: true)
74+
.handleToast(namespace: "ChatModelEdit")
7475
}
7576

7677
var nameTextField: some View {

Core/Sources/HostApp/AccountSettings/EmbeddingModelManagement/EmbeddingModelEdit.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import AIModel
2+
import Toast
23
import ComposableArchitecture
34
import Dependencies
45
import Keychain
@@ -39,7 +40,12 @@ struct EmbeddingModelEdit: ReducerProtocol {
3940
case baseURLSelection(BaseURLSelection.Action)
4041
}
4142

42-
@Dependency(\.toast) var toast
43+
var toast: (String, ToastType) -> Void {
44+
@Dependency(\.namespacedToast) var toast
45+
return {
46+
toast($0, $1, "EmbeddingModelEdit")
47+
}
48+
}
4349
@Dependency(\.apiKeyKeychain) var keychain
4450

4551
var body: some ReducerProtocol<State, Action> {

Core/Sources/HostApp/AccountSettings/EmbeddingModelManagement/EmbeddingModelEditView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct EmbeddingModelEditView: View {
6666
store.send(.appear)
6767
}
6868
.fixedSize(horizontal: false, vertical: true)
69+
.handleToast(namespace: "EmbeddingModelEdit")
6970
}
7071

7172
var nameTextField: some View {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import Dependencies
2+
import SwiftUI
3+
import Toast
4+
5+
struct ToastHandler: View {
6+
@ObservedObject var toastController: ToastController
7+
let namespace: String?
8+
9+
init(toastController: ToastController, namespace: String?) {
10+
_toastController = .init(wrappedValue: toastController)
11+
self.namespace = namespace
12+
}
13+
14+
var body: some View {
15+
VStack(spacing: 4) {
16+
ForEach(toastController.messages) { message in
17+
if let n = message.namespace, n != namespace {
18+
EmptyView()
19+
} else {
20+
message.content
21+
.foregroundColor(.white)
22+
.padding(8)
23+
.background({
24+
switch message.type {
25+
case .info: return Color.accentColor
26+
case .error: return Color(nsColor: .systemRed)
27+
case .warning: return Color(nsColor: .systemOrange)
28+
}
29+
}() as Color, in: RoundedRectangle(cornerRadius: 8))
30+
.shadow(color: Color.black.opacity(0.2), radius: 4)
31+
}
32+
}
33+
}
34+
.padding()
35+
.allowsHitTesting(false)
36+
}
37+
}
38+
39+
extension View {
40+
func handleToast(namespace: String? = nil) -> some View {
41+
@Dependency(\.toastController) var toastController
42+
return overlay(alignment: .bottom) {
43+
ToastHandler(toastController: toastController, namespace: namespace)
44+
}.environment(\.toast) { [toastController] content, type in
45+
toastController.toast(content: content, type: type, namespace: namespace)
46+
}
47+
}
48+
}
49+

Core/Sources/HostApp/TabContainer.swift

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -75,33 +75,12 @@ public struct TabContainer: View {
7575
}
7676
.environment(\.tabBarTabTag, tag)
7777
.frame(minHeight: 400)
78-
.overlay(alignment: .bottom) {
79-
VStack(spacing: 4) {
80-
ForEach(toastController.messages) { message in
81-
message.content
82-
.foregroundColor(.white)
83-
.padding(8)
84-
.background({
85-
switch message.type {
86-
case .info: return Color.accentColor
87-
case .error: return Color(nsColor: .systemRed)
88-
case .warning: return Color(nsColor: .systemOrange)
89-
}
90-
}() as Color, in: RoundedRectangle(cornerRadius: 8))
91-
.shadow(color: Color.black.opacity(0.2), radius: 4)
92-
}
93-
}
94-
.padding()
95-
.allowsHitTesting(false)
96-
}
9778
}
9879
.focusable(false)
9980
.padding(.top, 8)
10081
.background(.ultraThinMaterial.opacity(0.01))
10182
.background(Color(nsColor: .controlBackgroundColor).opacity(0.4))
102-
.environment(\.toast) { [toastController] content, type in
103-
toastController.toast(content: content, type: type)
104-
}
83+
.handleToast()
10584
.onPreferenceChange(TabBarItemPreferenceKey.self) { items in
10685
tabBarItems = items
10786
}

Core/Sources/SuggestionWidget/SuggestionWidgetController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public extension SuggestionWidgetController {
7070
}
7171

7272
func presentError(_ errorDescription: String) {
73-
store.send(.toastPanel(.toast(.toast(errorDescription, .error))))
73+
store.send(.toastPanel(.toast(.toast(errorDescription, .error, nil))))
7474
}
7575

7676
func presentChatRoom() {

Tool/Sources/Toast/Toast.swift

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,28 @@ public extension DependencyValues {
3030
set { self[ToastControllerDependencyKey.self] = newValue }
3131
}
3232

33-
var toast: (String, ToastType) -> Void { toastController.toast }
33+
var toast: (String, ToastType) -> Void {
34+
return { content, type in
35+
toastController.toast(content: content, type: type, namespace: nil)
36+
}
37+
}
38+
39+
var namespacedToast: (String, ToastType, String) -> Void {
40+
return {
41+
content, type, namespace in
42+
toastController.toast(content: content, type: type, namespace: namespace)
43+
}
44+
}
3445
}
3546

3647
public class ToastController: ObservableObject {
3748
public struct Message: Identifiable, Equatable {
49+
public var namespace: String?
3850
public var id: UUID
3951
public var type: ToastType
4052
public var content: Text
41-
public init(id: UUID, type: ToastType, content: Text) {
53+
public init(id: UUID, type: ToastType, namespace: String? = nil, content: Text) {
54+
self.namespace = namespace
4255
self.id = id
4356
self.type = type
4457
self.content = content
@@ -51,9 +64,9 @@ public class ToastController: ObservableObject {
5164
self.messages = messages
5265
}
5366

54-
public func toast(content: String, type: ToastType) {
67+
public func toast(content: String, type: ToastType, namespace: String? = nil) {
5568
let id = UUID()
56-
let message = Message(id: id, type: type, content: Text(content))
69+
let message = Message(id: id, type: type, namespace: namespace, content: Text(content))
5770

5871
Task { @MainActor in
5972
withAnimation(.easeInOut(duration: 0.2)) {
@@ -73,7 +86,7 @@ public struct Toast: ReducerProtocol {
7386
public struct State: Equatable {
7487
var isObservingToastController = false
7588
public var messages: [Message] = []
76-
89+
7790
public init(messages: [Message] = []) {
7891
self.messages = messages
7992
}
@@ -82,13 +95,13 @@ public struct Toast: ReducerProtocol {
8295
public enum Action: Equatable {
8396
case start
8497
case updateMessages([Message])
85-
case toast(String, ToastType)
98+
case toast(String, ToastType, String?)
8699
}
87100

88101
@Dependency(\.toastController) var toastController
89102

90103
struct CancelID: Hashable {}
91-
104+
92105
public init() {}
93106

94107
public var body: some ReducerProtocol<State, Action> {
@@ -114,8 +127,8 @@ public struct Toast: ReducerProtocol {
114127
case let .updateMessages(messages):
115128
state.messages = messages
116129
return .none
117-
case let .toast(content, type):
118-
toastController.toast(content: content, type: type)
130+
case let .toast(content, type, namespace):
131+
toastController.toast(content: content, type: type, namespace: namespace)
119132
return .none
120133
}
121134
}

0 commit comments

Comments
 (0)