From 355247a29ca41d42ea163675c09f5bfcf8528004 Mon Sep 17 00:00:00 2001 From: Anna Zakharova Date: Mon, 5 Aug 2024 16:51:30 +0100 Subject: [PATCH 1/2] IOS-3264 Impl readonly mode for version history --- .../Sources/Models/Documents/Document/BaseDocument.swift | 3 ++- .../Sources/Models/Documents/Document/DocumentMode.swift | 8 ++++++++ .../Models/ObjectPermissions/ObjectPermissions.swift | 8 +++++--- .../Relations/FlowRelationsView/FlowRelationsView.swift | 1 + .../FlowRelationsView/FlowRelationsViewModel.swift | 3 +++ .../SwiftUI/TitleWIthIconView/TitleWithIconView.swift | 7 ++++++- .../SetObjectWidgetInternalViewModel.swift | 3 ++- .../TextEditor/Set/EditorSetViewModel.swift | 3 ++- .../Set/Models/Builders/SetPermissionsBuilder.swift | 8 ++++++-- .../TextEditor/Set/Models/SetPermissions.swift | 3 +++ .../Set/Views/Collection/Cell/SetGalleryViewCell.swift | 3 ++- .../Set/Views/Collection/Cell/SetListViewCell.swift | 3 ++- .../TextEditor/Set/Views/Header/SetFullHeader.swift | 4 +++- .../Set/Views/Models/SetContentViewDataBuilder.swift | 5 ++++- .../Views/Table/Row/SetContentViewItemConfiguration.swift | 3 +++ .../TextEditor/Set/Views/Table/Row/SetTableViewRow.swift | 1 + 16 files changed, 53 insertions(+), 13 deletions(-) diff --git a/Anytype/Sources/Models/Documents/Document/BaseDocument.swift b/Anytype/Sources/Models/Documents/Document/BaseDocument.swift index 847fda4403..c3cfcc2397 100644 --- a/Anytype/Sources/Models/Documents/Document/BaseDocument.swift +++ b/Anytype/Sources/Models/Documents/Document/BaseDocument.swift @@ -304,7 +304,8 @@ final class BaseDocument: BaseDocumentProtocol { let newPermissios = ObjectPermissions( details: details ?? ObjectDetails(id: ""), isLocked: isLocked, - participantCanEdit: participantIsEditor, + participantCanEdit: participantIsEditor, + isVersionMode: mode.isVersion, objectRestrictions: objectRestrictions.objectRestriction ) diff --git a/Anytype/Sources/Models/Documents/Document/DocumentMode.swift b/Anytype/Sources/Models/Documents/Document/DocumentMode.swift index 2b1b94dcbe..1b9bfabc1b 100644 --- a/Anytype/Sources/Models/Documents/Document/DocumentMode.swift +++ b/Anytype/Sources/Models/Documents/Document/DocumentMode.swift @@ -6,4 +6,12 @@ enum DocumentMode: Hashable, Codable { var isHandling: Bool { self == .handling } + + var isVersion: Bool { + if case .version = self { + return true + } else { + return false + } + } } diff --git a/Anytype/Sources/Models/ObjectPermissions/ObjectPermissions.swift b/Anytype/Sources/Models/ObjectPermissions/ObjectPermissions.swift index 06ba26d385..4ba2306902 100644 --- a/Anytype/Sources/Models/ObjectPermissions/ObjectPermissions.swift +++ b/Anytype/Sources/Models/ObjectPermissions/ObjectPermissions.swift @@ -30,12 +30,13 @@ extension ObjectPermissions { details: ObjectDetails, isLocked: Bool, participantCanEdit: Bool, + isVersionMode: Bool, objectRestrictions: [ObjectRestriction] ) { let isArchive = details.isArchived let isTemplateType = details.isTemplateType - let canEdit = !isLocked && !isArchive && participantCanEdit + let canEdit = !isLocked && !isArchive && participantCanEdit && !isVersionMode let canApplyUneditableActions = participantCanEdit && !isArchive let specificTypes = details.layoutValue != .set @@ -70,7 +71,7 @@ extension ObjectPermissions { self.canShare = !isTemplateType self.canApplyTemplates = canEdit && !isTemplateType - if isLocked { + if isLocked || isVersionMode { self.editBlocks = .readonly(.locked) } else if isArchive { self.editBlocks = .readonly(.archived) @@ -99,7 +100,8 @@ extension ObjectDetails { ObjectPermissions( details: self, isLocked: false, - participantCanEdit: participantCanEdit, + participantCanEdit: participantCanEdit, + isVersionMode: false, objectRestrictions: restrictionsValue ) } diff --git a/Anytype/Sources/PresentationLayer/Common/SwiftUI/Relations/FlowRelationsView/FlowRelationsView.swift b/Anytype/Sources/PresentationLayer/Common/SwiftUI/Relations/FlowRelationsView/FlowRelationsView.swift index 58330c9e69..54f78260c1 100644 --- a/Anytype/Sources/PresentationLayer/Common/SwiftUI/Relations/FlowRelationsView/FlowRelationsView.swift +++ b/Anytype/Sources/PresentationLayer/Common/SwiftUI/Relations/FlowRelationsView/FlowRelationsView.swift @@ -16,6 +16,7 @@ struct FlowRelationsView: View { TitleWithIconView( icon: viewModel.icon, showIcon: viewModel.showIcon, + canEditIcon: viewModel.canEditIcon, title: viewModel.title, style: .list ) diff --git a/Anytype/Sources/PresentationLayer/Common/SwiftUI/Relations/FlowRelationsView/FlowRelationsViewModel.swift b/Anytype/Sources/PresentationLayer/Common/SwiftUI/Relations/FlowRelationsView/FlowRelationsViewModel.swift index 25ecaaf8b7..e4c7de6029 100644 --- a/Anytype/Sources/PresentationLayer/Common/SwiftUI/Relations/FlowRelationsView/FlowRelationsViewModel.swift +++ b/Anytype/Sources/PresentationLayer/Common/SwiftUI/Relations/FlowRelationsView/FlowRelationsViewModel.swift @@ -3,6 +3,7 @@ import SwiftUI class FlowRelationsViewModel: ObservableObject { let icon: Icon? let showIcon: Bool + let canEditIcon: Bool let title: String? let description: String? let relations: [Relation] @@ -10,12 +11,14 @@ class FlowRelationsViewModel: ObservableObject { init( icon: Icon? = nil, showIcon: Bool = true, + canEditIcon: Bool, title: String?, description: String?, relations: [Relation] ) { self.icon = icon self.showIcon = showIcon + self.canEditIcon = canEditIcon self.title = title self.description = description self.relations = relations diff --git a/Anytype/Sources/PresentationLayer/Common/SwiftUI/TitleWIthIconView/TitleWithIconView.swift b/Anytype/Sources/PresentationLayer/Common/SwiftUI/TitleWIthIconView/TitleWithIconView.swift index 8aa53e5764..fa3b27d379 100644 --- a/Anytype/Sources/PresentationLayer/Common/SwiftUI/TitleWIthIconView/TitleWithIconView.swift +++ b/Anytype/Sources/PresentationLayer/Common/SwiftUI/TitleWIthIconView/TitleWithIconView.swift @@ -4,6 +4,7 @@ import AnytypeCore struct TitleWithIconView: View { let icon: Icon? let showIcon: Bool + let canEditIcon: Bool let title: String? let style: TitleWithIconStyle @@ -22,6 +23,7 @@ struct TitleWithIconView: View { height: style.iconSize.height ) .padding(.top, 1) + .disabled(!canEditIcon) } } else { title(with: title) @@ -47,7 +49,8 @@ struct TitleWithIconView_Previews: PreviewProvider { static var previews: some View { TitleWithIconView( icon: .object(.emoji(Emoji("📘")!)), - showIcon: true, + showIcon: true, + canEditIcon: true, title: "Let's see how this TitleWithIconView looks like with image - header style", style: .header ) @@ -56,6 +59,7 @@ struct TitleWithIconView_Previews: PreviewProvider { TitleWithIconView( icon: .object(.emoji(Emoji("📘")!)), showIcon: true, + canEditIcon: true, title: "Let's see how this TitleWithIconView looks like with image - list style", style: .list ) @@ -64,6 +68,7 @@ struct TitleWithIconView_Previews: PreviewProvider { TitleWithIconView( icon: .object(.emoji(Emoji("📘")!)), showIcon: true, + canEditIcon: true, title: "Let's see how this TitleWithIconView looks like with image - gallery style", style: .gallery ) diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpecificInternalModels/SetObjectWidgetInternalViewModel.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpecificInternalModels/SetObjectWidgetInternalViewModel.swift index f9f7387d09..3c92e14a6a 100644 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpecificInternalModels/SetObjectWidgetInternalViewModel.swift +++ b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpecificInternalModels/SetObjectWidgetInternalViewModel.swift @@ -250,7 +250,8 @@ final class SetObjectWidgetInternalViewModel: ObservableObject { details, dataView: setDocument.dataView, activeView: setDocument.activeView, - viewRelationValueIsLocked: false, + viewRelationValueIsLocked: false, + canEditIcon: setDocument.setPermissions.canEditSetObjectIcon, storage: subscriptionStorage.detailsStorage, spaceId: setDocument.spaceId, onItemTap: { [weak self] in diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/EditorSetViewModel.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/EditorSetViewModel.swift index cba95c5769..8e47f9ca00 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/EditorSetViewModel.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/EditorSetViewModel.swift @@ -502,7 +502,8 @@ final class EditorSetViewModel: ObservableObject { records, dataView: setDocument.dataView, activeView: activeView, - viewRelationValueIsLocked: !setDocument.setPermissions.canEditRelationValuesInView, + viewRelationValueIsLocked: !setDocument.setPermissions.canEditRelationValuesInView, + canEditIcon: setDocument.setPermissions.canEditSetObjectIcon, storage: subscription.detailsStorage, spaceId: setDocument.spaceId, onItemTap: { [weak self] details in diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Models/Builders/SetPermissionsBuilder.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Models/Builders/SetPermissionsBuilder.swift index d5924d8aca..2eb66400f9 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Models/Builders/SetPermissionsBuilder.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Models/Builders/SetPermissionsBuilder.swift @@ -10,16 +10,20 @@ final class SetPermissionsBuilder: SetPermissionsBuilderProtocol { func build(setDocument: SetDocument, participantCanEdit: Bool) -> SetPermissions { + let isVersionMode = setDocument.mode.isVersion let isArchive = setDocument.details?.isArchived ?? true let isLocked = setDocument.document.isLocked - let canEdit = !isLocked && !isArchive && participantCanEdit + let canEdit = !isLocked && !isArchive && participantCanEdit && !isVersionMode return SetPermissions( canCreateObject: canEdit && canCreateObject(setDocument: setDocument, participantCanEdit: participantCanEdit), canEditView: canEdit, canTurnSetIntoCollection: canEdit && !setDocument.isCollection(), canChangeQuery: canEdit && !setDocument.isCollection(), - canEditRelationValuesInView: canEdit && canEditRelationValuesInView(setDocument: setDocument) + canEditRelationValuesInView: canEdit && canEditRelationValuesInView(setDocument: setDocument), + canEditTitle: canEdit, + canEditDescription: canEdit, + canEditSetObjectIcon: canEdit ) } diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Models/SetPermissions.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Models/SetPermissions.swift index a2fc5ee418..afbd691fde 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Models/SetPermissions.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Models/SetPermissions.swift @@ -8,4 +8,7 @@ struct SetPermissions { var canTurnSetIntoCollection: Bool = false var canChangeQuery: Bool = false var canEditRelationValuesInView: Bool = false + var canEditTitle: Bool = false + var canEditDescription: Bool = false + var canEditSetObjectIcon: Bool = false } diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Collection/Cell/SetGalleryViewCell.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Collection/Cell/SetGalleryViewCell.swift index e871c888d1..771b6ab462 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Collection/Cell/SetGalleryViewCell.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Collection/Cell/SetGalleryViewCell.swift @@ -19,7 +19,8 @@ struct SetGalleryViewCell: View { VStack(alignment: .leading, spacing: 0) { TitleWithIconView( icon: configuration.icon, - showIcon: configuration.showIcon, + showIcon: configuration.showIcon, + canEditIcon: configuration.canEditIcon, title: configuration.title, style: .gallery ) diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Collection/Cell/SetListViewCell.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Collection/Cell/SetListViewCell.swift index 44f988ba7e..081f11d295 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Collection/Cell/SetListViewCell.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Collection/Cell/SetListViewCell.swift @@ -17,7 +17,8 @@ struct SetListViewCell: View { FlowRelationsView( viewModel: FlowRelationsViewModel( icon: configuration.icon, - showIcon: configuration.showIcon, + showIcon: configuration.showIcon, + canEditIcon: configuration.canEditIcon, title: configuration.title, description: configuration.description, relations: configuration.relations.filter { diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Header/SetFullHeader.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Header/SetFullHeader.swift index e772dab2dd..bec07a37ba 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Header/SetFullHeader.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Header/SetFullHeader.swift @@ -77,7 +77,8 @@ extension SetFullHeader { text: $model.descriptionString ) .padding([.trailing], 20) - .foregroundStyle(Color.Text.primary) + .foregroundStyle(Color.Text.primary) + .disabled(!model.setDocument.setPermissions.canEditDescription) } else { EmptyView() } @@ -117,6 +118,7 @@ extension SetFullHeader { .padding([.trailing], 20) .foregroundStyle(Color.Text.primary) .disableAutocorrection(true) + .disabled(!model.setDocument.setPermissions.canEditTitle) } private var featuredRelationsView: some View { diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Models/SetContentViewDataBuilder.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Models/SetContentViewDataBuilder.swift index 821baa8ce4..8bb35dc9e4 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Models/SetContentViewDataBuilder.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Models/SetContentViewDataBuilder.swift @@ -16,6 +16,7 @@ protocol SetContentViewDataBuilderProtocol: AnyObject { dataView: BlockDataview, activeView: DataviewView, viewRelationValueIsLocked: Bool, + canEditIcon: Bool, storage: ObjectDetailsStorage, spaceId: String, onItemTap: @escaping @MainActor (ObjectDetails) -> Void @@ -80,6 +81,7 @@ final class SetContentViewDataBuilder: SetContentViewDataBuilderProtocol { dataView: BlockDataview, activeView: DataviewView, viewRelationValueIsLocked: Bool, + canEditIcon: Bool, storage: ObjectDetailsStorage, spaceId: String, onItemTap: @escaping @MainActor (ObjectDetails) -> Void @@ -108,7 +110,8 @@ final class SetContentViewDataBuilder: SetContentViewDataBuilderProtocol { id: item.details.id, title: item.details.title, description: item.details.description, - icon: item.details.objectIconImage, + icon: item.details.objectIconImage, + canEditIcon: canEditIcon, relations: item.relations, showIcon: !activeView.hideIcon, isSmallCardSize: activeView.isSmallCardSize, diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Table/Row/SetContentViewItemConfiguration.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Table/Row/SetContentViewItemConfiguration.swift index 461b11f9bf..d3462b8f58 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Table/Row/SetContentViewItemConfiguration.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Table/Row/SetContentViewItemConfiguration.swift @@ -7,6 +7,7 @@ struct SetContentViewItemConfiguration: Identifiable, Hashable { let title: String let description: String? let icon: Icon? + let canEditIcon: Bool let relations: [Relation] let showIcon: Bool let isSmallCardSize: Bool @@ -21,6 +22,7 @@ struct SetContentViewItemConfiguration: Identifiable, Hashable { title: String, description: String?, icon: Icon?, + canEditIcon: Bool, relations: [Relation], showIcon: Bool, isSmallCardSize: Bool, @@ -34,6 +36,7 @@ struct SetContentViewItemConfiguration: Identifiable, Hashable { self.title = title self.description = description self.icon = icon + self.canEditIcon = canEditIcon self.relations = relations self.showIcon = showIcon self.isSmallCardSize = isSmallCardSize diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Table/Row/SetTableViewRow.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Table/Row/SetTableViewRow.swift index e95849f459..91cd76a029 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Table/Row/SetTableViewRow.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Table/Row/SetTableViewRow.swift @@ -33,6 +33,7 @@ struct SetTableViewRow: View { if let icon = configuration.icon, configuration.showIcon { IconView(icon: icon).frame(width: 18, height: 18) .padding(.trailing, 8) + .disabled(!model.setDocument.setPermissions.canEditSetObjectIcon) } } } From 5decc529dc07d0c4a428c1d7c5048bfc025acc9a Mon Sep 17 00:00:00 2001 From: Anna Zakharova Date: Mon, 5 Aug 2024 19:03:09 +0100 Subject: [PATCH 2/2] IOS-3267 Impl verison restoration --- Anytype.xcodeproj/project.pbxproj | 4 ++ .../ObjectSettingsCoordinatorView.swift | 2 +- .../ObjectSettingsCoordinatorViewModel.swift | 15 ++++-- .../VersionHistoryCoordinatorView.swift | 6 +-- .../VersionHistoryCoordinatorViewModel.swift | 22 ++++++--- .../History/Object/ObjectVersionData.swift | 12 +++++ .../History/Object/ObjectVersionView.swift | 46 +++++++++++++++---- .../Object/ObjectVersionViewModel.swift | 33 +++++++++---- .../History/VersionHistoryViewModel.swift | 5 ++ .../TextEditor/Set/EditorSetView.swift | 1 + .../Set/Views/Header/SetFullHeader.swift | 1 + 11 files changed, 114 insertions(+), 33 deletions(-) create mode 100644 Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionData.swift diff --git a/Anytype.xcodeproj/project.pbxproj b/Anytype.xcodeproj/project.pbxproj index 845f463ced..056ac13c99 100644 --- a/Anytype.xcodeproj/project.pbxproj +++ b/Anytype.xcodeproj/project.pbxproj @@ -1057,6 +1057,7 @@ 2E88257A2C5A61A200FD59D3 /* ObjectVersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E8825792C5A61A200FD59D3 /* ObjectVersionView.swift */; }; 2E88257C2C5A61AC00FD59D3 /* ObjectVersionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E88257B2C5A61AC00FD59D3 /* ObjectVersionViewModel.swift */; }; 2E88257E2C5BDF0D00FD59D3 /* DocumentMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E88257D2C5BDF0D00FD59D3 /* DocumentMode.swift */; }; + 2E8825802C6140BB00FD59D3 /* ObjectVersionData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E88257F2C6140BB00FD59D3 /* ObjectVersionData.swift */; }; 2E92219D294B8B5000968750 /* DataViewBlockViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E92219C294B8B5000968750 /* DataViewBlockViewModel.swift */; }; 2E92219F294B8CDE00968750 /* DataViewBlockConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E92219E294B8CDE00968750 /* DataViewBlockConfiguration.swift */; }; 2E9221A1294B8D4900968750 /* DataViewBlockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E9221A0294B8D4900968750 /* DataViewBlockView.swift */; }; @@ -2918,6 +2919,7 @@ 2E8825792C5A61A200FD59D3 /* ObjectVersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectVersionView.swift; sourceTree = ""; }; 2E88257B2C5A61AC00FD59D3 /* ObjectVersionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectVersionViewModel.swift; sourceTree = ""; }; 2E88257D2C5BDF0D00FD59D3 /* DocumentMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentMode.swift; sourceTree = ""; }; + 2E88257F2C6140BB00FD59D3 /* ObjectVersionData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectVersionData.swift; sourceTree = ""; }; 2E92219C294B8B5000968750 /* DataViewBlockViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataViewBlockViewModel.swift; sourceTree = ""; }; 2E92219E294B8CDE00968750 /* DataViewBlockConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataViewBlockConfiguration.swift; sourceTree = ""; }; 2E9221A0294B8D4900968750 /* DataViewBlockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataViewBlockView.swift; sourceTree = ""; }; @@ -7922,6 +7924,7 @@ children = ( 2E8825792C5A61A200FD59D3 /* ObjectVersionView.swift */, 2E88257B2C5A61AC00FD59D3 /* ObjectVersionViewModel.swift */, + 2E88257F2C6140BB00FD59D3 /* ObjectVersionData.swift */, ); path = Object; sourceTree = ""; @@ -11732,6 +11735,7 @@ 2AB7AAED2AF537AB00ED3E02 /* RemoteStorageSegmentInfo.swift in Sources */, 2AF109562A02639700EDDE26 /* FileIconBuilder.swift in Sources */, 2AF109582A03C56600EDDE26 /* NSItemProvider+Async.swift in Sources */, + 2E8825802C6140BB00FD59D3 /* ObjectVersionData.swift in Sources */, 2AD7E2E52BB1768600F2CDA1 /* IdentifiableExtension.swift in Sources */, 123FDAD026C1505700F6F44B /* EditorPageController+UICollectionViewDelegate.swift in Sources */, 3D5A417A2704541900F1F6A1 /* SearchBar.swift in Sources */, diff --git a/Anytype/Sources/PresentationLayer/Flows/ObjectSettingsFlow/ObjectSettingsCoordinatorView.swift b/Anytype/Sources/PresentationLayer/Flows/ObjectSettingsFlow/ObjectSettingsCoordinatorView.swift index 13f9396cb3..b379241b68 100644 --- a/Anytype/Sources/PresentationLayer/Flows/ObjectSettingsFlow/ObjectSettingsCoordinatorView.swift +++ b/Anytype/Sources/PresentationLayer/Flows/ObjectSettingsFlow/ObjectSettingsCoordinatorView.swift @@ -28,7 +28,7 @@ struct ObjectSettingsCoordinatorView: View { RelationsListCoordinatorView(document: $0.document, output: model) } .sheet(item: $model.versionHistoryData) { - VersionHistoryCoordinatorView(data: $0) + VersionHistoryCoordinatorView(data: $0, output: model) } .onChange(of: model.dismiss) { _ in dismiss() diff --git a/Anytype/Sources/PresentationLayer/Flows/ObjectSettingsFlow/ObjectSettingsCoordinatorViewModel.swift b/Anytype/Sources/PresentationLayer/Flows/ObjectSettingsFlow/ObjectSettingsCoordinatorViewModel.swift index 33810e5772..adf97a17eb 100644 --- a/Anytype/Sources/PresentationLayer/Flows/ObjectSettingsFlow/ObjectSettingsCoordinatorViewModel.swift +++ b/Anytype/Sources/PresentationLayer/Flows/ObjectSettingsFlow/ObjectSettingsCoordinatorViewModel.swift @@ -4,9 +4,12 @@ import AnytypeCore import SwiftUI @MainActor -final class ObjectSettingsCoordinatorViewModel: ObservableObject, - ObjectSettingsModelOutput, - RelationValueCoordinatorOutput { +final class ObjectSettingsCoordinatorViewModel: + ObservableObject, + ObjectSettingsModelOutput, + RelationValueCoordinatorOutput, + ObjectVersionModuleOutput +{ let objectId: String private weak var output: (any ObjectSettingsCoordinatorOutput)? @@ -96,4 +99,10 @@ final class ObjectSettingsCoordinatorViewModel: ObservableObject, output?.showEditorScreen(data: data) } } + + // MARK: - ObjectVersionModuleOutput + + func versionRestored() { + dismiss.toggle() + } } diff --git a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Coordinator/VersionHistoryCoordinatorView.swift b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Coordinator/VersionHistoryCoordinatorView.swift index b87a3cee3e..d9a3d5029c 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Coordinator/VersionHistoryCoordinatorView.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Coordinator/VersionHistoryCoordinatorView.swift @@ -6,8 +6,8 @@ struct VersionHistoryCoordinatorView: View { @StateObject private var model: VersionHistoryCoordinatorViewModel @Environment(\.dismiss) private var dismiss - init(data: VersionHistoryData) { - _model = StateObject(wrappedValue: VersionHistoryCoordinatorViewModel(data: data)) + init(data: VersionHistoryData, output: (any ObjectVersionModuleOutput)?) { + _model = StateObject(wrappedValue: VersionHistoryCoordinatorViewModel(data: data, output: output)) } var body: some View { @@ -16,7 +16,7 @@ struct VersionHistoryCoordinatorView: View { output: model ) .sheet(item: $model.objectVersionData) { - ObjectVersionView(data: $0) + ObjectVersionView(data: $0, output: model) } } } diff --git a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Coordinator/VersionHistoryCoordinatorViewModel.swift b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Coordinator/VersionHistoryCoordinatorViewModel.swift index 43ab31d345..c381a75f87 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Coordinator/VersionHistoryCoordinatorViewModel.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Coordinator/VersionHistoryCoordinatorViewModel.swift @@ -2,19 +2,21 @@ import Services import SwiftUI @MainActor -protocol VersionHistoryModuleOutput: AnyObject { - func onVersionTap(title: String, icon: ObjectIcon?, versionId: String) -} - -@MainActor -final class VersionHistoryCoordinatorViewModel: ObservableObject, VersionHistoryModuleOutput { +final class VersionHistoryCoordinatorViewModel: + ObservableObject, + VersionHistoryModuleOutput, + ObjectVersionModuleOutput +{ @Published var objectVersionData: ObjectVersionData? let data: VersionHistoryData - init(data: VersionHistoryData) { + private weak var output: (any ObjectVersionModuleOutput)? + + init(data: VersionHistoryData, output: (any ObjectVersionModuleOutput)?) { self.data = data + self.output = output } // MARK: VersionHistoryModuleOutput @@ -29,5 +31,11 @@ final class VersionHistoryCoordinatorViewModel: ObservableObject, VersionHistory isListType: data.isListType ) } + + // MARK: ObjectVersionModuleOutput + + func versionRestored() { + output?.versionRestored() + } } diff --git a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionData.swift b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionData.swift new file mode 100644 index 0000000000..831c43a4da --- /dev/null +++ b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionData.swift @@ -0,0 +1,12 @@ +import Services + +struct ObjectVersionData: Identifiable, Hashable { + let title: String + let icon: ObjectIcon? + let objectId: String + let spaceId: String + let versionId: String + let isListType: Bool + + var id: Int { hashValue } +} diff --git a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionView.swift b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionView.swift index f9c278d27a..e7216ee31a 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionView.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionView.swift @@ -4,19 +4,26 @@ import SwiftUI struct ObjectVersionView: View { @StateObject private var model: ObjectVersionViewModel + @Environment(\.dismiss) private var dismiss - init(data: ObjectVersionData) { - _model = StateObject(wrappedValue: ObjectVersionViewModel(data: data)) + init(data: ObjectVersionData, output: (any ObjectVersionModuleOutput)?) { + _model = StateObject(wrappedValue: ObjectVersionViewModel(data: data, output: output)) } var body: some View { - content - .overlay(alignment: .topLeading) { - header - } - .task { - await model.setupObject() - } + VStack(spacing: 0) { + content + buttons + } + .overlay(alignment: .topLeading) { + header + } + .task { + await model.setupObject() + } + .onChange(of: model.dismiss) { _ in + dismiss() + } } private var header: some View { @@ -41,4 +48,25 @@ struct ObjectVersionView: View { EmptyView() } } + + private var buttons: some View { + HStack { + StandardButton( + Loc.cancel, + style: .secondaryMedium, + action: { model.onCancelTap() } + ) + StandardButton( + Loc.restore, + style: .primaryMedium, + action: { model.onRestoreTap() } + ) + } + .padding(.top, 16) + .padding(.horizontal, 20) + .overlay(alignment: .top) { + AnytypeDivider() + } + .background(Color.Background.primary) + } } diff --git a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionViewModel.swift b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionViewModel.swift index c2b22d58b9..e773814a1f 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionViewModel.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/Object/ObjectVersionViewModel.swift @@ -1,31 +1,44 @@ import Services import SwiftUI -struct ObjectVersionData: Identifiable, Hashable { - let title: String - let icon: ObjectIcon? - let objectId: String - let spaceId: String - let versionId: String - let isListType: Bool - - var id: Int { hashValue } +@MainActor +protocol ObjectVersionModuleOutput: AnyObject { + func versionRestored() } @MainActor final class ObjectVersionViewModel: ObservableObject { @Published var screenData: EditorScreenData? + @Published var dismiss = false + let data: ObjectVersionData - init(data: ObjectVersionData) { + @Injected(\.historyVersionsService) + private var historyVersionsService: any HistoryVersionsServiceProtocol + + private weak var output: (any ObjectVersionModuleOutput)? + + init(data: ObjectVersionData, output: (any ObjectVersionModuleOutput)?) { self.data = data + self.output = output } func setupObject() async { self.screenData = currentScreenData() } + func onCancelTap() { + dismiss.toggle() + } + + func onRestoreTap() { + Task { + try await historyVersionsService.setVersion(objectId: data.objectId, versionId: data.versionId) + output?.versionRestored() + } + } + private func currentScreenData() -> EditorScreenData? { let mode: DocumentMode = .version(data.versionId) if data.isListType { diff --git a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/VersionHistoryViewModel.swift b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/VersionHistoryViewModel.swift index 087a7d03d1..0118960fb8 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/VersionHistoryViewModel.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/EditorPage/Views/Settings/History/VersionHistoryViewModel.swift @@ -1,6 +1,11 @@ import Services import SwiftUI +@MainActor +protocol VersionHistoryModuleOutput: AnyObject { + func onVersionTap(title: String, icon: ObjectIcon?, versionId: String) +} + @MainActor final class VersionHistoryViewModel: ObservableObject { diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/EditorSetView.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/EditorSetView.swift index c91ae0a156..06bf721e8c 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/EditorSetView.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/EditorSetView.swift @@ -71,6 +71,7 @@ struct EditorSetView: View { VStack(spacing: 0) { Spacer.fixedHeight(headerMinimizedSize.height) contentTypeView + .background(Color.Background.primary) } } } diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Header/SetFullHeader.swift b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Header/SetFullHeader.swift index bec07a37ba..07ab8bedc4 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Header/SetFullHeader.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Set/Views/Header/SetFullHeader.swift @@ -13,6 +13,7 @@ struct SetFullHeader: View { header } } + .background(Color.Background.primary) } private var header: some View {