Allow wasm fetch patchstorage thigns, set system factory template
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
e389ca7469
commit
3af971534c
7 changed files with 248 additions and 38 deletions
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
#define GHC_OS_DETECTED
|
#define GHC_OS_DETECTED
|
||||||
#define GHC_OS_LINUX
|
#define GHC_OS_LINUX
|
||||||
|
#endif
|
||||||
|
|
||||||
#include_next <ghc/filesystem.hpp>
|
#include_next <ghc/filesystem.hpp>
|
||||||
|
|
|
@ -100,6 +100,10 @@ std::string getSpecialPath(const SpecialPath type)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
char* patchStorageSlug = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::string homeDir()
|
std::string homeDir()
|
||||||
{
|
{
|
||||||
# ifdef ARCH_WIN
|
# ifdef ARCH_WIN
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
# define REMOTE_HOST_PORT "2228"
|
# define REMOTE_HOST_PORT "2228"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
# define CARDINAL_IMPORTED_TEMPLATE_FILENAME "/imported.vcv"
|
||||||
|
#endif
|
||||||
|
|
||||||
extern const std::string CARDINAL_VERSION;
|
extern const std::string CARDINAL_VERSION;
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
|
@ -53,6 +57,10 @@ enum SpecialPath {
|
||||||
std::string getSpecialPath(SpecialPath type);
|
std::string getSpecialPath(SpecialPath type);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
extern char* patchStorageSlug;
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace rack
|
} // namespace rack
|
||||||
|
|
||||||
namespace patchUtils {
|
namespace patchUtils {
|
||||||
|
|
|
@ -34,24 +34,38 @@
|
||||||
# undef DEBUG
|
# undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBLO
|
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||||
# ifdef HEADLESS
|
# include <lo/lo.h>
|
||||||
# include <lo/lo.h>
|
# include "extra/Thread.hpp"
|
||||||
# include "extra/Thread.hpp"
|
|
||||||
# endif
|
|
||||||
# include "CardinalCommon.hpp"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
#include "CardinalCommon.hpp"
|
||||||
#include "DistrhoPluginUtils.hpp"
|
#include "DistrhoPluginUtils.hpp"
|
||||||
#include "PluginContext.hpp"
|
#include "PluginContext.hpp"
|
||||||
#include "extra/Base64.hpp"
|
#include "extra/Base64.hpp"
|
||||||
|
|
||||||
#ifndef DISTRHO_OS_WASM
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
# include <emscripten/emscripten.h>
|
||||||
|
#else
|
||||||
# include "extra/SharedResourcePointer.hpp"
|
# include "extra/SharedResourcePointer.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CARDINAL_VARIANT_FX
|
||||||
|
# define CARDINAL_FACTORY_TEMPLATE_NAME "template-fx.vcv"
|
||||||
|
#elif CARDINAL_VARIANT_SYNTH
|
||||||
|
# define CARDINAL_FACTORY_TEMPLATE_NAME "template-synth.vcv"
|
||||||
|
#else
|
||||||
|
# define CARDINAL_FACTORY_TEMPLATE_NAME "template.vcv"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
# define CARDINAL_TEMPLATE_NAME "template-wasm.vcv"
|
||||||
|
#else
|
||||||
|
# define CARDINAL_TEMPLATE_NAME CARDINAL_FACTORY_TEMPLATE_NAME
|
||||||
|
#endif
|
||||||
|
|
||||||
static const constexpr uint kCardinalStateBaseCount = 3; // patch, screenshot, comment
|
static const constexpr uint kCardinalStateBaseCount = 3; // patch, screenshot, comment
|
||||||
|
|
||||||
#ifndef HEADLESS
|
#ifndef HEADLESS
|
||||||
|
@ -63,14 +77,6 @@ static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount + 2; /
|
||||||
static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount;
|
static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CARDINAL_VARIANT_FX
|
|
||||||
# define CARDINAL_TEMPLATE_NAME "template-fx.vcv"
|
|
||||||
#elif CARDINAL_VARIANT_SYNTH
|
|
||||||
# define CARDINAL_TEMPLATE_NAME "template-synth.vcv"
|
|
||||||
#else
|
|
||||||
# define CARDINAL_TEMPLATE_NAME "template.vcv"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
namespace engine {
|
namespace engine {
|
||||||
void Engine_setAboutToClose(Engine*);
|
void Engine_setAboutToClose(Engine*);
|
||||||
|
@ -97,6 +103,21 @@ bool d_isDiffHigherThanLimit(const T& v1, const T& v2, const T& limit)
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
EM_JS(char*, getPatchStorageSlug, (), {
|
||||||
|
var searchParams = new URLSearchParams(window.location.search);
|
||||||
|
var patch = searchParams.get('patchstorage');
|
||||||
|
if (!patch)
|
||||||
|
return null;
|
||||||
|
var length = lengthBytesUTF8(patch) + 1;
|
||||||
|
var str = _malloc(length);
|
||||||
|
stringToUTF8(patch, str, length);
|
||||||
|
return str;
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
struct Initializer
|
struct Initializer
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||||
: public Thread
|
: public Thread
|
||||||
|
@ -107,6 +128,7 @@ struct Initializer
|
||||||
CardinalBasePlugin* oscPlugin = nullptr;
|
CardinalBasePlugin* oscPlugin = nullptr;
|
||||||
#endif
|
#endif
|
||||||
std::string templatePath;
|
std::string templatePath;
|
||||||
|
std::string factoryTemplatePath;
|
||||||
|
|
||||||
Initializer(const CardinalBasePlugin* const plugin)
|
Initializer(const CardinalBasePlugin* const plugin)
|
||||||
{
|
{
|
||||||
|
@ -158,6 +180,7 @@ struct Initializer
|
||||||
asset::bundlePath = system::join(resourcePath, "PluginManifests");
|
asset::bundlePath = system::join(resourcePath, "PluginManifests");
|
||||||
asset::systemDir = resourcePath;
|
asset::systemDir = resourcePath;
|
||||||
templatePath = system::join(asset::systemDir, CARDINAL_TEMPLATE_NAME);
|
templatePath = system::join(asset::systemDir, CARDINAL_TEMPLATE_NAME);
|
||||||
|
factoryTemplatePath = system::join(asset::systemDir, CARDINAL_FACTORY_TEMPLATE_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +193,7 @@ struct Initializer
|
||||||
if (system::exists(system::join(asset::systemDir, "res")))
|
if (system::exists(system::join(asset::systemDir, "res")))
|
||||||
{
|
{
|
||||||
templatePath = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR CARDINAL_TEMPLATE_NAME;
|
templatePath = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR CARDINAL_TEMPLATE_NAME;
|
||||||
|
factoryTemplatePath = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR CARDINAL_FACTORY_TEMPLATE_NAME;
|
||||||
}
|
}
|
||||||
// If source code dir does not exist use install target prefix as system dir
|
// If source code dir does not exist use install target prefix as system dir
|
||||||
else
|
else
|
||||||
|
@ -187,17 +211,20 @@ struct Initializer
|
||||||
asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal";
|
asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (! asset::systemDir.empty())
|
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
||||||
{
|
templatePath = system::join(asset::systemDir, CARDINAL_TEMPLATE_NAME);
|
||||||
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
factoryTemplatePath = system::join(asset::systemDir, CARDINAL_FACTORY_TEMPLATE_NAME);
|
||||||
templatePath = system::join(asset::systemDir, CARDINAL_TEMPLATE_NAME);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asset::userDir = asset::systemDir;
|
asset::userDir = asset::systemDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
if ((patchStorageSlug = getPatchStorageSlug()) != nullptr)
|
||||||
|
templatePath = CARDINAL_IMPORTED_TEMPLATE_FILENAME;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Log environment
|
// Log environment
|
||||||
INFO("%s %s v%s", APP_NAME.c_str(), APP_EDITION.c_str(), APP_VERSION.c_str());
|
INFO("%s %s v%s", APP_NAME.c_str(), APP_EDITION.c_str(), APP_VERSION.c_str());
|
||||||
INFO("%s", system::getOperatingSystemInfo().c_str());
|
INFO("%s", system::getOperatingSystemInfo().c_str());
|
||||||
|
@ -206,6 +233,7 @@ struct Initializer
|
||||||
INFO("System directory: %s", asset::systemDir.c_str());
|
INFO("System directory: %s", asset::systemDir.c_str());
|
||||||
INFO("User directory: %s", asset::userDir.c_str());
|
INFO("User directory: %s", asset::userDir.c_str());
|
||||||
INFO("Template patch: %s", templatePath.c_str());
|
INFO("Template patch: %s", templatePath.c_str());
|
||||||
|
INFO("System template patch: %s", factoryTemplatePath.c_str());
|
||||||
|
|
||||||
// Report to user if something is wrong with the installation
|
// Report to user if something is wrong with the installation
|
||||||
if (asset::systemDir.empty())
|
if (asset::systemDir.empty())
|
||||||
|
@ -564,6 +592,7 @@ public:
|
||||||
context->patch = new rack::patch::Manager;
|
context->patch = new rack::patch::Manager;
|
||||||
context->patch->autosavePath = fAutosavePath;
|
context->patch->autosavePath = fAutosavePath;
|
||||||
context->patch->templatePath = fInitializer->templatePath;
|
context->patch->templatePath = fInitializer->templatePath;
|
||||||
|
context->patch->factoryTemplatePath = fInitializer->factoryTemplatePath;
|
||||||
|
|
||||||
context->event = new rack::widget::EventState;
|
context->event = new rack::widget::EventState;
|
||||||
context->scene = new rack::app::Scene;
|
context->scene = new rack::app::Scene;
|
||||||
|
@ -572,28 +601,33 @@ public:
|
||||||
if (! isDummyInstance())
|
if (! isDummyInstance())
|
||||||
context->window = new rack::window::Window;
|
context->window = new rack::window::Window;
|
||||||
|
|
||||||
context->patch->loadTemplate();
|
#ifdef DISTRHO_OS_WASM
|
||||||
context->scene->rackScroll->reset();
|
if (rack::patchStorageSlug == nullptr)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
context->patch->loadTemplate();
|
||||||
|
context->scene->rackScroll->reset();
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||||
fInitializer->oscPlugin = this;
|
fInitializer->oscPlugin = this;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~CardinalPlugin() override
|
~CardinalPlugin() override
|
||||||
{
|
{
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
||||||
fInitializer->oscPlugin = nullptr;
|
fInitializer->oscPlugin = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
const ScopedContext sc(this);
|
const ScopedContext sc(this);
|
||||||
context->patch->clear();
|
context->patch->clear();
|
||||||
|
|
||||||
// do a little dance to prevent context scene deletion from saving to temp dir
|
// do a little dance to prevent context scene deletion from saving to temp dir
|
||||||
#ifndef HEADLESS
|
#ifndef HEADLESS
|
||||||
const ScopedValueSetter<bool> svs(rack::settings::headless, true);
|
const ScopedValueSetter<bool> svs(rack::settings::headless, true);
|
||||||
#endif
|
#endif
|
||||||
Engine_setAboutToClose(context->engine);
|
Engine_setAboutToClose(context->engine);
|
||||||
delete context;
|
delete context;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,11 +31,12 @@
|
||||||
#include <window/Window.hpp>
|
#include <window/Window.hpp>
|
||||||
|
|
||||||
#ifdef DISTRHO_OS_WASM
|
#ifdef DISTRHO_OS_WASM
|
||||||
#include <ui/Button.hpp>
|
# include <ui/Button.hpp>
|
||||||
#include <ui/Label.hpp>
|
# include <ui/Label.hpp>
|
||||||
#include <ui/MenuOverlay.hpp>
|
# include <ui/MenuOverlay.hpp>
|
||||||
#include <ui/SequentialLayout.hpp>
|
# include <ui/SequentialLayout.hpp>
|
||||||
#include "CardinalCommon.hpp"
|
# include "CardinalCommon.hpp"
|
||||||
|
# include <emscripten/emscripten.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
|
@ -189,6 +190,104 @@ struct WasmWelcomeDialog : rack::widget::OpaqueWidget
|
||||||
Widget::draw(args);
|
Widget::draw(args);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct WasmPatchStorageLoadingDialog : rack::widget::OpaqueWidget
|
||||||
|
{
|
||||||
|
static const constexpr float margin = 10;
|
||||||
|
|
||||||
|
rack::ui::MenuOverlay* overlay;
|
||||||
|
|
||||||
|
WasmPatchStorageLoadingDialog()
|
||||||
|
{
|
||||||
|
using rack::ui::Label;
|
||||||
|
using rack::ui::MenuOverlay;
|
||||||
|
using rack::ui::SequentialLayout;
|
||||||
|
|
||||||
|
box.size = rack::math::Vec(300, 50);
|
||||||
|
|
||||||
|
SequentialLayout* const layout = new SequentialLayout;
|
||||||
|
layout->box.pos = rack::math::Vec(0, 0);
|
||||||
|
layout->box.size = box.size;
|
||||||
|
layout->orientation = SequentialLayout::VERTICAL_ORIENTATION;
|
||||||
|
layout->margin = rack::math::Vec(margin, margin);
|
||||||
|
layout->spacing = rack::math::Vec(margin, margin);
|
||||||
|
layout->wrap = false;
|
||||||
|
addChild(layout);
|
||||||
|
|
||||||
|
Label* const label = new Label;
|
||||||
|
label->box.size.x = box.size.x - 2*margin;
|
||||||
|
label->box.size.y = box.size.y - 2*margin - 40;
|
||||||
|
label->fontSize = 16;
|
||||||
|
label->text = "Load patch from PatchStorage...\n";
|
||||||
|
layout->addChild(label);
|
||||||
|
|
||||||
|
overlay = new MenuOverlay;
|
||||||
|
overlay->bgColor = nvgRGBAf(0, 0, 0, 0.33);
|
||||||
|
overlay->addChild(this);
|
||||||
|
APP->scene->addChild(overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
void step() override
|
||||||
|
{
|
||||||
|
OpaqueWidget::step();
|
||||||
|
box.pos = parent->box.size.minus(box.size).div(2).round();
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw(const DrawArgs& args) override
|
||||||
|
{
|
||||||
|
bndMenuBackground(args.vg, 0.0, 0.0, box.size.x, box.size.y, 0);
|
||||||
|
Widget::draw(args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void downloadPatchStorageFailed(const char* const filename)
|
||||||
|
{
|
||||||
|
d_stdout("downloadPatchStorageFailed %s", filename);
|
||||||
|
CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP);
|
||||||
|
CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context->ui);
|
||||||
|
|
||||||
|
if (ui->psDialog != nullptr)
|
||||||
|
{
|
||||||
|
ui->psDialog->overlay->requestDelete();
|
||||||
|
asyncDialog::create("Failed to fetch patch from PatchStorage");
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace rack;
|
||||||
|
context->patch->templatePath = system::join(asset::systemDir, "template-synth.vcv"); // FIXME
|
||||||
|
context->patch->loadTemplate();
|
||||||
|
context->scene->rackScroll->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void downloadPatchStorageSucceeded(const char* const filename)
|
||||||
|
{
|
||||||
|
d_stdout("downloadPatchStorageSucceeded %s | %s", filename, APP->patch->templatePath.c_str());
|
||||||
|
CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP);
|
||||||
|
CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context->ui);
|
||||||
|
|
||||||
|
ui->psDialog->overlay->requestDelete();
|
||||||
|
ui->psDialog = nullptr;
|
||||||
|
|
||||||
|
if (FILE* f = fopen(filename, "r"))
|
||||||
|
{
|
||||||
|
uint8_t buf[8] = {};
|
||||||
|
fread(buf, 8, 1, f);
|
||||||
|
d_stdout("read patch %x %x %x %x %x %x %x %x",
|
||||||
|
buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
context->patch->load(CARDINAL_IMPORTED_TEMPLATE_FILENAME);
|
||||||
|
} catch (rack::Exception& e) {
|
||||||
|
const std::string message = rack::string::f("Could not load patch: %s", e.what());
|
||||||
|
asyncDialog::create(message.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->scene->rackScroll->reset();
|
||||||
|
context->patch->path = "";
|
||||||
|
context->history->setSaved();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
@ -288,7 +387,21 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DISTRHO_OS_WASM
|
#ifdef DISTRHO_OS_WASM
|
||||||
new WasmWelcomeDialog();
|
if (rack::patchStorageSlug != nullptr)
|
||||||
|
{
|
||||||
|
std::string url("/patchstorage.php?slug=");
|
||||||
|
url += rack::patchStorageSlug;
|
||||||
|
std::free(rack::patchStorageSlug);
|
||||||
|
rack::patchStorageSlug = nullptr;
|
||||||
|
|
||||||
|
psDialog = new WasmPatchStorageLoadingDialog();
|
||||||
|
emscripten_async_wget(url.c_str(), context->patch->templatePath.c_str(),
|
||||||
|
downloadPatchStorageSucceeded, downloadPatchStorageFailed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new WasmWelcomeDialog();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
context->window->step();
|
context->window->step();
|
||||||
|
|
|
@ -122,10 +122,6 @@ void handleHostParameterDrag(const CardinalPluginContext* pcontext, uint index,
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
struct CardinalAudioDevice;
|
|
||||||
struct CardinalMidiInputDevice;
|
|
||||||
struct CardinalMidiOutputDevice;
|
|
||||||
|
|
||||||
CardinalPluginContext* getRackContextFromPlugin(void* ptr);
|
CardinalPluginContext* getRackContextFromPlugin(void* ptr);
|
||||||
|
|
||||||
class CardinalBasePlugin : public Plugin {
|
class CardinalBasePlugin : public Plugin {
|
||||||
|
@ -139,12 +135,18 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef HEADLESS
|
#ifndef HEADLESS
|
||||||
|
struct WasmPatchStorageLoadingDialog;
|
||||||
|
|
||||||
class CardinalBaseUI : public UI {
|
class CardinalBaseUI : public UI {
|
||||||
public:
|
public:
|
||||||
CardinalPluginContext* const context;
|
CardinalPluginContext* const context;
|
||||||
bool saving;
|
bool saving;
|
||||||
bool savingUncompressed;
|
bool savingUncompressed;
|
||||||
|
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
WasmPatchStorageLoadingDialog* psDialog;
|
||||||
|
#endif
|
||||||
|
|
||||||
// for 3rd party modules
|
// for 3rd party modules
|
||||||
std::function<void(char* path)> filebrowseraction;
|
std::function<void(char* path)> filebrowseraction;
|
||||||
FileBrowserHandle filebrowserhandle;
|
FileBrowserHandle filebrowserhandle;
|
||||||
|
@ -154,6 +156,9 @@ public:
|
||||||
context(getRackContextFromPlugin(getPluginInstancePointer())),
|
context(getRackContextFromPlugin(getPluginInstancePointer())),
|
||||||
saving(false),
|
saving(false),
|
||||||
savingUncompressed(false),
|
savingUncompressed(false),
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
psDialog(nullptr),
|
||||||
|
#endif
|
||||||
filebrowseraction(),
|
filebrowseraction(),
|
||||||
filebrowserhandle(nullptr)
|
filebrowserhandle(nullptr)
|
||||||
{
|
{
|
||||||
|
|
43
src/emscripten/patchstorage.php
Normal file
43
src/emscripten/patchstorage.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
$slug = filter_input(INPUT_GET, 'slug', FILTER_SANITIZE_ENCODED);
|
||||||
|
if (!$slug) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
$api = 'https://patchstorage.com/api/alpha';
|
||||||
|
|
||||||
|
$search = file_get_contents($api.'/patches?platform=7834&slug='.$slug);
|
||||||
|
if (!$search) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
$searchJ = json_decode($search, true);
|
||||||
|
if (!$searchJ) { http_response_code(404); die(); }
|
||||||
|
if (!$searchJ[0]) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
$patchId = $searchJ[0]['id'];
|
||||||
|
if (!$patchId) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
$patchDetails = file_get_contents($api.'/patches/'.$patchId);
|
||||||
|
if (!$patchDetails) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
$patchDetailsJ = json_decode($patchDetails, true);
|
||||||
|
if (!$patchDetailsJ) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
$patchFiles = $patchDetailsJ['files'];
|
||||||
|
if (!$patchFiles) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
$patchFileDetails = $patchFiles[0];
|
||||||
|
if (!$patchFileDetails) { http_response_code(404); die(); }
|
||||||
|
if (!$patchFileDetails['filename']) { http_response_code(404); die(); }
|
||||||
|
if (!$patchFileDetails['url']) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
$contents = file_get_contents($patchFileDetails['url']);
|
||||||
|
if (!$contents) { http_response_code(404); die(); }
|
||||||
|
|
||||||
|
header('Content-Description: File Transfer');
|
||||||
|
header('Content-Type: application/octet-stream');
|
||||||
|
header('Content-Disposition: attachment; filename="'.$patchFileDetails['filename'].'"');
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate');
|
||||||
|
header('Pragma: public');
|
||||||
|
header('Content-Length: ' . strlen($contents));
|
||||||
|
flush();
|
||||||
|
die($contents);
|
||||||
|
?>
|
Loading…
Add table
Add a link
Reference in a new issue