| @@ -6,8 +6,13 @@ about: Bugs, build errors, compatibility/stability issues | |||||
| <-- | <-- | ||||
| To file a bug report, fill out the form below. | To file a bug report, fill out the form below. | ||||
| Post screenshots if the bug is visual. | |||||
| Use a descriptive title that best explains the bug in one sentence. | Use a descriptive title that best explains the bug in one sentence. | ||||
| Attach screenshots if the bug is visual. | |||||
| Attach your `<Rack user dir>/log.txt` file if something is crashing or not loading. | |||||
| Surround terminal output with three tildes | |||||
| ``` | |||||
| like this. | |||||
| ``` | |||||
| --> | --> | ||||
| ### Details | ### Details | ||||
| @@ -16,6 +16,7 @@ namespace plugin { | |||||
| struct Update { | struct Update { | ||||
| std::string pluginSlug; | std::string pluginSlug; | ||||
| std::string pluginName; | |||||
| std::string version; | std::string version; | ||||
| std::string changelogUrl; | std::string changelogUrl; | ||||
| float progress = 0.f; | float progress = 0.f; | ||||
| @@ -26,10 +27,11 @@ void init(); | |||||
| void destroy(); | void destroy(); | ||||
| void logIn(const std::string &email, const std::string &password); | void logIn(const std::string &email, const std::string &password); | ||||
| void logOut(); | void logOut(); | ||||
| bool isLoggedIn(); | |||||
| void queryUpdates(); | void queryUpdates(); | ||||
| void syncUpdate(Update *update); | void syncUpdate(Update *update); | ||||
| void syncUpdates(); | void syncUpdates(); | ||||
| bool isLoggedIn(); | |||||
| bool isSyncing(); | |||||
| Plugin *getPlugin(const std::string &pluginSlug); | Plugin *getPlugin(const std::string &pluginSlug); | ||||
| Model *getModel(const std::string &pluginSlug, const std::string &modelSlug); | Model *getModel(const std::string &pluginSlug, const std::string &modelSlug); | ||||
| std::string normalizeTag(const std::string &tag); | std::string normalizeTag(const std::string &tag); | ||||
| @@ -495,6 +495,11 @@ struct LogInItem : ui::MenuItem { | |||||
| }; | }; | ||||
| struct SyncItem : ui::MenuItem { | struct SyncItem : ui::MenuItem { | ||||
| void step() override { | |||||
| disabled = plugin::isSyncing(); | |||||
| MenuItem::step(); | |||||
| } | |||||
| void onAction(const event::Action &e) override { | void onAction(const event::Action &e) override { | ||||
| std::thread t([=]() { | std::thread t([=]() { | ||||
| plugin::syncUpdates(); | plugin::syncUpdates(); | ||||
| @@ -509,7 +514,7 @@ struct PluginSyncItem : ui::MenuItem { | |||||
| void setUpdate(plugin::Update *update) { | void setUpdate(plugin::Update *update) { | ||||
| this->update = update; | this->update = update; | ||||
| text = update->pluginSlug; | |||||
| text = update->pluginName; | |||||
| plugin::Plugin *p = plugin::getPlugin(update->pluginSlug); | plugin::Plugin *p = plugin::getPlugin(update->pluginSlug); | ||||
| if (p) { | if (p) { | ||||
| rightText += "v" + p->version + " → "; | rightText += "v" + p->version + " → "; | ||||
| @@ -532,6 +537,7 @@ struct PluginSyncItem : ui::MenuItem { | |||||
| } | } | ||||
| void step() override { | void step() override { | ||||
| disabled = plugin::isSyncing(); | |||||
| if (update->progress >= 1) { | if (update->progress >= 1) { | ||||
| rightText = CHECKMARK_STRING; | rightText = CHECKMARK_STRING; | ||||
| } | } | ||||
| @@ -610,7 +616,10 @@ struct PluginsMenu : ui::Menu { | |||||
| void refresh() { | void refresh() { | ||||
| clearChildren(); | clearChildren(); | ||||
| if (!plugin::isLoggedIn()) { | |||||
| if (settings::devMode) { | |||||
| addChild(createMenuLabel("Disabled in development mode")); | |||||
| } | |||||
| else if (!plugin::isLoggedIn()) { | |||||
| UrlItem *registerItem = new UrlItem; | UrlItem *registerItem = new UrlItem; | ||||
| registerItem->text = "Register VCV account"; | registerItem->text = "Register VCV account"; | ||||
| registerItem->url = "https://vcvrack.com/"; | registerItem->url = "https://vcvrack.com/"; | ||||
| @@ -515,9 +515,9 @@ struct ModuleBrowser : widget::OpaqueWidget { | |||||
| float score2 = get_default(settings::favoriteScores, std::make_tuple(m2->model->plugin->slug, m2->model->slug), 0.f); | float score2 = get_default(settings::favoriteScores, std::make_tuple(m2->model->plugin->slug, m2->model->slug), 0.f); | ||||
| if (score1 != score2) | if (score1 != score2) | ||||
| return score1 > score2; | return score1 > score2; | ||||
| // Sort by plugin name | |||||
| if (m1->model->plugin->name != m2->model->plugin->name) | |||||
| return m1->model->plugin->name < m2->model->plugin->name; | |||||
| // Sort by plugin brand | |||||
| if (m1->model->plugin->brand != m2->model->plugin->brand) | |||||
| return m1->model->plugin->brand < m2->model->plugin->brand; | |||||
| // Sort by module name | // Sort by module name | ||||
| return m1->model->name < m2->model->name; | return m1->model->name < m2->model->name; | ||||
| }); | }); | ||||
| @@ -339,6 +339,10 @@ void logOut() { | |||||
| settings::token = ""; | settings::token = ""; | ||||
| } | } | ||||
| bool isLoggedIn() { | |||||
| return settings::token != ""; | |||||
| } | |||||
| void queryUpdates() { | void queryUpdates() { | ||||
| if (settings::token.empty()) | if (settings::token.empty()) | ||||
| return; | return; | ||||
| @@ -393,8 +397,12 @@ void queryUpdates() { | |||||
| continue; | continue; | ||||
| } | } | ||||
| // Get plugin name | |||||
| json_t *nameJ = json_object_get(manifestJ, "name"); | |||||
| if (nameJ) | |||||
| update.pluginName = json_string_value(nameJ); | |||||
| // Get version | // Get version | ||||
| // TODO Change this to "version" when API changes | |||||
| json_t *versionJ = json_object_get(manifestJ, "version"); | json_t *versionJ = json_object_get(manifestJ, "version"); | ||||
| if (!versionJ) { | if (!versionJ) { | ||||
| WARN("Plugin %s has no version in manifest", update.pluginSlug.c_str()); | WARN("Plugin %s has no version in manifest", update.pluginSlug.c_str()); | ||||
| @@ -425,7 +433,15 @@ void queryUpdates() { | |||||
| } | } | ||||
| } | } | ||||
| static bool isSyncingUpdate = false; | |||||
| static bool isSyncingUpdates = false; | |||||
| void syncUpdate(Update *update) { | void syncUpdate(Update *update) { | ||||
| isSyncingUpdate = true; | |||||
| DEFER({ | |||||
| isSyncingUpdate = false; | |||||
| }); | |||||
| #if defined ARCH_WIN | #if defined ARCH_WIN | ||||
| std::string arch = "win"; | std::string arch = "win"; | ||||
| #elif ARCH_MAC | #elif ARCH_MAC | ||||
| @@ -451,6 +467,11 @@ void syncUpdate(Update *update) { | |||||
| } | } | ||||
| void syncUpdates() { | void syncUpdates() { | ||||
| isSyncingUpdates = true; | |||||
| DEFER({ | |||||
| isSyncingUpdates = false; | |||||
| }); | |||||
| if (settings::token.empty()) | if (settings::token.empty()) | ||||
| return; | return; | ||||
| @@ -459,12 +480,8 @@ void syncUpdates() { | |||||
| } | } | ||||
| } | } | ||||
| void cancelDownload() { | |||||
| // TODO | |||||
| } | |||||
| bool isLoggedIn() { | |||||
| return settings::token != ""; | |||||
| bool isSyncing() { | |||||
| return isSyncingUpdate || isSyncingUpdates; | |||||
| } | } | ||||
| Plugin *getPlugin(const std::string &pluginSlug) { | Plugin *getPlugin(const std::string &pluginSlug) { | ||||