contact 4 refactor
Some checks are pending
ContinuousDelivery / linux-ubuntu (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousDelivery / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousDelivery / windows (push) Waiting to run
ContinuousDelivery / windows-asan (push) Waiting to run
ContinuousDelivery / dumpsyms (push) Blocked by required conditions
ContinuousDelivery / release (push) Blocked by required conditions
ContinuousIntegration / linux (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:arm64-v8a vcpkg_toolkit:arm64-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:armeabi-v7a vcpkg_toolkit:arm-neon-android]) (push) Waiting to run
ContinuousIntegration / android (map[ndk_abi:x86_64 vcpkg_toolkit:x64-android]) (push) Waiting to run
ContinuousIntegration / macos (push) Waiting to run
ContinuousIntegration / windows (push) Waiting to run

This commit is contained in:
Green Sky 2025-03-06 19:12:35 +01:00
parent 77a95811f2
commit c29aa523dc
No known key found for this signature in database
GPG Key ID: DBE05085D874AB4A
24 changed files with 196 additions and 155 deletions

@ -1 +1 @@
Subproject commit e2917c497c91f91f8febcd1f43e462fad8359305 Subproject commit 0a03fc48b62b8e7127ffbf1b7f3ccb98f70b1e90

@ -1 +1 @@
Subproject commit e55fb46027f16a1bc078f797ae9fcc7609d15659 Subproject commit 2a3828b30d7ec5fb9e7c8a8a82d1be66e040ea74

@ -1 +1 @@
Subproject commit 491c30988e572fa172481ea77db300afcf0236ef Subproject commit c284e0779e69618f0524acba67849801cbb5a5d7

@ -1 +1 @@
Subproject commit 0ba56d428fb5e700a00cf016d368c21143c46857 Subproject commit 241a0c0906f75555218a04b99259b51b0c0c25a4

@ -1 +1 @@
Subproject commit dd7eb2702f3844085f3cd8495db1e1a087afd724 Subproject commit 24bbf2a3381de3e2a7c06c035eb0b19467c2a6b5

View File

