diff --git a/gallery/hotreload.cpp b/gallery/hotreload.cpp index a6025c2d4..2089630cf 100644 --- a/gallery/hotreload.cpp +++ b/gallery/hotreload.cpp @@ -14,18 +14,14 @@ #include #include -// TODO: not needed to sync dirs every second, just when a file was changed QString HotReload::syncScript() const { - return "#!/bin/sh \n\ -echo running hot reload sync directories ... \n\ -while true; do \n\ - rsync -ra " GALLERY_SOURCE_DIR "/qml/ HotReload/qml/ \n\ - rsync -ra " GALLERY_SOURCE_DIR "/../app/qml/ HotReload/app/qml/ \n\ - sleep 1 \n\ -done"; + return QString( "#!/bin/sh \n" + "echo 'Syncing modified files...' \n" + "rsync -rau \"%1/qml/\" HotReload/qml/ \n" + "rsync -rau \"%1/../app/qml/\" HotReload/app/qml/ \n" ) + .arg( GALLERY_SOURCE_DIR ); } - HotReload::HotReload( QQmlApplicationEngine &engine, QObject *parent ): _engine( engine ) { @@ -66,28 +62,52 @@ void HotReload::clearCache() void HotReload::startHotReload() { + _debounceTimer = new QTimer( this ); + _debounceTimer->setSingleShot( true ); + _debounceTimer->setInterval( 300 ); + + // when the timer starts, run the sync script ONCE, then reload + connect( _debounceTimer, &QTimer::timeout, this, [this]() + { + // run the sync synchronously so it finishes before reloading + QProcess::execute( "./syncGallery.sh" ); + emit watchedSourceChanged(); + } ); + _watcher = new QFileSystemWatcher( this ); - _watcher->addPath( "HotReload/qml" ); - _watcher->addPath( "HotReload/qml/Pages" ); - _watcher->addPath( "HotReload/app/qml/account" ); - _watcher->addPath( "HotReload/app/qml/account/components" ); - _watcher->addPath( "HotReload/app/qml/components" ); - _watcher->addPath( "HotReload/app/qml/dialogs" ); - _watcher->addPath( "HotReload/app/qml/form" ); - _watcher->addPath( "HotReload/app/qml/form/components" ); - _watcher->addPath( "HotReload/app/qml/form/editors" ); - _watcher->addPath( "HotReload/app/qml/gps" ); - _watcher->addPath( "HotReload/app/qml/inputs" ); - _watcher->addPath( "HotReload/app/qml/layers" ); - _watcher->addPath( "HotReload/app/qml/map" ); - _watcher->addPath( "HotReload/app/qml/project" ); - _watcher->addPath( "HotReload/app/qml/project/components" ); - _watcher->addPath( "HotReload/app/qml/settings" ); - _watcher->addPath( "HotReload/app/qml/settings/components" ); - // send signal for hot reloading + // Set up base paths for your source code + QString gallerySrc = QString( GALLERY_SOURCE_DIR ) + "/qml"; + QString appSrc = QString( GALLERY_SOURCE_DIR ) + "/../app/qml"; + + // Watch the SOURCE directories instead of the destination + _watcher->addPath( gallerySrc ); + _watcher->addPath( gallerySrc + "/Pages" ); + + _watcher->addPath( appSrc + "/account" ); + _watcher->addPath( appSrc + "/account/components" ); + _watcher->addPath( appSrc + "/components" ); + _watcher->addPath( appSrc + "/dialogs" ); + _watcher->addPath( appSrc + "/form" ); + _watcher->addPath( appSrc + "/form/components" ); + _watcher->addPath( appSrc + "/form/editors" ); + _watcher->addPath( appSrc + "/gps" ); + _watcher->addPath( appSrc + "/inputs" ); + _watcher->addPath( appSrc + "/layers" ); + _watcher->addPath( appSrc + "/map" ); + _watcher->addPath( appSrc + "/project" ); + _watcher->addPath( appSrc + "/project/components" ); + _watcher->addPath( appSrc + "/settings" ); + _watcher->addPath( appSrc + "/settings/components" ); + + // when you save the file, start the debounce timer connect( _watcher, &QFileSystemWatcher::directoryChanged, this, [this]( const QString & path ) { - emit watchedSourceChanged(); + _debounceTimer->start(); + } ); + + connect( _watcher, &QFileSystemWatcher::fileChanged, this, [this]( const QString & path ) + { + _debounceTimer->start(); } ); } diff --git a/gallery/hotreload.h b/gallery/hotreload.h index b1cecc0f6..fa8b62628 100644 --- a/gallery/hotreload.h +++ b/gallery/hotreload.h @@ -12,6 +12,7 @@ #include #include +#include class QFileSystemWatcher; @@ -34,6 +35,7 @@ class HotReload : public QObject private: QFileSystemWatcher *_watcher; QQmlApplicationEngine &_engine; + QTimer *_debounceTimer = nullptr; }; #endif // HOTRELOAD_H diff --git a/gallery/qml/Main.qml b/gallery/qml/Main.qml index 878a1bf5e..78d05319c 100644 --- a/gallery/qml/Main.qml +++ b/gallery/qml/Main.qml @@ -25,15 +25,29 @@ ApplicationWindow { property string currentPageSource: "InitialGalleryPage.qml" + Timer { + id: reloadTimer + interval: 50 + onTriggered: { + // delete the cache after 50ms + _hotReload.clearCache() + + mainLoader.source = Qt.binding(function () { + return (__isMobile ? "qrc:/qml/pages/" : ("file://" + _qmlWrapperPath)) + window.currentPageSource + }) + mainLoader.active = true + + console.log(new Date().toLocaleTimeString().split(' ')[0] + " ------ App reloaded 🔥 ------ ") + } + } Connections { target: __isMobile ? null : _hotReload enabled: !__isMobile function onWatchedSourceChanged() { mainLoader.active = false + mainLoader.setSource("") _hotReload.clearCache() - mainLoader.setSource("file:///" + _qmlWrapperPath + currentPageSource) - mainLoader.active = true - console.log( new Date().toLocaleTimeString().split(' ')[0] + " ------ App reloaded 🔥 ------ ") + reloadTimer.start() } }