fix(user-data): keep ikvxx persistence in text format
This commit is contained in:
@@ -2,10 +2,6 @@
|
||||
|
||||
#include <izo/Paths.hpp>
|
||||
#include <ikvxx/ikvxx.hpp>
|
||||
extern "C"
|
||||
{
|
||||
#include <ikv.h>
|
||||
}
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
@@ -133,6 +129,15 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<float> readFloat(const ikv::Value &value)
|
||||
{
|
||||
if (value.isDouble())
|
||||
return static_cast<float>(value.asDouble());
|
||||
if (value.isInt())
|
||||
return static_cast<float>(value.asInt64());
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Load settings from an ikv::Value "settings" object into UserData fields.
|
||||
// Returns true if anything useful was read.
|
||||
void loadSettings(const ikv::Value &settings, float &sidebar_width, float &details_width,
|
||||
@@ -142,16 +147,20 @@ namespace
|
||||
std::array<bool, 4> &sidebar_section_open,
|
||||
std::array<float, 4> &commit_table_column_widths)
|
||||
{
|
||||
if (settings.isMember("sidebar_width") && settings["sidebar_width"].isDouble())
|
||||
sidebar_width = static_cast<float>(settings["sidebar_width"].asDouble());
|
||||
if (settings.isMember("details_width") && settings["details_width"].isDouble())
|
||||
details_width = static_cast<float>(settings["details_width"].asDouble());
|
||||
if (settings.isMember("sidebar_width"))
|
||||
if (const auto value = readFloat(settings["sidebar_width"]); value)
|
||||
sidebar_width = *value;
|
||||
if (settings.isMember("details_width"))
|
||||
if (const auto value = readFloat(settings["details_width"]); value)
|
||||
details_width = *value;
|
||||
if (settings.isMember("sidebar_collapsed") && settings["sidebar_collapsed"].isBool())
|
||||
sidebar_collapsed = settings["sidebar_collapsed"].asBool();
|
||||
if (settings.isMember("commit_message_height") && settings["commit_message_height"].isDouble())
|
||||
commit_message_height = static_cast<float>(settings["commit_message_height"].asDouble());
|
||||
if (settings.isMember("working_composer_height") && settings["working_composer_height"].isDouble())
|
||||
working_composer_height = static_cast<float>(settings["working_composer_height"].asDouble());
|
||||
if (settings.isMember("commit_message_height"))
|
||||
if (const auto value = readFloat(settings["commit_message_height"]); value)
|
||||
commit_message_height = *value;
|
||||
if (settings.isMember("working_composer_height"))
|
||||
if (const auto value = readFloat(settings["working_composer_height"]); value)
|
||||
working_composer_height = *value;
|
||||
if (settings.isMember("pull_mode") && settings["pull_mode"].isInt())
|
||||
pull_mode = static_cast<int>(settings["pull_mode"].asInt64());
|
||||
if (settings.isMember("zoom_percent") && settings["zoom_percent"].isInt())
|
||||
@@ -162,7 +171,8 @@ namespace
|
||||
const ikv::Value &arr = settings["sidebar_sections"];
|
||||
const auto count = std::min(arr.size(), sidebar_section_heights.size());
|
||||
for (std::size_t i = 0; i < count; ++i)
|
||||
sidebar_section_heights[i] = static_cast<float>(arr[static_cast<ArrayIndex>(i)].asDouble());
|
||||
if (const auto value = readFloat(arr[static_cast<ArrayIndex>(i)]); value)
|
||||
sidebar_section_heights[i] = *value;
|
||||
}
|
||||
if (settings.isMember("sidebar_section_open") && settings["sidebar_section_open"].isArray())
|
||||
{
|
||||
@@ -176,7 +186,8 @@ namespace
|
||||
const ikv::Value &arr = settings["commit_table_columns"];
|
||||
const auto count = std::min(arr.size(), commit_table_column_widths.size());
|
||||
for (std::size_t i = 0; i < count; ++i)
|
||||
commit_table_column_widths[i] = static_cast<float>(arr[static_cast<ArrayIndex>(i)].asDouble());
|
||||
if (const auto value = readFloat(arr[static_cast<ArrayIndex>(i)]); value)
|
||||
commit_table_column_widths[i] = *value;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@@ -234,7 +245,17 @@ void UserData::load()
|
||||
// ── Primary load: iKvxx binary (.ikv) ────────────────────────────────────
|
||||
try
|
||||
{
|
||||
ikv::Value root = ikv::Value::loadBinary(binary_path.string());
|
||||
const ikv::Value root = [&]() -> ikv::Value
|
||||
{
|
||||
try
|
||||
{
|
||||
return ikv::Value::load(binary_path.string());
|
||||
}
|
||||
catch (const ikv::Error &)
|
||||
{
|
||||
return ikv::Value::loadBinary(binary_path.string());
|
||||
}
|
||||
}();
|
||||
|
||||
if (root.isMember("settings") && root["settings"].isObject())
|
||||
{
|
||||
@@ -536,76 +557,66 @@ void UserData::setPendingCommitDescription(const std::string &repo_path, const s
|
||||
void UserData::save() const
|
||||
{
|
||||
std::filesystem::create_directories(directory_);
|
||||
ikv::Value root(ikv::objectValue, "gitree");
|
||||
|
||||
ikv_node_t *root = ikv_create_object("gitree");
|
||||
if (!root)
|
||||
return;
|
||||
auto settings = root.makeObject("settings");
|
||||
settings["sidebar_width"] = static_cast<double>(sidebar_width_);
|
||||
settings["details_width"] = static_cast<double>(details_width_);
|
||||
settings["sidebar_collapsed"] = sidebar_collapsed_;
|
||||
settings["commit_message_height"] = static_cast<double>(commit_message_height_);
|
||||
settings["working_composer_height"] = static_cast<double>(working_composer_height_);
|
||||
settings["pull_mode"] = static_cast<int64_t>(pull_mode_);
|
||||
settings["zoom_percent"] = static_cast<int64_t>(zoom_percent_);
|
||||
|
||||
// ── settings ─────────────────────────────────────────────────────────────
|
||||
ikv_node_t *settings = ikv_object_add_object(root, "settings");
|
||||
ikv_object_set_float(settings, "sidebar_width", sidebar_width_);
|
||||
ikv_object_set_float(settings, "details_width", details_width_);
|
||||
ikv_object_set_bool(settings, "sidebar_collapsed", sidebar_collapsed_);
|
||||
ikv_object_set_float(settings, "commit_message_height", commit_message_height_);
|
||||
ikv_object_set_float(settings, "working_composer_height", working_composer_height_);
|
||||
ikv_object_set_int(settings, "pull_mode", pull_mode_);
|
||||
ikv_object_set_int(settings, "zoom_percent", zoom_percent_);
|
||||
|
||||
ikv_node_t *heights = ikv_object_add_array(settings, "sidebar_sections", IKV_FLOAT);
|
||||
auto heights = settings.makeArray("sidebar_sections", ikv::realValue);
|
||||
for (const float h : sidebar_section_heights_)
|
||||
ikv_array_add_float(heights, h);
|
||||
heights.append(static_cast<double>(h));
|
||||
|
||||
ikv_node_t *open = ikv_object_add_array(settings, "sidebar_section_open", IKV_BOOL);
|
||||
auto open = settings.makeArray("sidebar_section_open", ikv::booleanValue);
|
||||
for (const bool b : sidebar_section_open_)
|
||||
ikv_array_add_bool(open, b);
|
||||
open.append(b);
|
||||
|
||||
ikv_node_t *col_widths = ikv_object_add_array(settings, "commit_table_columns", IKV_FLOAT);
|
||||
auto col_widths = settings.makeArray("commit_table_columns", ikv::realValue);
|
||||
for (const float w : commit_table_column_widths_)
|
||||
ikv_array_add_float(col_widths, w);
|
||||
col_widths.append(static_cast<double>(w));
|
||||
|
||||
// ── per-repository settings ───────────────────────────────────────────────
|
||||
ikv_node_t *repos = ikv_object_add_array(root, "repository_settings", IKV_OBJECT);
|
||||
auto repos = root.makeArray("repository_settings", ikv::objectValue);
|
||||
for (const auto &[repo_path, rs] : repo_settings_)
|
||||
{
|
||||
ikv_node_t *entry = ikv_array_add_object(repos);
|
||||
ikv_object_set_string(entry, "path", repo_path.c_str());
|
||||
ikv_node_t *rw = ikv_object_add_array(entry, "commit_table_columns", IKV_FLOAT);
|
||||
auto entry = repos.appendObject();
|
||||
entry["path"] = repo_path;
|
||||
auto rw = entry.makeArray("commit_table_columns", ikv::realValue);
|
||||
for (const float w : rs.column_widths)
|
||||
ikv_array_add_float(rw, w);
|
||||
rw.append(static_cast<double>(w));
|
||||
if (!rs.pending_commit_summary.empty())
|
||||
ikv_object_set_string(entry, "commit_summary", rs.pending_commit_summary.c_str());
|
||||
entry["commit_summary"] = rs.pending_commit_summary;
|
||||
if (!rs.pending_commit_description.empty())
|
||||
ikv_object_set_string(entry, "commit_description", rs.pending_commit_description.c_str());
|
||||
entry["commit_description"] = rs.pending_commit_description;
|
||||
}
|
||||
|
||||
// ── recently closed ───────────────────────────────────────────────────────
|
||||
ikv_node_t *history = ikv_object_add_array(root, "recently_closed", IKV_STRING);
|
||||
auto history = root.makeArray("recently_closed", ikv::stringValue);
|
||||
for (const auto &p : recently_closed_)
|
||||
ikv_array_add_string(history, p.c_str());
|
||||
history.append(p);
|
||||
|
||||
// ── recent repositories ───────────────────────────────────────────────────
|
||||
ikv_node_t *recent = ikv_object_add_array(root, "recent_repositories", IKV_STRING);
|
||||
auto recent = root.makeArray("recent_repositories", ikv::stringValue);
|
||||
for (const auto &p : recent_repositories_)
|
||||
ikv_array_add_string(recent, p.c_str());
|
||||
recent.append(p);
|
||||
|
||||
// ── session ───────────────────────────────────────────────────────────────
|
||||
ikv_node_t *session = ikv_object_add_object(root, "session");
|
||||
ikv_object_set_int(session, "active_tab", static_cast<int64_t>(active_repository_));
|
||||
ikv_node_t *tabs = ikv_object_add_array(session, "tabs", IKV_STRING);
|
||||
auto session = root.makeObject("session");
|
||||
session["active_tab"] = static_cast<int64_t>(active_repository_);
|
||||
auto tabs = session.makeArray("tabs", ikv::stringValue);
|
||||
for (const auto &p : open_repositories_)
|
||||
ikv_array_add_string(tabs, p.c_str());
|
||||
tabs.append(p);
|
||||
|
||||
// ── credentials ───────────────────────────────────────────────────────────
|
||||
ikv_node_t *credentials = ikv_object_add_array(root, "credentials", IKV_OBJECT);
|
||||
auto credentials = root.makeArray("credentials", ikv::objectValue);
|
||||
for (const auto &[scope, secret] : encrypted_credentials_)
|
||||
{
|
||||
ikv_node_t *entry = ikv_array_add_object(credentials);
|
||||
ikv_object_set_string(entry, "scope", scope.c_str());
|
||||
ikv_object_set_string(entry, "secret", secret.c_str());
|
||||
auto entry = credentials.appendObject();
|
||||
entry["scope"] = scope;
|
||||
entry["secret"] = secret;
|
||||
}
|
||||
|
||||
ikvb_write_file_version(dataPath().string().c_str(), root, IKV_VERSION_2);
|
||||
ikv_free(root);
|
||||
root.write(dataPath().string(), ikv::Version::v2);
|
||||
removeLegacyFiles();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user