@ -167,6 +167,7 @@ target_compile_features(tomato PUBLIC cxx_std_17)
target_link_libraries(tomato PUBLIC target_link_libraries(tomato PUBLIC
solanaceae_util solanaceae_util
solanaceae_contact solanaceae_contact
solanaceae_contact_impl
solanaceae_message3 solanaceae_message3
solanaceae_message_serializer solanaceae_message_serializer

View File

@ -1,16 +1,20 @@
#pragma once #pragma once
#include <solanaceae/object_store/fwd.hpp> #include <solanaceae/object_store/fwd.hpp>
#include <solanaceae/contact/contact_model3.hpp> #include <solanaceae/contact/fwd.hpp>
#include <solanaceae/util/bitset.hpp> #include <solanaceae/util/bitset.hpp>
#include "./texture_cache.hpp" #include "./texture_cache.hpp"
#include <entt/entity/entity.hpp>
#include <entt/entity/registry.hpp>
#include <entt/entity/handle.hpp>
#include <optional> #include <optional>
struct ObjectContactSub final { struct ObjectContactSub final {
ObjectHandle o; ObjectHandle o;
Contact3 c{entt::null}; Contact4 c{entt::null};
}; };
template<> template<>

View File

@ -18,7 +18,7 @@
void renderAvatar( void renderAvatar(
const Theme& th, const Theme& th,
ContactTextureCache& contact_tc, ContactTextureCache& contact_tc,
const Contact3Handle c, const ContactHandle4 c,
ImVec2 box ImVec2 box
) { ) {
// deploy dummy of same size and check visibility // deploy dummy of same size and check visibility
@ -53,7 +53,7 @@ void renderAvatar(
bool renderContactBig( bool renderContactBig(
const Theme& th, const Theme& th,
ContactTextureCache& contact_tc, ContactTextureCache& contact_tc,
const Contact3Handle c, const ContactHandle4 c,
int line_height, int line_height,
const bool unread, const bool unread,
const bool selectable, const bool selectable,

View File

@ -4,7 +4,7 @@
#include "./theme.hpp" #include "./theme.hpp"
#include <solanaceae/contact/contact_model3.hpp> #include <solanaceae/contact/fwd.hpp>
enum class ThemeCol_Contact { enum class ThemeCol_Contact {
request_incoming, request_incoming,
@ -25,7 +25,7 @@ enum class ThemeCol_Contact {
void renderAvatar( void renderAvatar(
const Theme& th, const Theme& th,
ContactTextureCache& contact_tc, ContactTextureCache& contact_tc,
const Contact3Handle c, const ContactHandle4 c,
ImVec2 box ImVec2 box
); );
@ -39,7 +39,7 @@ void renderAvatar(
bool renderContactBig( bool renderContactBig(
const Theme& th, const Theme& th,
ContactTextureCache& contact_tc, ContactTextureCache& contact_tc,
const Contact3Handle c, const ContactHandle4 c,
int line_height = 3, int line_height = 3,
const bool unread = false, const bool unread = false,
const bool selectable = false, const bool selectable = false,

View File

@ -7,7 +7,7 @@
#include "../message_image_loader.hpp" #include "../message_image_loader.hpp"
#include "../bitset_image_loader.hpp" #include "../bitset_image_loader.hpp"
using ContactTextureCache = TextureCache<uint64_t, Contact3, ToxAvatarLoader>; using ContactTextureCache = TextureCache<uint64_t, Contact4, ToxAvatarLoader>;
using MessageTextureCache = TextureCache<uint64_t, Message3Handle, MessageImageLoader>; using MessageTextureCache = TextureCache<uint64_t, Message3Handle, MessageImageLoader>;
using BitsetTextureCache = TextureCache<uint64_t, ObjectHandle, BitsetImageLoader>; using BitsetTextureCache = TextureCache<uint64_t, ObjectHandle, BitsetImageLoader>;

View File

@ -1,11 +1,15 @@
#include "./chat_gui4.hpp" #include "./chat_gui4.hpp"
#include <solanaceae/util/utils.hpp>
#include <solanaceae/contact/contact_store_i.hpp>
#include <solanaceae/contact/contact_model4.hpp>
#include <solanaceae/message3/components.hpp> #include <solanaceae/message3/components.hpp>
#include <solanaceae/tox_messages/msg_components.hpp> #include <solanaceae/tox_messages/msg_components.hpp>
#include <solanaceae/tox_messages/obj_components.hpp> #include <solanaceae/tox_messages/obj_components.hpp>
#include <solanaceae/object_store/meta_components_file.hpp> #include <solanaceae/object_store/meta_components_file.hpp>
#include <solanaceae/contact/components.hpp> #include <solanaceae/contact/components.hpp>
#include <solanaceae/util/utils.hpp>
#include "./frame_streams/voip_model.hpp" #include "./frame_streams/voip_model.hpp"
@ -182,7 +186,7 @@ ChatGui4::ChatGui4(
ConfigModelI& conf, ConfigModelI& conf,
ObjectStore2& os, ObjectStore2& os,
RegistryMessageModelI& rmm, RegistryMessageModelI& rmm,
Contact3Registry& cr, ContactStore4I& cs,
TextureUploaderI& tu, TextureUploaderI& tu,
ContactTextureCache& contact_tc, ContactTextureCache& contact_tc,
MessageTextureCache& msg_tc, MessageTextureCache& msg_tc,
@ -192,7 +196,7 @@ ChatGui4::ChatGui4(
_os(os), _os(os),
_os_sr(_os.newSubRef(this)), _os_sr(_os.newSubRef(this)),
_rmm(rmm), _rmm(rmm),
_cr(cr), _cs(cs),
_contact_tc(contact_tc), _contact_tc(contact_tc),
_msg_tc(msg_tc), _msg_tc(msg_tc),
_b_tc(_bil, tu), _b_tc(_bil, tu),
@ -250,22 +254,23 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
ImGui::SameLine(); ImGui::SameLine();
if (_selected_contact) { if (_selected_contact) {
auto& cr = _cs.registry();
const std::string chat_label = "chat " + std::to_string(entt::to_integral(*_selected_contact)); const std::string chat_label = "chat " + std::to_string(entt::to_integral(*_selected_contact));
const std::vector<Contact3>* sub_contacts = nullptr; const std::vector<Contact4>* sub_contacts = nullptr;
if (_cr.all_of<Contact::Components::ParentOf>(*_selected_contact)) { if (cr.all_of<Contact::Components::ParentOf>(*_selected_contact)) {
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)}; const bool highlight_private {!cr.all_of<Contact::Components::TagPrivate>(*_selected_contact)};
if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, ImGuiChildFlags_Border, ImGuiWindowFlags_MenuBar)) { if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, ImGuiChildFlags_Border, ImGuiWindowFlags_MenuBar)) {
if (ImGui::BeginMenuBar()) { if (ImGui::BeginMenuBar()) {
// check if contact has voip model // check if contact has voip model
// use activesessioncomp instead? // use activesessioncomp instead?
if (_cr.all_of<VoIPModelI*>(*_selected_contact)) { if (cr.all_of<VoIPModelI*>(*_selected_contact)) {
if (ImGui::BeginMenu("VoIP")) { if (ImGui::BeginMenu("VoIP")) {
auto* voip_model = _cr.get<VoIPModelI*>(*_selected_contact); auto* voip_model = cr.get<VoIPModelI*>(*_selected_contact);
std::vector<ObjectHandle> contact_sessions; std::vector<ObjectHandle> contact_sessions;
std::vector<ObjectHandle> acceptable_sessions; std::vector<ObjectHandle> acceptable_sessions;
@ -362,9 +367,9 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
ImGui::SeparatorText("tox"); ImGui::SeparatorText("tox");
// TODO: cheese it and rename to copy id? // TODO: cheese it and rename to copy id?
if (_cr.all_of<Contact::Components::ToxGroupPersistent>(*_selected_contact)) { if (cr.all_of<Contact::Components::ToxGroupPersistent>(*_selected_contact)) {
if (ImGui::MenuItem("copy ngc chatid")) { if (ImGui::MenuItem("copy ngc chatid")) {
const auto& chat_id = _cr.get<Contact::Components::ToxGroupPersistent>(*_selected_contact).chat_id.data; const auto& chat_id = cr.get<Contact::Components::ToxGroupPersistent>(*_selected_contact).chat_id.data;
const auto chat_id_str = bin2hex(std::vector<uint8_t>{chat_id.begin(), chat_id.end()}); const auto chat_id_str = bin2hex(std::vector<uint8_t>{chat_id.begin(), chat_id.end()});
ImGui::SetClipboardText(chat_id_str.c_str()); ImGui::SetClipboardText(chat_id_str.c_str());
} }
@ -375,10 +380,10 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
ImGui::EndMenuBar(); ImGui::EndMenuBar();
} }
renderContactBig(_theme, _contact_tc, {_cr, *_selected_contact}, 3, false, false, false); renderContactBig(_theme, _contact_tc, {cr, *_selected_contact}, 3, false, false, false);
ImGui::Separator(); ImGui::Separator();
if (sub_contacts != nullptr && !_cr.all_of<Contact::Components::TagPrivate>(*_selected_contact) && _cr.all_of<Contact::Components::TagGroup>(*_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->empty()) { if (!sub_contacts->empty()) {
if (ImGui::BeginChild("subcontacts", {TEXT_BASE_WIDTH * 18.f, -100.f}, true)) { if (ImGui::BeginChild("subcontacts", {TEXT_BASE_WIDTH * 18.f, -100.f}, true)) {
ImGui::Text("subs: %zu", sub_contacts->size()); ImGui::Text("subs: %zu", sub_contacts->size());
@ -386,8 +391,8 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
for (const auto& c : *sub_contacts) { for (const auto& c : *sub_contacts) {
// TODO: can a sub be selected? no // TODO: can a sub be selected? no
//if (renderSubContactListContact(c, _selected_contact.has_value() && *_selected_contact == c)) { //if (renderSubContactListContact(c, _selected_contact.has_value() && *_selected_contact == c)) {
if (renderContactBig(_theme, _contact_tc, {_cr, c}, 1)) { if (renderContactBig(_theme, _contact_tc, {cr, c}, 1)) {
_text_input_buffer.insert(0, (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>") + ": "); _text_input_buffer.insert(0, (cr.all_of<Contact::Components::Name>(c) ? cr.get<Contact::Components::Name>(c).name : "<unk>") + ": ");
} }
} }
} }
@ -396,14 +401,14 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
} }
} }
const bool request_incoming = _cr.all_of<Contact::Components::RequestIncoming>(*_selected_contact); const bool request_incoming = cr.all_of<Contact::Components::RequestIncoming>(*_selected_contact);
const bool request_outgoing = _cr.all_of<Contact::Components::TagRequestOutgoing>(*_selected_contact); const bool request_outgoing = cr.all_of<Contact::Components::TagRequestOutgoing>(*_selected_contact);
if (request_incoming || request_outgoing) { if (request_incoming || request_outgoing) {
// TODO: theming // TODO: theming
ImGui::PushStyleColor(ImGuiCol_ChildBg, {0.90f, 0.70f, 0.00f, 0.32f}); ImGui::PushStyleColor(ImGuiCol_ChildBg, {0.90f, 0.70f, 0.00f, 0.32f});
if (ImGui::BeginChild("request", {0, TEXT_BASE_HEIGHT*6.1f}, true, ImGuiWindowFlags_NoScrollbar)) { if (ImGui::BeginChild("request", {0, TEXT_BASE_HEIGHT*6.1f}, true, ImGuiWindowFlags_NoScrollbar)) {
if (request_incoming) { if (request_incoming) {
const auto& ri = _cr.get<Contact::Components::RequestIncoming>(*_selected_contact); const auto& ri = cr.get<Contact::Components::RequestIncoming>(*_selected_contact);
ImGui::TextUnformatted("You got a request to add this contact."); ImGui::TextUnformatted("You got a request to add this contact.");
static std::string self_name = _conf.get_string("tox", "name").value_or("default_tomato"); static std::string self_name = _conf.get_string("tox", "name").value_or("default_tomato");
@ -423,7 +428,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
} }
if (ImGui::Button("Accept")) { if (ImGui::Button("Accept")) {
_cr.get<Contact::Components::ContactModel>(*_selected_contact)->acceptRequest(*_selected_contact, self_name, password); cr.get<Contact::Components::ContactModel>(*_selected_contact)->acceptRequest(*_selected_contact, self_name, password);
password.clear(); password.clear();
} }
ImGui::SameLine(); ImGui::SameLine();
@ -540,11 +545,11 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
// name // name
if (ImGui::TableNextColumn()) { if (ImGui::TableNextColumn()) {
const float img_y {TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2}; const float img_y {TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2};
renderAvatar(_theme, _contact_tc, {_cr, c_from.c}, {img_y, img_y}); renderAvatar(_theme, _contact_tc, {cr, c_from.c}, {img_y, img_y});
ImGui::SameLine(0.f, ImGui::GetStyle().ItemSpacing.x*0.5f); ImGui::SameLine(0.f, ImGui::GetStyle().ItemSpacing.x*0.5f);
if (_cr.all_of<Contact::Components::Name>(c_from.c)) { if (cr.all_of<Contact::Components::Name>(c_from.c)) {
ImGui::TextUnformatted(_cr.get<Contact::Components::Name>(c_from.c).name.c_str()); ImGui::TextUnformatted(cr.get<Contact::Components::Name>(c_from.c).name.c_str());
} else { } else {
ImGui::TextUnformatted("<unk>"); ImGui::TextUnformatted("<unk>");
} }
@ -581,7 +586,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
} }
// highlight self // highlight self
if (_cr.any_of<Contact::Components::TagSelfWeak, Contact::Components::TagSelfStrong>(c_from.c)) { if (cr.any_of<Contact::Components::TagSelfWeak, Contact::Components::TagSelfStrong>(c_from.c)) {
ImU32 cell_bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.7f, 0.3f, 0.20f)); ImU32 cell_bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.7f, 0.3f, 0.20f));
ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color); ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color);
} else { } else {
@ -593,7 +598,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
std::optional<ImVec4> row_bg; std::optional<ImVec4> row_bg;
// private group message // private group message
if (highlight_private && _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);
@ -652,13 +657,13 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
size_t other_contacts {0}; 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
continue; continue;
} else if (_cr.all_of<Contact::Components::TagSelfWeak>(c)) { } else if (cr.all_of<Contact::Components::TagSelfWeak>(c)) {
synced_by_text += "\n wself"; // TODO: add name? synced_by_text += "\n wself"; // TODO: add name?
} 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; 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;
@ -694,13 +699,13 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
const int64_t now_ts_s = int64_t(getTimeMS() / 1000u); const int64_t now_ts_s = int64_t(getTimeMS() / 1000u);
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
continue; continue;
} 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 {
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>");
} }
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)";
@ -786,15 +791,15 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
_rmm.throwEventConstruct(cg_view.end); _rmm.throwEventConstruct(cg_view.end);
} // else? we do nothing? } // else? we do nothing?
} else { } else {
bool begin_created {false}; bool begincreated {false};
if (!static_cast<bool>(cg_view.begin)) { if (!static_cast<bool>(cg_view.begin)) {
cg_view.begin = {msg_reg, msg_reg.create()}; cg_view.begin = {msg_reg, msg_reg.create()};
begin_created = true; begincreated = true;
} }
bool end_created {false}; bool endcreated {false};
if (!static_cast<bool>(cg_view.end)) { if (!static_cast<bool>(cg_view.end)) {
cg_view.end = {msg_reg, msg_reg.create()}; cg_view.end = {msg_reg, msg_reg.create()};
end_created = true; endcreated = true;
} }
cg_view.begin.emplace_or_replace<Message::Components::ViewCurserBegin>(cg_view.end); cg_view.begin.emplace_or_replace<Message::Components::ViewCurserBegin>(cg_view.end);
cg_view.end.emplace_or_replace<Message::Components::ViewCurserEnd>(cg_view.begin); cg_view.end.emplace_or_replace<Message::Components::ViewCurserEnd>(cg_view.begin);
@ -803,7 +808,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
auto& old_begin_ts = cg_view.begin.get_or_emplace<Message::Components::Timestamp>().ts; auto& old_begin_ts = cg_view.begin.get_or_emplace<Message::Components::Timestamp>().ts;
if (old_begin_ts != message_view_newest.get<Message::Components::Timestamp>().ts) { if (old_begin_ts != message_view_newest.get<Message::Components::Timestamp>().ts) {
old_begin_ts = message_view_newest.get<Message::Components::Timestamp>().ts; old_begin_ts = message_view_newest.get<Message::Components::Timestamp>().ts;
if (begin_created) { if (begincreated) {
std::cout << "CG: created view begin ts with " << old_begin_ts << "\n"; std::cout << "CG: created view begin ts with " << old_begin_ts << "\n";
_rmm.throwEventConstruct(cg_view.begin); _rmm.throwEventConstruct(cg_view.begin);
} else { } else {
@ -817,7 +822,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused
auto& old_end_ts = cg_view.end.get_or_emplace<Message::Components::Timestamp>().ts; auto& old_end_ts = cg_view.end.get_or_emplace<Message::Components::Timestamp>().ts;
if (old_end_ts != message_view_oldest.get<Message::Components::Timestamp>().ts) { if (old_end_ts != message_view_oldest.get<Message::Components::Timestamp>().ts) {
old_end_ts = message_view_oldest.get<Message::Components::Timestamp>().ts; old_end_ts = message_view_oldest.get<Message::Components::Timestamp>().ts;
if (end_created) { if (endcreated) {
std::cout << "CG: created view end ts with " << old_end_ts << "\n"; std::cout << "CG: created view end ts with " << old_end_ts << "\n";
_rmm.throwEventConstruct(cg_view.end); _rmm.throwEventConstruct(cg_view.end);
} else { } else {
@ -990,7 +995,7 @@ void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) {
); );
if (ImGui::BeginPopupContextItem("##text")) { if (ImGui::BeginPopupContextItem("##text")) {
if (ImGui::MenuItem("quote")) { if (ImGui::MenuItem("quote")) {
//text_buffer.insert(0, (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>") + ": "); //text_buffer.insert(0, (cr.all_of<Contact::Components::Name>(c) ? cr.get<Contact::Components::Name>(c).name : "<unk>") + ": ");
if (!_text_input_buffer.empty()) { if (!_text_input_buffer.empty()) {
_text_input_buffer += "\n"; _text_input_buffer += "\n";
} }
@ -1050,7 +1055,7 @@ void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) {
if (ImGui::BeginPopupContextItem("##text")) { if (ImGui::BeginPopupContextItem("##text")) {
if (ImGui::MenuItem("quote")) { if (ImGui::MenuItem("quote")) {
//text_buffer.insert(0, (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name : "<unk>") + ": "); //text_buffer.insert(0, (cr.all_of<Contact::Components::Name>(c) ? cr.get<Contact::Components::Name>(c).name : "<unk>") + ": ");
if (!_text_input_buffer.empty()) { if (!_text_input_buffer.empty()) {
_text_input_buffer += "\n"; _text_input_buffer += "\n";
} }
@ -1429,15 +1434,16 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
} }
if (ImGui::BeginMenu("forward", local_have_all)) { if (ImGui::BeginMenu("forward", local_have_all)) {
for (const auto& c : _cr.view<Contact::Components::TagBig>()) { auto& cr = _cs.registry();
for (const auto& c : cr.view<Contact::Components::TagBig>()) {
// filter // filter
if (_cr.any_of<Contact::Components::RequestIncoming, Contact::Components::TagRequestOutgoing>(c)) { if (cr.any_of<Contact::Components::RequestIncoming, Contact::Components::TagRequestOutgoing>(c)) {
continue; continue;
} }
// TODO: check for contact capability // TODO: check for contact capability
// or just error popup?/noti/toast // or just error popup?/noti/toast
if (renderContactBig(_theme, _contact_tc, {_cr, c}, 1, false, true, false)) { if (renderContactBig(_theme, _contact_tc, {cr, c}, 1, false, true, false)) {
// TODO: try object interface first instead, then fall back to send with SingleInfoLocal // TODO: try object interface first instead, then fall back to send with SingleInfoLocal
//_rmm.sendFileObj(c, o); //_rmm.sendFileObj(c, o);
std::filesystem::path path = o.get<ObjComp::F::SingleInfoLocal>().file_path; std::filesystem::path path = o.get<ObjComp::F::SingleInfoLocal>().file_path;
@ -1530,17 +1536,19 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) {
ImGui::TextDisabled("msgid:%u", reg.get<Message::Components::ToxGroupMessageID>(e).id); ImGui::TextDisabled("msgid:%u", reg.get<Message::Components::ToxGroupMessageID>(e).id);
} }
const auto& cr = _cs.registry();
if (reg.all_of<Message::Components::SyncedBy>(e)) { if (reg.all_of<Message::Components::SyncedBy>(e)) {
std::string synced_by_text {"syncedBy:"}; std::string synced_by_text {"syncedBy:"};
const int64_t now_ts_s = int64_t(getTimeMS() / 1000u); const int64_t now_ts_s = int64_t(getTimeMS() / 1000u);
for (const auto& [c, syned_ts] : reg.get<Message::Components::SyncedBy>(e).ts) { for (const auto& [c, syned_ts] : reg.get<Message::Components::SyncedBy>(e).ts) {
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) { if (cr.all_of<Contact::Components::TagSelfStrong>(c)) {
synced_by_text += "\n sself"; synced_by_text += "\n sself";
} 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 {
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>");
} }
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)";
@ -1555,12 +1563,12 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) {
const int64_t now_ts_s = int64_t(getTimeMS() / 1000u); const int64_t now_ts_s = int64_t(getTimeMS() / 1000u);
for (const auto& [c, syned_ts] : reg.get<Message::Components::ReceivedBy>(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"; // required (except when synced externally) 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 {
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>");
} }
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)";
@ -1572,8 +1580,9 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) {
void ChatGui4::renderContactList(void) { void ChatGui4::renderContactList(void) {
if (ImGui::BeginChild("contacts", {TEXT_BASE_WIDTH*35, 0})) { if (ImGui::BeginChild("contacts", {TEXT_BASE_WIDTH*35, 0})) {
auto& cr = _cs.registry();
//for (const auto& c : _cm.getBigContacts()) { //for (const auto& c : _cm.getBigContacts()) {
for (const auto& c : _cr.view<Contact::Components::TagBig>()) { for (const auto& c : cr.view<Contact::Components::TagBig>()) {
const bool selected = _selected_contact.has_value() && *_selected_contact == c; const bool selected = _selected_contact.has_value() && *_selected_contact == c;
// TODO: is there a better way? // TODO: is there a better way?
@ -1585,7 +1594,7 @@ void ChatGui4::renderContactList(void) {
} }
} }
if (renderContactBig(_theme, _contact_tc, {_cr, c}, 2, has_unread, true, selected)) { if (renderContactBig(_theme, _contact_tc, {cr, c}, 2, has_unread, true, selected)) {
_selected_contact = c; _selected_contact = c;
} }
} }
@ -1593,10 +1602,12 @@ void ChatGui4::renderContactList(void) {
ImGui::EndChild(); ImGui::EndChild();
} }
bool ChatGui4::renderContactListContactSmall(const Contact3 c, const bool selected) const { bool ChatGui4::renderContactListContactSmall(const Contact4 c, const bool selected) const {
std::string label; std::string label;
label += (_cr.all_of<Contact::Components::Name>(c) ? _cr.get<Contact::Components::Name>(c).name.c_str() : "<unk>"); const auto& cr = _cs.registry();
label += (cr.all_of<Contact::Components::Name>(c) ? cr.get<Contact::Components::Name>(c).name.c_str() : "<unk>");
label += "###"; label += "###";
label += std::to_string(entt::to_integral(c)); label += std::to_string(entt::to_integral(c));

View File

@ -28,7 +28,7 @@ class ChatGui4 : public ObjectStoreEventI {
ObjectStore2& _os; ObjectStore2& _os;
ObjectStoreEventProviderI::SubscriptionReference _os_sr; ObjectStoreEventProviderI::SubscriptionReference _os_sr;
RegistryMessageModelI& _rmm; RegistryMessageModelI& _rmm;
Contact3Registry& _cr; ContactStore4I& _cs;
ContactTextureCache& _contact_tc; ContactTextureCache& _contact_tc;
MessageTextureCache& _msg_tc; MessageTextureCache& _msg_tc;
@ -41,7 +41,7 @@ class ChatGui4 : public ObjectStoreEventI {
SendImagePopup _sip; SendImagePopup _sip;
// TODO: refactor this to allow multiple open contacts // TODO: refactor this to allow multiple open contacts
std::optional<Contact3> _selected_contact; std::optional<Contact4> _selected_contact;
// TODO: per contact // TODO: per contact
std::string _text_input_buffer; std::string _text_input_buffer;
@ -63,7 +63,7 @@ class ChatGui4 : public ObjectStoreEventI {
ConfigModelI& conf, ConfigModelI& conf,
ObjectStore2& os, ObjectStore2& os,
RegistryMessageModelI& rmm, RegistryMessageModelI& rmm,
Contact3Registry& cr, ContactStore4I& cs,
TextureUploaderI& tu, TextureUploaderI& tu,
ContactTextureCache& contact_tc, ContactTextureCache& contact_tc,
MessageTextureCache& msg_tc, MessageTextureCache& msg_tc,
@ -84,7 +84,7 @@ class ChatGui4 : public ObjectStoreEventI {
void renderMessageExtra(Message3Registry& reg, const Message3 e); void renderMessageExtra(Message3Registry& reg, const Message3 e);
void renderContactList(void); void renderContactList(void);
bool renderContactListContactSmall(const Contact3 c, const bool selected) const; bool renderContactListContactSmall(const Contact4 c, const bool selected) const;
//bool renderSubContactListContact(const Contact3 c, const bool selected) const; //bool renderSubContactListContact(const Contact3 c, const bool selected) const;
void pasteFile(const char* mime_type); void pasteFile(const char* mime_type);

View File

@ -1,8 +1,13 @@
#pragma once #pragma once
#include <solanaceae/contact/contact_model3.hpp> #include <solanaceae/contact/fwd.hpp>
#include <solanaceae/object_store/fwd.hpp> #include <solanaceae/object_store/fwd.hpp>
#include <entt/entity/registry.hpp>
#include <entt/entity/handle.hpp>
#include <vector>
struct VoIPModelI; struct VoIPModelI;
namespace Components::VoIP { namespace Components::VoIP {
@ -11,7 +16,7 @@ namespace Components::VoIP {
// getting called or invited by // getting called or invited by
struct Incoming { struct Incoming {
Contact3 c{entt::null}; Contact4 c{entt::null};
}; };
struct DefaultConfig { struct DefaultConfig {
@ -37,7 +42,7 @@ namespace Components::VoIP {
}; };
struct SessionContact { struct SessionContact {
Contact3 c{entt::null}; Contact4 c{entt::null};
}; };
struct StreamSources { struct StreamSources {
@ -65,7 +70,7 @@ struct VoIPModelI {
// - default stream sources/sinks ? // - default stream sources/sinks ?
// - enable a/v ? -> done on connecting to sources // - enable a/v ? -> done on connecting to sources
// returns object tieing together the VoIP session // returns object tieing together the VoIP session
virtual ObjectHandle enter(const Contact3 c, const Components::VoIP::DefaultConfig& defaults = {true, true, true, true}) { (void)c,(void)defaults; return {}; } virtual ObjectHandle enter(const Contact4 c, const Components::VoIP::DefaultConfig& defaults = {true, true, true, true}) { (void)c,(void)defaults; return {}; }
// accept/join an invite to a session // accept/join an invite to a session
virtual bool accept(ObjectHandle session, const Components::VoIP::DefaultConfig& defaults = {true, true, true, true}) { (void)session,(void)defaults; return false; } virtual bool accept(ObjectHandle session, const Components::VoIP::DefaultConfig& defaults = {true, true, true, true}) { (void)session,(void)defaults; return false; }

View File

@ -36,33 +36,33 @@ static std::unique_ptr<SystemTray> constructSystemTray(SimpleConfigModel& conf,
MainScreen::MainScreen(const SimpleConfigModel& conf_, SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins) : MainScreen::MainScreen(const SimpleConfigModel& conf_, SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector<std::string> plugins) :
renderer(renderer_), renderer(renderer_),
conf(conf_), conf(conf_),
rmm(cr), rmm(cs),
msnj{cr, os, {}, {}}, msnj{cs, os, {}, {}},
mts(rmm), mts(rmm),
sm(os), sm(os),
tc(conf, save_path, save_password), tc(conf, save_path, save_password),
tel(tc, std::cout), tel(tc, std::cout),
tpi(tc.getTox()), tpi(tc.getTox()),
ad(tc), ad(tc),
tcm(cr, tc, tc), tcm(cs, tc, tc),
tmm(rmm, cr, tcm, tc, tc), tmm(rmm, cs, tcm, tc, tc),
ttm(rmm, cr, tcm, tc, tc, os), ttm(rmm, cs, tcm, tc, tc, os),
tffom(cr, rmm, tcm, tc, tc), tffom(cs, rmm, tcm, tc, tc),
#if TOMATO_TOX_AV #if TOMATO_TOX_AV
tav(tc.getTox()), tav(tc.getTox()),
tavvoip(os, tav, cr, tcm), tavvoip(os, tav, cs, tcm),
#endif #endif
theme(theme_), theme(theme_),
mmil(rmm), mmil(rmm),
tam(/*rmm, */ os, cr, conf), tam(/*rmm, */ os, cs, conf),
sdlrtu(renderer_), sdlrtu(renderer_),
tal(cr), tal(cs),
contact_tc(tal, sdlrtu), contact_tc(tal, sdlrtu),
mil(), mil(),
msg_tc(mil, sdlrtu), msg_tc(mil, sdlrtu),
st(constructSystemTray(conf, SDL_GetRenderWindow(renderer_))), st(constructSystemTray(conf, SDL_GetRenderWindow(renderer_))),
si(rmm, cr, SDL_GetRenderWindow(renderer_), st.get()), si(rmm, cs, SDL_GetRenderWindow(renderer_), st.get()),
cg(conf, os, rmm, cr, sdlrtu, contact_tc, msg_tc, theme), cg(conf, os, rmm, cs, sdlrtu, contact_tc, msg_tc, theme),
sw(conf), sw(conf),
osui(os), osui(os),
tuiu(tc, conf, &tpi), tuiu(tc, conf, &tpi),
@ -95,7 +95,7 @@ MainScreen::MainScreen(const SimpleConfigModel& conf_, SDL_Renderer* renderer_,
g_provideInstance<ObjectStore2>("ObjectStore2", "host", &os); g_provideInstance<ObjectStore2>("ObjectStore2", "host", &os);
g_provideInstance<ConfigModelI>("ConfigModelI", "host", &conf); g_provideInstance<ConfigModelI>("ConfigModelI", "host", &conf);
g_provideInstance<Contact3Registry>("Contact3Registry", "1", "host", &cr); g_provideInstance<ContactStore4I>("ContactStore4I", "host", &cs);
g_provideInstance<RegistryMessageModelI>("RegistryMessageModelI", "host", &rmm); g_provideInstance<RegistryMessageModelI>("RegistryMessageModelI", "host", &rmm);
g_provideInstance<MessageSerializerNJ>("MessageSerializerNJ", "host", &msnj); g_provideInstance<MessageSerializerNJ>("MessageSerializerNJ", "host", &msnj);
@ -386,12 +386,13 @@ Screen* MainScreen::render(float time_delta, bool&) {
// TODO: move this somewhere else!!! // TODO: move this somewhere else!!!
// needs both tal and tc <.< // needs both tal and tc <.<
if (!cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars // TODO: move this code to events
std::vector<Contact3> to_purge; if (!cs.registry().storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars
cr.view<Contact::Components::TagAvatarInvalidate>().each([&to_purge](const Contact3 c) { std::vector<Contact4> to_purge;
cs.registry().view<Contact::Components::TagAvatarInvalidate>().each([&to_purge](const Contact4 c) {
to_purge.push_back(c); to_purge.push_back(c);
}); });
cr.remove<Contact::Components::TagAvatarInvalidate>(to_purge.cbegin(), to_purge.cend()); cs.registry().remove<Contact::Components::TagAvatarInvalidate>(to_purge.cbegin(), to_purge.cend());
contact_tc.invalidate(to_purge); contact_tc.invalidate(to_purge);
} }
// ACTUALLY NOT IF RENDERED, MOVED LOGIC TO ABOVE // ACTUALLY NOT IF RENDERED, MOVED LOGIC TO ABOVE

View File

@ -4,7 +4,7 @@
#include <solanaceae/object_store/object_store.hpp> #include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/util/simple_config_model.hpp> #include <solanaceae/util/simple_config_model.hpp>
#include <solanaceae/contact/contact_model3.hpp> #include <solanaceae/contact/contact_store_impl.hpp>
#include <solanaceae/message3/registry_message_model.hpp> #include <solanaceae/message3/registry_message_model.hpp>
#include <solanaceae/message3/registry_message_model_impl.hpp> #include <solanaceae/message3/registry_message_model_impl.hpp>
#include <solanaceae/message3/message_time_sort.hpp> #include <solanaceae/message3/message_time_sort.hpp>
@ -60,7 +60,7 @@ struct MainScreen final : public Screen {
ObjectStore2 os; ObjectStore2 os;
SimpleConfigModel conf; SimpleConfigModel conf;
Contact3Registry cr; ContactStore4Impl cs;
RegistryMessageModelImpl rmm; RegistryMessageModelImpl rmm;
MessageSerializerNJ msnj; MessageSerializerNJ msnj;
MessageTimeSort mts; MessageTimeSort mts;

View File

@ -2,7 +2,7 @@
#include <solanaceae/object_store/meta_components_file.hpp> #include <solanaceae/object_store/meta_components_file.hpp>
#include <solanaceae/contact/contact_model3.hpp> #include <solanaceae/contact/fwd.hpp>
#include <entt/container/dense_map.hpp> #include <entt/container/dense_map.hpp>
@ -13,7 +13,7 @@ namespace ObjectStore::Components {
namespace File { namespace File {
struct TransferStatsSeparated { struct TransferStatsSeparated {
entt::dense_map<Contact3, TransferStats> stats; entt::dense_map<Contact4, TransferStats> stats;
}; };
} // File } // File

View File

@ -1,5 +1,7 @@
#include "./status_indicator.hpp" #include "./status_indicator.hpp"
#include <solanaceae/contact/contact_store_i.hpp>
#include <solanaceae/contact/components.hpp> #include <solanaceae/contact/components.hpp>
#include <solanaceae/message3/components.hpp> #include <solanaceae/message3/components.hpp>
@ -36,12 +38,12 @@ void StatusIndicator::updateState(State state) {
StatusIndicator::StatusIndicator( StatusIndicator::StatusIndicator(
RegistryMessageModelI& rmm, RegistryMessageModelI& rmm,
Contact3Registry& cr, ContactStore4I& cs,
SDL_Window* main_window, SDL_Window* main_window,
SystemTray* tray SystemTray* tray
) : ) :
_rmm(rmm), _rmm(rmm),
_cr(cr), _cs(cs),
_main_window(main_window), _main_window(main_window),
_tray(tray) _tray(tray)
{ {
@ -55,7 +57,7 @@ void StatusIndicator::render(float delta) {
_cooldown = 1.f; // once a second _cooldown = 1.f; // once a second
bool has_unread = false; bool has_unread = false;
for (const auto& c : _cr.view<Contact::Components::TagBig>()) { for (const auto& c : _cs.registry().view<Contact::Components::TagBig>()) {
// maybe cache mm? // maybe cache mm?
if (const auto* mm = _rmm.get(c); mm != nullptr) { if (const auto* mm = _rmm.get(c); mm != nullptr) {
if (const auto* unread_storage = mm->storage<Message::Components::TagUnread>(); unread_storage != nullptr && !unread_storage->empty()) { if (const auto* unread_storage = mm->storage<Message::Components::TagUnread>(); unread_storage != nullptr && !unread_storage->empty()) {

View File

@ -10,7 +10,7 @@
class StatusIndicator { class StatusIndicator {
RegistryMessageModelI& _rmm; RegistryMessageModelI& _rmm;
Contact3Registry& _cr; ContactStore4I& _cs;
SDL_Window* _main_window; SDL_Window* _main_window;
SystemTray* _tray; SystemTray* _tray;
@ -28,7 +28,7 @@ class StatusIndicator {
public: public:
StatusIndicator( StatusIndicator(
RegistryMessageModelI& rmm, RegistryMessageModelI& rmm,
Contact3Registry& cr, ContactStore4I& cs,
SDL_Window* main_window, SDL_Window* main_window,
SystemTray* tray = nullptr SystemTray* tray = nullptr
); );

View File

@ -4,11 +4,13 @@
#include "./image_loader_qoi.hpp" #include "./image_loader_qoi.hpp"
#include "./image_loader_webp.hpp" #include "./image_loader_webp.hpp"
#include "./image_loader_sdl_image.hpp" #include "./image_loader_sdl_image.hpp"
#include "texture_uploader.hpp"
#include <solanaceae/contact/contact_store_i.hpp>
#include <solanaceae/contact/components.hpp> #include <solanaceae/contact/components.hpp>
#include <solanaceae/tox_contacts/components.hpp> #include <solanaceae/tox_contacts/components.hpp>
#include <entt/entity/registry.hpp>
#include <sodium/crypto_hash_sha256.h> #include <sodium/crypto_hash_sha256.h>
#include <iostream> #include <iostream>
@ -16,7 +18,7 @@
#include <cassert> #include <cassert>
#include <vector> #include <vector>
ToxAvatarLoader::ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) { ToxAvatarLoader::ToxAvatarLoader(ContactStore4I& cs) : _cs(cs) {
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>()); _image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
_image_loaders.push_back(std::make_unique<ImageLoaderQOI>()); _image_loaders.push_back(std::make_unique<ImageLoaderQOI>());
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>()); _image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
@ -115,13 +117,14 @@ static std::vector<uint8_t> generateToxIdenticon(const ToxKey& key) {
return pixels; return pixels;
} }
TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) { TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact4 c) {
if (!_cr.valid(c)) { const auto& cr = _cs.registry();
if (!cr.valid(c)) {
return {std::nullopt}; return {std::nullopt};
} }
if (_cr.all_of<Contact::Components::AvatarMemory>(c)) { if (cr.all_of<Contact::Components::AvatarMemory>(c)) {
const auto& a_m = _cr.get<Contact::Components::AvatarMemory>(c); const auto& a_m = cr.get<Contact::Components::AvatarMemory>(c);
TextureEntry new_entry; TextureEntry new_entry;
new_entry.timestamp_last_rendered = getTimeMS(); new_entry.timestamp_last_rendered = getTimeMS();
@ -139,8 +142,8 @@ TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) {
return {new_entry}; return {new_entry};
} }
if (_cr.all_of<Contact::Components::AvatarFile>(c)) { if (cr.all_of<Contact::Components::AvatarFile>(c)) {
const auto& a_f = _cr.get<Contact::Components::AvatarFile>(c); const auto& a_f = cr.get<Contact::Components::AvatarFile>(c);
std::ifstream file(a_f.file_path, std::ios::binary); std::ifstream file(a_f.file_path, std::ios::binary);
if (file.is_open()) { if (file.is_open()) {
@ -180,7 +183,7 @@ TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) {
} }
} // continues if loading img fails } // continues if loading img fails
if (!_cr.any_of< if (!cr.any_of<
Contact::Components::ToxFriendPersistent, Contact::Components::ToxFriendPersistent,
Contact::Components::ToxGroupPersistent, Contact::Components::ToxGroupPersistent,
Contact::Components::ToxGroupPeerPersistent, Contact::Components::ToxGroupPeerPersistent,
@ -190,16 +193,16 @@ TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) {
} }
std::vector<uint8_t> pixels; std::vector<uint8_t> pixels;
if (_cr.all_of<Contact::Components::ToxFriendPersistent>(c)) { if (cr.all_of<Contact::Components::ToxFriendPersistent>(c)) {
pixels = generateToxIdenticon(_cr.get<Contact::Components::ToxFriendPersistent>(c).key); pixels = generateToxIdenticon(cr.get<Contact::Components::ToxFriendPersistent>(c).key);
} else if (_cr.all_of<Contact::Components::ToxGroupPersistent>(c)) { } else if (cr.all_of<Contact::Components::ToxGroupPersistent>(c)) {
pixels = generateToxIdenticon(_cr.get<Contact::Components::ToxGroupPersistent>(c).chat_id); pixels = generateToxIdenticon(cr.get<Contact::Components::ToxGroupPersistent>(c).chat_id);
} else if (_cr.all_of<Contact::Components::ToxGroupPeerPersistent>(c)) { } else if (cr.all_of<Contact::Components::ToxGroupPeerPersistent>(c)) {
pixels = generateToxIdenticon(_cr.get<Contact::Components::ToxGroupPeerPersistent>(c).peer_key); pixels = generateToxIdenticon(cr.get<Contact::Components::ToxGroupPeerPersistent>(c).peer_key);
} else if (_cr.all_of<Contact::Components::ID>(c)) { } else if (cr.all_of<Contact::Components::ID>(c)) {
// TODO: should we really use toxidenticons for other protocols? // TODO: should we really use toxidenticons for other protocols?
// (this is required for self) // (this is required for self)
auto id_copy = _cr.get<Contact::Components::ID>(c).data; auto id_copy = cr.get<Contact::Components::ID>(c).data;
id_copy.resize(32); id_copy.resize(32);
pixels = generateToxIdenticon(id_copy); pixels = generateToxIdenticon(id_copy);
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <solanaceae/contact/contact_model3.hpp> #include <solanaceae/contact/fwd.hpp>
#include "./image_loader.hpp" #include "./image_loader.hpp"
#include "./texture_cache.hpp" #include "./texture_cache.hpp"
@ -8,12 +8,12 @@
#include <optional> #include <optional>
class ToxAvatarLoader { class ToxAvatarLoader {
Contact3Registry& _cr; ContactStore4I& _cs;
std::vector<std::unique_ptr<ImageLoaderI>> _image_loaders; std::vector<std::unique_ptr<ImageLoaderI>> _image_loaders;
public: public:
ToxAvatarLoader(Contact3Registry& cr); ToxAvatarLoader(ContactStore4I& cr);
TextureLoaderResult load(TextureUploaderI& tu, Contact3 c); TextureLoaderResult load(TextureUploaderI& tu, Contact4 c);
}; };

View File

@ -4,6 +4,8 @@
#include <solanaceae/util/config_model.hpp> #include <solanaceae/util/config_model.hpp>
#include <solanaceae/contact/contact_store_i.hpp>
//#include <solanaceae/message3/components.hpp> //#include <solanaceae/message3/components.hpp>
#include <solanaceae/object_store/meta_components_file.hpp> #include <solanaceae/object_store/meta_components_file.hpp>
// for comp transfer tox filekind (TODO: generalize -> content system?) // for comp transfer tox filekind (TODO: generalize -> content system?)
@ -29,11 +31,10 @@ namespace Components {
} }
ToxAvatarManager::ToxAvatarManager( ToxAvatarManager::ToxAvatarManager(
//RegistryMessageModel& rmm,
ObjectStore2& os, ObjectStore2& os,
Contact3Registry& cr, ContactStore4I& cs,
ConfigModelI& conf ConfigModelI& conf
) : /*_rmm(rmm)*/ _os(os), _os_sr(_os.newSubRef(this)), _cr(cr), _conf(conf) { ) : _os(os), _os_sr(_os.newSubRef(this)), _cs(cs), _conf(conf) {
_os_sr _os_sr
.subscribe(ObjectStore_Event::object_construct) .subscribe(ObjectStore_Event::object_construct)
.subscribe(ObjectStore_Event::object_update) .subscribe(ObjectStore_Event::object_update)
@ -53,11 +54,11 @@ ToxAvatarManager::ToxAvatarManager(
{ // scan tox contacts for cached avatars { // scan tox contacts for cached avatars
// old sts says pubkey.png // old sts says pubkey.png
_cr.view<Contact::Components::ToxFriendPersistent>().each([this](auto c, const Contact::Components::ToxFriendPersistent& tox_pers) { _cs.registry().view<Contact::Components::ToxFriendPersistent>().each([this](auto c, const Contact::Components::ToxFriendPersistent& tox_pers) {
addAvatarFileToContact(c, tox_pers.key); addAvatarFileToContact(c, tox_pers.key);
}); });
_cr.view<Contact::Components::ToxGroupPersistent>().each([this](auto c, const Contact::Components::ToxGroupPersistent& tox_pers) { _cs.registry().view<Contact::Components::ToxGroupPersistent>().each([this](auto c, const Contact::Components::ToxGroupPersistent& tox_pers) {
addAvatarFileToContact(c, tox_pers.chat_id); addAvatarFileToContact(c, tox_pers.chat_id);
}); });
@ -92,20 +93,25 @@ std::string ToxAvatarManager::getAvatarPath(const ToxKey& key) const {
return file_path.generic_u8string(); return file_path.generic_u8string();
} }
void ToxAvatarManager::addAvatarFileToContact(const Contact3 c, const ToxKey& key) { void ToxAvatarManager::addAvatarFileToContact(const Contact4 c, const ToxKey& key) {
const auto file_path = getAvatarPath(key); const auto file_path = getAvatarPath(key);
if (std::filesystem::is_regular_file(file_path)) { if (std::filesystem::is_regular_file(file_path)) {
// avatar file png file exists // avatar file png file exists
_cr.emplace_or_replace<Contact::Components::AvatarFile>(c, file_path); _cs.registry().emplace_or_replace<Contact::Components::AvatarFile>(c, file_path);
_cr.emplace_or_replace<Contact::Components::TagAvatarInvalidate>(c); _cs.registry().emplace_or_replace<Contact::Components::TagAvatarInvalidate>(c);
_cs.throwEventUpdate(c);
} }
} }
void ToxAvatarManager::clearAvatarFromContact(const Contact3 c) { void ToxAvatarManager::clearAvatarFromContact(const Contact4 c) {
if (_cr.all_of<Contact::Components::AvatarFile>(c)) { auto& cr = _cs.registry();
std::filesystem::remove(_cr.get<Contact::Components::AvatarFile>(c).file_path); if (cr.all_of<Contact::Components::AvatarFile>(c)) {
_cr.remove<Contact::Components::AvatarFile>(c); std::filesystem::remove(cr.get<Contact::Components::AvatarFile>(c).file_path);
_cr.emplace_or_replace<Contact::Components::TagAvatarInvalidate>(c); cr.remove<Contact::Components::AvatarFile>(c);
cr.emplace_or_replace<Contact::Components::TagAvatarInvalidate>(c);
_cs.throwEventUpdate(c);
} }
} }

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <solanaceae/object_store/object_store.hpp> #include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/contact/contact_model3.hpp> #include <solanaceae/contact/fwd.hpp>
#include <string> #include <string>
#include <vector> #include <vector>
@ -15,7 +15,7 @@ struct ToxKey;
class ToxAvatarManager : public ObjectStoreEventI { class ToxAvatarManager : public ObjectStoreEventI {
ObjectStore2& _os; ObjectStore2& _os;
ObjectStore2::SubscriptionReference _os_sr; ObjectStore2::SubscriptionReference _os_sr;
Contact3Registry& _cr; ContactStore4I& _cs;
ConfigModelI& _conf; ConfigModelI& _conf;
struct AcceptEntry { struct AcceptEntry {
@ -27,7 +27,7 @@ class ToxAvatarManager : public ObjectStoreEventI {
public: public:
ToxAvatarManager( ToxAvatarManager(
ObjectStore2& os, ObjectStore2& os,
Contact3Registry& cr, ContactStore4I& cs,
ConfigModelI& conf ConfigModelI& conf
); );
@ -36,8 +36,8 @@ class ToxAvatarManager : public ObjectStoreEventI {
protected: protected:
// TODO: become backend and work in objects instead // TODO: become backend and work in objects instead
std::string getAvatarPath(const ToxKey& key) const; std::string getAvatarPath(const ToxKey& key) const;
void addAvatarFileToContact(const Contact3 c, const ToxKey& key); void addAvatarFileToContact(const Contact4 c, const ToxKey& key);
void clearAvatarFromContact(const Contact3 c); void clearAvatarFromContact(const Contact4 c);
void checkObj(ObjectHandle o); void checkObj(ObjectHandle o);
protected: // os protected: // os

View File

@ -3,6 +3,7 @@
#include <solanaceae/util/time.hpp> #include <solanaceae/util/time.hpp>
#include <solanaceae/toxcore/tox_interface.hpp> #include <solanaceae/toxcore/tox_interface.hpp>
#include <solanaceae/contact/contact_store_i.hpp>
#include <solanaceae/contact/components.hpp> #include <solanaceae/contact/components.hpp>
#include <solanaceae/tox_contacts/components.hpp> #include <solanaceae/tox_contacts/components.hpp>
@ -27,12 +28,12 @@ namespace Contact::Components {
} // Contact::Components } // Contact::Components
ToxFriendFauxOfflineMessaging::ToxFriendFauxOfflineMessaging( ToxFriendFauxOfflineMessaging::ToxFriendFauxOfflineMessaging(
Contact3Registry& cr, ContactStore4I& cs,
RegistryMessageModelI& rmm, RegistryMessageModelI& rmm,
ToxContactModel2& tcm, ToxContactModel2& tcm,
ToxI& t, ToxI& t,
ToxEventProviderI& tep ToxEventProviderI& tep
) : _cr(cr), _rmm(rmm), _tcm(tcm), _t(t), _tep_sr(tep.newSubRef(this)) { ) : _cs(cs), _rmm(rmm), _tcm(tcm), _t(t), _tep_sr(tep.newSubRef(this)) {
_tep_sr.subscribe(Tox_Event_Type::TOX_EVENT_FRIEND_CONNECTION_STATUS); _tep_sr.subscribe(Tox_Event_Type::TOX_EVENT_FRIEND_CONNECTION_STATUS);
} }
@ -47,36 +48,40 @@ float ToxFriendFauxOfflineMessaging::tick(float time_delta) {
const uint64_t ts_now = getTimeMS(); const uint64_t ts_now = getTimeMS();
auto& cr = _cs.registry();
// check ALL // check ALL
// for each online tox friend // for each online tox friend
uint64_t min_next_attempt_ts {std::numeric_limits<uint64_t>::max()}; uint64_t min_next_attempt_ts {std::numeric_limits<uint64_t>::max()};
_cr.view<Contact::Components::ToxFriendEphemeral, Contact::Components::ConnectionState>() cr.view<Contact::Components::ToxFriendEphemeral, Contact::Components::ConnectionState>()
.each([this, &min_next_attempt_ts, ts_now](const Contact3 c, const auto& tfe, const auto& cs) { .each([this, &cr, &min_next_attempt_ts, ts_now](const Contact4 c, const auto& tfe, const auto& cs) {
if (cs.state == Contact::Components::ConnectionState::disconnected) { if (cs.state == Contact::Components::ConnectionState::disconnected) {
// cleanup // cleanup
if (_cr.all_of<Contact::Components::NextSendAttempt>(c)) { if (cr.all_of<Contact::Components::NextSendAttempt>(c)) {
_cr.remove<Contact::Components::NextSendAttempt>(c); // TODO: figure out if we want to throw update here
cr.remove<Contact::Components::NextSendAttempt>(c);
auto* mr = static_cast<const RegistryMessageModelI&>(_rmm).get(c); auto* mr = static_cast<const RegistryMessageModelI&>(_rmm).get(c);
if (mr != nullptr) { if (mr != nullptr) {
mr->storage<Message::Components::LastSendAttempt>().clear(); mr->storage<Message::Components::LastSendAttempt>().clear();
} }
} }
} else { } else {
if (!_cr.all_of<Contact::Components::NextSendAttempt>(c)) { if (!cr.all_of<Contact::Components::NextSendAttempt>(c)) {
if (false) { // has unsent messages if (false) { // has unsent messages
const auto& nsa = _cr.emplace<Contact::Components::NextSendAttempt>(c, ts_now + uint64_t(_delay_after_cc*1000)); // wait before first message is sent const auto& nsa = cr.emplace<Contact::Components::NextSendAttempt>(c, ts_now + uint64_t(_delay_after_cc*1000)); // wait before first message is sent
min_next_attempt_ts = std::min(min_next_attempt_ts, nsa.ts); min_next_attempt_ts = std::min(min_next_attempt_ts, nsa.ts);
} }
} else { } else {
auto ret = doFriendMessageCheck(c, tfe); auto ret = doFriendMessageCheck(c, tfe);
if (ret == dfmc_Ret::SENT_THIS_TICK) { if (ret == dfmc_Ret::SENT_THIS_TICK) {
const auto ts = _cr.get<Contact::Components::NextSendAttempt>(c).ts = ts_now + uint64_t(_delay_inbetween*1000); const auto ts = cr.get<Contact::Components::NextSendAttempt>(c).ts = ts_now + uint64_t(_delay_inbetween*1000);
min_next_attempt_ts = std::min(min_next_attempt_ts, ts); min_next_attempt_ts = std::min(min_next_attempt_ts, ts);
} else if (ret == dfmc_Ret::TOO_SOON) { } else if (ret == dfmc_Ret::TOO_SOON) {
// TODO: set to _delay_inbetween? prob expensive for no good reason // TODO: set to _delay_inbetween? prob expensive for no good reason
min_next_attempt_ts = std::min(min_next_attempt_ts, _cr.get<Contact::Components::NextSendAttempt>(c).ts); min_next_attempt_ts = std::min(min_next_attempt_ts, cr.get<Contact::Components::NextSendAttempt>(c).ts);
} else { } else {
_cr.remove<Contact::Components::NextSendAttempt>(c); // TODO: figure out if we want to throw update here
cr.remove<Contact::Components::NextSendAttempt>(c);
} }
} }
} }
@ -96,7 +101,7 @@ float ToxFriendFauxOfflineMessaging::tick(float time_delta) {
return _interval_timer; return _interval_timer;
} }
ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact3 c, const Contact::Components::ToxFriendEphemeral& tfe) { ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact4 c, const Contact::Components::ToxFriendEphemeral& tfe) {
// walk all messages and check if // walk all messages and check if
// unacked message // unacked message
// timeouts for exising unacked messages expired (send) // timeouts for exising unacked messages expired (send)
@ -109,11 +114,13 @@ ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendM
const uint64_t ts_now = getTimeMS(); const uint64_t ts_now = getTimeMS();
if (!_cr.all_of<Contact::Components::Self>(c)) { const auto& cr = _cs.registry();
if (!cr.all_of<Contact::Components::Self>(c)) {
return dfmc_Ret::NO_MSG; // error return dfmc_Ret::NO_MSG; // error
} }
const auto self_c = _cr.get<Contact::Components::Self>(c).self; const auto self_c = cr.get<Contact::Components::Self>(c).self;
// filter for unconfirmed messages // filter for unconfirmed messages
@ -222,7 +229,8 @@ bool ToxFriendFauxOfflineMessaging::onToxEvent(const Tox_Event_Friend_Connection
return false; return false;
} }
_cr.emplace_or_replace<Contact::Components::NextSendAttempt>(c, getTimeMS() + uint64_t(_delay_after_cc*1000)); // wait before first message is sent // TODO: should we throw update?
_cs.registry().emplace_or_replace<Contact::Components::NextSendAttempt>(c, getTimeMS() + uint64_t(_delay_after_cc*1000)); // wait before first message is sent
_interval_timer = 0.f; _interval_timer = 0.f;

View File

@ -2,7 +2,7 @@
#include <solanaceae/toxcore/tox_event_interface.hpp> #include <solanaceae/toxcore/tox_event_interface.hpp>
#include <solanaceae/tox_contacts/tox_contact_model2.hpp> #include <solanaceae/tox_contacts/tox_contact_model2.hpp>
#include <solanaceae/contact/contact_model3.hpp> #include <solanaceae/contact/fwd.hpp>
#include <solanaceae/message3/registry_message_model.hpp> #include <solanaceae/message3/registry_message_model.hpp>
// fwd // fwd
@ -14,7 +14,7 @@ namespace Contact::Components {
// resends unconfirmed messages. // resends unconfirmed messages.
// timers get reset on connection changes, and send order is preserved. // timers get reset on connection changes, and send order is preserved.
class ToxFriendFauxOfflineMessaging : public ToxEventI { class ToxFriendFauxOfflineMessaging : public ToxEventI {
Contact3Registry& _cr; ContactStore4I& _cs;
RegistryMessageModelI& _rmm; RegistryMessageModelI& _rmm;
ToxContactModel2& _tcm; ToxContactModel2& _tcm;
ToxI& _t; ToxI& _t;
@ -29,7 +29,7 @@ class ToxFriendFauxOfflineMessaging : public ToxEventI {
public: public:
ToxFriendFauxOfflineMessaging( ToxFriendFauxOfflineMessaging(
Contact3Registry& cr, ContactStore4I& cs,
RegistryMessageModelI& rmm, RegistryMessageModelI& rmm,
ToxContactModel2& tcm, ToxContactModel2& tcm,
ToxI& t, ToxI& t,
@ -47,7 +47,7 @@ class ToxFriendFauxOfflineMessaging : public ToxEventI {
// only called for online friends // only called for online friends
// returns true if a message was sent // returns true if a message was sent
// dont call this too often // dont call this too often
dfmc_Ret doFriendMessageCheck(const Contact3 c, const Contact::Components::ToxFriendEphemeral& tfe); dfmc_Ret doFriendMessageCheck(const Contact4 c, const Contact::Components::ToxFriendEphemeral& tfe);
protected: protected:
bool onToxEvent(const Tox_Event_Friend_Connection_Status* e) override; bool onToxEvent(const Tox_Event_Friend_Connection_Status* e) override;