Skip to content

Commit e6bd718

Browse files
authored
Merge pull request #4188 from anyproto/ios-5255-update-object-settings-menu-converted-to-project-2
IOS-5255 Migrate object settings menu to Observation framework
2 parents 5a450f1 + c0a4308 commit e6bd718

File tree

9 files changed

+112
-52
lines changed

9 files changed

+112
-52
lines changed

Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/ObjectActions/ObjectActionsView.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import SwiftUI
22
import AnytypeCore
33

44
struct ObjectActionsView: View {
5-
6-
@StateObject private var viewModel: ObjectActionsViewModel
5+
6+
@State private var viewModel: ObjectActionsViewModel
77
@Environment(\.dismiss) private var dismiss
8-
8+
99
init(objectId: String, spaceId: String, output: (any ObjectActionsOutput)?) {
10-
self._viewModel = StateObject(wrappedValue: ObjectActionsViewModel(objectId: objectId, spaceId: spaceId, output: output))
10+
self._viewModel = State(wrappedValue: ObjectActionsViewModel(objectId: objectId, spaceId: spaceId, output: output))
1111
}
1212

1313
var body: some View {

Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/ObjectActions/ObjectActionsViewModel.swift

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,58 @@
11
import Foundation
2-
import Combine
32
import Services
43
import AnytypeCore
54
import UIKit
65
import DeepLinks
76

87
@MainActor
9-
final class ObjectActionsViewModel: ObservableObject {
8+
@Observable
9+
final class ObjectActionsViewModel {
1010

11+
@ObservationIgnored
1112
private let objectId: String
13+
@ObservationIgnored
1214
private let spaceId: String
15+
@ObservationIgnored
1316
private weak var output: (any ObjectActionsOutput)?
14-
17+
18+
@ObservationIgnored
1519
private lazy var document: any BaseDocumentProtocol = {
1620
openDocumentsProvider.document(objectId: objectId, spaceId: spaceId)
1721
}()
18-
22+
23+
@ObservationIgnored
1924
private lazy var widgetObject: (any BaseDocumentProtocol)? = {
2025
guard let info = workspaceStorage.spaceInfo(spaceId: spaceId) else {
2126
anytypeAssertionFailure("info not found")
2227
return nil
2328
}
2429
return openDocumentsProvider.document(objectId: info.widgetsId, spaceId: spaceId)
2530
}()
26-
27-
@Injected(\.objectActionsService)
31+
32+
@Injected(\.objectActionsService) @ObservationIgnored
2833
private var service: any ObjectActionsServiceProtocol
29-
@Injected(\.blockService)
34+
@Injected(\.blockService) @ObservationIgnored
3035
private var blockService: any BlockServiceProtocol
31-
@Injected(\.templatesService)
36+
@Injected(\.templatesService) @ObservationIgnored
3237
private var templatesService: any TemplatesServiceProtocol
33-
@Injected(\.documentsProvider)
38+
@Injected(\.documentsProvider) @ObservationIgnored
3439
private var documentsProvider: any DocumentsProviderProtocol
35-
@Injected(\.blockWidgetService)
40+
@Injected(\.blockWidgetService) @ObservationIgnored
3641
private var blockWidgetService: any BlockWidgetServiceProtocol
37-
@Injected(\.spaceViewsStorage)
42+
@Injected(\.spaceViewsStorage) @ObservationIgnored
3843
private var workspaceStorage: any SpaceViewsStorageProtocol
39-
@Injected(\.deepLinkParser)
44+
@Injected(\.deepLinkParser) @ObservationIgnored
4045
private var deepLinkParser: any DeepLinkParserProtocol
41-
@Injected(\.universalLinkParser)
46+
@Injected(\.universalLinkParser) @ObservationIgnored
4247
private var universalLinkParser: any UniversalLinkParserProtocol
43-
@Injected(\.openedDocumentProvider)
48+
@Injected(\.openedDocumentProvider) @ObservationIgnored
4449
private var openDocumentsProvider: any OpenedDocumentsProviderProtocol
45-
@Injected(\.workspaceService)
50+
@Injected(\.workspaceService) @ObservationIgnored
4651
private var workspaceService: any WorkspaceServiceProtocol
47-
48-
@Published var objectActions: [ObjectAction] = []
49-
@Published var toastData: ToastBarData?
50-
@Published var dismiss = false
52+
53+
var objectActions: [ObjectAction] = []
54+
var toastData: ToastBarData?
55+
var dismiss = false
5156

5257
init(objectId: String, spaceId: String, output: (any ObjectActionsOutput)?) {
5358
self.objectId = objectId
@@ -110,6 +115,7 @@ final class ObjectActionsViewModel: ObservableObject {
110115
position: first.map { .above(widgetId: $0.id) } ?? .end
111116
)
112117
}
118+
toastData = ToastBarData(pinned ? Loc.unpinned : Loc.pinned)
113119
dismiss.toggle()
114120
}
115121

Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/ObjectSettings/Model/ObjectSetting.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ extension ObjectSetting {
5252
Loc.icon
5353
case .cover:
5454
Loc.cover
55-
case .description:
56-
Loc.description
55+
case .description(let isVisible):
56+
isVisible ? Loc.hideDescription : Loc.showDescription
5757
case .relations:
5858
Loc.fields
5959
case .history:

Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/ObjectSettings/ObjectSettingsView.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import Services
33
import AnytypeCore
44

55
struct ObjectSettingsView: View {
6-
7-
@StateObject private var viewModel: ObjectSettingsViewModel
8-
6+
7+
@State private var viewModel: ObjectSettingsViewModel
8+
99
init(
1010
objectId: String,
1111
spaceId: String,
1212
output: some ObjectSettingsModelOutput
1313
) {
14-
self._viewModel = StateObject(wrappedValue: ObjectSettingsViewModel(objectId: objectId, spaceId: spaceId, output: output))
14+
self._viewModel = State(wrappedValue: ObjectSettingsViewModel(objectId: objectId, spaceId: spaceId, output: output))
1515
}
1616

1717
var body: some View {

Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/ObjectSettings/ObjectSettingsViewModel.swift

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import Foundation
2-
import Combine
32
import Services
43
import UIKit
54
import FloatingPanel
@@ -26,27 +25,32 @@ protocol ObjectSettingsModelOutput: AnyObject, ObjectHeaderRouterProtocol, Objec
2625
}
2726

2827
@MainActor
29-
final class ObjectSettingsViewModel: ObservableObject, ObjectActionsOutput {
28+
@Observable
29+
final class ObjectSettingsViewModel: ObjectActionsOutput {
3030

31-
@Injected(\.openedDocumentProvider)
31+
@Injected(\.openedDocumentProvider) @ObservationIgnored
3232
private var openDocumentsProvider: any OpenedDocumentsProviderProtocol
33-
@Injected(\.propertiesService)
33+
@Injected(\.propertiesService) @ObservationIgnored
3434
private var propertiesService: any PropertiesServiceProtocol
35-
@Injected(\.objectSettingsBuilder)
35+
@Injected(\.objectSettingsBuilder) @ObservationIgnored
3636
private var settingsBuilder: any ObjectSettingsBuilderProtocol
37-
@Injected(\.objectSettingsConflictManager)
37+
@Injected(\.objectSettingsConflictManager) @ObservationIgnored
3838
private var conflictManager: any ObjectSettingsPrimitivesConflictManagerProtocol
39-
39+
40+
@ObservationIgnored
4041
private weak var output: (any ObjectSettingsModelOutput)?
41-
42+
43+
@ObservationIgnored
4244
private lazy var document: any BaseDocumentProtocol = {
4345
openDocumentsProvider.document(objectId: objectId, spaceId: spaceId)
4446
}()
45-
47+
48+
@ObservationIgnored
4649
let objectId: String
50+
@ObservationIgnored
4751
let spaceId: String
48-
@Published var settings: [ObjectSetting] = []
49-
@Published var showConflictAlert = false
52+
var settings: [ObjectSetting] = []
53+
var showConflictAlert = false
5054

5155
init(
5256
objectId: String,

Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/ObjectSettingsMenu/ObjectSettingsMenuView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import AnytypeCore
33

44
struct ObjectSettingsMenuView: View {
55

6-
@StateObject private var viewModel: ObjectSettingsMenuViewModel
6+
@State private var viewModel: ObjectSettingsMenuViewModel
77

88
init(
99
objectId: String,
@@ -12,7 +12,7 @@ struct ObjectSettingsMenuView: View {
1212
) {
1313
let settingsVM = ObjectSettingsViewModel(objectId: objectId, spaceId: spaceId, output: output)
1414
let actionsVM = ObjectActionsViewModel(objectId: objectId, spaceId: spaceId, output: settingsVM)
15-
self._viewModel = StateObject(wrappedValue: ObjectSettingsMenuViewModel(settingsViewModel: settingsVM, actionsViewModel: actionsVM))
15+
self._viewModel = State(wrappedValue: ObjectSettingsMenuViewModel(settingsViewModel: settingsVM, actionsViewModel: actionsVM))
1616
}
1717

1818
var body: some View {

Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/ObjectSettingsMenu/ObjectSettingsMenuViewModel.swift

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import Foundation
2-
import Combine
32
import SwiftUI
43

54
@MainActor
6-
final class ObjectSettingsMenuViewModel: ObservableObject {
5+
@Observable
6+
final class ObjectSettingsMenuViewModel {
77

8-
@Published var menuConfig = ObjectMenuConfiguration(sections: [])
8+
var menuConfig = ObjectMenuConfiguration(sections: [])
99

10+
@ObservationIgnored
1011
let settingsViewModel: ObjectSettingsViewModel
12+
@ObservationIgnored
1113
let actionsViewModel: ObjectActionsViewModel
12-
private var cancellables = Set<AnyCancellable>()
1314

1415
var showConflictAlert: Binding<Bool> {
1516
Binding(
@@ -42,17 +43,30 @@ final class ObjectSettingsMenuViewModel: ObservableObject {
4243
}
4344

4445
private func setupSubscriptions() {
45-
settingsViewModel.$settings
46-
.sink { [weak self] _ in
46+
observeSettings()
47+
observeActions()
48+
}
49+
50+
private func observeSettings() {
51+
withObservationTracking {
52+
_ = settingsViewModel.settings
53+
} onChange: { [weak self] in
54+
Task { @MainActor [weak self] in
4755
self?.rebuildMenu()
56+
self?.observeSettings()
4857
}
49-
.store(in: &cancellables)
58+
}
59+
}
5060

51-
actionsViewModel.$objectActions
52-
.sink { [weak self] _ in
61+
private func observeActions() {
62+
withObservationTracking {
63+
_ = actionsViewModel.objectActions
64+
} onChange: { [weak self] in
65+
Task { @MainActor [weak self] in
5366
self?.rebuildMenu()
67+
self?.observeActions()
5468
}
55-
.store(in: &cancellables)
69+
}
5670
}
5771

5872
private func rebuildMenu() {

Modules/Loc/Sources/Loc/Generated/Strings.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ public enum Loc {
369369
public static let header = Loc.tr("UI", "Header", fallback: "Header")
370370
public static let hidden = Loc.tr("UI", "Hidden", fallback: "Hidden")
371371
public static let hide = Loc.tr("UI", "Hide", fallback: "Hide")
372+
public static let hideDescription = Loc.tr("UI", "Hide Description", fallback: "Hide Description")
372373
public static let hideTypes = Loc.tr("UI", "Hide types", fallback: "Hide types")
373374
public static let highlight = Loc.tr("UI", "Highlight", fallback: "Highlight")
374375
public static let history = Loc.tr("UI", "History", fallback: "History")
@@ -579,6 +580,7 @@ public enum Loc {
579580
public static let settings = Loc.tr("UI", "Settings", fallback: "Settings")
580581
public static let share = Loc.tr("UI", "Share", fallback: "Share")
581582
public static let show = Loc.tr("UI", "Show", fallback: "Show")
583+
public static let showDescription = Loc.tr("UI", "Show Description", fallback: "Show Description")
582584
public static let showTypes = Loc.tr("UI", "Show types", fallback: "Show types")
583585
public static let skip = Loc.tr("UI", "Skip", fallback: "Skip")
584586
public static let sky = Loc.tr("UI", "Sky", fallback: "Sky")
@@ -633,6 +635,7 @@ public enum Loc {
633635
public static let unlocked = Loc.tr("UI", "Unlocked", fallback: "Unlocked")
634636
public static let unmute = Loc.tr("UI", "Unmute", fallback: "Unmute")
635637
public static let unpin = Loc.tr("UI", "Unpin", fallback: "Unpin")
638+
public static let unpinned = Loc.tr("UI", "Unpinned", fallback: "Unpinned")
636639
public static let unpublish = Loc.tr("UI", "Unpublish", fallback: "Unpublish")
637640
public static let unread = Loc.tr("UI", "Unread", fallback: "Unread")
638641
public static let unselectAll = Loc.tr("UI", "Unselect all", fallback: "Unselect all")

Modules/Loc/Sources/Loc/Resources/UI.xcstrings

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44547,6 +44547,17 @@
4454744547
}
4454844548
}
4454944549
},
44550+
"Hide Description" : {
44551+
"extractionState" : "manual",
44552+
"localizations" : {
44553+
"en" : {
44554+
"stringUnit" : {
44555+
"state" : "translated",
44556+
"value" : "Hide Description"
44557+
}
44558+
}
44559+
}
44560+
},
4455044561
"Hide types" : {
4455144562
"extractionState" : "manual",
4455244563
"localizations" : {
@@ -69135,6 +69146,17 @@
6913569146
}
6913669147
}
6913769148
},
69149+
"Unpinned" : {
69150+
"extractionState" : "manual",
69151+
"localizations" : {
69152+
"en" : {
69153+
"stringUnit" : {
69154+
"state" : "translated",
69155+
"value" : "Unpinned"
69156+
}
69157+
}
69158+
}
69159+
},
6913869160
"Preferences" : {
6913969161
"extractionState" : "manual",
6914069162
"localizations" : {
@@ -83950,6 +83972,17 @@
8395083972
}
8395183973
}
8395283974
},
83975+
"Show Description" : {
83976+
"extractionState" : "manual",
83977+
"localizations" : {
83978+
"en" : {
83979+
"stringUnit" : {
83980+
"state" : "translated",
83981+
"value" : "Show Description"
83982+
}
83983+
}
83984+
}
83985+
},
8395383986
"Show types" : {
8395483987
"extractionState" : "manual",
8395583988
"localizations" : {

0 commit comments

Comments
 (0)