Improve usability and make the license check even less aggressive

pull/300/head
James H Ball 2025-04-23 10:48:48 +01:00
rodzic b7da40b90c
commit e92978c136
7 zmienionych plików z 83 dodań i 16 usunięć

Wyświetl plik

@ -59,7 +59,8 @@ CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String app
setResizable(true, true);
setResizeLimits(250, 250, 999999, 999999);
tooltipDropShadow.setOwner(&tooltipWindow);
tooltipDropShadow.setOwner(&tooltipWindow.get());
tooltipWindow->setMillisecondsBeforeTipAppears(0);
updateTitle();

Wyświetl plik

@ -69,7 +69,8 @@ public:
VolumeComponent volume{audioProcessor};
std::unique_ptr<juce::FileChooser> chooser;
juce::MenuBarComponent menuBar; juce::TooltipWindow tooltipWindow{nullptr, 0};
juce::MenuBarComponent menuBar;
juce::SharedResourcePointer<juce::TooltipWindow> tooltipWindow;
juce::DropShadower tooltipDropShadow{juce::DropShadow(juce::Colours::black.withAlpha(0.5f), 6, {0,0})};
LicenseRegistrationComponent licenseRegistration {audioProcessor, [this](bool success) {

Wyświetl plik

@ -365,6 +365,12 @@ void CommonAudioProcessor::saveGlobalSettings()
globalSettings->saveIfNeeded();
}
void CommonAudioProcessor::reloadGlobalSettings()
{
if (globalSettings != nullptr)
globalSettings->reload();
}
juce::File CommonAudioProcessor::getLastOpenedDirectory()
{
juce::String savedDir = getGlobalStringValue("lastOpenedDirectory");
@ -508,4 +514,4 @@ bool CommonAudioProcessor::ensureFFmpegExists(std::function<void()> onStart, std
});
return false;
}
}

Wyświetl plik

@ -82,9 +82,12 @@ public:
void setGlobalValue(const juce::String& keyName, const juce::var& value);
void removeGlobalValue(const juce::String& keyName);
void saveGlobalSettings();
void reloadGlobalSettings();
bool hasSetSessionStartTime = false;
bool programCrashedAndUserWantsToReset();
std::atomic<bool> licenseVerified = true;
juce::SpinLock audioPlayerListenersLock;
std::vector<AudioPlayerListener*> audioPlayerListeners;

Wyświetl plik

