Browse Source

Extract message links with explicit schemes and punctuation boundaries

master
evgeny 1 week ago
parent
commit
394ac93dc4
  1. 3
      tools/chatgui/CMakeLists.txt
  2. 28
      tools/chatgui/src/message_links.cpp
  3. 14
      tools/chatgui/src/message_links.h

3
tools/chatgui/CMakeLists.txt

@ -105,6 +105,7 @@ add_executable(vibechat
src/channelsettingsdialog.cpp
src/chatview.cpp
src/messagedelegate.cpp
src/message_links.cpp
src/messagelist.cpp
src/accountlist.cpp
src/accountdelegate.cpp
@ -232,7 +233,7 @@ target_link_libraries(test_emoji_playback PRIVATE ${QT_LIBS} ${QT_TEST_LIB} rlot
add_test(NAME test_emoji_playback COMMAND test_emoji_playback)
set_tests_properties(test_emoji_playback PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=offscreen" TIMEOUT 30)
add_executable(test_invite_links tests/test_invite_links.cpp src/messagedelegate.cpp src/chatview.cpp
add_executable(test_invite_links tests/test_invite_links.cpp src/message_links.cpp src/messagedelegate.cpp src/chatview.cpp
src/accountdelegate.cpp src/flagpainter.cpp src/animtimer.cpp src/lottieicon.cpp src/emoji.cpp
src/voiceplayback.cpp src/sound_manager.cpp src/voice_audio_io.cpp src/audio_device.cpp
transport/miniaudio_impl.c transport/audio_diagnostics.cpp)

28
tools/chatgui/src/message_links.cpp

@ -0,0 +1,28 @@
#include "message_links.h"
#include <QRegularExpression>
#include <QUrl>
/* Отделить адрес от текста, сохраняя сбалансированные скобки внутри пути/query. */
QVector<MessageLink> messageLinks(const QString& text) {
static const QRegularExpression pattern(QStringLiteral(
"utun://[A-Za-z0-9+/]+={0,2}|(?i:https?://)[^\\s\\p{Z}\\p{Cc}<>\"'`«»“”‘’]+"));
QVector<MessageLink> links;
auto matches = pattern.globalMatch(text);
while (matches.hasNext()) {
const auto match = matches.next();
QString url = match.captured();
if (!url.startsWith(QStringLiteral("utun://"))) {
while (!url.isEmpty()) {
const QChar last = url.back();
const int closing = QStringLiteral(")]}").indexOf(last);
const bool unmatched = closing >= 0 && url.count(last) > url.count(QStringLiteral("([{").at(closing));
if (!QStringLiteral(".,;:!?").contains(last) && !unmatched) break;
url.chop(1);
}
const QUrl parsed(url, QUrl::StrictMode);
if (!parsed.isValid() || parsed.host().isEmpty()) continue;
}
links.append({(int)match.capturedStart(), (int)url.length(), url});
}
return links;
}

14
tools/chatgui/src/message_links.h

@ -0,0 +1,14 @@
/* Ссылки в обычном тексте сообщения: границы UTF-16 и полный адрес для подсветки и нажатия.
* Поддерживает utun:// и HTTP/HTTPS; внешняя пунктуация не входит в адрес.
* Разбор не меняет сообщение и не открывает адреса. Некорректные URL остаются обычным текстом. */
#pragma once
#include <QString>
#include <QVector>
struct MessageLink {
int start;
int length;
QString url;
};
QVector<MessageLink> messageLinks(const QString& text);
Loading…
Cancel
Save