| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -17,10 +17,8 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "./media_meta_info_loader.hpp"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "./sdl_clipboard_utils.hpp"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include "SDL_clipboard.h"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <cctype>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <cstdint>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <ctime>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <cstdio>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <chrono>
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -28,10 +26,7 @@
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <fstream>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <iomanip>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <sstream>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <string>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <variant>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				#include <vector>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				namespace Components {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -72,6 +67,48 @@ static std::string file_path_url_escape(const std::string&& value) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return escaped.str();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				const void* clipboard_callback(void* userdata, const char* mime_type, size_t* size) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (mime_type == nullptr) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// cleared or new data is set
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (userdata == nullptr) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// error
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					auto* cg = static_cast<ChatGui4*>(userdata);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					std::lock_guard lg{cg->_set_clipboard_data_mutex};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (!cg->_set_clipboard_data.count(mime_type)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					const auto& sh_vec = cg->_set_clipboard_data.at(mime_type);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (!static_cast<bool>(sh_vec)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// error, empty shared pointer
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return nullptr;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					*size = sh_vec->size();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return sh_vec->data();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void ChatGui4::setClipboardData(std::vector<std::string> mime_types, std::shared_ptr<std::vector<uint8_t>>&& data) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					std::vector<const char*> tmp_mimetype_list;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (const auto& mime_type : mime_types) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						tmp_mimetype_list.push_back(mime_type.data());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					std::lock_guard lg{_set_clipboard_data_mutex};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (const auto& mime_type : mime_types) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						_set_clipboard_data[mime_type] = data;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					SDL_SetClipboardData(clipboard_callback, nullptr, this, tmp_mimetype_list.data(), tmp_mimetype_list.size());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ChatGui4::ChatGui4(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ConfigModelI& conf,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					RegistryMessageModel& rmm,
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -80,6 +117,17 @@ ChatGui4::ChatGui4(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu), _msg_tc(_mil, tu), _sip(tu) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				ChatGui4::~ChatGui4(void) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// TODO: this is bs
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					SDL_ClearClipboardData();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// this might be better, need to see if this works (docs needs improving)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					//for (const auto& [k, _] : _set_clipboard_data) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						//const auto* tmp_mime_type = k.c_str();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						//SDL_SetClipboardData(nullptr, nullptr, nullptr, &tmp_mime_type, 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					//}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void ChatGui4::render(float time_delta) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (!_cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						std::vector<Contact3> to_purge;
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -514,7 +562,7 @@ void ChatGui4::render(float time_delta) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										_fss.requestFile(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											[](const auto& path) -> bool { return std::filesystem::is_regular_file(path); },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											[this](const auto& path){
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												_rmm.sendFilePath(*_selected_contact, path.filename().u8string(), path.u8string());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												_rmm.sendFilePath(*_selected_contact, path.filename().generic_u8string(), path.generic_u8string());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											[](){}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										);
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -577,7 +625,7 @@ void ChatGui4::render(float time_delta) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void ChatGui4::sendFilePath(const char* file_path) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (_selected_contact && std::filesystem::is_regular_file(file_path)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						_rmm.sendFilePath(*_selected_contact, std::filesystem::path(file_path).filename().u8string(), file_path);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						_rmm.sendFilePath(*_selected_contact, std::filesystem::path(file_path).filename().generic_u8string(), file_path);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -671,10 +719,10 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							//for (const auto& c : _cr.view<entt::get_t<Contact::Components::TagBig>, entt::exclude_t<Contact::Components::RequestIncoming, Contact::Components::TagRequestOutgoing>>()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							for (const auto& c : _cr.view<Contact::Components::TagBig>()) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if (renderContactListContactSmall(c, false)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									//_rmm.sendFilePath(*_selected_contact, path.filename().u8string(), path.u8string());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									//_rmm.sendFilePath(*_selected_contact, path.filename().generic_u8string(), path.generic_u8string());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									const auto& fil = reg.get<Message::Components::Transfer::FileInfoLocal>(e);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									for (const auto& path : fil.file_list) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										_rmm.sendFilePath(c, std::filesystem::path{path}.filename().u8string(), path);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										_rmm.sendFilePath(c, std::filesystem::path{path}.filename().generic_u8string(), path);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -761,10 +809,19 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							const auto& local_info = reg.get<Message::Components::Transfer::FileInfoLocal>(e);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (local_info.file_list.size() > i && ImGui::BeginPopupContextItem("##file_c")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if (ImGui::MenuItem("open")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									std::string url{"file://" + file_path_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).u8string())};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									const std::string url{"file://" + file_path_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).generic_u8string())};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									std::cout << "opening file '" << url << "'\n";
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									SDL_OpenURL(url.c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if (ImGui::MenuItem("copy file")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									const std::string url{"file://" + file_path_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).generic_u8string())};
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									//ImGui::SetClipboardText(url.c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									setClipboardData({"text/uri-list", "text/x-moz-url"}, std::make_shared<std::vector<uint8_t>>(url.begin(), url.end()));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if (ImGui::MenuItem("copy filepath")) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									const auto file_path = std::filesystem::canonical(local_info.file_list.at(i)).u8string(); //TODO: use generic over native?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									ImGui::SetClipboardText(file_path.c_str());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								ImGui::EndPopup();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				@@ -1065,7 +1122,7 @@ void ChatGui4::pasteFile(const char* mime_type) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							std::ofstream(tmp_file_path, std::ios_base::out | std::ios_base::binary)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								.write(reinterpret_cast<const char*>(img_data.data()), img_data.size());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							_rmm.sendFilePath(*_selected_contact, tmp_file_name.str(), tmp_file_path.u8string());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							_rmm.sendFilePath(*_selected_contact, tmp_file_name.str(), tmp_file_path.generic_u8string());
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						[](){}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					);
 | 
			
		
		
	
	
		
			
				
					
					| 
						
					 | 
				
			
			 | 
			 | 
			
				 
 |