diff --git a/Bark.xcodeproj/project.pbxproj b/Bark.xcodeproj/project.pbxproj index 57c76f5..33af421 100644 --- a/Bark.xcodeproj/project.pbxproj +++ b/Bark.xcodeproj/project.pbxproj @@ -64,6 +64,8 @@ 0637FA8C20E0D7A700E80174 /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0637FA8B20E0D7A700E80174 /* BaseViewController.swift */; }; 063B909B272149BF00431EC2 /* HomeViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 063B909A272149BF00431EC2 /* HomeViewModelTests.swift */; }; 063C499520E36BF9001BCA35 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 063C499720E36BF9001BCA35 /* Localizable.strings */; }; + 0642B55A27EB13F100453D91 /* MutableTextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0642B55927EB13F100453D91 /* MutableTextCell.swift */; }; + 0642B55C27EB149900453D91 /* MutableTextCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0642B55B27EB149900453D91 /* MutableTextCellViewModel.swift */; }; 064CAB9E256BE9090018155C /* PreviewCardCellViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 064CAB9D256BE9090018155C /* PreviewCardCellViewModel.swift */; }; 064CABA6256BE9510018155C /* PreviewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 064CABA5256BE9510018155C /* PreviewModel.swift */; }; 065A4D4220EE1A31002EB2DB /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 063C499720E36BF9001BCA35 /* Localizable.strings */; }; @@ -222,6 +224,8 @@ 063B909A272149BF00431EC2 /* HomeViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewModelTests.swift; sourceTree = ""; }; 063C499620E36BF9001BCA35 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 063C499820E36C15001BCA35 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 0642B55927EB13F100453D91 /* MutableTextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutableTextCell.swift; sourceTree = ""; }; + 0642B55B27EB149900453D91 /* MutableTextCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MutableTextCellViewModel.swift; sourceTree = ""; }; 064CAB9D256BE9090018155C /* PreviewCardCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewCardCellViewModel.swift; sourceTree = ""; }; 064CABA5256BE9510018155C /* PreviewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewModel.swift; sourceTree = ""; }; 065BE43F2563D649002A8CA4 /* SoundsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundsViewModel.swift; sourceTree = ""; }; @@ -377,6 +381,8 @@ 06AE311D266F54CC00B39FBB /* GroupCellViewModel.swift */, 06C2CF222685B88D0034B127 /* TextCell.swift */, 06C2CF242685BDB80034B127 /* SpacerCell.swift */, + 0642B55927EB13F100453D91 /* MutableTextCell.swift */, + 0642B55B27EB149900453D91 /* MutableTextCellViewModel.swift */, ); path = View; sourceTree = ""; @@ -929,6 +935,7 @@ 0672CB06256903F700570C9D /* MessageListViewModel.swift in Sources */, 0633E80A256A091B00ED0680 /* MJRefresh+Rx.swift in Sources */, 0637FA8C20E0D7A700E80174 /* BaseViewController.swift in Sources */, + 0642B55C27EB149900453D91 /* MutableTextCellViewModel.swift in Sources */, 062B98C8251B27AE004562E7 /* UINavigationItem+Extension.swift in Sources */, 060481EE250F404500BC9799 /* SoundsViewController.swift in Sources */, 0603706D20E23EC000F4CA05 /* BarkSFSafariViewController.swift in Sources */, @@ -965,6 +972,7 @@ 0637FA7C20E0930E00E80174 /* BarkApi.swift in Sources */, 06C2CF252685BDB80034B127 /* SpacerCell.swift in Sources */, 06BBB8BC2567B3AD0076F63E /* ArchiveSettingCellViewModel.swift in Sources */, + 0642B55A27EB13F100453D91 /* MutableTextCell.swift in Sources */, 0637FA8020E0981E00E80174 /* BarkSettings.swift in Sources */, 065BE4402563D649002A8CA4 /* SoundsViewModel.swift in Sources */, 065BE4462563D7E5002A8CA4 /* ViewModelType.swift in Sources */, diff --git a/Bark/en.lproj/Localizable.strings b/Bark/en.lproj/Localizable.strings index 7e102e8..41548db 100644 --- a/Bark/en.lproj/Localizable.strings +++ b/Bark/en.lproj/Localizable.strings @@ -87,7 +87,7 @@ showAllGroups = "Select All Groups"; groupMessagesNotice = "Grouping of messages allows you to view messages by group."; messageGroup = "Message grouping"; -buildInfo = "Build Info"; +info = "Info"; buildDesc = "Bark was uploaded to the App Store by Github Actions."; other = "Other"; @@ -103,3 +103,5 @@ interruptionLevelNotice = "The interruption level can be set for notifications; badge = "Modify a Notification Badge"; badgeNotice = "The notification badge can be set with a number."; + +deviceTokenInfo = "Token for APNs, click to copy to clipboard."; diff --git a/Bark/zh-Hans.lproj/Localizable.strings b/Bark/zh-Hans.lproj/Localizable.strings index dc5d101..079db73 100644 --- a/Bark/zh-Hans.lproj/Localizable.strings +++ b/Bark/zh-Hans.lproj/Localizable.strings @@ -89,8 +89,8 @@ showAllGroups = "选择所有群组"; groupMessagesNotice = "对消息进行分组,推送将按group分组显示在通知中心中。\n也可在历史消息列表中选择查看不同的群组。"; messageGroup = "推送消息分组"; -buildInfo = "构建信息"; -buildDesc = "Bark 由 GitHub Actions 构建后上传到 App Store,此信息可帮助你确认当前版本是由开源代码所构建,未经任何人修改。"; +info = "信息"; +buildDesc = "Bark 由 GitHub Actions 构建后上传到 App Store,此信息可帮助你确认当前版本是由开源代码所构建,未经任何人(包含作者)修改。"; other = "其他"; faq = "常见问题"; @@ -106,3 +106,5 @@ interruptionLevelNotice = "可对通知设置中断级别,不设置则默认 badge = "设置角标"; badgeNotice = "可以为推送设置角标,角标可以是任意数字。"; + +deviceTokenInfo = "用于 APNs 推送的 Token,请勿泄露,点击可复制到剪切板。"; diff --git a/Controller/HomeViewController.swift b/Controller/HomeViewController.swift index 39d5cce..eaad784 100644 --- a/Controller/HomeViewController.swift +++ b/Controller/HomeViewController.swift @@ -51,7 +51,7 @@ class HomeViewController: BaseViewController { navigationItem.setBarButtonItems(items: [ UIBarButtonItem(customView: newButton), - UIBarButtonItem(customView: serversButton), +// UIBarButtonItem(customView: serversButton), ], position: .right) self.view.addSubview(self.tableView) diff --git a/Controller/MessageSettingsViewController.swift b/Controller/MessageSettingsViewController.swift index ae0078a..0eabc34 100644 --- a/Controller/MessageSettingsViewController.swift +++ b/Controller/MessageSettingsViewController.swift @@ -18,6 +18,7 @@ class MessageSettingsViewController: BaseViewController { tableView.register(iCloudStatusCell.self, forCellReuseIdentifier: "\(iCloudStatusCell.self)") tableView.register(ArchiveSettingCell.self, forCellReuseIdentifier: "\(ArchiveSettingCell.self)") tableView.register(DetailTextCell.self, forCellReuseIdentifier: "\(DetailTextCell.self)") + tableView.register(MutableTextCell.self, forCellReuseIdentifier: "\(MutableTextCell.self)") tableView.register(SpacerCell.self, forCellReuseIdentifier: "\(SpacerCell.self)") return tableView @@ -38,7 +39,8 @@ class MessageSettingsViewController: BaseViewController { } let output = viewModel.transform( input: MessageSettingsViewModel.Input( - itemSelected: self.tableView.rx.modelSelected(MessageSettingItem.self).asDriver() + itemSelected: self.tableView.rx.modelSelected(MessageSettingItem.self).asDriver(), + deviceToken: Client.shared.deviceToken.asDriver() ) ) @@ -65,6 +67,11 @@ class MessageSettingsViewController: BaseViewController { cell.detailTextLabel?.textColor = textColor return cell } + case let .deviceToken(viewModel): + if let cell = tableView.dequeueReusableCell(withIdentifier: "\(MutableTextCell.self)") as? MutableTextCell { + cell.bindViewModel(model: viewModel) + return cell + } case let .spacer(height, color): if let cell = tableView.dequeueReusableCell(withIdentifier: "\(SpacerCell.self)") as? SpacerCell { cell.height = height @@ -83,5 +90,10 @@ class MessageSettingsViewController: BaseViewController { output.openUrl.drive { [weak self] url in self?.navigationController?.present(BarkSFSafariViewController(url: url), animated: true, completion: nil) }.disposed(by: rx.disposeBag) + + output.copyDeviceToken.drive { [weak self] deviceToken in + UIPasteboard.general.string = deviceToken + self?.showSnackbar(text: NSLocalizedString("Copy")) + }.disposed(by: rx.disposeBag) } } diff --git a/Controller/MessageSettingsViewModel.swift b/Controller/MessageSettingsViewModel.swift index 6b2f140..75b3022 100644 --- a/Controller/MessageSettingsViewModel.swift +++ b/Controller/MessageSettingsViewModel.swift @@ -15,11 +15,13 @@ import RxSwift class MessageSettingsViewModel: ViewModel, ViewModelType { struct Input { var itemSelected: Driver + var deviceToken: Driver } struct Output { var settings: Driver<[SectionModel]> var openUrl: Driver + var copyDeviceToken: Driver } func transform(input: Input) -> Output { @@ -28,14 +30,28 @@ class MessageSettingsViewModel: ViewModel, ViewModelType { settings.append(.label(text: "iCloud")) settings.append(.iCloudStatus) settings.append(.label(text: NSLocalizedString("iCloudSync"))) - settings.append(.label(text: NSLocalizedString("defaultArchiveSettings"))) settings.append(.archiveSetting(viewModel: ArchiveSettingCellViewModel(on: ArchiveSettingManager.shared.isArchive))) settings.append(.label(text: NSLocalizedString("archiveNote"))) + settings.append(.label(text: NSLocalizedString("info"))) + settings.append(.deviceToken( + viewModel: MutableTextCellViewModel( + title: "Device Token", + text: input + .deviceToken + .map { + deviceToken in + if let deviceToken = deviceToken { + return "\(deviceToken.prefix(2))****\(deviceToken.suffix(4))" + } + return NSLocalizedString("unknown") + }) + )) + settings.append(.label(text: NSLocalizedString("deviceTokenInfo"))) + if let infoDict = Bundle.main.infoDictionary, let runId = infoDict["GitHub Run Id"] as? String { - settings.append(.label(text: NSLocalizedString("buildInfo"))) settings.append(.detail( title: "Github Run Id", text: "\(runId)", @@ -86,10 +102,21 @@ class MessageSettingsViewModel: ViewModel, ViewModelType { return nil } + let deviceTokenValue: BehaviorRelay = BehaviorRelay(value: nil) + input.deviceToken.drive(deviceTokenValue) + .disposed(by: rx.disposeBag) + let copyDeviceToken = input.itemSelected.compactMap { item -> String? in + if case MessageSettingItem.deviceToken = item { + return deviceTokenValue.value + } + return nil + } + return Output( settings: Driver<[SectionModel]> .just([SectionModel(model: "model", items: settings)]), - openUrl: openUrl) + openUrl: openUrl, + copyDeviceToken: copyDeviceToken) } } @@ -102,6 +129,8 @@ enum MessageSettingItem { case archiveSetting(viewModel: ArchiveSettingCellViewModel) // 带 详细按钮的 文本cell case detail(title: String?, text: String?, textColor: UIColor?, url: URL?) + // deviceToken + case deviceToken(viewModel: MutableTextCellViewModel) // 分隔线 case spacer(height: CGFloat, color: UIColor?) } diff --git a/View/MutableTextCell.swift b/View/MutableTextCell.swift new file mode 100644 index 0000000..b94a783 --- /dev/null +++ b/View/MutableTextCell.swift @@ -0,0 +1,35 @@ +// +// DeviceTokenCell.swift +// Bark +// +// Created by huangfeng on 2022/3/23. +// Copyright © 2022 Fin. All rights reserved. +// + +import UIKit + +class MutableTextCell: BaseTableViewCell { + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: UITableViewCell.CellStyle.value1, reuseIdentifier: reuseIdentifier) + self.selectionStyle = .none + self.accessoryType = .none + self.backgroundColor = BKColor.background.secondary + } + + @available(*, unavailable) + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func bindViewModel(model: ViewModel) { + super.bindViewModel(model: model) + guard let viewModel = model as? MutableTextCellViewModel else { + return + } + self.textLabel?.text = viewModel.title + viewModel.text + .drive(self.detailTextLabel!.rx.text) + .disposed(by: rx.reuseBag) + } +} diff --git a/View/MutableTextCellViewModel.swift b/View/MutableTextCellViewModel.swift new file mode 100644 index 0000000..790c093 --- /dev/null +++ b/View/MutableTextCellViewModel.swift @@ -0,0 +1,19 @@ +// +// DeviceTokenCellViewModel.swift +// Bark +// +// Created by huangfeng on 2022/3/23. +// Copyright © 2022 Fin. All rights reserved. +// + +import RxCocoa +import UIKit +class MutableTextCellViewModel: ViewModel { + var title: String + var text: Driver + init(title: String, text: Driver) { + self.title = title + self.text = text + super.init() + } +}