ui: connect when a SimpleX link is pasted as a markdown hyperlink (#7348)

* ui: connect when a SimpleX link is pasted as a markdown hyperlink

* remove comments

Co-authored-by: Evgeny <evgeny@poberezkin.com>

---------

Co-authored-by: Evgeny <evgeny@poberezkin.com>
This commit is contained in:
Narasimha-sc
2026-08-12 14:54:45 +01:00
committed by GitHub
co-authored by Evgeny
parent ec6e975001
commit 486c2abf26
3 changed files with 37 additions and 3 deletions
@@ -859,8 +859,8 @@ enum ConnectTarget {
func strConnectTarget(_ str: String) -> ConnectTarget? {
let parsedMd = parseSimpleXMarkdown(str)
let links = parsedMd?.filter { $0.format?.isSimplexLink ?? false } ?? []
return if links.count == 1, case let .simplexLink(_, linkType, _, smpHosts) = links[0].format {
.link(text: links[0].text, linkType: linkType, linkText: simplexLinkText(linkType, smpHosts))
return if links.count == 1, case let .simplexLink(showText, linkType, simplexUri, smpHosts) = links[0].format {
.link(text: showText != nil ? simplexUri : links[0].text, linkType: linkType, linkText: simplexLinkText(linkType, smpHosts))
} else if links.isEmpty,
let nameFt = parsedMd?.first(where: { if case .simplexName = $0.format { true } else { false } }),
case let .simplexName(nameInfo) = nameFt.format {
@@ -836,7 +836,8 @@ fun strConnectTarget(str: String): ConnectTarget? {
val links = parsedMd.filter { it.format?.isSimplexLink ?: false }
if (links.size == 1) {
val fmt = links[0].format as Format.SimplexLink
return ConnectTarget.Link(links[0].text, fmt.linkType, fmt.simplexLinkText)
val text = if (fmt.showText != null) fmt.simplexUri else links[0].text
return ConnectTarget.Link(text, fmt.linkType, fmt.simplexLinkText)
}
if (links.isEmpty()) {
val nameFt = parsedMd.firstOrNull { it.format is Format.SimplexName }
@@ -0,0 +1,33 @@
# Connecting via a SimpleX link written as a markdown hyperlink
## Problem
Pasting a short SimpleX link written as a markdown hyperlink — `[label](https://smp6.simplex.im/a#...)` — into the chat list search, the new chat sheet search, or "Tap to paste link" fails with "Invalid connection link" instead of connecting.
## Cause
`markdownP` parses such a link into a single fragment whose `format` is `SimplexLink` but whose `text` is the whole markdown source:
```
[{"format":{"type":"simplexLink","showText":"label","linkType":"contact",
"simplexUri":"simplex:/a#...?h=smp6.simplex.im","smpHosts":["smp6.simplex.im"]},
"text":"[label](https://smp6.simplex.im/a#...)"}]
```
`strConnectTarget` returns that `text` as the string to connect with. For a bare link `text` is the link, so it works; for a hyperlink it is `[label](link)`, which the core rejects as `InvalidConnReq`.
## Design
Use `simplexUri` — the link the parser already resolved — when the fragment came from the hyperlink parser, and keep using `text` otherwise:
```
text = if showText != null then simplexUri else text
```
`showText` is an exact discriminator, not a heuristic: `simplexUriFormat` is called with `Just t` only from `sowLinkP` (the hyperlink parser) and with `Nothing` from `wordMD` (bare link). Gating on it leaves every bare-link path unchanged.
This also matches how the chat item renderer already resolves the same format — `TextItemView.kt` takes `simplexUri`, never the fragment `text`, when `showText` is set. `strConnectTarget` was the outlier.
## Scope
Short links only. `sowLinkP` rejects a full link inside a hyperlink (`fail "full SimpleX link in hyperlink"`), so `[label](full-link)` yields no formatting at all and never reaches this code — it stays treated as search text, as before. Bare full links are unaffected.