@ -616,7 +616,7 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, ju
threadManager.write(OsciPoint(x, y, 1));
// Apply mute if active
if (muteParameter->getBoolValue()) {
if (muteParameter->getBoolValue() || !licenseVerified) {
x = 0.0;
y = 0.0;
}

Wyświetl plik

@ -5,15 +5,49 @@ LicenseRegistrationComponent::LicenseRegistrationComponent(CommonAudioProcessor&
{
setupComponents();
// If we have a saved license, validate it in the background
if (validateSavedLicense())
audioProcessor.reloadGlobalSettings();
auto savedKey = audioProcessor.getGlobalStringValue("license_key");
if (savedKey.isNotEmpty())
{
// Use Timer to ensure component is properly initialized before hiding
juce::MessageManager::callAsync([this]() {
setVisible(false);
});
// Start periodic checks every hour
startTimer(1000 * 60 * 60);
// Pre-populate the license key field
licenseKeyEditor.setText(savedKey, false);
auto lastValidated = audioProcessor.getGlobalStringValue("license_last_validated");
if (lastValidated.isNotEmpty())
{
auto lastValidationTime = juce::Time::fromISO8601(lastValidated);
auto weekAgo = juce::Time::getCurrentTime() - juce::RelativeTime::weeks(1);
auto hourAgo = juce::Time::getCurrentTime() - juce::RelativeTime::hours(1);
if (lastValidationTime > weekAgo)
{
// If validated within the last week, hide immediately
juce::WeakReference<LicenseRegistrationComponent> weakThis(this);
juce::MessageManager::callAsync([weakThis]() {
if (auto* strongThis = weakThis.get()) {
strongThis->setVisible(false);
}
});
if (onLicenseVerified != nullptr) {
onLicenseVerified(true);
}
audioProcessor.licenseVerified = true;
} else {
audioProcessor.licenseVerified = false;
}
if (lastValidationTime < hourAgo) {
// Validate the license key in the background
validateSavedLicense();
}
// Start periodic checks every hour
startTimer(1000 * 60 * 60);
}
} else {
audioProcessor.licenseVerified = false;
}
}
@ -35,11 +69,21 @@ void LicenseRegistrationComponent::setupComponents()
addAndMakeVisible(instructionsLabel);
licenseKeyEditor.setTextToShowWhenEmpty("XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX", juce::Colours::grey);
licenseKeyEditor.setInputRestrictions(35, "0123456789ABCDEF-"); // Only allow hex digits and hyphens
licenseKeyEditor.setInputRestrictions(35, "0123456789ABCDEFabcdef-"); // Allow both upper and lowercase hex digits and hyphens
licenseKeyEditor.onReturnKey = [this] { verifyButton.triggerClick(); };
licenseKeyEditor.setFont(juce::Font(24.0f));
licenseKeyEditor.onTextChange = [this] {
auto currentText = licenseKeyEditor.getText();
auto upperText = currentText.toUpperCase();
if (currentText != upperText)
{
auto cursorPos = licenseKeyEditor.getCaretPosition();
licenseKeyEditor.setText(upperText, false);
licenseKeyEditor.setCaretPosition(cursorPos);
}
};
addAndMakeVisible(licenseKeyEditor);
verifyButton.setButtonText("Verify License");
verifyButton.onClick = [this] {
if (!isVerifying)
@ -71,7 +115,8 @@ void LicenseRegistrationComponent::resized()
licenseKeyEditor.setBounds(row.reduced(50, 0));
bounds.removeFromTop(20);
verifyButton.setBounds(bounds.removeFromTop(40).withSizeKeepingCentre(120, 40));
auto buttonBounds = bounds.removeFromTop(40);
verifyButton.setBounds(buttonBounds.withSizeKeepingCentre(120, 40));
}
void LicenseRegistrationComponent::verifyLicense(const juce::String& licenseKey, bool showErrorDialog)
@ -81,6 +126,7 @@ void LicenseRegistrationComponent::verifyLicense(const juce::String& licenseKey,
isVerifying = true;
verifyButton.setEnabled(false);
verifyButton.setVisible(false);
juce::URL url("https://api.osci-render.com/api/verify-license");
@ -117,10 +163,17 @@ void LicenseRegistrationComponent::verifyLicense(const juce::String& licenseKey,
audioProcessor.setGlobalValue("license_key", licenseKey);
audioProcessor.setGlobalValue("license_last_validated", juce::Time::getCurrentTime().toISO8601(true));
audioProcessor.saveGlobalSettings();
audioProcessor.licenseVerified = true;
successfullyVerified = true;
setVisible(false);
juce::WeakReference<LicenseRegistrationComponent> weakThis(this);
juce::MessageManager::callAsync([weakThis]() {
if (auto* strongThis = weakThis.get()) {
strongThis->setVisible(false);
}
});
startTimer(1000 * 60 * 60); // Check every hour
}
else if (showErrorDialog)
@ -149,6 +202,7 @@ void LicenseRegistrationComponent::verifyLicense(const juce::String& licenseKey,
isVerifying = false;
verifyButton.setEnabled(true);
verifyButton.setVisible(true);
if (onLicenseVerified != nullptr) {
onLicenseVerified(successfullyVerified);
@ -177,6 +231,7 @@ void LicenseRegistrationComponent::clearLicense()
audioProcessor.removeGlobalValue("license_last_validated");
audioProcessor.saveGlobalSettings();
setVisible(true);
audioProcessor.licenseVerified = false;
}
void LicenseRegistrationComponent::timerCallback()

Wyświetl plik

@ -34,4 +34,5 @@ private:
std::function<void(bool)> onLicenseVerified;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LicenseRegistrationComponent)
JUCE_DECLARE_WEAK_REFERENCEABLE(LicenseRegistrationComponent)
};