Compare commits

...

10 Commits

Author SHA1 Message Date
d0761bf60e revert crop by default (did not work as intended) 2024-02-29 19:15:33 +01:00
0f41ee6a2e add screencap to readme 2024-02-23 11:20:49 +01:00
0aeafec019 fix month starting at 0 2024-02-15 15:34:44 +01:00
9a0df4f577 date change 2024-02-15 15:29:01 +01:00
61714836bb typos 2024-02-12 14:13:57 +01:00
cff0c100ec add fragment store draft doc 2024-02-11 19:01:48 +01:00
010c49d100 stable names 2024-02-10 12:23:40 +01:00
ff5dbaffc0 fix some file selector glitches 2024-02-08 18:11:51 +01:00
b56d581e4b fix normal feeling sluggish 2024-02-05 16:15:10 +01:00
aa661aaaa7 default to normal fps mode again 2024-02-05 16:10:30 +01:00
11 changed files with 123 additions and 11 deletions

View File

@ -2,3 +2,7 @@
![tomato](res/icon/tomato_v1_256.png)
## Highly experimental solanaceae client with Tox built-in
![group chat](res/tomato_screenshot_group_bot_text_23-02-2024.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View File

@ -324,6 +324,7 @@ float ChatGui4::render(float time_delta) {
//tmp_view.use<Message::Components::Timestamp>();
//tmp_view.each([&](const Message3 e, Message::Components::ContactFrom& c_from, Message::Components::ContactTo& c_to, Message::Components::Timestamp ts
//) {
uint64_t prev_ts {0};
auto tmp_view = msg_reg.view<Message::Components::Timestamp>();
for (auto view_it = tmp_view.rbegin(), view_last = tmp_view.rend(); view_it != view_last; view_it++) {
const Message3 e = *view_it;
@ -341,6 +342,34 @@ float ChatGui4::render(float time_delta) {
// TODO: why?
ImGui::TableNextRow(0, TEXT_BASE_HEIGHT);
{ // check if date changed
// TODO: find defined ways of casting to time_t
std::time_t prev = prev_ts / 1000;
std::time_t next = ts.ts / 1000;
std::tm prev_tm = *std::localtime(&prev);
std::tm next_tm = *std::localtime(&next);
if (
prev_tm.tm_yday != next_tm.tm_yday ||
prev_tm.tm_year != next_tm.tm_year // making sure
) {
// name
if (ImGui::TableNextColumn()) {
//ImGui::TextDisabled("---");
}
// msg
if (ImGui::TableNextColumn()) {
ImGui::TextDisabled("DATE CHANGED from %d.%d.%d to %d.%d.%d",
1900+prev_tm.tm_year, 1+prev_tm.tm_mon, prev_tm.tm_mday,
1900+next_tm.tm_year, 1+next_tm.tm_mon, next_tm.tm_mday
);
}
ImGui::TableNextRow(0, TEXT_BASE_HEIGHT);
}
prev_ts = ts.ts;
}
ImGui::PushID(entt::to_integral(e));
// name
@ -737,7 +766,11 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
) {
if (ImGui::Button("save to")) {
_fss.requestFile(
[](const auto& path) -> bool { return std::filesystem::is_directory(path); },
[](std::filesystem::path& path) -> bool {
// remove file path
path.remove_filename();
return std::filesystem::is_directory(path);
},
[this, &reg, e](const auto& path) {
if (reg.valid(e)) { // still valid
// TODO: trim file?

View File

@ -18,7 +18,7 @@ FileSelector::FileSelector(void) {
}
void FileSelector::requestFile(
std::function<bool(const std::filesystem::path& path)>&& is_valid,
std::function<bool(std::filesystem::path& path)>&& is_valid,
std::function<void(const std::filesystem::path& path)>&& on_choose,
std::function<void(void)>&& on_cancel
) {
@ -77,7 +77,9 @@ void FileSelector::render(void) {
if (current_path.has_parent_path()) {
if (ImGui::TableNextColumn()) {
if (ImGui::Selectable("D##..", false, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowItemOverlap)) {
_current_file_path = _current_file_path.parent_path();
// the first "parent_path()" only removes the filename and the ending "/"
_current_file_path = _current_file_path.parent_path().parent_path() / "";
//_current_file_path = _current_file_path.remove_filename().parent_path() / "";
}
}

View File

@ -8,7 +8,7 @@ struct FileSelector {
bool _open_popup {false};
std::function<bool(const std::filesystem::path& path)> _is_valid = [](auto){ return true; };
std::function<bool(std::filesystem::path& path)> _is_valid = [](auto){ return true; };
std::function<void(const std::filesystem::path& path)> _on_choose = [](auto){};
std::function<void(void)> _on_cancel = [](){};
@ -18,8 +18,9 @@ struct FileSelector {
FileSelector(void);
// TODO: supply hints
// HACK: until we supply hints, is_valid can modify
void requestFile(
std::function<bool(const std::filesystem::path& path)>&& is_valid,
std::function<bool(std::filesystem::path& path)>&& is_valid,
std::function<void(const std::filesystem::path& path)>&& on_choose,
std::function<void(void)>&& on_cancel
);

View File

@ -0,0 +1,72 @@
# Fragment Store
Fragments are are pieces of information split into Metadata and Data.
They can be stored seperated or together.
They can be used as a Transport protocol/logic too.
# Store types
### Object Store
Fragment files are stored with the first 2 hex chars as sub folders:
eg:
`objects/` (object store root)
- `5f/` (first 2hex subfolder)
- `4fffffff` (the fragment file without the first 2 hexchars)
### Split Object Store
Same as Object Store, but medadata and data stored in seperate files.
Metadata files have the `.meta` suffix. They also have a filetype specific suffix, like `.json`, `.msgpack` etc.
### Memory Store
Just keeps the Fragments in memory.
# File formats
Files can be compressed and encrypted. Since compression needs the data structure to funcion, it is applied before it is encrypted.
### Text Json
Text json only makes sense for metadata if it's neither compressed nor encrypted. (otherwise its binary on disk anyway, so why waste bytes).
Since the content of data is not looked at, nothing stops you from using text json and ecrypt it, but atleast basic compression is advised.
A Metadata json object has the following keys:
- `enc` (uint) Encryption type of the data, if any
- `comp` (uint) Compression type of the data, if any
- `metadata` (obj) the
## Binary file headers
### Split Metadata
file magic bytes `SOLMET` (6 bytes)
1 byte encryption type (`0x00` is none)
1 byte compression type (`0x00` is none)
...metadata here...
note that the encryption and compression are for the metadata only.
The metadata itself contains encryption and compression info about the data.
### Split Data
(none) all the data is in the metadata file.
This is mostly to allow direct storage for files in the Fragment store without excessive duplication.
Keep in mind to not use the actual file name as the data/meta file name.
### Single fragment
file magic bytes `SOLFIL` (6 bytes)
1 byte encryption type (`0x00` is none)
1 byte compression type (`0x00` is none)
...metadata here...
...data here...

View File

@ -275,7 +275,7 @@ Screen* MainScreen::render(float time_delta, bool&) {
struct PerfProfileRender {
float low_delay_window {1.5f};
float low_delay_min {1.f/60.f};
float low_delay_max {1.f/30.f};
float low_delay_max {1.f/60.f};
float mid_delay_window {30.f};
float mid_delay_min {1.f/60.f};
@ -289,7 +289,7 @@ Screen* MainScreen::render(float time_delta, bool&) {
const static PerfProfileRender normalPerfProfile{
//1.5f, // low_delay_window
//1.f/60.f, // low_delay_min
//1.f/30.f, // low_delay_max
//1.f/60.f, // low_delay_max
//30.f, // mid_delay_window
//1.f/60.f, // mid_delay_min

View File

@ -94,7 +94,7 @@ struct MainScreen final : public Screen {
// 0 - normal
// 1 - reduced
// 2 - power save
int _fps_perf_mode {1};
int _fps_perf_mode {0};
// 0 - normal
// 1 - power save
int _compute_perf_mode {0};

View File

@ -32,7 +32,7 @@ struct SendImagePopup {
Rect crop_rect;
Rect crop_before_drag;
bool cropping {true};
bool cropping {false};
bool dragging_last_frame_ul {false};
bool dragging_last_frame_lr {false};