From 4fcf45d5453df39c4b3d885a5c483b1a4e79e18f Mon Sep 17 00:00:00 2001 From: evgeny Date: Sun, 4 Oct 2026 19:12:18 +0200 Subject: [PATCH] Accept browser URL paths on Android and drag within the tested link --- .../java/com/utun/chat/data/MessageLinks.kt | 17 +++++++++-------- tools/chatgui/tests/test_invite_links.cpp | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/MessageLinks.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/MessageLinks.kt index 619a387f..a4ca1da8 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/MessageLinks.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/MessageLinks.kt @@ -1,21 +1,22 @@ package com.utun.chat.data -import java.net.URI +import java.net.URL /** Границы UTF-16 и полный адрес; разбор не меняет текст и не открывает ссылки. */ data class MessageLink(val start: Int, val end: Int, val url: String) object MessageLinks { private val pattern = Regex("utun://[A-Za-z0-9+/]+={0,2}|(?i:https?://)[^\\s\\p{Z}\\p{Cc}<>\"'`«»“”‘’]+") + private val invalidEscape = Regex("%(?![0-9A-Fa-f]{2})") /** Некорректные URL в пользовательском тексте остаются обычным текстом. */ - fun isWebUrl(url: String): Boolean = try { - val uri = URI(url) - (uri.scheme.equals("http", true) || uri.scheme.equals("https", true)) && - uri.toURL().let { it.host.isNotEmpty() && it.port in -1..65535 } - } catch (_: IllegalArgumentException) { false } - catch (_: java.net.URISyntaxException) { false } - catch (_: java.net.MalformedURLException) { false } + fun isWebUrl(url: String): Boolean { + if (!pattern.matches(url) || invalidEscape.containsMatchIn(url)) return false + return try { + val parsed = URL(url) + (parsed.protocol == "http" || parsed.protocol == "https") && parsed.host.isNotEmpty() && parsed.port in -1..65535 + } catch (_: java.net.MalformedURLException) { false } + } fun parse(text: String): List = pattern.findAll(text).mapNotNull { match -> var url = match.value diff --git a/tools/chatgui/tests/test_invite_links.cpp b/tools/chatgui/tests/test_invite_links.cpp index 6953223a..19b63ed5 100644 --- a/tools/chatgui/tests/test_invite_links.cpp +++ b/tools/chatgui/tests/test_invite_links.cpp @@ -61,7 +61,7 @@ private slots: const QString hit = delegate.linkAt(option, index, QPoint(x, y)); if (hit.isEmpty()) continue; QVERIFY(hit == first || hit == second || hit == invite); - points[hit] = QPoint(x, y); + if (!points.contains(hit)) points[hit] = QPoint(x, y); if (hit == first) rows.insert(y); } }