Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/notificationmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ void NotificationModel::onNotificationClicked( uint id )
emit showSyncFailedDialogClicked();
break;
}
case NotificationType::ActionType::ShowProjectNewVersionAction:
{
remove( id );
emit showProjectNewVersionClicked();
break;
}
default: break;
}
}
Expand Down
4 changes: 3 additions & 1 deletion app/notificationmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class NotificationType
NoAction,
ShowProjectIssuesAction,
ShowSwitchWorkspaceAction,
ShowSyncFailedDialog
ShowSyncFailedDialog,
ShowProjectNewVersionAction
};
Q_ENUM( ActionType )

Expand Down Expand Up @@ -111,6 +112,7 @@ class NotificationModel : public QAbstractListModel
void rowCountChanged();
void showProjectIssuesActionClicked();
void showSwitchWorkspaceActionClicked();
void showProjectNewVersionClicked();
void showSyncFailedDialogClicked();

private:
Expand Down
21 changes: 21 additions & 0 deletions app/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ ApplicationWindow {

// Stop/Start sync animation when user goes to map
syncButton.iconRotateAnimationRunning = ( __syncManager.hasPendingSync( __activeProject.projectFullName() ) )

if ( __activeProject.projectFullName() !== "" ) {
__merginApi.isProjectSyncNeeded( __activeProject.projectFullName(), true )
}
}
else if ( stateManager.state === "projects" ) {
projectController.openPanel()
Expand Down Expand Up @@ -1090,6 +1094,17 @@ ApplicationWindow {
{
ssoExpiredTokenDialog.open()
}

function onProjectSyncRequired( projectFullName )
{
if ( __activeProject.projectFullName() === projectFullName )
{
__notificationModel.addInfo(
__inputUtils.htmlLink( qsTr( "There is a new version of the project available" ), __style.forestColor ),
MM.NotificationType.ShowProjectNewVersionAction
)
}
}
}

Connections {
Expand All @@ -1112,6 +1127,9 @@ ApplicationWindow {
function onShowSyncFailedDialogClicked() {
syncFailedDialog.open()
}
function onShowProjectNewVersionClicked() {
__activeProject.requestSync()
}
}

Connections {
Expand Down Expand Up @@ -1159,6 +1177,9 @@ ApplicationWindow {

AppSettings.defaultProject = __activeProject.localProject.qgisProjectFilePath ?? ""
AppSettings.activeProject = __activeProject.localProject.qgisProjectFilePath ?? ""
if ( __activeProject.projectFullName() !== "" ) {
__merginApi.isProjectSyncNeeded( __activeProject.projectFullName(), true )
}
}

function onProjectWillBeReloaded() {
Expand Down
39 changes: 39 additions & 0 deletions core/merginapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4597,3 +4597,42 @@ bool MerginApi::serverVersionIsAtLeast( const int requiredMajor, const int requi
// check patch
return serverPatch >= requiredPatch;
}

void MerginApi::isProjectSyncNeededFinished()
{
QNetworkReply *r = qobject_cast<QNetworkReply *>( sender() );
Q_ASSERT( r );

QString projectFullName = r->request().attribute( static_cast<QNetworkRequest::Attribute>( AttrProjectFullName ) ).toString();
mPendingSyncChecks.remove( projectFullName );

if ( r->error() == QNetworkReply::NoError )
{
QByteArray data = r->readAll();
MerginProjectMetadata serverProject = MerginProjectMetadata::fromJson( data );

// skip if a sync is already in progress for this project
if ( !mTransactionalStatus.contains( projectFullName ) )
{
LocalProject projectInfo = mLocalProjects.projectFromMerginName( projectFullName );
if ( projectInfo.isValid() && projectInfo.localVersion != -1 && projectInfo.localVersion < serverProject.version )
{
emit projectSyncRequired( projectFullName );
}
}
}
r->deleteLater();
}

void MerginApi::isProjectSyncNeeded( const QString &projectFullName, bool withAuth )
{
if ( mPendingSyncChecks.contains( projectFullName ) )
return;

QNetworkReply *reply = getProjectInfo( projectFullName, withAuth );
if ( !reply )
return;

mPendingSyncChecks.insert( projectFullName );
connect( reply, &QNetworkReply::finished, this, &MerginApi::isProjectSyncNeededFinished );
}
7 changes: 7 additions & 0 deletions core/merginapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,8 @@ class MerginApi: public QObject
*/
Q_INVOKABLE void reloadProjectRole( const QString &projectFullName );

Q_INVOKABLE void isProjectSyncNeeded( const QString &projectFullName, bool withAuth );

/**
* Returns the network manager used for Mergin API requests
*/
Expand Down Expand Up @@ -689,6 +691,7 @@ class MerginApi: public QObject

void listProjectsFinished( const MerginProjectsList &merginProjects, int projectCount, int page, QString requestId );
void listProjectsFailed();
void projectSyncRequired( const QString &projectFullName );
void listProjectsByNameFinished( const MerginProjectsList &merginProjects, QString requestId );
void syncProjectFinished( const QString &projectFullName, bool successfully, int version );
void projectReloadNeededAfterSync( const QString &projectFullName );
Expand Down Expand Up @@ -783,6 +786,8 @@ class MerginApi: public QObject

// Pull slots
void pullInfoReplyFinished();
void isProjectSyncNeededFinished();

void downloadItemReplyFinished( DownloadQueueItem item );
void cacheServerConfig();

Expand Down Expand Up @@ -979,6 +984,8 @@ class MerginApi: public QObject
MerginServerType::ServerType mServerType = MerginServerType::ServerType::OLD;
QString mServerDiagnosticLogsUrl = MerginApi::sDefaultReportLogUrl;

QSet<QString> mPendingSyncChecks; // not yet updated projects with isProjectSyncNeeded request

QOAuth2AuthorizationCodeFlow mOauth2Flow;
#ifdef MOBILE_OS
QOAuthUriSchemeReplyHandler *mOauth2ReplyHandler = nullptr; // parented by mOauth2Flow
Expand Down
Loading