fix(ui): finish refresh and diff navigation polish
This commit is contained in:
@@ -1,73 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include "models/repository.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class GitManager
|
||||
{
|
||||
public:
|
||||
#pragma once
|
||||
|
||||
#include "models/repository.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class GitManager
|
||||
{
|
||||
public:
|
||||
GitManager();
|
||||
~GitManager();
|
||||
|
||||
bool openRepositoryHandle(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool openRepositoryHandle(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool openRepository(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool initializeRepository(RepositoryView &repository, const std::string &path,
|
||||
const std::string &initial_branch, std::string &error);
|
||||
bool cloneRepository(RepositoryView &repository, const std::string &url,
|
||||
const std::string &path, bool shallow, std::string &error);
|
||||
bool reload(RepositoryView &repository, std::string &error);
|
||||
bool cloneRepository(RepositoryView &repository, const std::string &url,
|
||||
const std::string &path, bool shallow, std::string &error);
|
||||
bool reload(RepositoryView &repository, std::string &error);
|
||||
bool loadMoreCommits(RepositoryView &repository, size_t page_size, std::string &error);
|
||||
bool checkoutBranch(RepositoryView &repository, const std::string &branch, std::string &error);
|
||||
bool mergeBranch(RepositoryView &repository, const std::string &source_branch,
|
||||
const std::string &target_branch, std::string &error);
|
||||
bool fetch(RepositoryView &repository, const std::string &remote, std::string &error);
|
||||
bool pull(RepositoryView &repository, int mode, std::string &error);
|
||||
bool push(RepositoryView &repository, std::string &error);
|
||||
bool pushBranch(RepositoryView &repository, const std::string &branch, std::string &error);
|
||||
bool stash(RepositoryView &repository, std::string &error);
|
||||
bool popStash(RepositoryView &repository, std::string &error);
|
||||
bool undoCommit(RepositoryView &repository, std::string &error);
|
||||
bool redoCommit(RepositoryView &repository, std::string &error);
|
||||
bool stageAll(RepositoryView &repository, std::string &error);
|
||||
bool unstageAll(RepositoryView &repository, std::string &error);
|
||||
bool stageFile(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool unstageFile(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool discardFile(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool discardAll(RepositoryView &repository, std::string &error);
|
||||
bool commit(RepositoryView &repository, const std::string &summary,
|
||||
const std::string &description, bool amend, std::string &error);
|
||||
bool createBranch(RepositoryView &repository, const std::string &name,
|
||||
const std::string &start_point, bool checkout, std::string &error);
|
||||
bool createTag(RepositoryView &repository, const std::string &name,
|
||||
const std::string &target, std::string &error);
|
||||
bool addRemote(RepositoryView &repository, const std::string &name,
|
||||
const std::string &url, std::string &error);
|
||||
bool addWorktree(RepositoryView &repository, const std::string &path,
|
||||
const std::string &branch, std::string &error);
|
||||
bool addSubmodule(RepositoryView &repository, const std::string &url,
|
||||
const std::string &path, std::string &error);
|
||||
bool updateSubmodule(RepositoryView &repository, const std::string &name, std::string &error);
|
||||
std::string worktreePath(RepositoryView &repository, const std::string &name, std::string &error);
|
||||
bool loadCommitChanges(RepositoryView &repository, int commit_index, std::string &error);
|
||||
bool loadCommitFiles(RepositoryView &repository, int commit_index, std::string &error);
|
||||
bool captureGit(RepositoryView &repository, const std::vector<std::string> &arguments,
|
||||
std::string &output, std::string &error);
|
||||
bool applyPatch(RepositoryView &repository, const std::string &patch, bool cached,
|
||||
bool reverse, std::string &error);
|
||||
|
||||
private:
|
||||
static std::string lastError(const char *fallback);
|
||||
static std::string formatTime(git_time_t value, int offset_minutes);
|
||||
void loadToolbarHistoryActions(RepositoryView &repository);
|
||||
void readBranches(RepositoryView &repository, git_branch_t type, std::vector<std::string> &output);
|
||||
void loadBranchDivergence(RepositoryView &repository);
|
||||
void loadRefBadges(RepositoryView &repository);
|
||||
void computeGraphLanes(RepositoryView &repository);
|
||||
bool loadRepositoryData(RepositoryView &repository, std::string &error);
|
||||
void loadWorkingTree(RepositoryView &repository);
|
||||
bool prepareCredentials(RepositoryView &repository, std::string &error);
|
||||
bool runGit(RepositoryView &repository, const std::vector<std::string> &arguments,
|
||||
const char *success_message, std::string &message, bool reload = true);
|
||||
};
|
||||
bool pull(RepositoryView &repository, int mode, std::string &error);
|
||||
bool push(RepositoryView &repository, std::string &error);
|
||||
bool pushBranch(RepositoryView &repository, const std::string &branch, std::string &error);
|
||||
bool stash(RepositoryView &repository, std::string &error);
|
||||
bool popStash(RepositoryView &repository, std::string &error);
|
||||
bool undoCommit(RepositoryView &repository, std::string &error);
|
||||
bool redoCommit(RepositoryView &repository, std::string &error);
|
||||
bool stageAll(RepositoryView &repository, std::string &error);
|
||||
bool unstageAll(RepositoryView &repository, std::string &error);
|
||||
bool stageFile(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool unstageFile(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool discardFile(RepositoryView &repository, const std::string &path, std::string &error);
|
||||
bool discardAll(RepositoryView &repository, std::string &error);
|
||||
bool commit(RepositoryView &repository, const std::string &summary,
|
||||
const std::string &description, bool amend, std::string &error);
|
||||
bool createBranch(RepositoryView &repository, const std::string &name,
|
||||
const std::string &start_point, bool checkout, std::string &error);
|
||||
bool createTag(RepositoryView &repository, const std::string &name,
|
||||
const std::string &target, std::string &error);
|
||||
bool addRemote(RepositoryView &repository, const std::string &name,
|
||||
const std::string &url, std::string &error);
|
||||
bool addWorktree(RepositoryView &repository, const std::string &path,
|
||||
const std::string &branch, std::string &error);
|
||||
bool addSubmodule(RepositoryView &repository, const std::string &url,
|
||||
const std::string &path, std::string &error);
|
||||
bool updateSubmodule(RepositoryView &repository, const std::string &name, std::string &error);
|
||||
std::string worktreePath(RepositoryView &repository, const std::string &name, std::string &error);
|
||||
bool loadCommitChanges(RepositoryView &repository, int commit_index, std::string &error);
|
||||
bool loadCommitFiles(RepositoryView &repository, int commit_index, std::string &error);
|
||||
bool captureGit(RepositoryView &repository, const std::vector<std::string> &arguments,
|
||||
std::string &output, std::string &error);
|
||||
bool applyPatch(RepositoryView &repository, const std::string &patch, bool cached,
|
||||
bool reverse, std::string &error);
|
||||
|
||||
private:
|
||||
static std::string lastError(const char *fallback);
|
||||
static std::string formatTime(git_time_t value, int offset_minutes);
|
||||
void loadToolbarHistoryActions(RepositoryView &repository);
|
||||
void readBranches(RepositoryView &repository, git_branch_t type, std::vector<std::string> &output);
|
||||
void loadBranchDivergence(RepositoryView &repository);
|
||||
void loadRefBadges(RepositoryView &repository);
|
||||
void computeGraphLanes(RepositoryView &repository);
|
||||
bool loadRepositoryData(RepositoryView &repository, std::string &error);
|
||||
void loadWorkingTree(RepositoryView &repository);
|
||||
bool prepareCredentials(RepositoryView &repository, std::string &error);
|
||||
bool runGit(RepositoryView &repository, const std::vector<std::string> &arguments,
|
||||
const char *success_message, std::string &message, bool reload = true);
|
||||
};
|
||||
|
||||
@@ -48,6 +48,8 @@ AvatarCache* g_avatar_cache = nullptr;
|
||||
std::array<char, 256> g_filter{};
|
||||
std::array<char, 128> g_branch_filter{};
|
||||
std::string g_notice;
|
||||
std::string g_last_footer_notice;
|
||||
std::chrono::steady_clock::time_point g_last_footer_notice_change{};
|
||||
bool g_init_popup = false;
|
||||
bool g_clone_popup = false;
|
||||
bool g_about_popup = false;
|
||||
@@ -304,6 +306,26 @@ void sync_notice_toast() {
|
||||
push_toast(g_notice, infer_toast_kind(g_notice));
|
||||
}
|
||||
|
||||
float footer_notice_alpha() {
|
||||
if (g_notice.empty()) {
|
||||
g_last_footer_notice.clear();
|
||||
return 0.0f;
|
||||
}
|
||||
if (g_notice != g_last_footer_notice) {
|
||||
g_last_footer_notice = g_notice;
|
||||
g_last_footer_notice_change = RefreshClock::now();
|
||||
}
|
||||
if (g_notice.ends_with("...")) return 1.0f;
|
||||
|
||||
constexpr float notice_hold_seconds = 2.0f;
|
||||
constexpr float notice_fade_seconds = 1.5f;
|
||||
const float elapsed = std::chrono::duration<float>(
|
||||
RefreshClock::now() - g_last_footer_notice_change).count();
|
||||
if (elapsed <= notice_hold_seconds) return 1.0f;
|
||||
if (elapsed >= notice_hold_seconds + notice_fade_seconds) return 0.0f;
|
||||
return 1.0f - ((elapsed - notice_hold_seconds) / notice_fade_seconds);
|
||||
}
|
||||
|
||||
void transfer_repository_state(RepositoryView& source, RepositoryView& target) {
|
||||
if (&source == &target) return;
|
||||
target.close();
|
||||
@@ -381,8 +403,8 @@ GitAsyncResult execute_git_async_request(const GitAsyncRequest& request) {
|
||||
bool action_ok = true;
|
||||
switch (request.operation) {
|
||||
case GitAsyncOperation::reload:
|
||||
break;
|
||||
action_ok = manager.reload(repository, result.notice);
|
||||
break;
|
||||
case GitAsyncOperation::capture: {
|
||||
std::string output;
|
||||
action_ok = manager.captureGit(repository, request.arguments, output, result.notice) &&
|
||||
@@ -3528,7 +3550,17 @@ void draw_popups() {
|
||||
|
||||
void draw_footer() {
|
||||
ImGui::Separator();
|
||||
ImGui::TextDisabled("%s", g_notice.empty() ? "Ready" : g_notice.c_str());
|
||||
const float notice_alpha = footer_notice_alpha();
|
||||
const bool show_notice = !g_notice.empty() && notice_alpha > 0.02f;
|
||||
if (show_notice) {
|
||||
ImVec4 notice_color = ImGui::GetStyleColorVec4(ImGuiCol_TextDisabled);
|
||||
notice_color.w *= notice_alpha;
|
||||
ImGui::PushStyleColor(ImGuiCol_TextDisabled, notice_color);
|
||||
ImGui::TextDisabled("%s", g_notice.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
} else {
|
||||
ImGui::TextDisabled("Ready");
|
||||
}
|
||||
const char* version = "Gitree " GITREE_VERSION;
|
||||
const std::string zoom_label = std::string(ICON_TB_MAGNIFYING_GLASS " ") +
|
||||
std::to_string(g_zoom_percent) + "%";
|
||||
@@ -4044,7 +4076,7 @@ int runGitree(int argc, char** argv) {
|
||||
for (const std::string& path : user_data.openRepositories()) {
|
||||
g_tabs.push_back(std::make_unique<RepositoryView>());
|
||||
if (!path.empty() && git_manager.openRepositoryHandle(*g_tabs.back(), path, g_notice))
|
||||
g_tabs.back()->pending_background_refresh = true;
|
||||
g_tabs.back()->pending_background_refresh = true;
|
||||
}
|
||||
g_active_tab = std::min(user_data.activeRepository(), g_tabs.size() - 1);
|
||||
g_tab_to_select = g_tabs[g_active_tab].get();
|
||||
|
||||
Reference in New Issue
Block a user