core, ios: check notifications token status, offer to re-register token (#5610)

* core: api to check token

* ios

* update library

* refactor

* texts

* errors

* check active token on start

* text

* Revert "check active token on start"

This reverts commit c7b6e51f94.

* update simplexmq

* offer re-register

* text

* update simplexmq

* offer on check

* rework

* text

* unset test result

* simplexmq

* alerts

* invalid reasons

* rework alert

* update simplexmq

* fix

* simplexmq

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
spaced4ndyandEvgeny Poberezkin authored and GitHub committed 2025-02-07 13:41:15 +00:00
1 parent dac8389263
commit e4d6a8822c
12 files changed
+202 -38

No files matched your search

+17
View File
@@ -288,8 +288,10 @@ struct ContentView: View {
}
prefShowLANotice = true
connectViaUrl()
showReRegisterTokenAlert()
}
.onChange(of: chatModel.appOpenUrl) { _ in connectViaUrl() }
.onChange(of: chatModel.reRegisterTknStatus) { _ in showReRegisterTokenAlert() }
.sheet(item: $noticesSheetItem) { item in
switch item {
case let .whatsNew(updatedConditions):
@@ -468,6 +470,21 @@ struct ContentView: View {
}
}
func showReRegisterTokenAlert() {
dismissAllSheets() {
let m = ChatModel.shared
if let errorTknStatus = m.reRegisterTknStatus, let token = chatModel.deviceToken {
chatModel.reRegisterTknStatus = nil
AlertManager.shared.showAlert(Alert(
title: Text("Notifications error"),
message: Text(tokenStatusInfo(errorTknStatus, register: true)),
primaryButton: .default(Text("Register")) { reRegisterToken(token: token) },
secondaryButton: .cancel()
))
}
}
}
private func showPlanAndConnectAlert(_ alert: PlanAndConnectAlert) {
AlertManager.shared.showAlert(planAndConnectAlert(alert, dismiss: false))
}
+1
View File
@@ -267,6 +267,7 @@ final class ChatModel: ObservableObject {
@Published var deviceToken: DeviceToken?
@Published var savedToken: DeviceToken?
@Published var tokenRegistered = false
@Published var reRegisterTknStatus: NtfTknStatus? = nil
@Published var tokenStatus: NtfTknStatus?
@Published var notificationMode = NotificationsMode.off
@Published var notificationServer: String?
+45 -1
View File
@@ -542,7 +542,12 @@ func registerToken(token: DeviceToken) {
Task {
do {
let status = try await apiRegisterToken(token: token, notificationMode: mode)
await MainActor.run { m.tokenStatus = status }
await MainActor.run {
m.tokenStatus = status
if !status.workingToken {
m.reRegisterTknStatus = status
}
}
} catch let error {
logger.error("registerToken apiRegisterToken error: \(responseError(error))")
}
@@ -550,10 +555,49 @@ func registerToken(token: DeviceToken) {
}
}
func tokenStatusInfo(_ status: NtfTknStatus, register: Bool) -> String {
String.localizedStringWithFormat(NSLocalizedString("Token status: %@.", comment: "token status"), status.text)
+ "\n" + status.info(register: register)
}
func reRegisterToken(token: DeviceToken) {
let m = ChatModel.shared
let mode = m.notificationMode
logger.debug("reRegisterToken \(mode.rawValue)")
Task {
do {
let status = try await apiRegisterToken(token: token, notificationMode: mode)
await MainActor.run {
m.tokenStatus = status
showAlert(
status.workingToken
? NSLocalizedString("Notifications status", comment: "alert title")
: NSLocalizedString("Notifications error", comment: "alert title"),
message: tokenStatusInfo(status, register: false)
)
}
} catch let error {
logger.error("reRegisterToken apiRegisterToken error: \(responseError(error))")
await MainActor.run {
showAlert(
NSLocalizedString("Error registering for notifications", comment: "alert title"),
message: responseError(error)
)
}
}
}
}
func apiVerifyToken(token: DeviceToken, nonce: String, code: String) async throws {
try await sendCommandOkResp(.apiVerifyToken(token: token, nonce: nonce, code: code))
}
func apiCheckToken(token: DeviceToken) async throws -> NtfTknStatus {
let r = await chatSendCmd(.apiCheckToken(token: token))
if case let .ntfTokenStatus(status) = r { return status }
throw r
}
func apiDeleteToken(token: DeviceToken) async throws {
try await sendCommandOkResp(.apiDeleteToken(token: token))
}
@@ -13,7 +13,7 @@ struct NotificationsView: View {
@EnvironmentObject var m: ChatModel
@EnvironmentObject var theme: AppTheme
@State private var notificationMode: NotificationsMode = ChatModel.shared.notificationMode
@State private var showAlert: NotificationAlert?
@State private var ntfAlert: NotificationAlert?
@State private var legacyDatabase = dbContainerGroupDefault.get() == .documents
@State private var testing = false
@State private var testedSuccess: Bool? = nil
@@ -25,7 +25,7 @@ struct NotificationsView: View {
ProgressView().scaleEffect(2)
}
}
.alert(item: $showAlert) { alert in
.alert(item: $ntfAlert) { alert in
if let token = m.deviceToken {
return notificationAlert(alert, token)
} else {
@@ -41,7 +41,7 @@ struct NotificationsView: View {
List {
Section {
SelectionListView(list: NotificationsMode.values, selection: $notificationMode) { mode in
showAlert = .setMode(mode: mode)
ntfAlert = .setMode(mode: mode)
}
} footer: {
VStack(alignment: .leading) {
@@ -95,7 +95,7 @@ struct NotificationsView: View {
if let server = m.notificationServer {
smpServers("Push server", [server], theme.colors.secondary)
testServerButton(server)
testTokenButton(server)
}
} header: {
Text("Push notifications")
@@ -163,7 +163,7 @@ struct NotificationsView: View {
await MainActor.run {
let err = responseError(error)
logger.error("apiDeleteToken error: \(err)")
showAlert = .error(title: "Error deleting token", error: err)
ntfAlert = .error(title: "Error deleting token", error: err)
}
}
default:
@@ -181,19 +181,19 @@ struct NotificationsView: View {
await MainActor.run {
let err = responseError(error)
logger.error("apiRegisterToken error: \(err)")
showAlert = .error(title: "Error enabling notifications", error: err)
ntfAlert = .error(title: "Error enabling notifications", error: err)
}
}
}
}
}
private func testServerButton(_ server: String) -> some View {
private func testTokenButton(_ server: String) -> some View {
HStack {
Button("Test server") {
Button("Test notifications") {
testing = true
Task {
await testServer(server)
await testServerAndToken(server)
await MainActor.run { testing = false }
}
}
@@ -215,22 +215,61 @@ struct NotificationsView: View {
}
}
private func testServer(_ server: String) async {
private func testServerAndToken(_ server: String) async {
do {
let r = try await testProtoServer(server: server)
switch r {
case .success:
await MainActor.run {
testedSuccess = true
if let token = m.deviceToken {
do {
let status = try await apiCheckToken(token: token)
await MainActor.run {
m.tokenStatus = status
testedSuccess = status.workingToken
if status.workingToken {
showAlert(
NSLocalizedString("Notifications status", comment: "alert title"),
message: tokenStatusInfo(status, register: false)
)
} else {
showAlert(
title: NSLocalizedString("Notifications error", comment: "alert title"),
message: tokenStatusInfo(status, register: true),
buttonTitle: "Register",
buttonAction: {
reRegisterToken(token: token)
testedSuccess = nil
},
cancelButton: true
)
}
}
} catch let error {
await MainActor.run {
let err = responseError(error)
logger.error("apiCheckToken \(err)")
ntfAlert = .error(title: "Error checking token status", error: err)
}
}
} else {
await MainActor.run {
showAlert(
NSLocalizedString("No token!", comment: "alert title")
)
}
}
case let .failure(f):
await MainActor.run {
showAlert = .testFailure(testFailure: f)
ntfAlert = .testFailure(testFailure: f)
testedSuccess = false
}
}
} catch let error {
logger.error("testServerConnection \(responseError(error))")
await MainActor.run {
let err = responseError(error)
logger.error("testServerConnection \(err)")
ntfAlert = .error(title: "Error testing server connection", error: err)
}
}
}
}
@@ -477,7 +477,11 @@ struct SettingsView: View {
case .registered:
icon = "bolt.fill"
color = theme.colors.secondary
case .invalid:
case .invalid: fallthrough
case .invalidBad: fallthrough
case .invalidTopic: fallthrough
case .invalidExpired: fallthrough
case .invalidUnregistered:
icon = "bolt.slash"
color = theme.colors.secondary
case .confirmed:
+20 -20
View File
@@ -166,17 +166,17 @@
647F090E288EA27B00644C40 /* GroupMemberInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 647F090D288EA27B00644C40 /* GroupMemberInfoView.swift */; };
648010AB281ADD15009009B9 /* CIFileView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648010AA281ADD15009009B9 /* CIFileView.swift */; };
648679AB2BC96A74006456E7 /* ChatItemForwardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648679AA2BC96A74006456E7 /* ChatItemForwardingView.swift */; };
649B28DD2CFE07CF00536B68 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649B28D82CFE07CF00536B68 /* libffi.a */; };
649B28DE2CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649B28D92CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a */; };
649B28DF2CFE07CF00536B68 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649B28DA2CFE07CF00536B68 /* libgmpxx.a */; };
649B28E02CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649B28DB2CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a */; };
649B28E12CFE07CF00536B68 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 649B28DC2CFE07CF00536B68 /* libgmp.a */; };
649BCDA0280460FD00C3A862 /* ComposeImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCD9F280460FD00C3A862 /* ComposeImageView.swift */; };
649BCDA22805D6EF00C3A862 /* CIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649BCDA12805D6EF00C3A862 /* CIImageView.swift */; };
64AA1C6927EE10C800AC7277 /* ContextItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6827EE10C800AC7277 /* ContextItemView.swift */; };
64AA1C6C27F3537400AC7277 /* DeletedItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */; };
64C06EB52A0A4A7C00792D4D /* ChatItemInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */; };
64C3B0212A0D359700E19930 /* CustomTimePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64C3B0202A0D359700E19930 /* CustomTimePicker.swift */; };
64C8299D2D54AEEE006B9E89 /* libgmp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C829982D54AEED006B9E89 /* libgmp.a */; };
64C8299E2D54AEEE006B9E89 /* libffi.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C829992D54AEEE006B9E89 /* libffi.a */; };
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a */; };
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a */; };
64C829A12D54AEEE006B9E89 /* libgmpxx.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 64C8299C2D54AEEE006B9E89 /* libgmpxx.a */; };
64D0C2C029F9688300B38D5F /* UserAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2BF29F9688300B38D5F /* UserAddressView.swift */; };
64D0C2C229FA57AB00B38D5F /* UserAddressLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */; };
64D0C2C629FAC1EC00B38D5F /* AddContactLearnMore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64D0C2C529FAC1EC00B38D5F /* AddContactLearnMore.swift */; };
@@ -519,17 +519,17 @@
648010AA281ADD15009009B9 /* CIFileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIFileView.swift; sourceTree = "<group>"; };
648679AA2BC96A74006456E7 /* ChatItemForwardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemForwardingView.swift; sourceTree = "<group>"; };
6493D667280ED77F007A76FB /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
649B28D82CFE07CF00536B68 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
649B28D92CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a"; sourceTree = "<group>"; };
649B28DA2CFE07CF00536B68 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
649B28DB2CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a"; sourceTree = "<group>"; };
649B28DC2CFE07CF00536B68 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
649BCD9F280460FD00C3A862 /* ComposeImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeImageView.swift; sourceTree = "<group>"; };
649BCDA12805D6EF00C3A862 /* CIImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIImageView.swift; sourceTree = "<group>"; };
64AA1C6827EE10C800AC7277 /* ContextItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextItemView.swift; sourceTree = "<group>"; };
64AA1C6B27F3537400AC7277 /* DeletedItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeletedItemView.swift; sourceTree = "<group>"; };
64C06EB42A0A4A7C00792D4D /* ChatItemInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatItemInfoView.swift; sourceTree = "<group>"; };
64C3B0202A0D359700E19930 /* CustomTimePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTimePicker.swift; sourceTree = "<group>"; };
64C829982D54AEED006B9E89 /* libgmp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmp.a; sourceTree = "<group>"; };
64C829992D54AEEE006B9E89 /* libffi.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libffi.a; sourceTree = "<group>"; };
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a"; sourceTree = "<group>"; };
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a"; sourceTree = "<group>"; };
64C8299C2D54AEEE006B9E89 /* libgmpxx.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libgmpxx.a; sourceTree = "<group>"; };
64D0C2BF29F9688300B38D5F /* UserAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressView.swift; sourceTree = "<group>"; };
64D0C2C129FA57AB00B38D5F /* UserAddressLearnMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAddressLearnMore.swift; sourceTree = "<group>"; };
64D0C2C529FAC1EC00B38D5F /* AddContactLearnMore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddContactLearnMore.swift; sourceTree = "<group>"; };
@@ -675,14 +675,14 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
649B28DF2CFE07CF00536B68 /* libgmpxx.a in Frameworks */,
5CE2BA93284534B000EC33A6 /* libiconv.tbd in Frameworks */,
649B28E12CFE07CF00536B68 /* libgmp.a in Frameworks */,
5CE2BA94284534BB00EC33A6 /* libz.tbd in Frameworks */,
649B28E02CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a in Frameworks */,
64C8299D2D54AEEE006B9E89 /* libgmp.a in Frameworks */,
64C8299E2D54AEEE006B9E89 /* libffi.a in Frameworks */,
64C829A12D54AEEE006B9E89 /* libgmpxx.a in Frameworks */,
64C8299F2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a in Frameworks */,
64C829A02D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a in Frameworks */,
CE38A29C2C3FCD72005ED185 /* SwiftyGif in Frameworks */,
649B28DE2CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a in Frameworks */,
649B28DD2CFE07CF00536B68 /* libffi.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -759,11 +759,11 @@
5C764E5C279C70B7000C6508 /* Libraries */ = {
isa = PBXGroup;
children = (
649B28D82CFE07CF00536B68 /* libffi.a */,
649B28DC2CFE07CF00536B68 /* libgmp.a */,
649B28DA2CFE07CF00536B68 /* libgmpxx.a */,
649B28D92CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a */,
649B28DB2CFE07CF00536B68 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a */,
64C829992D54AEEE006B9E89 /* libffi.a */,
64C829982D54AEED006B9E89 /* libgmp.a */,
64C8299C2D54AEEE006B9E89 /* libgmpxx.a */,
64C8299A2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ-ghc9.6.3.a */,
64C8299B2D54AEEE006B9E89 /* libHSsimplex-chat-6.3.0.3-2g9X994zhsoKwinyJQVzkZ.a */,
);
path = Libraries;
sourceTree = "<group>";
+3
View File
@@ -62,6 +62,7 @@ public enum ChatCommand {
case apiGetNtfToken
case apiRegisterToken(token: DeviceToken, notificationMode: NotificationsMode)
case apiVerifyToken(token: DeviceToken, nonce: String, code: String)
case apiCheckToken(token: DeviceToken)
case apiDeleteToken(token: DeviceToken)
case apiGetNtfConns(nonce: String, encNtfInfo: String)
case apiGetConnNtfMessages(connIds: [String])
@@ -238,6 +239,7 @@ public enum ChatCommand {
case .apiGetNtfToken: return "/_ntf get "
case let .apiRegisterToken(token, notificationMode): return "/_ntf register \(token.cmdString) \(notificationMode.rawValue)"
case let .apiVerifyToken(token, nonce, code): return "/_ntf verify \(token.cmdString) \(nonce) \(code)"
case let .apiCheckToken(token): return "/_ntf check \(token.cmdString)"
case let .apiDeleteToken(token): return "/_ntf delete \(token.cmdString)"
case let .apiGetNtfConns(nonce, encNtfInfo): return "/_ntf conns \(nonce) \(encNtfInfo)"
case let .apiGetConnNtfMessages(connIds): return "/_ntf conn messages \(connIds.joined(separator: ","))"
@@ -409,6 +411,7 @@ public enum ChatCommand {
case .apiGetNtfToken: return "apiGetNtfToken"
case .apiRegisterToken: return "apiRegisterToken"
case .apiVerifyToken: return "apiVerifyToken"
case .apiCheckToken: return "apiCheckToken"
case .apiDeleteToken: return "apiDeleteToken"
case .apiGetNtfConns: return "apiGetNtfConns"
case .apiGetConnNtfMessages: return "apiGetConnNtfMessages"
+52
View File
@@ -4124,9 +4124,61 @@ public enum NtfTknStatus: String, Decodable, Hashable {
case new = "NEW"
case registered = "REGISTERED"
case invalid = "INVALID"
case invalidBad = "INVALID,BAD"
case invalidTopic = "INVALID,TOPIC"
case invalidExpired = "INVALID,EXPIRED"
case invalidUnregistered = "INVALID,UNREGISTERED"
case confirmed = "CONFIRMED"
case active = "ACTIVE"
case expired = "EXPIRED"
public var workingToken: Bool {
switch self {
case .new: true
case .registered: true
case .invalid: false
case .invalidBad: false
case .invalidTopic: false
case .invalidExpired: false
case .invalidUnregistered: false
case .confirmed: true
case .active: true
case .expired: false
}
}
public var text: String {
switch self {
case .new: NSLocalizedString("New", comment: "token status text")
case .registered: NSLocalizedString("Registered", comment: "token status text")
case .invalid: NSLocalizedString("Invalid", comment: "token status text")
case .invalidBad: NSLocalizedString("Invalid (bad token)", comment: "token status text")
case .invalidTopic: NSLocalizedString("Invalid (wrong topic)", comment: "token status text")
case .invalidExpired: NSLocalizedString("Invalid (expired)", comment: "token status text")
case .invalidUnregistered: NSLocalizedString("Invalid (unregistered)", comment: "token status text")
case .confirmed: NSLocalizedString("Confirmed", comment: "token status text")
case .active: NSLocalizedString("Active", comment: "token status text")
case .expired: NSLocalizedString("Expired", comment: "token status text")
}
}
public func info(register: Bool) -> String {
switch self {
case .new: return NSLocalizedString("Please wait for token to be registered.", comment: "token info")
case .registered: fallthrough
case .confirmed: return NSLocalizedString("Please wait for token activation to complete.", comment: "token info")
case .active: return NSLocalizedString("You should receive notifications.", comment: "token info")
case .invalid: fallthrough
case .invalidBad: fallthrough
case .invalidTopic: fallthrough
case .invalidExpired: fallthrough
case .invalidUnregistered: fallthrough
case .expired:
return register
? NSLocalizedString("Register notification token?", comment: "token info")
: NSLocalizedString("Please try to disable and re-enable notfications.", comment: "token info")
}
}
}
public struct SndFileTransfer: Decodable, Hashable {
+1 -1
View File
@@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: 45373e7f1f755ac3dfaa3f8efa03d8dc7b2d69ce
tag: 5dbe6337eab6a210d64a3b7cbdad5f0ee107686d
source-repository-package
type: git
+1 -1
View File
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."45373e7f1f755ac3dfaa3f8efa03d8dc7b2d69ce" = "0rz1n3hl59b6khnhrvwhlwdrmrb9fm291i3h03ddlqkrpg1x36m6";
"https://github.com/simplex-chat/simplexmq.git"."5dbe6337eab6a210d64a3b7cbdad5f0ee107686d" = "1adml8g8zj3z0a83zlwzl1s9fv3saj1b3q95xm8p95d2w90v3s4r";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
+1
View File
@@ -350,6 +350,7 @@ data ChatCommand
| APIGetNtfToken
| APIRegisterToken DeviceToken NotificationsMode
| APIVerifyToken DeviceToken C.CbNonce ByteString
| APICheckToken DeviceToken
| APIDeleteToken DeviceToken
| APIGetNtfConns {nonce :: C.CbNonce, encNtfInfo :: ByteString}
| ApiGetConnNtfMessages {connIds :: NonEmpty AgentConnId}
+3
View File
@@ -1288,6 +1288,8 @@ processChatCommand' vr = \case
APIRegisterToken token mode -> withUser $ \_ ->
CRNtfTokenStatus <$> withAgent (\a -> registerNtfToken a token mode)
APIVerifyToken token nonce code -> withUser $ \_ -> withAgent (\a -> verifyNtfToken a token nonce code) >> ok_
APICheckToken token -> withUser $ \_ ->
CRNtfTokenStatus <$> withAgent (`checkNtfToken` token)
APIDeleteToken token -> withUser $ \_ -> withAgent (`deleteNtfToken` token) >> ok_
APIGetNtfConns nonce encNtfInfo -> withUser $ \user -> do
ntfInfos <- withAgent $ \a -> getNotificationConns a nonce encNtfInfo
@@ -3746,6 +3748,7 @@ chatCommandP =
"/_ntf get" $> APIGetNtfToken,
"/_ntf register " *> (APIRegisterToken <$> strP_ <*> strP),
"/_ntf verify " *> (APIVerifyToken <$> strP <* A.space <*> strP <* A.space <*> strP),
"/_ntf check " *> (APICheckToken <$> strP),
"/_ntf delete " *> (APIDeleteToken <$> strP),
"/_ntf conns " *> (APIGetNtfConns <$> strP <* A.space <*> strP),
"/_ntf conn messages " *> (ApiGetConnNtfMessages <$> strP),