diff --git a/Bark.xcodeproj/project.pbxproj b/Bark.xcodeproj/project.pbxproj index 3226fe5c..898da235 100644 --- a/Bark.xcodeproj/project.pbxproj +++ b/Bark.xcodeproj/project.pbxproj @@ -100,6 +100,7 @@ 066890082D1946D500E106F2 /* MessageItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 066890072D1946D500E106F2 /* MessageItemView.swift */; }; 0668900B2D19525400E106F2 /* ShowLessAndClearView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0668900A2D19525400E106F2 /* ShowLessAndClearView.swift */; }; 0668900D2D19582400E106F2 /* MessageGroupHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0668900C2D19582400E106F2 /* MessageGroupHeaderView.swift */; }; + 066DF4822D2D31A60092B04E /* MessageDeleteTimeRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 066DF4812D2D31A30092B04E /* MessageDeleteTimeRange.swift */; }; 066E0C8C2BB6AC9A00873838 /* AddSoundCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 066E0C8B2BB6AC9A00873838 /* AddSoundCell.swift */; }; 0672CB06256903F700570C9D /* MessageListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0672CB05256903F700570C9D /* MessageListViewModel.swift */; }; 06787C392A710568008ABDD7 /* GesturePassTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06787C382A710568008ABDD7 /* GesturePassTextView.swift */; }; @@ -112,6 +113,7 @@ 0687F2AA2CCB7FA500B2A52F /* UIFont+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0687F2A72CCB791A00B2A52F /* UIFont+Extension.swift */; }; 06885EB6247FB9880004A303 /* MessageSettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06885EB5247FB9880004A303 /* MessageSettingsViewController.swift */; }; 0689CF4C2C7484A7007203A6 /* BarkTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0689CF4B2C7484A7007203A6 /* BarkTabBarController.swift */; }; + 068A4B962D2E11CD00982449 /* MessageDeleteTimeRangeTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068A4B952D2E11CD00982449 /* MessageDeleteTimeRangeTest.swift */; }; 068EC15827ED99C900D5D11E /* ServerListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068EC15727ED99C900D5D11E /* ServerListViewController.swift */; }; 068EC15A27ED99E700D5D11E /* ServerListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068EC15927ED99E700D5D11E /* ServerListViewModel.swift */; }; 068F66B3247BD84C00DAD25A /* MessageListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068F66B2247BD84C00DAD25A /* MessageListViewController.swift */; }; @@ -343,6 +345,7 @@ 066890072D1946D500E106F2 /* MessageItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageItemView.swift; sourceTree = ""; }; 0668900A2D19525400E106F2 /* ShowLessAndClearView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowLessAndClearView.swift; sourceTree = ""; }; 0668900C2D19582400E106F2 /* MessageGroupHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageGroupHeaderView.swift; sourceTree = ""; }; + 066DF4812D2D31A30092B04E /* MessageDeleteTimeRange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageDeleteTimeRange.swift; sourceTree = ""; }; 066E0C8B2BB6AC9A00873838 /* AddSoundCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSoundCell.swift; sourceTree = ""; }; 0672CB05256903F700570C9D /* MessageListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListViewModel.swift; sourceTree = ""; }; 06787C382A710568008ABDD7 /* GesturePassTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GesturePassTextView.swift; sourceTree = ""; }; @@ -355,6 +358,7 @@ 0687F2A72CCB791A00B2A52F /* UIFont+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIFont+Extension.swift"; sourceTree = ""; }; 06885EB5247FB9880004A303 /* MessageSettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSettingsViewController.swift; sourceTree = ""; }; 0689CF4B2C7484A7007203A6 /* BarkTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkTabBarController.swift; sourceTree = ""; }; + 068A4B952D2E11CD00982449 /* MessageDeleteTimeRangeTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageDeleteTimeRangeTest.swift; sourceTree = ""; }; 068EC15727ED99C900D5D11E /* ServerListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerListViewController.swift; sourceTree = ""; }; 068EC15927ED99E700D5D11E /* ServerListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerListViewModel.swift; sourceTree = ""; }; 068F66B2247BD84C00DAD25A /* MessageListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListViewController.swift; sourceTree = ""; }; @@ -538,6 +542,7 @@ 0604F7DD20620D3800B32F09 /* Model */ = { isa = PBXGroup; children = ( + 066DF4812D2D31A30092B04E /* MessageDeleteTimeRange.swift */, 06B1158E247BB1FB006D91FB /* Message.swift */, 067B2EB425693E38008B6BE1 /* MessageSection.swift */, 061E35852D1E5028009A2D6F /* MessageItemModel.swift */, @@ -728,6 +733,7 @@ 06EE1FD226843E9300586708 /* BarkTests.swift */, 06EE1FD426843E9300586708 /* Info.plist */, 063B909A272149BF00431EC2 /* HomeViewModelTests.swift */, + 068A4B952D2E11CD00982449 /* MessageDeleteTimeRangeTest.swift */, ); path = BarkTests; sourceTree = ""; @@ -1256,6 +1262,7 @@ 065BE4502563D939002A8CA4 /* SoundCellViewModel.swift in Sources */, 06F08EA729B1DDFE006AB9CA /* Error+Extension.swift in Sources */, 0687F2A82CCB791A00B2A52F /* UIFont+Extension.swift in Sources */, + 066DF4822D2D31A60092B04E /* MessageDeleteTimeRange.swift in Sources */, 06B1158F247BB1FB006D91FB /* Message.swift in Sources */, 06BCAE562CDB19260092867A /* GroupMuteSettingManager.swift in Sources */, 06172FDA27F6DAEF002333A4 /* ServerListTableViewCell.swift in Sources */, @@ -1353,6 +1360,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 068A4B962D2E11CD00982449 /* MessageDeleteTimeRangeTest.swift in Sources */, 06EE1FD326843E9300586708 /* BarkTests.swift in Sources */, 063B909B272149BF00431EC2 /* HomeViewModelTests.swift in Sources */, ); diff --git a/Bark/Localizable.xcstrings b/Bark/Localizable.xcstrings index e35af0aa..5252fa60 100644 --- a/Bark/Localizable.xcstrings +++ b/Bark/Localizable.xcstrings @@ -369,6 +369,98 @@ } } }, + "beforeAMonth" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Before a month" + } + }, + "tr" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Bir Ay Önce" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "一个月之前" + } + } + } + }, + "beforeAnHour" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Before an hour" + } + }, + "tr" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Bir Saat Önce" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "一小时之前" + } + } + } + }, + "beforeToday" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Before today" + } + }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bugünden Önce" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "今天之前" + } + } + } + }, + "beforeYesterday" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Before yesterday" + } + }, + "tr" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "Dünden Önce" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "昨天之前" + } + } + } + }, "buildDesc" : { "extractionState" : "manual", "localizations" : { @@ -1835,7 +1927,30 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "过去一小时" + "value" : "最近一小时" + } + } + } + }, + "lastMonth" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The last month" + } + }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Son Ay" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "最近一个月" } } } @@ -1886,6 +2001,29 @@ } } }, + "more" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "More" + } + }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Daha" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "更多" + } + } + } + }, "MoreActions" : { "extractionState" : "manual", "localizations" : { diff --git a/BarkTests/MessageDeleteTimeRangeTest.swift b/BarkTests/MessageDeleteTimeRangeTest.swift new file mode 100644 index 00000000..c531d3f2 --- /dev/null +++ b/BarkTests/MessageDeleteTimeRangeTest.swift @@ -0,0 +1,69 @@ +// +// MessageDeleteTimeRangeTest.swift +// BarkTests +// +// Created by huangfeng on 1/8/25. +// Copyright © 2025 Fin. All rights reserved. +// +@testable import Bark +import Testing + +struct MessageDeleteTimeRangeTest { + @Test("检查时间范围区间是否正确", arguments: [ + MessageDeleteTimeRange.lastHour, + MessageDeleteTimeRange.today, + MessageDeleteTimeRange.todayAndYesterday, + MessageDeleteTimeRange.lastMonth, + MessageDeleteTimeRange.allTime, + MessageDeleteTimeRange.beforeOneHour, + MessageDeleteTimeRange.beforeToday, + MessageDeleteTimeRange.beforeYesterday, + MessageDeleteTimeRange.beforeOneMonth + ]) + func testRange(range: MessageDeleteTimeRange) async throws { + let now = Date() + let lastHour = Calendar.current.date(byAdding: .hour, value: -1, to: now)! + let today = now.startOfDay + let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: today)!.startOfDay + let lastMonth = Calendar.current.date(byAdding: .month, value: -1, to: now)! + + switch range { + case .lastHour: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == lastHour.timeInterval && endDate.timeInterval == now.timeInterval) + case .today: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == today.timeInterval && endDate.timeInterval == now.timeInterval) + case .todayAndYesterday: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == yesterday.timeInterval && endDate.timeInterval == now.timeInterval) + case .lastMonth: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == lastMonth.timeInterval && endDate.timeInterval == now.timeInterval) + case .allTime: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == 0 && endDate.timeInterval == now.timeInterval) + case .beforeOneHour: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == 0 && endDate.timeInterval == lastHour.timeInterval) + case .beforeToday: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == 0 && endDate.timeInterval == today.timeInterval) + case .beforeYesterday: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == 0 && endDate.timeInterval == yesterday.timeInterval) + case .beforeOneMonth: + let startDate = range.startDate + let endDate = range.endDate + #expect(startDate.timeInterval == 0 && endDate.timeInterval == lastMonth.timeInterval) + } + } +} diff --git a/Common/Date+Extension.swift b/Common/Date+Extension.swift index 8d43589c..ad447435 100644 --- a/Common/Date+Extension.swift +++ b/Common/Date+Extension.swift @@ -44,27 +44,39 @@ extension Date { } } +extension Date { + var month: Int { + return Calendar.current.component(.month, from: self) + } + + var timeInterval: Int { + return Int(timeIntervalSince1970) + } + + var isLastDayOfMonth: Bool { + return dayAfter.month != month + } +} + extension Date { static var yesterday: Date { return Date().dayBefore } static var tomorrow: Date { return Date().dayAfter } static var lastHour: Date { return Calendar.current.date(byAdding: .hour, value: -1, to: Date())! } + static var lastMonth: Date { return Calendar.current.date(byAdding: .month, value: -1, to: Date())! } + var dayBefore: Date { - return Calendar.current.date(byAdding: .day, value: -1, to: noon)! + return Calendar.current.date(byAdding: .day, value: -1, to: startOfDay)! } var dayAfter: Date { - return Calendar.current.date(byAdding: .day, value: 1, to: noon)! + return Calendar.current.date(byAdding: .day, value: 1, to: startOfDay)! } - var noon: Date { + var startOfDay: Date { return Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: self)! } - var month: Int { - return Calendar.current.component(.month, from: self) - } - - var isLastDayOfMonth: Bool { - return dayAfter.month != month + var endOfDay: Date { + return Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: self)! } } diff --git a/Controller/MessageListViewController.swift b/Controller/MessageListViewController.swift index b2d5da4f..f9985c2d 100644 --- a/Controller/MessageListViewController.swift +++ b/Controller/MessageListViewController.swift @@ -14,28 +14,38 @@ import RxDataSources import RxSwift import UIKit -enum MessageDeleteType: Int { - case lastHour = 0 - case today - case todayAndYesterday - case allTime - - var string: String { - return [ - NSLocalizedString("lastHour"), - NSLocalizedString("today"), - NSLocalizedString("todayAndYesterday"), - NSLocalizedString("allTime") - ][self.rawValue] - } -} - class MessageListViewController: BaseViewController { - let deleteButton: UIBarButtonItem = { - let btn = BKButton() - btn.setImage(UIImage(named: "baseline_delete_outline_black_24pt"), for: .normal) - btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40) - return UIBarButtonItem(customView: btn) + lazy var deleteButton: UIBarButtonItem = { + if #available(iOS 14.0, *) { + var menuElements = [UIMenuElement]() + for range in [MessageDeleteTimeRange.lastHour, .today, .todayAndYesterday, .lastMonth, .allTime] { + let action = UIAction(title: range.string) { [weak self] _ in + self?.clearAlert(range) + } + menuElements.append(action) + } + + var subMenuElements = [UIMenuElement]() + for range in [MessageDeleteTimeRange.beforeOneHour, .beforeToday, .beforeYesterday, .beforeOneMonth] { + let action = UIAction(title: range.string) { [weak self] _ in + self?.clearAlert(range) + } + subMenuElements.append(action) + } + menuElements.append(UIMenu(title: NSLocalizedString("more"), children: subMenuElements)) + + let addNewMenu = UIMenu( + title: NSLocalizedString("clearFrom"), + children: menuElements + ) + return UIBarButtonItem(image: UIImage(named: "baseline_delete_outline_black_24pt"), menu: addNewMenu) + } else { + let btn = BKButton() + btn.setImage(UIImage(named: "baseline_delete_outline_black_24pt"), for: .normal) + btn.frame = CGRect(x: 0, y: 0, width: 40, height: 40) + return UIBarButtonItem(customView: btn) + } + }() let groupButton: UIBarButtonItem = { @@ -77,7 +87,9 @@ class MessageListViewController: BaseViewController { private let refreshRelay = PublishRelay() /// 重新刷新已加载的页的数据 (最多10页) private let reloadRelay = PublishRelay() - + /// 按时间范围清除消息事件流 + private let clearRelay = PublishRelay() + override func makeUI() { navigationItem.searchController = UISearchController(searchResultsController: nil) navigationItem.searchController?.obscuresBackgroundDuringPresentation = false @@ -90,6 +102,13 @@ class MessageListViewController: BaseViewController { make.edges.equalToSuperview() } + if #available(iOS 14.0, *) { + // iOS 14 以上,使用 UIMenu + } else { + // 使用 UIAlertController + subscribeDeleteTap() + } + // 点击tab按钮,回到顶部 Client.shared.currentTabBarController? .tabBarItemDidClick @@ -130,7 +149,8 @@ class MessageListViewController: BaseViewController { reloadAnimation: .none, deleteAnimation: .left ), - configureCell: { _, tableView, _, item -> UITableViewCell in + configureCell: { [weak self] _, tableView, _, item -> UITableViewCell in + guard let self else { return UITableViewCell() } switch item { case .message(let message): @@ -192,7 +212,7 @@ class MessageListViewController: BaseViewController { loadMore: tableView.mj_footer!.rx.refresh.asDriver(), itemDelete: tableView.rx.modelDeleted(MessageListCellItem.self).asDriver(), itemDeleteInGroup: itemDeleteInGroupRelay.asDriver(onErrorDriveWith: .empty()), - delete: getBatchDeleteDriver(), + delete: clearRelay.asDriver(onErrorDriveWith: .empty()), groupToggleTap: groupBtn.rx.tap.asDriver(), searchText: navigationItem.searchController!.searchBar.rx.text.asObservable(), reload: reloadRelay.asDriver(onErrorDriveWith: .empty()) @@ -232,51 +252,46 @@ class MessageListViewController: BaseViewController { .drive((groupButton.customView as! UIButton).rx.isHidden).disposed(by: rx.disposeBag) } - private func getBatchDeleteDriver() -> Driver { + private func subscribeDeleteTap() { guard let deleteBtn = deleteButton.customView as? BKButton else { - return Driver.never() + return } - return deleteBtn.rx - .tap - .flatMapLatest { _ -> PublishRelay in - let relay = PublishRelay() - - func alert(_ type: MessageDeleteType) { - let alertController = UIAlertController(title: nil, message: "\(NSLocalizedString("clearFrom"))\n\(type.string)", preferredStyle: .alert) - alertController.addAction(UIAlertAction(title: NSLocalizedString("clear"), style: .destructive, handler: { _ in - relay.accept(type) - })) - alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil)) - self.navigationController?.present(alertController, animated: true, completion: nil) - } - - let alertController = UIAlertController(title: nil, message: NSLocalizedString("clearFrom"), preferredStyle: .actionSheet) - alertController.addAction(UIAlertAction(title: NSLocalizedString("lastHour"), style: .default, handler: { _ in - alert(.lastHour) - })) - alertController.addAction(UIAlertAction(title: NSLocalizedString("today"), style: .default, handler: { _ in - alert(.today) - })) - alertController.addAction(UIAlertAction(title: NSLocalizedString("todayAndYesterday"), style: .default, handler: { _ in - alert(.todayAndYesterday) - })) - alertController.addAction(UIAlertAction(title: NSLocalizedString("allTime"), style: .default, handler: { _ in - alert(.allTime) - })) - alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil)) - if UIDevice.current.userInterfaceIdiom == .pad { - alertController.modalPresentationStyle = .popover - if #available(iOS 16.0, *) { - alertController.popoverPresentationController?.sourceItem = self.deleteButton - } else { - alertController.popoverPresentationController?.barButtonItem = self.deleteButton - } + deleteBtn.rx.tap.subscribe(onNext: { [weak self] _ in + guard let self else { return } + + let alertController = UIAlertController(title: nil, message: NSLocalizedString("clearFrom"), preferredStyle: .actionSheet) + alertController.addAction(UIAlertAction(title: NSLocalizedString("lastHour"), style: .default, handler: { [weak self] _ in + self?.clearAlert(.lastHour) + })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("today"), style: .default, handler: { [weak self] _ in + self?.clearAlert(.today) + })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("todayAndYesterday"), style: .default, handler: { [weak self] _ in + self?.clearAlert(.todayAndYesterday) + })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("allTime"), style: .default, handler: { [weak self] _ in + self?.clearAlert(.allTime) + })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil)) + if UIDevice.current.userInterfaceIdiom == .pad { + alertController.modalPresentationStyle = .popover + if #available(iOS 16.0, *) { + alertController.popoverPresentationController?.sourceItem = self.deleteButton + } else { + alertController.popoverPresentationController?.barButtonItem = self.deleteButton } - self.navigationController?.present(alertController, animated: true, completion: nil) - - return relay } - .asDriver(onErrorDriveWith: .empty()) + self.navigationController?.present(alertController, animated: true, completion: nil) + }).disposed(by: rx.disposeBag) + } + + func clearAlert(_ range: MessageDeleteTimeRange) { + let alertController = UIAlertController(title: nil, message: "\(NSLocalizedString("clearFrom"))\n\(range.string)", preferredStyle: .alert) + alertController.addAction(UIAlertAction(title: NSLocalizedString("clear"), style: .destructive, handler: { [weak self] _ in + self?.clearRelay.accept(range) + })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil)) + self.navigationController?.present(alertController, animated: true, completion: nil) } private func alertMessage(message: MessageItemModel, sourceView: UIView, sourceCell: UITableViewCell) { diff --git a/Controller/MessageListViewModel.swift b/Controller/MessageListViewModel.swift index f1808fdc..5ddb6932 100644 --- a/Controller/MessageListViewModel.swift +++ b/Controller/MessageListViewModel.swift @@ -37,7 +37,7 @@ class MessageListViewModel: ViewModel, ViewModelType { /// 删除群组中某一条消息 var itemDeleteInGroup: Driver /// 批量删除 - var delete: Driver + var delete: Driver /// 切换群组和列表显示样式 var groupToggleTap: Driver /// 搜索 @@ -398,23 +398,11 @@ class MessageListViewModel: ViewModel, ViewModelType { }).disposed(by: rx.disposeBag) // 批量删除 - input.delete.drive(onNext: { [weak self] type in - guard let strongSelf = self else { return } - - var date = Date() - switch type { - case .allTime: - date = Date(timeIntervalSince1970: 0) - case .todayAndYesterday: - date = Date.yesterday - case .today: - date = Date().noon - case .lastHour: - date = Date.lastHour - } + input.delete.drive(onNext: { [weak self] range in + guard let self else { return } if let realm = try? Realm() { - guard let messages = strongSelf.getResults(filterGroups: filterGroups.value, searchText: nil)?.filter("createDate >= %@", date) else { + guard let messages = self.getResults(filterGroups: filterGroups.value, searchText: nil)?.filter("createDate >= %@ and createDate <= %@ ", range.startDate, range.endDate) else { return } @@ -423,8 +411,8 @@ class MessageListViewModel: ViewModel, ViewModelType { } } - strongSelf.page = 0 - messagesRelay.accept([MessageSection(header: "model", messages: strongSelf.getNextPage())]) + self.page = 0 + messagesRelay.accept([MessageSection(header: "model", messages: self.getNextPage())]) }).disposed(by: rx.disposeBag) diff --git a/Model/MessageDeleteTimeRange.swift b/Model/MessageDeleteTimeRange.swift new file mode 100644 index 00000000..c38919fc --- /dev/null +++ b/Model/MessageDeleteTimeRange.swift @@ -0,0 +1,92 @@ +// +// MessageDeleteTimeRange.swift +// Bark +// +// Created by huangfeng on 1/7/25. +// Copyright © 2025 Fin. All rights reserved. +// + +import Foundation + +enum MessageDeleteTimeRange { + /// 最近一小时 + case lastHour + /// 今天 + case today + /// 今天和昨天 + case todayAndYesterday + /// 最近一个月 + case lastMonth + /// 全部时间 + case allTime + + /// 一小时之前 + case beforeOneHour + /// 一天之前 + case beforeToday + /// 昨天之前 + case beforeYesterday + /// 一月之前 + case beforeOneMonth + + var string: String { + switch self { + case .lastHour: + return NSLocalizedString("lastHour") + case .today: + return NSLocalizedString("today") + case .todayAndYesterday: + return NSLocalizedString("todayAndYesterday") + case .lastMonth: + return NSLocalizedString("lastMonth") + case .allTime: + return NSLocalizedString("allTime") + case .beforeOneHour: + return NSLocalizedString("beforeAnHour") + case .beforeToday: + return NSLocalizedString("beforeToday") + case .beforeYesterday: + return NSLocalizedString("beforeYesterday") + case .beforeOneMonth: + return NSLocalizedString("beforeAMonth") + } + } + + var startDate: Date { + switch self { + case .lastHour: + return Date.lastHour + case .today: + return Date().startOfDay + case .todayAndYesterday: + return Date.yesterday + case .lastMonth: + return Date.lastMonth + case .allTime, + .beforeOneHour, + .beforeToday, + .beforeYesterday, + .beforeOneMonth: + return Date(timeIntervalSince1970: 0) + } + } + + var endDate: Date { + switch self { + case .lastHour, + .today, + .todayAndYesterday, + .lastMonth, + .allTime: + return Date() + case .beforeOneHour: + return Date.lastHour + case .beforeToday: + return Date().startOfDay + case .beforeYesterday: + return Date.yesterday + case .beforeOneMonth: + return Date.lastMonth + } + } +}