diff --git a/include/plugin.hpp b/include/plugin.hpp index 21a7b59d..29b9aa45 100644 --- a/include/plugin.hpp +++ b/include/plugin.hpp @@ -29,6 +29,7 @@ void logIn(const std::string &email, const std::string &password); void logOut(); bool isLoggedIn(); void queryUpdates(); +bool hasUpdates(); void syncUpdate(Update *update); void syncUpdates(); bool isSyncing(); @@ -46,6 +47,7 @@ extern std::vector plugins; extern std::string loginStatus; extern std::vector updates; +extern bool updatesFinished; } // namespace plugin diff --git a/src/app/MenuBar.cpp b/src/app/MenuBar.cpp index 6bf179e8..3e42124a 100644 --- a/src/app/MenuBar.cpp +++ b/src/app/MenuBar.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -496,7 +497,7 @@ struct LogInItem : ui::MenuItem { struct SyncItem : ui::MenuItem { void step() override { - disabled = plugin::isSyncing(); + disabled = !plugin::hasUpdates() || plugin::isSyncing(); MenuItem::step(); } @@ -540,6 +541,7 @@ struct PluginSyncItem : ui::MenuItem { disabled = plugin::isSyncing(); if (update->progress >= 1) { rightText = CHECKMARK_STRING; + disabled = true; } else if (update->progress > 0) { rightText = string::f("%.0f%%", update->progress * 100.f); @@ -556,44 +558,6 @@ struct PluginSyncItem : ui::MenuItem { } }; - -#if 0 -struct SyncButton : ui::Button { - bool checked = false; - /** Updates are available */ - bool available = false; - /** Plugins have been updated */ - bool completed = false; - - void step() override { - // Check for plugin update on first step() - if (!checked) { - std::thread t([this]() { - if (plugin::sync(true)) - available = true; - }); - t.detach(); - checked = true; - } - // Display message if we've completed updates - if (completed) { - if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "All plugins have been updated. Close Rack and re-launch it to load new updates.")) { - APP->window->close(); - } - completed = false; - } - } - void onAction(const event::Action &e) override { - available = false; - std::thread t([this]() { - if (plugin::sync(false)) - completed = true; - }); - t.detach(); - } -}; -#endif - struct LogOutItem : ui::MenuItem { void onAction(const event::Action &e) override { plugin::logOut(); @@ -608,12 +572,14 @@ struct PluginsMenu : ui::Menu { } void step() override { + // Refresh menu when appropriate if (!loggedIn && plugin::isLoggedIn()) refresh(); Menu::step(); } void refresh() { + setChildMenu(NULL); clearChildren(); if (settings::devMode) { @@ -646,7 +612,7 @@ struct PluginsMenu : ui::Menu { loggedIn = true; UrlItem *manageItem = new UrlItem; - manageItem->text = "VCV Plugin Manager"; + manageItem->text = "Manage plugins"; manageItem->url = "https://vcvrack.com/plugins.html"; addChild(manageItem); @@ -656,10 +622,9 @@ struct PluginsMenu : ui::Menu { SyncItem *syncItem = new SyncItem; syncItem->text = "Update all"; - syncItem->disabled = plugin::updates.empty(); addChild(syncItem); - if (!plugin::updates.empty()) { + if (plugin::hasUpdates()) { addChild(new ui::MenuEntry); ui::MenuLabel *updatesLabel = new ui::MenuLabel; @@ -693,7 +658,16 @@ struct PluginsButton : MenuButton { void step() override { notification->box.pos = math::Vec(0, 0); - notification->visible = false; + notification->visible = plugin::hasUpdates(); + + // Popup when updates finish downloading + if (plugin::updatesFinished) { + plugin::updatesFinished = false; + if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "All plugins have been downloaded. Close and re-launch Rack to load new updates.")) { + APP->window->close(); + } + } + MenuButton::step(); } }; diff --git a/src/network.cpp b/src/network.cpp index 831cd92e..3776c6aa 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -108,7 +108,7 @@ static int xferInfoCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, float *progress = (float*) clientp; if (progress) { if (dltotal <= 0) - *progress = 1.0; + *progress = 0.f; else *progress = (float)dlnow / dltotal; } @@ -116,9 +116,6 @@ static int xferInfoCallback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, } bool requestDownload(std::string url, const std::string &filename, float *progress) { - if (progress) - *progress = 0.f; - CURL *curl = curl_easy_init(); if (!curl) return false; diff --git a/src/plugin.cpp b/src/plugin.cpp index 6b840f7f..dd8ba1f8 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -315,28 +315,32 @@ void logIn(const std::string &email, const std::string &password) { loginStatus = "No response from server"; return; } + DEFER({ + json_decref(resJ); + }); json_t *errorJ = json_object_get(resJ, "error"); if (errorJ) { const char *errorStr = json_string_value(errorJ); loginStatus = errorStr; + return; } - else { - json_t *tokenJ = json_object_get(resJ, "token"); - if (tokenJ) { - const char *tokenStr = json_string_value(tokenJ); - settings::token = tokenStr; - loginStatus = ""; - } - else { - loginStatus = "No token in response"; - } + + json_t *tokenJ = json_object_get(resJ, "token"); + if (!tokenJ) { + loginStatus = "No token in response"; + return; } - json_decref(resJ); + + const char *tokenStr = json_string_value(tokenJ); + settings::token = tokenStr; + loginStatus = ""; + queryUpdates(); } void logOut() { settings::token = ""; + updates.clear(); } bool isLoggedIn() { @@ -433,6 +437,14 @@ void queryUpdates() { } } +bool hasUpdates() { + for (Update &update : updates) { + if (update.progress < 1.f) + return true; + } + return false; +} + static bool isSyncingUpdate = false; static bool isSyncingUpdates = false; @@ -476,8 +488,10 @@ void syncUpdates() { return; for (Update &update : updates) { - syncUpdate(&update); + if (update.progress < 1.f) + syncUpdate(&update); } + updatesFinished = true; } bool isSyncing() { @@ -626,6 +640,7 @@ std::vector plugins; std::string loginStatus; std::vector updates; +bool updatesFinished = false; } // namespace plugin