sync and delivery (and unused read) states and other smaller refactors
This commit is contained in:
parent
7c576dd4d0
commit
20b4cdc5f1
2
external/solanaceae_message3
vendored
2
external/solanaceae_message3
vendored
@ -1 +1 @@
|
|||||||
Subproject commit d0a53a6366e3f52e8c84d9fd63dd925ef93e10ce
|
Subproject commit 4ae7c4068f91cedd4291521a5777af00c0ff052f
|
2
external/solanaceae_tox
vendored
2
external/solanaceae_tox
vendored
@ -1 +1 @@
|
|||||||
Subproject commit c01d91144ce10486ff6e98a2e6e8cc5e20a5c412
|
Subproject commit 75ed1dffebe254d9cc79753d31f4c73c40238f72
|
2
external/solanaceae_toxcore
vendored
2
external/solanaceae_toxcore
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 80140ae9b6cc9d6280cfc8c16c6f8c3e40b51f2a
|
Subproject commit 9d3d81d4ff55b152cb779cec2a37b960fcedd584
|
@ -123,14 +123,20 @@ void ChatGui4::render(float time_delta) {
|
|||||||
|
|
||||||
if (_selected_contact) {
|
if (_selected_contact) {
|
||||||
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;
|
||||||
|
if (_cr.all_of<Contact::Components::ParentOf>(*_selected_contact)) {
|
||||||
|
sub_contacts = &_cr.get<Contact::Components::ParentOf>(*_selected_contact).subs;
|
||||||
|
}
|
||||||
|
|
||||||
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 (_cr.all_of<Contact::Components::ParentOf>(*_selected_contact)) {
|
||||||
const auto sub_contacts = _cr.get<Contact::Components::ParentOf>(*_selected_contact).subs;
|
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());
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
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)) {
|
||||||
_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>") + ": ");
|
||||||
@ -233,9 +239,10 @@ void ChatGui4::render(float time_delta) {
|
|||||||
ImGuiTableFlags_RowBg |
|
ImGuiTableFlags_RowBg |
|
||||||
ImGuiTableFlags_SizingFixedFit
|
ImGuiTableFlags_SizingFixedFit
|
||||||
;
|
;
|
||||||
if (msg_reg_ptr != nullptr && ImGui::BeginTable("chat_table", 4, table_flags)) {
|
if (msg_reg_ptr != nullptr && ImGui::BeginTable("chat_table", 5, table_flags)) {
|
||||||
ImGui::TableSetupColumn("name", 0, TEXT_BASE_WIDTH * 15.f);
|
ImGui::TableSetupColumn("name", 0, TEXT_BASE_WIDTH * 15.f);
|
||||||
ImGui::TableSetupColumn("message", ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("message", ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
ImGui::TableSetupColumn("delivered/read");
|
||||||
ImGui::TableSetupColumn("timestamp");
|
ImGui::TableSetupColumn("timestamp");
|
||||||
ImGui::TableSetupColumn("extra_info", _show_chat_extra_info ? ImGuiTableColumnFlags_None : ImGuiTableColumnFlags_Disabled);
|
ImGui::TableSetupColumn("extra_info", _show_chat_extra_info ? ImGuiTableColumnFlags_None : ImGuiTableColumnFlags_Disabled);
|
||||||
|
|
||||||
@ -354,6 +361,84 @@ void ChatGui4::render(float time_delta) {
|
|||||||
ImGui::TextDisabled("---");
|
ImGui::TextDisabled("---");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remote received and read state
|
||||||
|
if (ImGui::TableNextColumn()) {
|
||||||
|
// TODO: theming for hardcoded values
|
||||||
|
|
||||||
|
if (msg_reg.all_of<Message::Components::Remote::TimestampReceived>(e)) {
|
||||||
|
const auto list = msg_reg.get<Message::Components::Remote::TimestampReceived>(e).ts;
|
||||||
|
// wrongly assumes contacts never get removed from a group
|
||||||
|
if (sub_contacts != nullptr && list.size() < sub_contacts->size()) {
|
||||||
|
// if partically delivered
|
||||||
|
ImGui::TextColored(ImVec4{0.7f, 0.7f, 0.1f, 0.5f}, "d");
|
||||||
|
} else {
|
||||||
|
// if fully delivered
|
||||||
|
ImGui::TextColored(ImVec4{0.1f, 0.8f, 0.1f, 0.5f}, "D");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginItemTooltip()) {
|
||||||
|
std::string synced_by_text {"delivery confirmed by:"};
|
||||||
|
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
|
||||||
|
|
||||||
|
for (const auto& [c, syned_ts] : list) {
|
||||||
|
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
|
||||||
|
synced_by_text += "\n sself(!)"; // makes no sense
|
||||||
|
} else if (_cr.all_of<Contact::Components::TagSelfWeak>(c)) {
|
||||||
|
synced_by_text += "\n wself";
|
||||||
|
} else {
|
||||||
|
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;
|
||||||
|
synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)";
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("%s", synced_by_text.c_str());
|
||||||
|
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::TextDisabled("_");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
// TODO: dedup
|
||||||
|
if (msg_reg.all_of<Message::Components::Remote::TimestampRead>(e)) {
|
||||||
|
const auto list = msg_reg.get<Message::Components::Remote::TimestampRead>(e).ts;
|
||||||
|
// wrongly assumes contacts never get removed from a group
|
||||||
|
if (sub_contacts != nullptr && list.size() < sub_contacts->size()) {
|
||||||
|
// if partially read
|
||||||
|
ImGui::TextColored(ImVec4{0.7f, 0.7f, 0.1f, 0.5f}, "r");
|
||||||
|
} else {
|
||||||
|
// if fully read
|
||||||
|
ImGui::TextColored(ImVec4{0.1f, 0.8f, 0.1f, 0.5f}, "R");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::BeginItemTooltip()) {
|
||||||
|
std::string synced_by_text {"read confirmed by:"};
|
||||||
|
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
|
||||||
|
|
||||||
|
for (const auto& [c, syned_ts] : list) {
|
||||||
|
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
|
||||||
|
synced_by_text += "\n sself(!)"; // makes no sense
|
||||||
|
} else if (_cr.all_of<Contact::Components::TagSelfWeak>(c)) {
|
||||||
|
synced_by_text += "\n wself";
|
||||||
|
} else {
|
||||||
|
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;
|
||||||
|
synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)";
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("%s", synced_by_text.c_str());
|
||||||
|
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ImGui::TextDisabled("_");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ts
|
// ts
|
||||||
if (ImGui::TableNextColumn()) {
|
if (ImGui::TableNextColumn()) {
|
||||||
auto time = std::chrono::system_clock::to_time_t(
|
auto time = std::chrono::system_clock::to_time_t(
|
||||||
@ -707,8 +792,9 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) {
|
|||||||
|
|
||||||
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 auto& synced_by = reg.get<Message::Components::SyncedBy>(e).list;
|
const int64_t now_ts_s = int64_t(Message::getTimeMS() / 1000u);
|
||||||
for (const auto& c : synced_by) {
|
|
||||||
|
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)) {
|
||||||
@ -716,7 +802,30 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) {
|
|||||||
} 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;
|
||||||
|
synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui::TextDisabled("%s", synced_by_text.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove?
|
||||||
|
if (reg.all_of<Message::Components::Remote::TimestampReceived>(e)) {
|
||||||
|
std::string synced_by_text {"receivedBy:"};
|
||||||
|
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) {
|
||||||
|
if (_cr.all_of<Contact::Components::TagSelfStrong>(c)) {
|
||||||
|
synced_by_text += "\n sself(!)"; // makes no sense
|
||||||
|
} else if (_cr.all_of<Contact::Components::TagSelfWeak>(c)) {
|
||||||
|
synced_by_text += "\n wself";
|
||||||
|
} else {
|
||||||
|
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;
|
||||||
|
synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)";
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::TextDisabled("%s", synced_by_text.c_str());
|
ImGui::TextDisabled("%s", synced_by_text.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,11 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
namespace Message {
|
||||||
|
uint64_t getTimeMS(void);
|
||||||
|
}
|
||||||
|
|
||||||
MessageImageLoader::MessageImageLoader(void) {
|
MessageImageLoader::MessageImageLoader(void) {
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
||||||
@ -52,7 +57,7 @@ std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Messa
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextureEntry new_entry;
|
TextureEntry new_entry;
|
||||||
new_entry.timestamp_last_rendered = getNowMS();
|
new_entry.timestamp_last_rendered = Message::getTimeMS();
|
||||||
new_entry.current_texture = 0;
|
new_entry.current_texture = 0;
|
||||||
for (const auto& [ms, data] : res.frames) {
|
for (const auto& [ms, data] : res.frames) {
|
||||||
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
|
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
namespace Message {
|
||||||
|
uint64_t getTimeMS(void);
|
||||||
|
}
|
||||||
|
|
||||||
SendImagePopup::SendImagePopup(TextureUploaderI& tu) : _tu(tu) {
|
SendImagePopup::SendImagePopup(TextureUploaderI& tu) : _tu(tu) {
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
||||||
@ -76,7 +81,7 @@ bool SendImagePopup::load(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
preview_image.timestamp_last_rendered = getNowMS();
|
preview_image.timestamp_last_rendered = Message::getTimeMS();
|
||||||
preview_image.current_texture = 0;
|
preview_image.current_texture = 0;
|
||||||
for (const auto& [ms, data] : original_image.frames) {
|
for (const auto& [ms, data] : original_image.frames) {
|
||||||
const auto n_t = _tu.uploadRGBA(data.data(), original_image.width, original_image.height);
|
const auto n_t = _tu.uploadRGBA(data.data(), original_image.width, original_image.height);
|
||||||
@ -169,7 +174,7 @@ void SendImagePopup::render(float time_delta) {
|
|||||||
const auto TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
|
const auto TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x;
|
||||||
const auto TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing();
|
const auto TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing();
|
||||||
|
|
||||||
preview_image.doAnimation(getNowMS());
|
preview_image.doAnimation(Message::getTimeMS());
|
||||||
|
|
||||||
time += time_delta;
|
time += time_delta;
|
||||||
time = fmod(time, 1.f); // fract()
|
time = fmod(time, 1.f); // fract()
|
||||||
|
@ -21,7 +21,7 @@ void TextureEntry::doAnimation(const int64_t ts_now) {
|
|||||||
|
|
||||||
TextureEntry generateTestAnim(TextureUploaderI& tu) {
|
TextureEntry generateTestAnim(TextureUploaderI& tu) {
|
||||||
TextureEntry new_entry;
|
TextureEntry new_entry;
|
||||||
new_entry.timestamp_last_rendered = getNowMS();
|
new_entry.timestamp_last_rendered = Message::getTimeMS();
|
||||||
new_entry.current_texture = 0;
|
new_entry.current_texture = 0;
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
// hack
|
// hack
|
||||||
@ -54,7 +54,3 @@ TextureEntry generateTestAnim(TextureUploaderI& tu) {
|
|||||||
return new_entry;
|
return new_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getNowMS(void) {
|
|
||||||
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -71,8 +71,10 @@ struct TextureEntry {
|
|||||||
|
|
||||||
TextureEntry generateTestAnim(TextureUploaderI& tu);
|
TextureEntry generateTestAnim(TextureUploaderI& tu);
|
||||||
|
|
||||||
// TODO: move to utils or something
|
// fwd
|
||||||
uint64_t getNowMS(void);
|
namespace Message {
|
||||||
|
uint64_t getTimeMS(void);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename TextureType, typename KeyType, class Loader>
|
template<typename TextureType, typename KeyType, class Loader>
|
||||||
struct TextureCache {
|
struct TextureCache {
|
||||||
@ -132,7 +134,7 @@ struct TextureCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void update(void) {
|
void update(void) {
|
||||||
const uint64_t ts_now = getNowMS();
|
const uint64_t ts_now = Message::getTimeMS();
|
||||||
|
|
||||||
std::vector<KeyType> to_purge;
|
std::vector<KeyType> to_purge;
|
||||||
for (auto&& [key, te] : _cache) {
|
for (auto&& [key, te] : _cache) {
|
||||||
|
@ -14,6 +14,11 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
namespace Message {
|
||||||
|
uint64_t getTimeMS(void);
|
||||||
|
}
|
||||||
|
|
||||||
ToxAvatarLoader::ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) {
|
ToxAvatarLoader::ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) {
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>());
|
||||||
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
_image_loaders.push_back(std::make_unique<ImageLoaderWebP>());
|
||||||
@ -121,7 +126,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
|||||||
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 = getNowMS();
|
new_entry.timestamp_last_rendered = Message::getTimeMS();
|
||||||
new_entry.current_texture = 0;
|
new_entry.current_texture = 0;
|
||||||
|
|
||||||
new_entry.width = a_m.width;
|
new_entry.width = a_m.width;
|
||||||
@ -159,7 +164,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextureEntry new_entry;
|
TextureEntry new_entry;
|
||||||
new_entry.timestamp_last_rendered = getNowMS();
|
new_entry.timestamp_last_rendered = Message::getTimeMS();
|
||||||
new_entry.current_texture = 0;
|
new_entry.current_texture = 0;
|
||||||
for (const auto& [ms, data] : res.frames) {
|
for (const auto& [ms, data] : res.frames) {
|
||||||
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
|
const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height);
|
||||||
@ -195,7 +200,7 @@ std::optional<TextureEntry> ToxAvatarLoader::load(TextureUploaderI& tu, Contact3
|
|||||||
}
|
}
|
||||||
|
|
||||||
TextureEntry new_entry;
|
TextureEntry new_entry;
|
||||||
new_entry.timestamp_last_rendered = getNowMS();
|
new_entry.timestamp_last_rendered = Message::getTimeMS();
|
||||||
new_entry.current_texture = 0;
|
new_entry.current_texture = 0;
|
||||||
|
|
||||||
const auto n_t = tu.uploadRGBA(pixels.data(), 5, 5);
|
const auto n_t = tu.uploadRGBA(pixels.data(), 5, 5);
|
||||||
|
Loading…
Reference in New Issue
Block a user