mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-22 15:22:07 +00:00
opuse 5.5 /goal iterations
This commit is contained in:
1 parent
ab61d51afd
commit
0a245c67cb
10 files changed
+36
-83
No files matched your search
@@ -1496,7 +1496,7 @@ enum NameRegistration: Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
// stock derivation cannot read this: the core tags it flat as {"type": ...}, not in swift's nested shape
|
||||
// stock derivation cannot decode this: the core encodes it with a flat "type" tag, not swift's nested shape
|
||||
extension NameRegistration: Decodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case type, expires, graceUntil, reservedReason_, pricing, reservedReason
|
||||
|
||||
@@ -1344,7 +1344,7 @@ func recordSimplexNameResolved(_ domain: SimplexDomain, _ reg: NameRegistration?
|
||||
saveNamesResolvedAt(m)
|
||||
}
|
||||
|
||||
func forgetSimplexNameResolved(_ fullDomainName: String) {
|
||||
func clearSimplexNameResolved(_ fullDomainName: String) {
|
||||
var m = simplexNamesResolvedAtDefault.get()
|
||||
if m.removeValue(forKey: fullDomainName) != nil { saveNamesResolvedAt(m) }
|
||||
}
|
||||
@@ -1358,13 +1358,6 @@ private func nameCentsPerYear(_ pricing: NamePricing, _ domain: SimplexDomain) -
|
||||
return "$\(cents / 100)" + (cents % 100 == 0 ? "" : String(format: ".%02lld", cents % 100))
|
||||
}
|
||||
|
||||
private func showNameNotRegisteredAlert() {
|
||||
showAlert(
|
||||
NSLocalizedString("Name not registered", comment: "alert title"),
|
||||
message: NSLocalizedString("This SimpleX name is not registered. Please check the name.", comment: "")
|
||||
)
|
||||
}
|
||||
|
||||
private func showNameRegistrationAlert(
|
||||
domain: SimplexDomain,
|
||||
reg: NameRegistration,
|
||||
@@ -1520,6 +1513,7 @@ func planAndConnect(
|
||||
case .contactAddress(.ownLink, _), .groupLink(.ownLink, _): true
|
||||
default: false
|
||||
}
|
||||
let notConnectable = if case .nameNotConnectable = connectionPlan { true } else { false }
|
||||
let handled = await MainActor.run {
|
||||
var openExisting: (() -> Void)? = nil
|
||||
if let contact = knownContact {
|
||||
@@ -1545,7 +1539,7 @@ func planAndConnect(
|
||||
domain: nameDomain,
|
||||
reg: nameReg,
|
||||
isOwn: isOwnName,
|
||||
notConnectable: { if case .nameNotConnectable = connectionPlan { true } else { false } }(),
|
||||
notConnectable: notConnectable,
|
||||
hasLocalChat: knownContact != nil || knownGroup != nil,
|
||||
openExistingChat: openExisting,
|
||||
cleanup: cleanup
|
||||
@@ -1554,19 +1548,12 @@ func planAndConnect(
|
||||
if handled { return }
|
||||
}
|
||||
guard let connectionLink = result.connLink else {
|
||||
await MainActor.run {
|
||||
if case .nameNotConnectable = connectionPlan { showNameNotRegisteredAlert() }
|
||||
cleanup?()
|
||||
}
|
||||
await MainActor.run { cleanup?() }
|
||||
return
|
||||
}
|
||||
switch connectionPlan {
|
||||
case .nameNotConnectable:
|
||||
logger.debug("planAndConnect, .nameNotConnectable")
|
||||
await MainActor.run {
|
||||
showNameNotRegisteredAlert()
|
||||
cleanup?()
|
||||
}
|
||||
break
|
||||
case let .invitationLink(ilp):
|
||||
switch ilp {
|
||||
case let .ok(contactSLinkData_, ownerVerification):
|
||||
|
||||
@@ -205,7 +205,7 @@ struct UserAddressView: View {
|
||||
save: { simplexDomain in
|
||||
do {
|
||||
let u = try await apiSetUserDomain(simplexDomain)
|
||||
if let d = chatModel.currentUser?.profile.contactDomain?.domain { forgetSimplexNameResolved(d) }
|
||||
if let d = chatModel.currentUser?.profile.contactDomain?.domain { clearSimplexNameResolved(d) }
|
||||
await MainActor.run { chatModel.updateUser(u) }
|
||||
return true
|
||||
} catch {
|
||||
|
||||
+3
-21
@@ -108,7 +108,7 @@ fun recordSimplexNameResolved(domain: SimplexDomain, reg: NameRegistration?) {
|
||||
saveNamesResolvedAt(m)
|
||||
}
|
||||
|
||||
fun forgetSimplexNameResolved(fullDomainName: String) {
|
||||
fun clearSimplexNameResolved(fullDomainName: String) {
|
||||
val m = loadNamesResolvedAt()
|
||||
if (m.remove(fullDomainName) != null) saveNamesResolvedAt(m)
|
||||
}
|
||||
@@ -254,12 +254,7 @@ private suspend fun planAndConnectTask(
|
||||
val label = if (it.nameType == SimplexNameType.publicGroup) MR.strings.connect_plan_join_name else MR.strings.connect_plan_connect_to_name
|
||||
generalGetString(label).format(it.shortStr)
|
||||
}
|
||||
val nameReg = when (connectionPlan) {
|
||||
is ConnectionPlan.NameNotConnectable -> connectionPlan.nameRegistration
|
||||
is ConnectionPlan.ContactAddress -> connectionPlan.nameRegistration_
|
||||
is ConnectionPlan.GroupLink -> connectionPlan.nameRegistration_
|
||||
else -> null
|
||||
}
|
||||
val nameReg = connectionPlan.nameRegistration()
|
||||
val nameDomain = when (connectionPlan) {
|
||||
is ConnectionPlan.NameNotConnectable -> connectionPlan.simplexDomain
|
||||
else -> planSimplexName?.nameDomain
|
||||
@@ -290,24 +285,11 @@ private suspend fun planAndConnectTask(
|
||||
if (handled) return completable
|
||||
}
|
||||
val connectionLink = connectionLink_ ?: run {
|
||||
when (connectionPlan) {
|
||||
is ConnectionPlan.NameNotConnectable -> AlertManager.privacySensitive.showAlertMsg(
|
||||
generalGetString(MR.strings.simplex_name_not_registered),
|
||||
generalGetString(MR.strings.simplex_name_not_found_desc)
|
||||
)
|
||||
else -> {}
|
||||
}
|
||||
cleanup()
|
||||
return completable
|
||||
}
|
||||
when (connectionPlan) {
|
||||
is ConnectionPlan.NameNotConnectable -> {
|
||||
AlertManager.privacySensitive.showAlertMsg(
|
||||
generalGetString(MR.strings.simplex_name_not_registered),
|
||||
generalGetString(MR.strings.simplex_name_not_found_desc)
|
||||
)
|
||||
cleanup()
|
||||
}
|
||||
is ConnectionPlan.NameNotConnectable -> {}
|
||||
is ConnectionPlan.InvitationLink -> when (connectionPlan.invitationLinkPlan) {
|
||||
is InvitationLinkPlan.Ok ->
|
||||
if (connectionPlan.invitationLinkPlan.contactSLinkData_ != null) {
|
||||
|
||||
+1
-1
@@ -388,7 +388,7 @@ private fun UserAddressLayout(
|
||||
save = { simplexDomain ->
|
||||
try {
|
||||
val u = chatModel.controller.apiSetUserDomain(user?.remoteHostId, simplexDomain)
|
||||
domain?.let { forgetSimplexNameResolved(it) }
|
||||
domain?.let { clearSimplexNameResolved(it) }
|
||||
withContext(Dispatchers.Main) { chatModel.updateUser(u) }
|
||||
true
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -1150,9 +1150,9 @@ data ChatDeleteMode
|
||||
|
||||
data ConnectionPlan
|
||||
= CPInvitationLink {invitationLinkPlan :: InvitationLinkPlan}
|
||||
| CPContactAddress {contactAddressPlan :: ContactAddressPlan, nameRegistration_ :: Maybe NameRegistration} -- nameRegistration_ is set when the target was a name
|
||||
| CPContactAddress {contactAddressPlan :: ContactAddressPlan, nameRegistration_ :: Maybe NameRegistration}
|
||||
| CPGroupLink {groupLinkPlan :: GroupLinkPlan, nameRegistration_ :: Maybe NameRegistration}
|
||||
| CPNameNotConnectable {simplexDomain :: SimplexDomain, nameRegistration :: NameRegistration} -- the name is not registered, expired or has no usable link, and no local chat has it
|
||||
| CPNameNotConnectable {simplexDomain :: SimplexDomain, nameRegistration :: NameRegistration}
|
||||
| CPError {chatError :: ChatError}
|
||||
deriving (Show)
|
||||
|
||||
|
||||
@@ -4419,14 +4419,13 @@ processChatCommand cxt nm = \case
|
||||
tryAllErrors (resolveNameRegistration user nm d) >>= \case
|
||||
Right reg -> do
|
||||
expired <- nameExpired reg
|
||||
case reg of
|
||||
NRRegistered {nameRecord = nr}
|
||||
| not expired && isJust (firstNameLink CCTChannel (nrSimplexChannel nr)) ->
|
||||
(setPlanRegistration reg <$> connectPlanName NTPublicGroup (Right reg)) `catchAllErrors` \e ->
|
||||
(setPlanRegistration reg <$> connectPlanName NTContact (Right reg) `catchAllErrors` \_ -> throwError e)
|
||||
| not expired && isJust (firstNameLink CCTContact (nrSimplexContact nr)) ->
|
||||
setPlanRegistration reg <$> connectPlanName NTContact (Right reg)
|
||||
_ -> connectPlanLocal reg
|
||||
let connectable nameType = not expired && nameHasLink nameType reg
|
||||
if
|
||||
| connectable NTPublicGroup ->
|
||||
(setPlanRegistration reg <$> connectPlanName NTPublicGroup (Right reg)) `catchAllErrors` \e ->
|
||||
(setPlanRegistration reg <$> connectPlanName NTContact (Right reg) `catchAllErrors` \_ -> throwError e)
|
||||
| connectable NTContact -> setPlanRegistration reg <$> connectPlanName NTContact (Right reg)
|
||||
| otherwise -> connectPlanLocal reg
|
||||
Left e -> connectPlanNoName e
|
||||
where
|
||||
connectPlanLocal reg =
|
||||
@@ -4438,10 +4437,9 @@ processChatCommand cxt nm = \case
|
||||
connectPlanName nameType nr_ = setOtherName <$> connectPlan user (nameTarget nameType) resolveMode sig_ (Just nr_)
|
||||
where
|
||||
setOtherName (l, planName, _, p) = (l, planName, otherName, p)
|
||||
otherName = case nr_ of
|
||||
Right NRRegistered {nameRecord = NameRecord {nrSimplexContact, nrSimplexChannel}} -> case nameType of
|
||||
NTContact -> SimplexNameInfo NTPublicGroup d <$ firstNameLink CCTChannel nrSimplexChannel
|
||||
NTPublicGroup -> SimplexNameInfo NTContact d <$ firstNameLink CCTContact nrSimplexContact
|
||||
otherName = case (nameType, nr_) of
|
||||
(NTContact, Right reg) | nameHasLink NTPublicGroup reg -> Just $ SimplexNameInfo NTPublicGroup d
|
||||
(NTPublicGroup, Right reg) | nameHasLink NTContact reg -> Just $ SimplexNameInfo NTContact d
|
||||
_ -> Nothing
|
||||
nameTarget nameType = ACTarget SCMContact $ CTShortContact $ CTName $ SimplexNameInfo nameType d
|
||||
connectPlanNoName e =
|
||||
@@ -4454,10 +4452,10 @@ processChatCommand cxt nm = \case
|
||||
| CTName ni <- nl, isNothing nameRec, resolveMode /= PRMNever -> do
|
||||
reg <- resolveNameRegistration user nm (nameDomain ni)
|
||||
expired <- nameExpired reg
|
||||
if nameHasLink ni reg && not expired
|
||||
then setPlanRegistration reg <$> connectPlan user (ACTarget SCMContact (CTShortContact nl)) resolveMode sig_ (Just (Right reg))
|
||||
if nameHasLink (nameType ni) reg && not expired
|
||||
then setPlanRegistration reg <$> connectPlan user (ACTarget SCMContact ct) resolveMode sig_ (Just (Right reg))
|
||||
else
|
||||
(setPlanRegistration reg <$> connectPlan user (ACTarget SCMContact (CTShortContact nl)) PRMNever sig_ (Just (Right reg)))
|
||||
(setPlanRegistration reg <$> connectPlan user (ACTarget SCMContact ct) PRMNever sig_ (Just (Right reg)))
|
||||
`catchAllErrors` \_ -> pure (Nothing, Nothing, Nothing, CPNameNotConnectable (nameDomain ni) reg)
|
||||
CTShortContact nl ->
|
||||
(\(l, p) -> (Just l, simplexName_, Nothing, p)) <$> case ctType of
|
||||
@@ -5124,8 +5122,8 @@ nameExpired = \case
|
||||
NRRegistered {expires = Just expires} -> (expires <) <$> liftIO getSystemSeconds
|
||||
_ -> pure False
|
||||
|
||||
nameHasLink :: SimplexNameInfo -> NameRegistration -> Bool
|
||||
nameHasLink SimplexNameInfo {nameType} = \case
|
||||
nameHasLink :: SimplexNameType -> NameRegistration -> Bool
|
||||
nameHasLink nameType = \case
|
||||
NRRegistered {nameRecord = NameRecord {nrSimplexContact, nrSimplexChannel}} -> case nameType of
|
||||
NTContact -> isJust (firstNameLink CCTContact nrSimplexContact)
|
||||
NTPublicGroup -> isJust (firstNameLink CCTChannel nrSimplexChannel)
|
||||
|
||||
@@ -2250,11 +2250,10 @@ viewNameRegistration = \case
|
||||
["registered" <> expiryNote expires graceUntil <> maybe "" ((", reserved: " <>) . plain . textEncode) reservedReason_]
|
||||
Just NRAvailable {pricing = NamePricing {basePrice = USDCents c, minLabelLength}} ->
|
||||
["available: " <> plain (show c) <> " cents/year, min length " <> plain (show minLabelLength)]
|
||||
Just NRReserved {reservedReason} -> ["reserved: " <> plain (textEncode reservedReason :: Text)]
|
||||
Just NRReserved {reservedReason} -> ["reserved: " <> plain (textEncode reservedReason)]
|
||||
Nothing -> []
|
||||
expiryNote expires graceUntil = case expires of
|
||||
Nothing -> ""
|
||||
Just e -> ", expires " <> plain (show (roundedSeconds e)) <> maybe "" (\g -> ", grace until " <> plain (show (roundedSeconds g))) graceUntil
|
||||
expiryNote expires graceUntil = maybe "" (\e -> ", expires " <> showTime e <> maybe "" ((", grace until " <>) . showTime) graceUntil) expires
|
||||
showTime = plain . show . roundedSeconds
|
||||
|
||||
viewConnectionPlan :: ChatConfig -> Maybe ACreatedConnLink -> ConnectionPlan -> [StyledString]
|
||||
viewConnectionPlan ChatConfig {logLevel, testView} _connLink = \case
|
||||
@@ -2277,10 +2276,7 @@ viewConnectionPlan ChatConfig {logLevel, testView} _connLink = \case
|
||||
| business -> ("business address: " <>)
|
||||
_ -> ("invitation link: " <>)
|
||||
CPContactAddress cap _ -> case cap of
|
||||
CAPOk contactSLinkData ov addressChanged ->
|
||||
[addrOrBiz contactSLinkData (if addressChanged then "ok to connect, address changed" else "ok to connect")]
|
||||
<> viewSigVerification ov
|
||||
<> [viewJSON contactSLinkData | testView]
|
||||
CAPOk contactSLinkData ov addressChanged -> [addrOrBiz contactSLinkData ("ok to connect" <> (if addressChanged then ", address changed" else ""))] <> viewSigVerification ov <> [viewJSON contactSLinkData | testView]
|
||||
CAPOwnLink -> [ctAddr "own address"]
|
||||
CAPConnectingConfirmReconnect -> [ctAddr "connecting, allowed to reconnect"]
|
||||
CAPConnectingProhibit ct -> [ctAddr ("connecting to contact " <> ttyContact' ct)]
|
||||
|
||||
@@ -48,7 +48,7 @@ testConnectByName :: HasCallStack => TestParams -> IO ()
|
||||
testConnectByName ps = withSmpServerAndNames $ \reg ->
|
||||
testChat2 aliceProfile bobProfile (test reg) ps
|
||||
where
|
||||
aliceName = aliceSimplexName
|
||||
aliceName = SimplexNameInfo NTContact (SimplexDomain TLDSimplex "alice" [])
|
||||
test reg alice bob = do
|
||||
mapM_ enableNamesRole [alice, bob]
|
||||
alice ##> "/ad"
|
||||
@@ -393,7 +393,7 @@ testPlanNameReservedOther = withAliceName $ \reg _l _alice bob -> do
|
||||
|
||||
testPlanNameNoValidLink :: HasCallStack => TestParams -> IO ()
|
||||
testPlanNameNoValidLink = withAliceName $ \reg _l _alice bob -> do
|
||||
registerName reg boogaloo (emptyNameRecord "boogaloo.simplex")
|
||||
registerName reg boogaloo (emptyRecord "boogaloo.simplex")
|
||||
bob ##> "/_connect plan 1 @boogaloo.simplex"
|
||||
bob <## "SimpleX name boogaloo.simplex: nothing to connect to"
|
||||
bob <## "registered"
|
||||
|
||||
+2
-12
@@ -15,7 +15,7 @@ module NameResolver
|
||||
registerAvailableName,
|
||||
unregisterName,
|
||||
failNameResolution,
|
||||
emptyNameRecord,
|
||||
emptyRecord,
|
||||
contactNameRecord,
|
||||
channelNameRecord,
|
||||
contactAndChannelNameRecord,
|
||||
@@ -61,16 +61,14 @@ withNameResolver action = do
|
||||
Just (AnswerRegistration registration) -> (ok200, J.encode NameResponse {lastBlockTs = Nothing, registration})
|
||||
Nothing -> (ok200, J.encode NameResponse {lastBlockTs = Nothing, registration = NRAvailable {pricing = testPricing 1}})
|
||||
|
||||
-- | Register a name's domain to resolve to the given record, as a live registration.
|
||||
-- | Register a name's domain to resolve to the given record.
|
||||
registerName :: NameRegistry -> SimplexNameInfo -> NameRecord -> IO ()
|
||||
registerName reg ni nameRecord =
|
||||
registerRegistration reg ni NRRegistered {expires = Nothing, graceUntil = Nothing, reservedReason_ = Nothing, nameRecord}
|
||||
|
||||
-- | Register any registration the registry could answer with.
|
||||
registerRegistration :: NameRegistry -> SimplexNameInfo -> NameRegistration -> IO ()
|
||||
registerRegistration reg ni r = atomically $ modifyTVar' reg $ M.insert (registryKey ni) (AnswerRegistration r)
|
||||
|
||||
-- | A name that expired a day ago, renewable by its owner for another 30 days.
|
||||
registerExpiredName :: NameRegistry -> SimplexNameInfo -> NameRecord -> IO ()
|
||||
registerExpiredName reg ni nameRecord = do
|
||||
RoundedSystemTime now <- getSystemSeconds
|
||||
@@ -78,19 +76,15 @@ registerExpiredName reg ni nameRecord = do
|
||||
graceUntil = Just $ RoundedSystemTime (now + 30 * 86400)
|
||||
registerRegistration reg ni NRRegistered {expires, graceUntil, reservedReason_ = Nothing, nameRecord}
|
||||
|
||||
-- | A name the registry holds back.
|
||||
registerReservedName :: NameRegistry -> SimplexNameInfo -> NameReservedReason -> IO ()
|
||||
registerReservedName reg ni reservedReason = registerRegistration reg ni NRReserved {reservedReason}
|
||||
|
||||
-- | A name that is free, priced with the given minimum label length.
|
||||
registerAvailableName :: NameRegistry -> SimplexNameInfo -> Int -> IO ()
|
||||
registerAvailableName reg ni minLen = registerRegistration reg ni NRAvailable {pricing = testPricing minLen}
|
||||
|
||||
-- | Make the resolver fail for this name, as a registry that is down or erroring would.
|
||||
failNameResolution :: NameRegistry -> SimplexNameInfo -> IO ()
|
||||
failNameResolution reg ni = atomically $ modifyTVar' reg $ M.insert (registryKey ni) AnswerFails
|
||||
|
||||
-- | Drop a name, so it resolves as available again.
|
||||
unregisterName :: NameRegistry -> SimplexNameInfo -> IO ()
|
||||
unregisterName reg ni = atomically $ modifyTVar' reg $ M.delete (registryKey ni)
|
||||
|
||||
@@ -112,10 +106,6 @@ contactAndChannelNameRecord :: Text -> Text -> Text -> NameRecord
|
||||
contactAndChannelNameRecord name contactLink channelLink =
|
||||
(emptyRecord name) {nrSimplexContact = [contactLink], nrSimplexChannel = [channelLink]}
|
||||
|
||||
-- | A registered name whose record holds no usable link.
|
||||
emptyNameRecord :: Text -> NameRecord
|
||||
emptyNameRecord = emptyRecord
|
||||
|
||||
emptyRecord :: Text -> NameRecord
|
||||
emptyRecord name =
|
||||
NameRecord
|
||||
|
||||
Reference in new issue
Block a user