diff --git a/Bark/Localizable.xcstrings b/Bark/Localizable.xcstrings index 6badce5..3835d8c 100644 --- a/Bark/Localizable.xcstrings +++ b/Bark/Localizable.xcstrings @@ -3594,6 +3594,35 @@ } } }, + "setServerName" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Set Server Name" + } + }, + "ja" : { + "stringUnit" : { + "state" : "translated", + "value" : "サーバー名を設定" + } + }, + "tr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sunucu Adını Ayarla" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "设置服务器名称" + } + } + } + }, "setSounds" : { "extractionState" : "manual", "localizations" : { diff --git a/Common/ServerManager.swift b/Common/ServerManager.swift index e2097b0..e80b65a 100644 --- a/Common/ServerManager.swift +++ b/Common/ServerManager.swift @@ -17,6 +17,7 @@ class Server: Codable { let address: String var key: String var state: Client.ClienState + var name: String? var host: String { return URL(string: address)?.host ?? "" @@ -33,6 +34,7 @@ class Server: Codable { case id case address case key + case name } // 解码 @@ -41,6 +43,7 @@ class Server: Codable { id = try container.decode(String.self, forKey: .id) address = try container.decode(String.self, forKey: .address) key = try container.decode(String.self, forKey: .key) + name = try container.decode(String.self, forKey: .name) state = .ok } } @@ -182,4 +185,9 @@ class ServerManager: NSObject { self.saveServers() } } + + func setServerName(server: Server, name: String?) { + server.name = name + saveServers() + } } diff --git a/Controller/ServerListViewController.swift b/Controller/ServerListViewController.swift index 671f0f1..a257d97 100644 --- a/Controller/ServerListViewController.swift +++ b/Controller/ServerListViewController.swift @@ -17,6 +17,7 @@ enum ServerActionType { case copy case reset(key: String?) case delete + case setName(name: String?) } func == (lhs: ServerActionType, rhs: ServerActionType) -> Bool { @@ -90,12 +91,21 @@ class ServerListViewController: BaseViewController { } return nil }.asDriver(onErrorDriveWith: .empty()) + + // 设置服务器名称 + let setServerName = action.compactMap { r -> (Server, String?)? in + if case ServerActionType.setName(let name) = r.1 { + return (r.0, name) + } + return nil + }.asDriver(onErrorDriveWith: .empty()) let output = viewModel.transform(input: ServerListViewModel.Input( selectServer: selectServer, copyServer: copyServer, deleteServer: deleteServer, - resetServer: resetServer + resetServer: resetServer, + setServerName: setServerName )) let dataSource = RxTableViewSectionedReloadDataSource> { _, tableView, _, item -> UITableViewCell in @@ -136,7 +146,7 @@ class ServerListViewController: BaseViewController { return relay } - let alertController = UIAlertController(title: nil, message: "\(viewModel.address.value)", preferredStyle: .actionSheet) + let alertController = UIAlertController(title: nil, message: "\(URL(string: viewModel.server.address)?.host ?? "")", preferredStyle: .actionSheet) alertController.addAction(UIAlertAction(title: NSLocalizedString("copyAddressAndKey"), style: .default, handler: { _ in relay.accept((viewModel.server, .copy)) })) @@ -157,6 +167,18 @@ class ServerListViewController: BaseViewController { relay.accept((viewModel.server, .select)) })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("setServerName"), style: .default, handler: { _ in + let alertController = UIAlertController(title: NSLocalizedString("setServerName"), message: nil, preferredStyle: .alert) + alertController.addTextField { textField in + textField.text = viewModel.server.name + } + alertController.addAction(UIAlertAction(title: NSLocalizedString("confirm"), style: .default, handler: { _ in + relay.accept((viewModel.server, .setName(name: alertController.textFields?.first?.text))) + })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("Cancel"), style: .cancel, handler: nil)) + self.navigationController?.present(alertController, animated: true, completion: nil) + })) + alertController.addAction(UIAlertAction(title: NSLocalizedString("deleteServer"), style: .destructive, handler: { _ in let alertController = UIAlertController(title: nil, message: NSLocalizedString("confirmDeleteServer"), preferredStyle: .alert) diff --git a/Controller/ServerListViewModel.swift b/Controller/ServerListViewModel.swift index c4088d7..d00cef8 100644 --- a/Controller/ServerListViewModel.swift +++ b/Controller/ServerListViewModel.swift @@ -19,6 +19,7 @@ class ServerListViewModel: ViewModel, ViewModelType { let copyServer: Driver let deleteServer: Driver let resetServer: Driver<(Server, String?)> + let setServerName: Driver<(Server, String?)> } struct Output { @@ -37,6 +38,11 @@ class ServerListViewModel: ViewModel, ViewModelType { let copy = input.copyServer.map { server -> String in "\(server.address)/\(server.key)/" } + + // 设置服务器名称 + input.setServerName.drive(onNext: { server, name in + ServerManager.shared.setServerName(server: server, name: name) + }).disposed(by: rx.disposeBag) // 删除检查,需要至少保留一个服务器 let deleteCheck = input.deleteServer.map { server -> Server? in @@ -134,7 +140,8 @@ class ServerListViewModel: ViewModel, ViewModelType { .merge( Observable.just(()), serverDeleted, - serverResetSuccess + serverResetSuccess, + input.setServerName.map { _ in () }.asObservable() ) .map { [SectionModel( diff --git a/View/ServerListTableViewCell.swift b/View/ServerListTableViewCell.swift index cd6d306..cbd896e 100644 --- a/View/ServerListTableViewCell.swift +++ b/View/ServerListTableViewCell.swift @@ -101,7 +101,7 @@ class ServerListTableViewCell: BaseTableViewCell + let name: BehaviorRelay let key: BehaviorRelay let state: BehaviorRelay init(server: Server) { self.server = server - self.address = BehaviorRelay(value: { - URL(string: server.address)?.host ?? "Invalid Server" + self.name = BehaviorRelay(value: { + var serverName = URL(string: server.address)?.host ?? "Invalid Server" + if let name = server.name, !name.isEmpty { + serverName = name + "\n" + serverName + } + return serverName }()) self.key = BehaviorRelay(value: !server.key.isEmpty ? server.key : "none") self.state = BehaviorRelay(value: server.state == .ok)