diff --git a/Anytype/Sources/Analytics/AnalyticsConstants.swift b/Anytype/Sources/Analytics/AnalyticsConstants.swift index 7339ba9a91..513ff7974a 100644 --- a/Anytype/Sources/Analytics/AnalyticsConstants.swift +++ b/Anytype/Sources/Analytics/AnalyticsConstants.swift @@ -102,7 +102,6 @@ enum AnalyticsEventsMigrationType: String { } enum AnalyticsWidgetSource { - case allObjects case pinned case recent case recentOpen @@ -112,8 +111,6 @@ enum AnalyticsWidgetSource { var analyticsId: String { switch self { - case .allObjects: - return "AllObjects" case .pinned: return "Pinned" case .recent: @@ -489,7 +486,6 @@ enum ClickNavBarAddMenuRoute: String { case screenBin = "ScreenBin" case screenDate = "ScreenDate" case screenType = "ScreenType" - case screenAllObjects = "ScreenAllObjects" } enum ClickNavBarAddMenuType: String { diff --git a/Anytype/Sources/Analytics/Converters/ObjectType+Analytics.swift b/Anytype/Sources/Analytics/Converters/ObjectType+Analytics.swift index e90aa6474c..d8ee031715 100644 --- a/Anytype/Sources/Analytics/Converters/ObjectType+Analytics.swift +++ b/Anytype/Sources/Analytics/Converters/ObjectType+Analytics.swift @@ -15,18 +15,12 @@ extension WidgetSource { extension AnytypeWidgetId { var analyticsSource: AnalyticsWidgetSource { switch self { - case .allObjects: - return .allObjects case .pinned: return .pinned case .recent: return .recent case .recentOpen: return .recentOpen - case .bin: - return .bin - case .chat: - return .chat } } } diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Models/ObjectTypeSection.swift b/Anytype/Sources/PresentationLayer/Common/SwiftUI/Search/GlobalSearch/Models/ObjectTypeSection.swift similarity index 100% rename from Anytype/Sources/PresentationLayer/Modules/AllObjects/Models/ObjectTypeSection.swift rename to Anytype/Sources/PresentationLayer/Common/SwiftUI/Search/GlobalSearch/Models/ObjectTypeSection.swift diff --git a/Anytype/Sources/PresentationLayer/Flows/EditorFlow/EditorCoordinatorView.swift b/Anytype/Sources/PresentationLayer/Flows/EditorFlow/EditorCoordinatorView.swift index c1622222d7..730d65a430 100644 --- a/Anytype/Sources/PresentationLayer/Flows/EditorFlow/EditorCoordinatorView.swift +++ b/Anytype/Sources/PresentationLayer/Flows/EditorFlow/EditorCoordinatorView.swift @@ -39,8 +39,6 @@ struct EditorCoordinatorView: View { EditorPageCoordinatorView(data: data, showHeader: true, setupEditorInput: { _, _ in }) case let .list(data): EditorSetCoordinatorView(data: data, showHeader: true) - case let .allObjects(spaceId): - AllObjectsCoordinatorView(spaceId: spaceId, output: model) case let .date(data): DateCoordinatorView(data: data) case let .type(data): diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsStateStorage/AllObjectsStateStorageService.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsStateStorage/AllObjectsStateStorageService.swift deleted file mode 100644 index 5dff840868..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsStateStorage/AllObjectsStateStorageService.swift +++ /dev/null @@ -1,28 +0,0 @@ -import AnytypeCore - -protocol AllObjectsStateStorageServiceProtocol: AnyObject { - func storeSort(_ sort: ObjectSort, spaceId: String) - func restoreSort(for spaceId: String) -> ObjectSort? - func clear() -} - -final class AllObjectsStateStorageService: AllObjectsStateStorageServiceProtocol { - - // [SpaceId : ObjectSort] - @UserDefault("UserData.AllContentStateStorage", defaultValue: [:]) - private var spacesSorts: [String: ObjectSort] - - // MARK: - AllContentSavedStatesServiceProtocol - - func storeSort(_ sort: ObjectSort, spaceId: String) { - spacesSorts[spaceId] = sort - } - - func restoreSort(for spaceId: String) -> ObjectSort? { - spacesSorts[spaceId] - } - - func clear() { - spacesSorts.removeAll() - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsView.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsView.swift deleted file mode 100644 index 9309edc9ec..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsView.swift +++ /dev/null @@ -1,145 +0,0 @@ -import SwiftUI - -struct AllObjectsView: View { - - @StateObject private var model: AllObjectsViewModel - - init(spaceId: String, output: (any AllObjectsModuleOutput)?) { - _model = StateObject(wrappedValue: AllObjectsViewModel(spaceId: spaceId, output: output)) - } - - var body: some View { - VStack(spacing: 0) { - navigationBar - sections - SearchBar(text: $model.searchText, focused: false, placeholder: Loc.search) - content - } - .homeBottomPanelHidden(false) - .task { - await model.startParticipantTask() - } - .task(id: model.state) { - await model.restartSubscription() - } - .task(id: model.searchText) { - await model.search() - } - .onAppear() { - model.onAppear() - } - .onDisappear() { - model.onDisappear() - } - .onChange(of: model.state.sort) { _, newValue in - model.onChangeSort() - } - .onChange(of: model.state.mode) { _, newValue in - model.onChangeMode() - } - } - - private var navigationBar: some View { - PageNavigationHeader(title: model.state.mode.title) { - settingsMenu - } - } - - private var settingsMenu: some View { - AllObjectsSettingsMenu( - state: $model.state, - binTapped: { - model.binTapped() - } - ) - } - - @ViewBuilder - private var content: some View { - if model.firstOpen { - Spacer() - } else if model.sections.isEmpty { - emptyState - } else { - list - } - } - - private var list: some View { - PlainList { - if model.state.mode == .unlinked { - onlyUnlinkedBanner - } - ForEach(model.sections) { section in - if let title = section.data, title.isNotEmpty { - ListSectionHeaderView(title: title) - .padding(.horizontal, 20) - } - ForEach(section.rows, id: \.id) { row in - WidgetObjectListRowView(model: row) - .onAppear { - model.onAppearLastRow(row.id) - } - .if(row.canArchive) { - $0.swipeActions { - Button(Loc.toBin, role: .destructive) { - model.onDelete(objectId: row.objectId) - } - } - } - } - } - AnytypeNavigationSpacer(minHeight: 130) - } - .scrollIndicators(.never) - .scrollDismissesKeyboard(.immediately) - .id(model.state.scrollId + model.searchText) - } - - private var sections: some View { - ScrollView(.horizontal, showsIndicators: false) { - HStack(spacing: 20) { - ForEach(ObjectTypeSection.allObjectsSupportedSections, id: \.self) { section in - Button { - UISelectionFeedbackGenerator().selectionChanged() - model.sectionChanged(section) - } label: { - AnytypeText( - section.title, - style: .uxTitle2Medium - ) - .foregroundColor(model.state.section == section ? Color.Control.primary : Color.Control.secondary) - } - } - } - .frame(height: 40) - .padding(.horizontal, 20) - } - } - - private var onlyUnlinkedBanner: some View { - VStack(spacing: 0) { - Spacer.fixedHeight(14) - AnytypeText(Loc.AllObjects.Settings.Unlinked.description, style: .caption1Regular) - .foregroundColor(.Text.secondary) - Spacer.fixedHeight(14) - } - .divider(spacing: 0, alignment: .leading) - .padding(.horizontal, 16) - } - - private var emptyState: some View { - let emptySearchText = model.searchText.isEmpty - let title = emptySearchText ? Loc.EmptyView.Default.title : Loc.AllObjects.Search.Empty.State.title - let subtitle = emptySearchText ? Loc.EmptyView.Default.subtitle : Loc.AllObjects.Search.Empty.State.subtitle - return EmptyStateView( - title: title, - subtitle: subtitle, - style: .plain - ) - } -} - -#Preview { - AllObjectsView(spaceId: "", output: nil) -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsViewModel.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsViewModel.swift deleted file mode 100644 index 4fd35e8758..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/AllObjectsViewModel.swift +++ /dev/null @@ -1,204 +0,0 @@ -import Foundation -import Services -import OrderedCollections -import UIKit - -@MainActor -protocol AllObjectsModuleOutput: AnyObject { - func onObjectSelected(screenData: ScreenData) -} - -@MainActor -final class AllObjectsViewModel: ObservableObject { - - private var details = [ObjectDetails]() - private var objectsToLoad = 0 - var firstOpen = true - - @Published var sections = [ListSectionData]() - @Published var state = AllObjectsState() - @Published var searchText = "" - @Published private var participantCanEdit = false - - @Injected(\.allObjectsSubscriptionService) - private var allObjectsSubscriptionService: any AllObjectsSubscriptionServiceProtocol - @Injected(\.searchService) - private var searchService: any SearchServiceProtocol - @Injected(\.allObjectsStateStorageService) - private var allObjectsStateStorageService: any AllObjectsStateStorageServiceProtocol - - @Injected(\.objectActionsService) - private var objectActionService: any ObjectActionsServiceProtocol - @Injected(\.accountParticipantsStorage) - private var accountParticipantStorage: any AccountParticipantsStorageProtocol - - private let dateFormatter = AnytypeRelativeDateTimeFormatter() - - private let spaceId: String - private weak var output: (any AllObjectsModuleOutput)? - - init(spaceId: String, output: (any AllObjectsModuleOutput)?) { - self.spaceId = spaceId - self.output = output - self.restoreSort() - } - - func onAppear() { - AnytypeAnalytics.instance().logScreenLibrary() - } - - func startParticipantTask() async { - for await participant in accountParticipantStorage.participantPublisher(spaceId: spaceId).values { - participantCanEdit = participant.canEdit - updateRows() - } - } - - func restartSubscription() async { - await allObjectsSubscriptionService.startSubscription( - spaceId: spaceId, - section: state.section, - sort: state.sort, - onlyUnlinked: state.mode == .unlinked, - limitedObjectsIds: state.limitedObjectsIds, - limit: state.limit, - update: { [weak self] details, objectsToLoad in - self?.updateFirstOpenIfNeeded() - self?.details = details - self?.objectsToLoad = objectsToLoad - self?.updateRows() - } - ) - } - - func search() async { - do { - guard searchText.isNotEmpty else { - state.limitedObjectsIds = nil - return - } - - try await Task.sleep(seconds: 0.3) - - state.limitedObjectsIds = try await searchService.searchAll(text: searchText, spaceId: spaceId).map { $0.id } - } catch is CancellationError { - // Ignore cancellations. That means we was run new search. - } catch { - state.limitedObjectsIds = nil - } - - AnytypeAnalytics.instance().logSearchInput(spaceId: spaceId, route: .library) - } - - func sectionChanged(_ section: ObjectTypeSection) { - state.section = section - AnytypeAnalytics.instance().logChangeLibraryType(type: section.analyticsValue) - } - - func binTapped() { - output?.onObjectSelected(screenData: .editor(.bin(spaceId: spaceId))) - } - - func onDisappear() { - stopSubscription() - } - - func onAppearLastRow(_ id: String) { - guard objectsToLoad > 0, details.last?.id == id else { return } - objectsToLoad = 0 - state.updateLimit() - } - - func onDelete(objectId: String) { - setArchive(objectId: objectId) - } - - func onChangeSort() { - storeSort() - AnytypeAnalytics.instance().logChangeLibrarySort( - type: state.sort.relation.analyticsValue, - sort: state.sort.type.analyticValue - ) - } - - func onChangeMode() { - AnytypeAnalytics.instance().logChangeLibraryTypeLink(type: state.mode.analyticsValue) - } - - private func setArchive(objectId: String) { - AnytypeAnalytics.instance().logMoveToBin(true) - Task { try? await objectActionService.setArchive(objectIds: [objectId], true) } - UISelectionFeedbackGenerator().selectionChanged() - } - - private func stopSubscription() { - Task { - await allObjectsSubscriptionService.stopSubscription() - } - } - - private func updateRows() { - guard state.sort.relation.canGroupByDate else { - sections = [listSectionData(title: nil, details: details)] - return - } - - let today = Date() - let dict = OrderedDictionary( - grouping: details, - by: { dateFormatter.localizedString(for: sortValue(for: $0) ?? today, relativeTo: today) } - ) - - if dict.count == 1 { - sections = [listSectionData(title: nil, details: details)] - } else { - sections = dict.map { (key, details) in - listSectionData(title: key, details: details) - } - } - } - - private func listSectionData(title: String?, details: [ObjectDetails]) -> ListSectionData { - ListSectionData( - id: title ?? UUID().uuidString, - data: title, - rows: details.map { details in - WidgetObjectListRowModel( - details: details, - canArchive: details.permissions(participantCanEdit: participantCanEdit).canArchive, - onTap: { [weak self] in - self?.output?.onObjectSelected(screenData: details.screenData()) - AnytypeAnalytics.instance().logLibraryResult() - } - ) - } - ) - } - - private func sortValue(for details: ObjectDetails) -> Date? { - switch state.sort.relation { - case .dateUpdated: - return details.lastModifiedDate - case .dateCreated: - return details.createdDate - case .name: - return nil - } - } - - private func updateFirstOpenIfNeeded() { - guard firstOpen else { return } - firstOpen = false - } - - // MARK: - Save states - - private func storeSort() { - allObjectsStateStorageService.storeSort(state.sort, spaceId: spaceId) - } - - private func restoreSort() { - guard let sort = allObjectsStateStorageService.restoreSort(for: spaceId) else { return } - state.sort = sort - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Coordinator/AllObjectsCoordinatorView.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/Coordinator/AllObjectsCoordinatorView.swift deleted file mode 100644 index 260d9d8520..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Coordinator/AllObjectsCoordinatorView.swift +++ /dev/null @@ -1,21 +0,0 @@ -import SwiftUI - -struct AllObjectsCoordinatorView: View { - - @StateObject private var model: AllObjectsCoordinatorViewModel - - init(spaceId: String, output: (any WidgetObjectListCommonModuleOutput)?) { - _model = StateObject(wrappedValue: AllObjectsCoordinatorViewModel(spaceId: spaceId, output: output)) - } - - var body: some View { - AllObjectsView( - spaceId: model.spaceId, - output: model - ) - } -} - -#Preview { - AllObjectsCoordinatorView(spaceId: "", output: nil) -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Coordinator/AllObjectsCoordinatorViewModel.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/Coordinator/AllObjectsCoordinatorViewModel.swift deleted file mode 100644 index 4d3ada9800..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Coordinator/AllObjectsCoordinatorViewModel.swift +++ /dev/null @@ -1,19 +0,0 @@ -import Foundation - -@MainActor -final class AllObjectsCoordinatorViewModel: ObservableObject, AllObjectsModuleOutput { - - let spaceId: String - private weak var output: (any WidgetObjectListCommonModuleOutput)? - - init(spaceId: String, output: (any WidgetObjectListCommonModuleOutput)?) { - self.spaceId = spaceId - self.output = output - } - - // MARK: - AllObjectsModuleOutput - - func onObjectSelected(screenData: ScreenData) { - output?.onObjectSelected(screenData: screenData) - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Menu/AllObjectsSettingsMenu.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/Menu/AllObjectsSettingsMenu.swift deleted file mode 100644 index c9c3fa49be..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Menu/AllObjectsSettingsMenu.swift +++ /dev/null @@ -1,46 +0,0 @@ -import SwiftUI -import Services - -struct AllObjectsSettingsMenu: View { - @Binding var state: AllObjectsState - let binTapped: () -> Void - - init(state: Binding, binTapped: @escaping () -> Void) { - self._state = state - self.binTapped = binTapped - } - - var body: some View { - Menu { - mode - Divider() - AllObjectsSortMenu(sort: $state.sort) - Divider() - bin - } label: { - IconView(icon: .asset(.X24.more)) - .frame(width: 24, height: 24) - } - .menuOrder(.fixed) - } - - private var mode: some View { - Picker("", selection: $state.mode) { - ForEach(AllObjectsMode.allCases, id: \.self) { mode in - AnytypeText(mode.title, style: .uxTitle2Medium) - .foregroundColor(.Control.primary) - } - } - } - - private var bin: some View { - Button { - binTapped() - } label: { - AnytypeText( - Loc.AllObjects.Settings.viewBin, - style: .uxTitle2Medium - ) - } - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Menu/AllObjectsSortMenu.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/Menu/AllObjectsSortMenu.swift deleted file mode 100644 index f2fca1b2ec..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Menu/AllObjectsSortMenu.swift +++ /dev/null @@ -1,18 +0,0 @@ -import SwiftUI -import Services - -struct AllObjectsSortMenu: View { - @Binding var sort: ObjectSort - - var body: some View { - ObjectsSortMenu( - sort: $sort, - label: { - AnytypeText(Loc.AllObjects.Settings.Sort.title, style: .uxTitle2Medium) - .foregroundColor(.Control.primary) - Text(sort.relation.title) - } - ) - .menuActionDismissBehavior(.disabled) - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Models/AllContentState.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/Models/AllContentState.swift deleted file mode 100644 index c9fab82ae4..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Models/AllContentState.swift +++ /dev/null @@ -1,23 +0,0 @@ -struct AllObjectsState: Equatable, Hashable { - var mode = AllObjectsMode.allObjects { didSet { resetLimit() } } - var section = ObjectTypeSection.pages { didSet { resetLimit()} } - var sort = ObjectSort(relation: .dateUpdated) { didSet { resetLimit() } } - var limitedObjectsIds: [String]? = nil { didSet { resetLimit() } } - var limit = Constants.limit - - mutating func updateLimit() { - limit += Constants.limit - } - - mutating func resetLimit() { - limit = Constants.limit - } - - var scrollId: String { - mode.rawValue + section.rawValue + sort.id - } - - private enum Constants { - static let limit = 100 - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Models/AllObjectsMode.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/Models/AllObjectsMode.swift deleted file mode 100644 index d82ab525fb..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Models/AllObjectsMode.swift +++ /dev/null @@ -1,24 +0,0 @@ -import Services - -enum AllObjectsMode: String, CaseIterable { - case allObjects - case unlinked - - var title: String { - switch self { - case .allObjects: - Loc.allObjects - case .unlinked: - Loc.AllObjects.Settings.Unlinked.title - } - } - - var analyticsValue: String { - switch self { - case .allObjects: - "All" - case .unlinked: - "Unlinked" - } - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Subscription/AllObjectsSubscriptionService.swift b/Anytype/Sources/PresentationLayer/Modules/AllObjects/Subscription/AllObjectsSubscriptionService.swift deleted file mode 100644 index bcf76dee8c..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/AllObjects/Subscription/AllObjectsSubscriptionService.swift +++ /dev/null @@ -1,76 +0,0 @@ -import Foundation -import Services - -@MainActor -protocol AllObjectsSubscriptionServiceProtocol: AnyObject { - func startSubscription( - spaceId: String, - section: ObjectTypeSection, - sort: ObjectSort, - onlyUnlinked: Bool, - limitedObjectsIds: [String]?, - limit: Int, - update: @escaping @MainActor ([ObjectDetails], Int) -> Void - ) async - func stopSubscription() async -} - -@MainActor -final class AllObjectsSubscriptionService: AllObjectsSubscriptionServiceProtocol { - - @Injected(\.subscriptionStorageProvider) - private var subscriptionStorageProvider: any SubscriptionStorageProviderProtocol - private lazy var subscriptionStorage: any SubscriptionStorageProtocol = { - subscriptionStorageProvider.createSubscriptionStorage(subId: subscriptionId) - }() - private let subscriptionId = "AllObjects-\(UUID().uuidString)" - - nonisolated init() {} - - func startSubscription( - spaceId: String, - section: ObjectTypeSection, - sort: ObjectSort, - onlyUnlinked: Bool, - limitedObjectsIds: [String]?, - limit: Int, - update: @escaping @MainActor ([ObjectDetails], Int) -> Void - ) async { - - let filters: [DataviewFilter] = .builder { - SearchFiltersBuilder.build(isArchived: false, layouts: section.supportedLayouts) - if onlyUnlinked { - SearchHelper.onlyUnlinked() - } - if let limitedObjectsIds { - SearchHelper.objectsIds(limitedObjectsIds) - } - } - - let sort = sort.asDataviewSort() - let keys: [BundledPropertyKey] = .builder { - BundledPropertyKey.createdDate - BundledPropertyKey.lastModifiedDate - BundledPropertyKey.objectListKeys - } - let searchData: SubscriptionData = .search( - SubscriptionData.Search( - identifier: subscriptionId, - spaceId: spaceId, - sorts: [sort], - filters: filters, - limit: limit, - offset: 0, - keys: keys.map { $0.rawValue } - ) - ) - - try? await subscriptionStorage.startOrUpdateSubscription(data: searchData) { data in - await update(data.items, data.prevCount) - } - } - - func stopSubscription() async { - try? await subscriptionStorage.stopSubscription() - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeNavigationContainer/Panel/ScreenData+Analytics.swift b/Anytype/Sources/PresentationLayer/Modules/HomeNavigationContainer/Panel/ScreenData+Analytics.swift index 667a49e92e..61a1fd4e29 100644 --- a/Anytype/Sources/PresentationLayer/Modules/HomeNavigationContainer/Panel/ScreenData+Analytics.swift +++ b/Anytype/Sources/PresentationLayer/Modules/HomeNavigationContainer/Panel/ScreenData+Analytics.swift @@ -21,8 +21,6 @@ extension EditorScreenData: HomeClinkNavBarAddMenuRouteProvider { return .screenDate case .type: return .screenType - case .allObjects: - return .screenAllObjects } } } diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/HomeWidgetSubmoduleView.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/HomeWidgetSubmoduleView.swift index ccd944ba9b..4896718c1c 100644 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/HomeWidgetSubmoduleView.swift +++ b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/HomeWidgetSubmoduleView.swift @@ -23,8 +23,6 @@ struct HomeWidgetSubmoduleView: View { @ViewBuilder private func viewForAnytypeWidgetId(_ anytypeWidgetId: AnytypeWidgetId) -> some View { switch (anytypeWidgetId, widgetInfo.fixedLayout) { - case (.allObjects, _): - AllObjectsWidgetView(data: widgetData) case (.pinned, .tree): PinnedTreeWidgetsubmoduleView(data: widgetData) case (.pinned, .list): @@ -43,10 +41,6 @@ struct HomeWidgetSubmoduleView: View { RecentOpenListWidgetSubmoduleView(data: widgetData) case (.recentOpen, .compactList): RecentOpenCompactListWidgetSubmoduleView(data: widgetData) - case (.bin, _): - BinWidgetView(data: widgetData) - case (.chat, _): - SpaceChatLegacyWidgetView(data: widgetData) case _: EmptyView() } diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/HomeWidgetsViewModel.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/HomeWidgetsViewModel.swift index 0206174456..16d8a1b964 100644 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/HomeWidgetsViewModel.swift +++ b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/HomeWidgetsViewModel.swift @@ -143,8 +143,6 @@ final class HomeWidgetsViewModel { var newWidgetBlocks = blocks .compactMap { widgetObject.widgetInfo(block: $0) } - newWidgetBlocks.removeAll { $0.source == .library(.chat) || $0.source == .library(.allObjects) || $0.source == .library(.bin) } - guard widgetBlocks != newWidgetBlocks else { continue } widgetBlocks = newWidgetBlocks diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/Models/WidgetSource.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/Models/WidgetSource.swift index 2e1dad87e4..bd7fb9d08e 100644 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/Models/WidgetSource.swift +++ b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Container/Models/WidgetSource.swift @@ -37,8 +37,6 @@ extension WidgetSource { switch library { case .pinned, .recent, .recentOpen: return [.compactList, .list, .tree] - case .allObjects, .bin, .chat: - return [.link] } } } diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/AllObjects/AllObjectsWidgetView.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/AllObjects/AllObjectsWidgetView.swift deleted file mode 100644 index e2d78d5f45..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/AllObjects/AllObjectsWidgetView.swift +++ /dev/null @@ -1,44 +0,0 @@ -import Foundation -import SwiftUI -import AnytypeCore - -struct AllObjectsWidgetView: View { - - @StateObject private var model: AllObjectsWidgetViewModel - @Binding var homeState: HomeWidgetsState - - init(data: WidgetSubmoduleData) { - _homeState = data.homeState - _model = StateObject(wrappedValue: AllObjectsWidgetViewModel(data: data)) - } - - var body: some View { - LinkWidgetViewContainer( - isExpanded: .constant(false), - dragId: model.dragId, - homeState: $homeState, - allowMenuContent: true, - allowContent: false, - header: { - LinkWidgetDefaultHeader(title: Loc.allObjects, icon: .asset(.X24.allObjects), onTap: { - model.onHeaderTap() - }) - }, - menu: { - menu - }, - content: { EmptyView() } - ) - .id(model.data.widgetBlockId) - } - - private var menu: some View { - WidgetCommonActionsMenuView( - items: [.removeSystemWidget], - widgetBlockId: model.data.widgetBlockId, - widgetObject: model.data.widgetObject, - homeState: homeState, - output: model.data.output - ) - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/AllObjects/AllObjectsWidgetViewModel.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/AllObjects/AllObjectsWidgetViewModel.swift deleted file mode 100644 index b7e3ee26a6..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/AllObjects/AllObjectsWidgetViewModel.swift +++ /dev/null @@ -1,20 +0,0 @@ -import Foundation -import Combine -import Services - -@MainActor -final class AllObjectsWidgetViewModel: ObservableObject { - - let data: WidgetSubmoduleData - var dragId: String { data.widgetBlockId } - - init(data: WidgetSubmoduleData) { - self.data = data - } - - func onHeaderTap() { - guard let info = data.widgetObject.widgetInfo(blockId: data.widgetBlockId) else { return } - AnytypeAnalytics.instance().logClickWidgetTitle(source: .allObjects, createType: info.widgetCreateType) - data.output?.onObjectSelected(screenData: .editor(.allObjects(spaceId: data.workspaceInfo.accountSpaceId))) - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/BinWidgetView.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/BinWidgetView.swift deleted file mode 100644 index 10cc45f163..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/BinWidgetView.swift +++ /dev/null @@ -1,62 +0,0 @@ -import Foundation -import SwiftUI -import AnytypeCore - -struct BinWidgetView: View { - - let data: WidgetSubmoduleData - - var body: some View { - BinWidgetSubmoduleInternalView(data: data) - .id(data.widgetBlockId) - } -} - -private struct BinWidgetSubmoduleInternalView: View { - - @Binding private var homeState: HomeWidgetsState - @StateObject private var model: BinWidgetViewModel - - init(data: WidgetSubmoduleData) { - self._homeState = data.homeState - self._model = StateObject(wrappedValue: BinWidgetViewModel(data: data)) - } - - var body: some View { - LinkWidgetViewContainer( - isExpanded: .constant(false), - dragId: model.dragId, - homeState: $homeState, - allowMenuContent: true, - allowContent: false, - header: { - LinkWidgetDefaultHeader(title: Loc.bin, icon: .asset(.X24.bin), onTap: { - model.onHeaderTap() - }) - }, - menu: { - menu - }, - content: { EmptyView() } - ) - .anytypeSheet(item: $model.binAlertData) { data in - BinConfirmationAlert(data: data) - } - .snackbar(toastBarData: $model.toastData) - } - - @ViewBuilder - private var menu: some View { - WidgetCommonActionsMenuView( - items: [.removeSystemWidget], - widgetBlockId: model.widgetBlockId, - widgetObject: model.widgetObject, - homeState: homeState, - output: model.output - ) - Divider() - AsyncButton(Loc.Widgets.Actions.emptyBin, role: .destructive) { - try await model.onEmptyBinTap() - } - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/BinWidgetViewModel.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/BinWidgetViewModel.swift deleted file mode 100644 index b12502f5e8..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/BinWidgetViewModel.swift +++ /dev/null @@ -1,45 +0,0 @@ -import Foundation -import Combine -import Services -import UIKit - -@MainActor -final class BinWidgetViewModel: ObservableObject { - - // MARK: - DI - - @Injected(\.searchService) - private var searchService: any SearchServiceProtocol - - let data: WidgetSubmoduleData - - var widgetBlockId: String { data.widgetBlockId } - var widgetObject: any BaseDocumentProtocol { data.widgetObject } - weak var output: (any CommonWidgetModuleOutput)? { data.output } - - // MARK: - State - - @Published var toastData: ToastBarData? - @Published var binAlertData: BinConfirmationAlertData? = nil - var dragId: String { data.widgetBlockId } - - init(data: WidgetSubmoduleData) { - self.data = data - } - - func onHeaderTap() { - guard let info = widgetObject.widgetInfo(blockId: widgetBlockId) else { return } - AnytypeAnalytics.instance().logClickWidgetTitle(source: .bin, createType: info.widgetCreateType) - data.output?.onObjectSelected(screenData: .editor(.bin(spaceId: data.workspaceInfo.accountSpaceId))) - } - - func onEmptyBinTap() async throws { - let binIds = try await searchService.searchArchiveObjectIds(spaceId: data.workspaceInfo.accountSpaceId) - guard binIds.isNotEmpty else { - toastData = ToastBarData(Loc.Widgets.Actions.binConfirm(binIds.count)) - return - } - binAlertData = BinConfirmationAlertData(ids: binIds) - UISelectionFeedbackGenerator().selectionChanged() - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/ConfirmationView/BinConfirmationAlert.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/BinLink/ConfirmationView/BinConfirmationAlert.swift similarity index 100% rename from Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/ConfirmationView/BinConfirmationAlert.swift rename to Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/BinLink/ConfirmationView/BinConfirmationAlert.swift diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/ConfirmationView/BinConfirmationAlertModel.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/BinLink/ConfirmationView/BinConfirmationAlertModel.swift similarity index 100% rename from Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/Bin/ConfirmationView/BinConfirmationAlertModel.swift rename to Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/BinLink/ConfirmationView/BinConfirmationAlertModel.swift diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpaceChat/SpaceChatLegacyWidgetView.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpaceChat/SpaceChatLegacyWidgetView.swift deleted file mode 100644 index 3e07186864..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpaceChat/SpaceChatLegacyWidgetView.swift +++ /dev/null @@ -1,56 +0,0 @@ -import Foundation -import SwiftUI -import AnytypeCore - -struct SpaceChatLegacyWidgetView: View { - - @StateObject private var model: SpaceChatLegacyWidgetViewModel - @Binding var homeState: HomeWidgetsState - - init(data: WidgetSubmoduleData) { - self._homeState = data.homeState - self._model = StateObject(wrappedValue: SpaceChatLegacyWidgetViewModel(data: data)) - } - - var body: some View { - LinkWidgetViewContainer( - isExpanded: .constant(false), - dragId: nil, - homeState: $homeState, - allowMenuContent: true, - allowContent: false, - header: { - LinkWidgetDefaultHeader( - title: Loc.chat, - icon: .asset(.X24.chat), - rightAccessory: { - HStack(spacing: 4) { - if model.hasMentions { - MentionBadge(style: model.muted ? .muted : .highlighted) - } - if model.messageCount > 0 { - CounterView(count: model.messageCount, style: model.muted ? .muted : .highlighted) - } - } - }, - onTap: { - model.onHeaderTap() - } - ) - }, - menu: { - WidgetCommonActionsMenuView( - items: [.remove], - widgetBlockId: model.widgetBlockId, - widgetObject: model.widgetObject, - homeState: homeState, - output: model.output - ) - }, - content: { EmptyView() } - ) - .task { - await model.startSubscriptions() - } - } -} diff --git a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpaceChat/SpaceChatLegacyWidgetViewModel.swift b/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpaceChat/SpaceChatLegacyWidgetViewModel.swift deleted file mode 100644 index f9130c9f21..0000000000 --- a/Anytype/Sources/PresentationLayer/Modules/HomeWidgets/Widgets/SpaceChat/SpaceChatLegacyWidgetViewModel.swift +++ /dev/null @@ -1,51 +0,0 @@ -import Foundation -import Combine -import Services -import AnytypeCore - -@MainActor -final class SpaceChatLegacyWidgetViewModel: ObservableObject { - - @Injected(\.workspaceStorage) - private var workspaceStorage: any WorkspacesStorageProtocol - @Injected(\.chatMessagesPreviewsStorage) - private var chatMessagesPreviewsStorage: any ChatMessagesPreviewsStorageProtocol - - private let data: WidgetSubmoduleData - - @Published var hasMentions: Bool = false - @Published var messageCount: Int = 0 - @Published var muted = false - - var widgetBlockId: String { data.widgetBlockId } - var widgetObject: any BaseDocumentProtocol { data.widgetObject } - weak var output: (any CommonWidgetModuleOutput)? { data.output } - - init(data: WidgetSubmoduleData) { - self.data = data - } - - func onHeaderTap() { - let spaceId = data.workspaceInfo.accountSpaceId - guard let chatId = workspaceStorage.spaceView(spaceId: spaceId)?.chatId, chatId.isNotEmpty else { return } - AnytypeAnalytics.instance().logClickWidgetTitle(source: .chat, createType: .manual) - data.output?.onObjectSelected(screenData: .spaceChat(SpaceChatCoordinatorData(spaceId: spaceId))) - } - - func startSubscriptions() async { - let spaceId = data.workspaceInfo.accountSpaceId - let spaceView = workspaceStorage.spaceView(spaceId: spaceId) - muted = FeatureFlags.muteSpacePossibility && !(spaceView?.pushNotificationMode.isUnmutedAll ?? true) - - let chatId = spaceView?.chatId - let sequence = (await chatMessagesPreviewsStorage.previewsSequence) - .compactMap { $0.first { $0.spaceId == spaceId && $0.chatId == chatId }} - .removeDuplicates() - .throttle(milliseconds: 300) - - for await counters in sequence { - messageCount = counters.unreadCounter - hasMentions = counters.mentionCounter > 0 - } - } -} diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Assembly/EditorScreenData+Details.swift b/Anytype/Sources/PresentationLayer/TextEditor/Assembly/EditorScreenData+Details.swift index c1444d886a..f0798f741e 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Assembly/EditorScreenData+Details.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Assembly/EditorScreenData+Details.swift @@ -46,7 +46,7 @@ extension EditorScreenData { var objectId: String? { switch self { - case .pinned, .recentEdit, .recentOpen, .bin, .allObjects, .date: + case .pinned, .recentEdit, .recentOpen, .bin, .date: return nil case .page(let object): return object.objectId @@ -67,8 +67,6 @@ extension EditorScreenData { return spaceId case .bin(let spaceId): return spaceId - case .allObjects(let spaceId): - return spaceId case .page(let object): return object.spaceId case .list(let object): diff --git a/Anytype/Sources/PresentationLayer/TextEditor/Assembly/EditorScreenData.swift b/Anytype/Sources/PresentationLayer/TextEditor/Assembly/EditorScreenData.swift index 8548bf23b1..3e1ec09b96 100644 --- a/Anytype/Sources/PresentationLayer/TextEditor/Assembly/EditorScreenData.swift +++ b/Anytype/Sources/PresentationLayer/TextEditor/Assembly/EditorScreenData.swift @@ -16,8 +16,6 @@ enum EditorScreenData: Hashable, Codable, Equatable, Identifiable { case date(EditorDateObject) case type(EditorTypeObject) - case allObjects(spaceId: String) - var id: Int { hashValue } diff --git a/Anytype/Sources/ServiceLayer/ServicesDI.swift b/Anytype/Sources/ServiceLayer/ServicesDI.swift index 22f7e72bb8..2252fe6492 100644 --- a/Anytype/Sources/ServiceLayer/ServicesDI.swift +++ b/Anytype/Sources/ServiceLayer/ServicesDI.swift @@ -304,14 +304,6 @@ extension Container { self { UserDefaultsStorage() }.singleton } - var allObjectsSubscriptionService: Factory { - self { AllObjectsSubscriptionService() } - } - - var allObjectsStateStorageService: Factory { - self { AllObjectsStateStorageService() }.shared - } - var chatActionService: Factory { self { ChatActionService() } } diff --git a/Modules/Services/Sources/Models/Details/Entities/AnytypeWidgetId.swift b/Modules/Services/Sources/Models/Details/Entities/AnytypeWidgetId.swift index 2c3c429a01..45d5d15692 100644 --- a/Modules/Services/Sources/Models/Details/Entities/AnytypeWidgetId.swift +++ b/Modules/Services/Sources/Models/Details/Entities/AnytypeWidgetId.swift @@ -2,9 +2,6 @@ import Foundation public enum AnytypeWidgetId: String, CaseIterable, Sendable { case pinned = "favorite" - case chat = "chat" // Delete aflter release 13 - case allObjects = "allObjects" case recent = "recent" case recentOpen = "recentOpen" - case bin = "bin" // Delete aflter release 13 }