commit 07f07589865992ced56c7322658fbe5f7a20a510
parent 14c63c416367535e63a70d24a0adca23a712b4f8
Author: jatinchowdhury18 <jatinchowdhury18@gmail.com>
Date: Sun, 23 Aug 2020 11:27:03 -0700
Add simple auto-update checking (#74)
* Add simple auto-update checking
* Update changelog
Co-authored-by: jatinchowdhury18 <jatinchowdhury18@users.noreply.github.com>
Diffstat:
6 files changed, 243 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -6,6 +6,7 @@ this file.
- Updated delay lines in wow/flutter processing to use 3-point
Lagrange interpolation.
- Change Newton-Raphson solver to use 4 or 8 iterations, in unrolled loop.
+- Added simple behavior to automatically check for updates.
- Improved loss filter sliders.
- Fixed tooltip name sometimes not appearing.
- Fixed save/load bug for VST3 in Ableton.
diff --git a/Plugin/CHOWTapeModel.jucer b/Plugin/CHOWTapeModel.jucer
@@ -19,6 +19,9 @@
<FILE id="bQP3yl" name="RobotoCondensed-Regular.ttf" compile="0" resource="1"
file="Source/GUI/Assets/RobotoCondensed-Regular.ttf"/>
</GROUP>
+ <FILE id="XNEbSl" name="AutoUpdating.cpp" compile="1" resource="0"
+ file="Source/GUI/AutoUpdating.cpp"/>
+ <FILE id="u8IfBD" name="AutoUpdating.h" compile="0" resource="0" file="Source/GUI/AutoUpdating.h"/>
<FILE id="rOj90C" name="InfoComp.cpp" compile="1" resource="0" file="Source/GUI/InfoComp.cpp"/>
<FILE id="FxvDV3" name="InfoComp.h" compile="0" resource="0" file="Source/GUI/InfoComp.h"/>
<FILE id="IgOtsG" name="MyLNF.cpp" compile="1" resource="0" file="Source/GUI/MyLNF.cpp"/>
diff --git a/Plugin/Source/GUI/AutoUpdating.cpp b/Plugin/Source/GUI/AutoUpdating.cpp
@@ -0,0 +1,167 @@
+#include "AutoUpdating.h"
+
+namespace
+{
+ const String updateFilePath = "ChowdhuryDSP/ChowTape/UpdateManage.txt";
+ const String currentVersion = "v" + String (JucePlugin_VersionString);
+ const String versionURL = "https://api.github.com/repos/jatinchowdhury18/AnalogTapeModel/releases/latest";
+ const String updateURL = "https://github.com/jatinchowdhury18/AnalogTapeModel/releases/latest";
+ const Colour backgroundColour = Colour (0xFF31323A).withAlpha (0.9f);
+}
+
+AutoUpdater::AutoUpdater()
+{
+ auto setupButton = [=] (TextButton& button)
+ {
+ addAndMakeVisible (button);
+ button.setColour (TextButton::buttonColourId, backgroundColour);
+ button.setColour (TextButton::textColourOffId, Colour (0xFFEAA92C));
+ button.setColour (ComboBox::outlineColourId, Colours::transparentBlack);
+ button.setOpaque (false);
+ button.setMouseCursor (MouseCursor::PointingHandCursor);
+ button.setLookAndFeel (&ubLNF);
+ };
+
+ setupButton (yesButton);
+ setupButton (noButton);
+
+ yesButton.onClick = std::bind (&AutoUpdater::yesButtonPressed, this);
+ noButton.onClick = std::bind (&AutoUpdater::noButtonPressed, this);
+}
+
+AutoUpdater::~AutoUpdater()
+{
+ yesButton.setLookAndFeel (nullptr);
+ noButton.setLookAndFeel (nullptr);
+}
+
+void AutoUpdater::yesButtonPressed()
+{
+ // open update link
+ URL updateLink (updateURL);
+ updateLink.launchInDefaultBrowser();
+
+ // reset update check file
+ setVisible (false);
+ editUpdateCheckFile (newVersion, true);
+}
+
+void AutoUpdater::noButtonPressed()
+{
+ // reset update check file
+ setVisible (false);
+ editUpdateCheckFile (newVersion, false);
+}
+
+void AutoUpdater::paint (Graphics& g)
+{
+ g.fillAll (backgroundColour);
+
+ g.setColour (Colours::white);
+ g.setFont (Font (36.0f));
+
+ String updatePrompt = String ("Version " + newVersion.removeCharacters ("v") + " of CHOW Tape is available. Would you like to download?");
+
+ const auto promptWidth = getWidth() * 2 / 3;
+ const auto promptX = getWidth() / 6;
+ const auto promptHeight = 50;
+ const auto promptY = getHeight() / 2 - promptHeight;
+
+ g.drawFittedText (updatePrompt, promptX, promptY, promptWidth, promptHeight, Justification::centred, 2);
+}
+
+void AutoUpdater::resized()
+{
+ const auto y = getHeight() / 2 + 10;
+ const auto width = 90;
+ const auto pad = 5;
+ const auto height = 40;
+
+ yesButton.setBounds (getWidth() / 2 - width - pad, y, width, height);
+ noButton.setBounds (getWidth() / 2 + pad, y, width, height);
+}
+
+bool AutoUpdater::runAutoUpdateCheck()
+{
+ auto updateFile = getUpdateCheckFile();
+ String latestVersion = getLatestVersion();
+
+ if (latestVersion.isEmpty()) // unable to get latest version
+ return false;
+
+ if (latestVersion == currentVersion) // you're up to date!
+ return false;
+
+ String updateVersion = getUpdateFileVersion (updateFile);
+ bool lastYesNo = getUpdateFileYesNo (updateFile);
+
+ // you've already said you don't want to update to this version
+ if ((updateVersion == latestVersion) && (lastYesNo == false))
+ return false;
+
+ newVersion = latestVersion;
+ return true;
+}
+
+File AutoUpdater::getUpdateCheckFile()
+{
+ File updateCheckFile = File::getSpecialLocation (File::userApplicationDataDirectory);
+ updateCheckFile = updateCheckFile.getChildFile (updateFilePath);
+
+ if (! updateCheckFile.existsAsFile())
+ {
+ updateCheckFile.create();
+ updateCheckFile.appendText (currentVersion + "\n");
+ updateCheckFile.appendText ("YES\n");
+ }
+
+ return updateCheckFile;
+}
+
+String AutoUpdater::getLatestVersion()
+{
+ URL latestVersionURL (versionURL);
+ std::unique_ptr<InputStream> inStream (latestVersionURL.createInputStream (false, nullptr, nullptr, {}, 5000));
+
+ if (inStream == nullptr)
+ return {};
+
+ auto content = inStream->readEntireStreamAsString();
+ auto latestReleaseDetails = JSON::parse (content);
+
+ auto* json = latestReleaseDetails.getDynamicObject();
+
+ if (json == nullptr)
+ return {};
+
+ return json->getProperty ("tag_name").toString();
+}
+
+String AutoUpdater::getUpdateFileVersion (const File& updateFile)
+{
+ StringArray lines;
+ updateFile.readLines (lines);
+
+ return lines[0];
+}
+
+bool AutoUpdater::getUpdateFileYesNo (const File& updateFile)
+{
+ StringArray lines;
+ updateFile.readLines (lines);
+
+ return lines[1] == "YES";
+}
+
+void AutoUpdater::editUpdateCheckFile (String version, bool wantsUpdate)
+{
+ auto updateFile = getUpdateCheckFile();
+ updateFile.deleteFile();
+ updateFile.create();
+ updateFile.appendText (version + "\n");
+
+ if (wantsUpdate)
+ updateFile.appendText ("YES\n");
+ else
+ updateFile.appendText ("NO\n");
+}
diff --git a/Plugin/Source/GUI/AutoUpdating.h b/Plugin/Source/GUI/AutoUpdating.h
@@ -0,0 +1,55 @@
+#ifndef AUTOUPDATING_H_INCLUDED
+#define AUTOUPDATING_H_INCLUDED
+
+#include <JuceHeader.h>
+#include "MyLNF.h"
+
+struct UpdateButtonLNF : public MyLNF
+{
+ UpdateButtonLNF() {}
+
+ Font getTextButtonFont (TextButton&, int /*buttonHeight*/) override
+ {
+ return Font (30.0f).boldened();
+ }
+
+ void drawButtonBackground (Graphics& g, Button& button, const Colour& backgroundColour, bool, bool) override
+ {
+ LookAndFeel_V4::drawButtonBackground (g, button, backgroundColour, false, false);
+ }
+
+private:
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UpdateButtonLNF)
+};
+
+class AutoUpdater : public Component
+{
+public:
+ AutoUpdater();
+ ~AutoUpdater();
+
+ void paint (Graphics& g) override;
+ void resized() override;
+
+ bool runAutoUpdateCheck();
+ void noButtonPressed();
+ void yesButtonPressed();
+
+private:
+ File getUpdateCheckFile();
+ String getLatestVersion();
+ String getUpdateFileVersion (const File& updateFile);
+ bool getUpdateFileYesNo (const File& updateFile);
+ void editUpdateCheckFile (String version, bool wantsUpdate);
+
+ String newVersion = String (JucePlugin_VersionString);
+
+ TextButton yesButton { "Yes" };
+ TextButton noButton { "No" };
+ UpdateButtonLNF ubLNF;
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AutoUpdater)
+};
+
+
+#endif // AUTOUPDATING_H_INCLUDED
diff --git a/Plugin/Source/PluginProcessor.cpp b/Plugin/Source/PluginProcessor.cpp
@@ -12,7 +12,6 @@
#include "GUI/InfoComp.h"
#include "GUI/TitleComp.h"
#include "GUI/TooltipComp.h"
-#include "GUI/MyLNF.h"
//==============================================================================
ChowtapeModelAudioProcessor::ChowtapeModelAudioProcessor()
@@ -38,6 +37,8 @@ ChowtapeModelAudioProcessor::ChowtapeModelAudioProcessor()
scope = magicState.createAndAddObject<foleys::MagicOscilloscope> ("scope");
LookAndFeel::setDefaultLookAndFeel (&myLNF);
+
+ needsUpdate = updater.runAutoUpdateCheck();
}
ChowtapeModelAudioProcessor::~ChowtapeModelAudioProcessor()
@@ -273,7 +274,17 @@ AudioProcessorEditor* ChowtapeModelAudioProcessor::createEditor()
return new foleys::MagicPluginEditor (magicState, BinaryData::preset_save_gui_xml, BinaryData::preset_save_gui_xmlSize, std::move (builder));
#else
- return new foleys::MagicPluginEditor (magicState, BinaryData::gui_xml, BinaryData::gui_xmlSize, std::move (builder));
+ auto* editor = new foleys::MagicPluginEditor (magicState, BinaryData::gui_xml, BinaryData::gui_xmlSize, std::move (builder));
+
+ if (needsUpdate)
+ {
+ needsUpdate = false;
+
+ editor->addAndMakeVisible (updater);
+ updater.setBounds (0, 0, editor->getWidth(), editor->getHeight());
+ }
+
+ return editor;
#endif
}
diff --git a/Plugin/Source/PluginProcessor.h b/Plugin/Source/PluginProcessor.h
@@ -21,6 +21,7 @@
#include "Processors/Timing_Effects/DelayProcessor.h"
#include "Presets/PresetManager.h"
#include "GUI/MyLNF.h"
+#include "GUI/AutoUpdating.h"
//==============================================================================
/**
@@ -92,6 +93,9 @@ private:
PresetManager presetManager;
MyLNF myLNF;
+ AutoUpdater updater;
+ bool needsUpdate = false;
+
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChowtapeModelAudioProcessor)
};