aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2023-03-11 23:12:25 +0100
committerdec05eba <dec05eba@protonmail.com>2023-03-11 23:12:25 +0100
commit118ea78d95a82d9f943180c8f976befc5d2dc97e (patch)
treec8daf5216042f35a0019edcfee44f343df864807 /src/plugins
parentcf28b9984b9661fbc64684cf046fa3256040ed1d (diff)
Matrix: allow pressing enter on a message with a room alias to join the room
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/Matrix.cpp83
1 files changed, 82 insertions, 1 deletions
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 062d16a..d847719 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -3464,6 +3464,74 @@ namespace QuickMedia {
return email.substr(0, index);
}
+ // Not 100% correct on the server name part, but good enough
+ static std::string_view extract_matrix_identifier(const char *str, size_t size) {
+ if(size == 0)
+ return {};
+
+ size_t index = 0;
+ switch(str[index]) {
+ case '@':
+ case '!':
+ case '$':
+ case '+':
+ case '#':
+ break;
+ default:
+ return {};
+ }
+
+ ++index;
+ const size_t local_part_start = index;
+ bool found_colon = false;
+ // Parse local part
+ for(; index < size; ++index) {
+ char c = str[index];
+ if((c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '=' || c == '_' || c == '/') {
+
+ } else if(c == ':') {
+ found_colon = true;
+ break;
+ }
+ }
+
+ if(!found_colon || index - local_part_start == 0)
+ return {};
+
+ ++index;
+ const size_t server_part_start = index;
+ // Parse server name
+ for(; index < size; ++index) {
+ char c = str[index];
+ if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '.' || c == ':' || c == '[' || c == ']') {
+
+ } else {
+ break;
+ }
+ }
+
+ if(index - server_part_start == 0)
+ return {};
+
+ return { str, index };
+ }
+
+ std::vector<std::string> matrix_extract_room_ids(const std::string &str) {
+ std::vector<std::string> result;
+ size_t index = 0;
+ while(index < str.size()) {
+ std::string_view room_id = extract_matrix_identifier(str.data() + index, str.size() - index);
+ // TODO: Support ! room id joining. It doesn't work right now. Seems like matrix itself doesn't support that
+ if(room_id.empty() || (room_id[0] != '#'/* && room_id[0] != '!'*/)) {
+ ++index;
+ } else {
+ index += room_id.size();
+ result.emplace_back(room_id.data(), room_id.size());
+ }
+ }
+ return result;
+ }
+
static std::string combine_user_display_names_for_room_name(std::vector<std::shared_ptr<UserInfo>> &user_info, const std::string &fallback_user_id) {
std::string result;
if(user_info.size() == 0)
@@ -5446,8 +5514,21 @@ namespace QuickMedia {
return true;
}
+ static std::string room_id_extract_server_name(const std::string &room_id) {
+ size_t index = room_id.find(':');
+ if(index == std::string::npos)
+ return "";
+ else
+ return room_id.substr(index + 1);
+ }
+
PluginResult Matrix::join_room(const std::string &room_id_or_name) {
assert(delegate);
+
+ std::string url = homeserver + "/_matrix/client/r0/join/" + url_param_encode(room_id_or_name);
+ if(!room_id_or_name.empty() && room_id_or_name[0] == '!')
+ url += "?via=" + url_param_encode(room_id_extract_server_name(room_id_or_name));
+
std::vector<CommandArg> additional_args = {
{ "-X", "POST" },
{ "-H", "content-type: application/json" },
@@ -5457,7 +5538,7 @@ namespace QuickMedia {
rapidjson::Document json_root;
std::string err_msg;
- DownloadResult download_result = download_json(json_root, homeserver + "/_matrix/client/r0/join/" + url_param_encode(room_id_or_name), std::move(additional_args), true, &err_msg);
+ DownloadResult download_result = download_json(json_root, url, std::move(additional_args), true, &err_msg);
if(download_result != DownloadResult::OK) return download_result_to_plugin_result(download_result);
if(!json_root.IsObject())