Compare commits

...

4 Commits

18 changed files with 90 additions and 51 deletions

View File

@ -52,14 +52,14 @@ add_executable(tomato
./sdl_clipboard_utils.hpp ./sdl_clipboard_utils.hpp
./sdl_clipboard_utils.cpp ./sdl_clipboard_utils.cpp
./file_selector.hpp ./chat_gui/file_selector.hpp
./file_selector.cpp ./chat_gui/file_selector.cpp
./send_image_popup.hpp ./chat_gui/send_image_popup.hpp
./send_image_popup.cpp ./chat_gui/send_image_popup.cpp
./settings_window.hpp ./chat_gui/settings_window.hpp
./settings_window.cpp ./chat_gui/settings_window.cpp
./tox_ui_utils.hpp ./tox_ui_utils.hpp
./tox_ui_utils.cpp ./tox_ui_utils.cpp

View File

@ -1,10 +1,10 @@
#include "./send_image_popup.hpp" #include "./send_image_popup.hpp"
#include "./image_loader_sdl_bmp.hpp" #include "../image_loader_sdl_bmp.hpp"
#include "./image_loader_stb.hpp" #include "../image_loader_stb.hpp"
#include "./image_loader_webp.hpp" #include "../image_loader_webp.hpp"
#include "./image_loader_qoi.hpp" #include "../image_loader_qoi.hpp"
#include "./image_loader_sdl_image.hpp" #include "../image_loader_sdl_image.hpp"
#include <imgui/imgui.h> #include <imgui/imgui.h>

View File

@ -5,8 +5,8 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "./image_loader.hpp" #include "../image_loader.hpp"
#include "./texture_cache.hpp" #include "../texture_cache.hpp"
struct SendImagePopup { struct SendImagePopup {
TextureUploaderI& _tu; TextureUploaderI& _tu;

View File

@ -1,7 +1,5 @@
#include "./chat_gui4.hpp" #include "./chat_gui4.hpp"
#include "./file_selector.hpp"
#include <solanaceae/message3/components.hpp> #include <solanaceae/message3/components.hpp>
#include <solanaceae/tox_messages/components.hpp> #include <solanaceae/tox_messages/components.hpp>
#include <solanaceae/contact/components.hpp> #include <solanaceae/contact/components.hpp>
@ -197,9 +195,10 @@ float ChatGui4::render(float time_delta) {
sub_contacts = &_cr.get<Contact::Components::ParentOf>(*_selected_contact).subs; sub_contacts = &_cr.get<Contact::Components::ParentOf>(*_selected_contact).subs;
} }
const bool highlight_private {!_cr.all_of<Contact::Components::TagPrivate>(*_selected_contact)};
if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, true)) { if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, true)) {
//if (_cr.all_of<Contact::Components::ParentOf>(*_selected_contact)) { if (sub_contacts != nullptr && !_cr.all_of<Contact::Components::TagPrivate>(*_selected_contact) && _cr.all_of<Contact::Components::TagGroup>(*_selected_contact)) {
if (sub_contacts != nullptr) {
if (!sub_contacts->empty()) { if (!sub_contacts->empty()) {
if (ImGui::BeginChild("subcontacts", {150, -100}, true)) { if (ImGui::BeginChild("subcontacts", {150, -100}, true)) {
ImGui::Text("subs: %zu", sub_contacts->size()); ImGui::Text("subs: %zu", sub_contacts->size());
@ -417,7 +416,7 @@ float ChatGui4::render(float time_delta) {
std::optional<ImVec4> row_bg; std::optional<ImVec4> row_bg;
// private group message // private group message
if (_cr.any_of<Contact::Components::TagSelfWeak, Contact::Components::TagSelfStrong>(c_to.c)) { if (highlight_private && _cr.any_of<Contact::Components::TagSelfWeak, Contact::Components::TagSelfStrong>(c_to.c)) {
const ImVec4 priv_msg_hi_col = ImVec4(0.5f, 0.2f, 0.5f, 0.35f); const ImVec4 priv_msg_hi_col = ImVec4(0.5f, 0.2f, 0.5f, 0.35f);
ImU32 row_bg_color = ImGui::GetColorU32(priv_msg_hi_col); ImU32 row_bg_color = ImGui::GetColorU32(priv_msg_hi_col);
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, row_bg_color); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, row_bg_color);
@ -456,8 +455,11 @@ float ChatGui4::render(float time_delta) {
if (ImGui::TableNextColumn()) { if (ImGui::TableNextColumn()) {
// TODO: theming for hardcoded values // TODO: theming for hardcoded values
if (msg_reg.all_of<Message::Components::Remote::TimestampReceived>(e)) { if (!msg_reg.all_of<Message::Components::ReceivedBy>(e)) {
const auto list = msg_reg.get<Message::Components::Remote::TimestampReceived>(e).ts; // TODO: dedup?
ImGui::TextDisabled("_");
} else {
const auto list = msg_reg.get<Message::Components::ReceivedBy>(e).ts;
// wrongly assumes contacts never get removed from a group // wrongly assumes contacts never get removed from a group
if (sub_contacts != nullptr && list.size() < sub_contacts->size()) { if (sub_contacts != nullptr && list.size() < sub_contacts->size()) {
// if partically delivered // if partically delivered
@ -471,6 +473,7 @@ float ChatGui4::render(float time_delta) {
std::string synced_by_text {"delivery confirmed by:"}; std::string synced_by_text {"delivery confirmed by:"};
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u); const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
size_t other_contacts {0};
for (const auto& [c, syned_ts] : list) { for (const auto& [c, syned_ts] : list) {
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) { if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
//synced_by_text += "\n sself(!)"; // makes no sense //synced_by_text += "\n sself(!)"; // makes no sense
@ -480,23 +483,26 @@ float ChatGui4::render(float time_delta) {
} else { } else {
synced_by_text += "\n >" + (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>"); synced_by_text += "\n >" + (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>");
} }
other_contacts += 1;
const int64_t seconds_ago = (int64_t(syned_ts / 1000u) - now_ts_s) * -1; const int64_t seconds_ago = (int64_t(syned_ts / 1000u) - now_ts_s) * -1;
synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)"; synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)";
} }
ImGui::Text("%s", synced_by_text.c_str()); if (other_contacts > 0) {
ImGui::Text("%s", synced_by_text.c_str());
} else {
ImGui::TextUnformatted("no delivery confirmation");
}
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
} else {
ImGui::TextDisabled("_");
} }
ImGui::SameLine(); ImGui::SameLine();
// TODO: dedup // TODO: dedup
if (msg_reg.all_of<Message::Components::Remote::TimestampRead>(e)) { if (msg_reg.all_of<Message::Components::ReadBy>(e)) {
const auto list = msg_reg.get<Message::Components::Remote::TimestampRead>(e).ts; const auto list = msg_reg.get<Message::Components::ReadBy>(e).ts;
// wrongly assumes contacts never get removed from a group // wrongly assumes contacts never get removed from a group
if (sub_contacts != nullptr && list.size() < sub_contacts->size()) { if (sub_contacts != nullptr && list.size() < sub_contacts->size()) {
// if partially read // if partially read
@ -1045,13 +1051,13 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) {
} }
// TODO: remove? // TODO: remove?
if (reg.all_of<Message::Components::Remote::TimestampReceived>(e)) { if (reg.all_of<Message::Components::ReceivedBy>(e)) {
std::string synced_by_text {"receivedBy:"}; std::string synced_by_text {"receivedBy:"};
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u); const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
for (const auto& [c, syned_ts] : reg.get<Message::Components::Remote::TimestampReceived>(e).ts) { for (const auto& [c, syned_ts] : reg.get<Message::Components::ReceivedBy>(e).ts) {
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) { if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
synced_by_text += "\n sself(!)"; // makes no sense synced_by_text += "\n sself"; // required (except when synced externally)
} else if (_cr.all_of<Contact::Components::TagSelfWeak>(c)) { } else if (_cr.all_of<Contact::Components::TagSelfWeak>(c)) {
synced_by_text += "\n wself"; synced_by_text += "\n wself";
} else { } else {

View File

@ -7,8 +7,8 @@
#include "./texture_cache.hpp" #include "./texture_cache.hpp"
#include "./tox_avatar_loader.hpp" #include "./tox_avatar_loader.hpp"
#include "./message_image_loader.hpp" #include "./message_image_loader.hpp"
#include "./file_selector.hpp" #include "./chat_gui/file_selector.hpp"
#include "./send_image_popup.hpp" #include "./chat_gui/send_image_popup.hpp"
#include <entt/container/dense_map.hpp> #include <entt/container/dense_map.hpp>

View File

@ -12,7 +12,7 @@
#include <memory> #include <memory>
#include <cmath> #include <cmath>
MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::vector<std::string> plugins) : MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins) :
renderer(renderer_), renderer(renderer_),
rmm(cr), rmm(cr),
msnj{cr, {}, {}}, msnj{cr, {}, {}},
@ -44,9 +44,10 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::stri
conf.set("tox", "save_file_path", save_path); conf.set("tox", "save_file_path", save_path);
{ // name stuff { // name stuff
// a new profile will not have this set
auto name = tc.toxSelfGetName(); auto name = tc.toxSelfGetName();
if (name.empty()) { if (name.empty()) {
name = "tomato"; name = new_username;
} }
conf.set("tox", "name", name); conf.set("tox", "name", name);
tc.setSelfName(name); // TODO: this is ugly tc.setSelfName(name); // TODO: this is ugly

View File

@ -28,7 +28,7 @@
#include "./message_image_loader.hpp" #include "./message_image_loader.hpp"
#include "./chat_gui4.hpp" #include "./chat_gui4.hpp"
#include "./settings_window.hpp" #include "./chat_gui/settings_window.hpp"
#include "./tox_ui_utils.hpp" #include "./tox_ui_utils.hpp"
#include "./tox_dht_cap_histo.hpp" #include "./tox_dht_cap_histo.hpp"
#include "./tox_friend_faux_offline_messaging.hpp" #include "./tox_friend_faux_offline_messaging.hpp"
@ -89,7 +89,7 @@ struct MainScreen final : public Screen {
uint64_t _window_hidden_ts {0}; uint64_t _window_hidden_ts {0};
float _time_since_event {0.f}; float _time_since_event {0.f};
MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::vector<std::string> plugins); MainScreen(SDL_Renderer* renderer_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins);
~MainScreen(void); ~MainScreen(void);
bool handleEvent(SDL_Event& e) override; bool handleEvent(SDL_Event& e) override;

View File

@ -5,6 +5,7 @@
#include <imgui/imgui.h> #include <imgui/imgui.h>
#include <imgui/misc/cpp/imgui_stdlib.h> #include <imgui/misc/cpp/imgui_stdlib.h>
#include <cctype>
#include <memory> #include <memory>
#include <filesystem> #include <filesystem>
@ -33,13 +34,13 @@ Screen* StartScreen::render(float, bool&) {
_fss.requestFile( _fss.requestFile(
[](const auto& path) -> bool { return std::filesystem::is_regular_file(path); }, [](const auto& path) -> bool { return std::filesystem::is_regular_file(path); },
[this](const auto& path) { [this](const auto& path) {
tox_profile_path = path.string(); _tox_profile_path = path.string();
}, },
[](){} [](){}
); );
} }
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextUnformatted(tox_profile_path.c_str()); ImGui::TextUnformatted(_tox_profile_path.c_str());
ImGui::TextUnformatted("password:"); ImGui::TextUnformatted("password:");
ImGui::SameLine(); ImGui::SameLine();
@ -56,8 +57,22 @@ Screen* StartScreen::render(float, bool&) {
if (ImGui::BeginTabItem("create profile")) { if (ImGui::BeginTabItem("create profile")) {
_new_save = true; _new_save = true;
ImGui::TextUnformatted("TODO: profile path"); ImGui::TextUnformatted("username:");
ImGui::TextUnformatted("TODO: profile name"); ImGui::SameLine();
if (ImGui::InputText("##user_name", &_user_name)) {
std::string tmp_copy = _user_name;
for (auto& c : tmp_copy) {
if (!std::isalnum(static_cast<unsigned char>(c)) && c != '-' && c != '.') {
c = '_';
}
}
if (tmp_copy.empty()) {
tmp_copy = "unnamed-tomato";
}
_tox_profile_path = tmp_copy + ".tox";
}
ImGui::TextUnformatted("password:"); ImGui::TextUnformatted("password:");
ImGui::SameLine(); ImGui::SameLine();
@ -69,6 +84,8 @@ Screen* StartScreen::render(float, bool&) {
ImGui::SameLine(); ImGui::SameLine();
ImGui::Checkbox("show password", &_show_password); ImGui::Checkbox("show password", &_show_password);
ImGui::TextUnformatted("TODO: profile path (current path for now)");
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("plugins")) { if (ImGui::BeginTabItem("plugins")) {
@ -81,7 +98,6 @@ Screen* StartScreen::render(float, bool&) {
continue; continue;
} }
ImGui::SameLine(); ImGui::SameLine();
ImGui::TextUnformatted(it->c_str()); ImGui::TextUnformatted(it->c_str());
ImGui::PopID(); ImGui::PopID();
@ -105,7 +121,7 @@ Screen* StartScreen::render(float, bool&) {
ImGui::Separator(); ImGui::Separator();
if (!_new_save && !std::filesystem::is_regular_file(tox_profile_path)) { if (!_new_save && !std::filesystem::is_regular_file(_tox_profile_path)) {
// load but file missing // load but file missing
ImGui::BeginDisabled(); ImGui::BeginDisabled();
@ -115,7 +131,7 @@ Screen* StartScreen::render(float, bool&) {
if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_AllowWhenDisabled)) {
ImGui::SetTooltip("file does not exist"); ImGui::SetTooltip("file does not exist");
} }
} else if (_new_save && std::filesystem::exists(tox_profile_path)) { } else if (_new_save && std::filesystem::exists(_tox_profile_path)) {
// new but file exists // new but file exists
ImGui::BeginDisabled(); ImGui::BeginDisabled();
@ -127,7 +143,7 @@ Screen* StartScreen::render(float, bool&) {
} }
} else { } else {
if (ImGui::Button("load", {60, 25})) { if (ImGui::Button("load", {60, 25})) {
auto new_screen = std::make_unique<MainScreen>(_renderer, tox_profile_path, _password, queued_plugin_paths); auto new_screen = std::make_unique<MainScreen>(_renderer, _tox_profile_path, _password, _user_name, queued_plugin_paths);
return new_screen.release(); return new_screen.release();
} }
} }

View File

@ -2,7 +2,7 @@
#include "./screen.hpp" #include "./screen.hpp"
#include "./file_selector.hpp" #include "./chat_gui/file_selector.hpp"
#include <vector> #include <vector>
#include <string> #include <string>
@ -17,11 +17,12 @@ struct StartScreen final : public Screen {
FileSelector _fss; FileSelector _fss;
bool _new_save {false}; bool _new_save {false};
std::string _user_name {"unnamed-tomato"};
bool _show_password {false}; bool _show_password {false};
std::string _password; std::string _password;
std::string tox_profile_path {"tomato.tox"}; std::string _tox_profile_path {"unnamed-tomato.tox"};
std::vector<std::string> queued_plugin_paths; std::vector<std::string> queued_plugin_paths;
StartScreen(void) = delete; StartScreen(void) = delete;

View File

@ -107,6 +107,12 @@ ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendM
const uint64_t ts_now = Message::getTimeMS(); const uint64_t ts_now = Message::getTimeMS();
if (!_cr.all_of<Contact::Components::Self>(c)) {
return dfmc_Ret::NO_MSG; // error
}
const auto self_c = _cr.get<Contact::Components::Self>(c).self;
// filter for unconfirmed messages // filter for unconfirmed messages
// we assume sorted // we assume sorted
@ -127,9 +133,8 @@ ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendM
continue; // skip continue; // skip
} }
// exclude if (!mr->any_of<
if (mr->any_of< Message::Components::ReceivedBy
Message::Components::Remote::TimestampReceived // this acts like a tag, which is wrong in groups
>(msg) >(msg)
) { ) {
continue; // skip continue; // skip
@ -139,6 +144,16 @@ ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendM
continue; // not outbound (in private) continue; // not outbound (in private)
} }
const auto& ts_received = mr->get<Message::Components::ReceivedBy>(msg).ts;
// not target
if (ts_received.contains(c)) {
continue;
}
// needs to contain self
if (!ts_received.contains(self_c)) {
continue;
}
valid_unsent = true; valid_unsent = true;
uint64_t msg_ts = msg_view.get<Message::Components::Timestamp>(msg).ts; uint64_t msg_ts = msg_view.get<Message::Components::Timestamp>(msg).ts;