Skip to content

Commit

Permalink
in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
VitorVieiraZ committed Dec 9, 2024
1 parent 7a01cc6 commit eabfc85
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 80 deletions.
66 changes: 15 additions & 51 deletions app/activeproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ ActiveProject::ActiveProject( AppSettings &appSettings
setAutosyncEnabled( mAppSettings.autosyncAllowed() );

QObject::connect( &mAppSettings, &AppSettings::autosyncAllowedChanged, this, &ActiveProject::setAutosyncEnabled );

QObject::connect(
mMerginApi,
&MerginApi::projectMetadataRoleUpdated,
this, [this]( const QString & projectFullName, const QString & role )
{
if ( projectFullName == this->projectFullName() )
{
setProjectRole( role );
}
} );
}

ActiveProject::~ActiveProject() = default;
Expand Down Expand Up @@ -103,7 +114,7 @@ bool ActiveProject::load( const QString &filePath )
bool ActiveProject::forceLoad( const QString &filePath, bool force )
{
// update user's role each time a project is opened, following #3174
updateProjectMetadata();
mMerginApi->updateProjectMetadataRole( projectFullName() );

CoreUtils::log( QStringLiteral( "Project loading" ), filePath + " " + ( force ? "true" : "false" ) );

Expand Down Expand Up @@ -559,56 +570,9 @@ bool ActiveProject::positionTrackingSupported() const
return mQgsProject->readBoolEntry( QStringLiteral( "Mergin" ), QStringLiteral( "PositionTracking/Enabled" ), false );
}

bool ActiveProject::updateProjectMetadata()
{
if ( !mMerginApi )
{
return false;
}

QNetworkReply *reply = mMerginApi->getProjectInfo( projectFullName() );
if ( !reply )
{
restoreCachedRole();
return false;
}

reply->request().setAttribute( static_cast<QNetworkRequest::Attribute>( mMerginApi->AttrProjectFullName ), projectFullName() );

connect( reply, &QNetworkReply::finished, this, &ActiveProject::updateProjectMetadataReplyFinished );

return true;
}

void ActiveProject::updateProjectMetadataReplyFinished()
{
QNetworkReply *r = qobject_cast<QNetworkReply *>( sender() );
Q_ASSERT( r );

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

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

MerginProjectMetadata serverProject = MerginProjectMetadata::fromJson( data );
QString role = serverProject.role;
setProjectRole( role );
}
else
{
restoreCachedRole();
}

r->deleteLater();
}

void ActiveProject::restoreCachedRole()
{
MerginProjectMetadata cachedProjectMetadata = MerginProjectMetadata::fromCachedJson( mLocalProject.projectDir + "/" + mMerginApi->sMetadataFile );
QString role = cachedProjectMetadata.role;
setProjectRole( role );
}
// read cached role from metadata -> get reply -> update if changed
// metadataRoleFetchFinishedSignal -> (data)
// store role in app settings or update only role in cached json or nothing :)

QString ActiveProject::projectRole() const
{
Expand Down
13 changes: 1 addition & 12 deletions app/activeproject.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#include "localprojectsmanager.h"
#include "autosynccontroller.h"
#include "inputmapsettings.h"
#include "../core/merginapi.h"
#include "merginapi.h"

/**
* \brief The ActiveProject class can load a QGIS project and holds its data.
Expand Down Expand Up @@ -128,17 +128,6 @@ class ActiveProject: public QObject

void setProjectRole( const QString &role );

/**
* Restores cached project role in metadata
*/
void restoreCachedRole();

/**
* Creates a network request to fetch latest project information and define user role in this project
*/
Q_INVOKABLE bool updateProjectMetadata();
void updateProjectMetadataReplyFinished();

signals:
void qgsProjectChanged();
void localProjectChanged( LocalProject project );
Expand Down
2 changes: 1 addition & 1 deletion app/qml/project/MMProjectController.qml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Item {
// just hide the panel - project already loaded
hidePanel()
// update user's role in project ( in case user has changed )
__activeProject.updateProjectMetadata()
__merginApi.updateProjectMetadataRole( __activeProject.projectFullName() )
}
else
{
Expand Down
95 changes: 95 additions & 0 deletions core/merginapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3449,6 +3449,45 @@ bool MerginApi::writeData( const QByteArray &data, const QString &path )
return true;
}

bool MerginApi::updateCachedProjectRole( const QString &projectFullName, const QString &newRole )
{
LocalProject project = mLocalProjects.projectFromMerginName( projectFullName );
if ( !project.isValid() )
{
return false;
}

QString metadataPath = project.projectDir + "/" + sMetadataFile;

QFile file( metadataPath );
if ( !file.open( QIODevice::ReadOnly ) )
{
return false;
}

QByteArray data = file.readAll();
file.close();

QJsonDocument doc = QJsonDocument::fromJson( data );
if ( !doc.isObject() )
{
return false;
}

QJsonObject obj = doc.object();
obj["role"] = newRole;
doc.setObject( obj );

if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
{
return false;
}

bool success = ( file.write( doc.toJson() ) != -1 );
file.close();

return success;
}

void MerginApi::createPathIfNotExists( const QString &filePath )
{
Expand Down Expand Up @@ -3945,3 +3984,59 @@ DownloadQueueItem::DownloadQueueItem( const QString &fp, qint64 s, int v, qint64
tempFileName = CoreUtils::uuidWithoutBraces( QUuid::createUuid() );
}

void MerginApi::updateProjectMetadataRole( const QString &projectFullName )
{
if ( projectFullName.isEmpty() )
{
return;
}

QString projectDir = mLocalProjects.projectFromMerginName( projectFullName ).projectDir;
MerginProjectMetadata cachedProjectMetadata = MerginProjectMetadata::fromCachedJson( projectDir + "/" + sMetadataFile );
QString cachedRole = cachedProjectMetadata.role;

QNetworkReply *reply = getProjectInfo( projectFullName );
if ( !reply )
{
emit projectMetadataRoleUpdated( projectFullName, cachedRole );
return;
}

reply->request().setAttribute( static_cast<QNetworkRequest::Attribute>( AttrProjectFullName ), projectFullName );
reply->request().setAttribute( static_cast<QNetworkRequest::Attribute>( AttrCachedRole ), cachedRole );
connect( reply, &QNetworkReply::finished, this, &MerginApi::updateProjectMetadataRoleReplyFinished );
}

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

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

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

if ( role != cachedRole )
{
if ( updateCachedProjectRole( projectFullName, role ) )
{
emit projectMetadataRoleUpdated( projectFullName, role );
}
else
{
CoreUtils::log( "metadata", QString( "Failed to update cached role for project %1" ).arg( projectFullName ) );
}
}
}
else
{
emit projectMetadataRoleUpdated( projectFullName, cachedRole );
}

r->deleteLater();
}
42 changes: 26 additions & 16 deletions core/merginapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -573,23 +573,10 @@ class MerginApi: public QObject
*/
bool apiSupportsWorkspaces();

/** Creates a request to get project details (list of project files).
*/
QNetworkReply *getProjectInfo( const QString &projectFullName, bool withAuth = true );

enum CustomAttribute
{
AttrProjectFullName = QNetworkRequest::User,
AttrTempFileName = QNetworkRequest::User + 1,
AttrWorkspaceName = QNetworkRequest::User + 2,
AttrAcceptFlag = QNetworkRequest::User + 3,
};

/**
* Extracts detail (message) of an error json. If its not json or detail cannot be parsed, the whole data are return;
* \param data Data received from mergin server on a request failed.
*/
QString extractServerErrorMsg( const QByteArray &data );
* Updates project metadata role by fetching latest information from server.
*/
Q_INVOKABLE void updateProjectMetadataRole( const QString &projectFullName );

signals:
void apiSupportsSubscriptionsChanged();
Expand Down Expand Up @@ -668,6 +655,7 @@ class MerginApi: public QObject
void apiSupportsWorkspacesChanged();

void serverWasUpgraded();
void projectMetadataRoleUpdated( const QString &projectFullName, const QString &role );

private slots:
void listProjectsReplyFinished( QString requestId );
Expand Down Expand Up @@ -762,11 +750,20 @@ class MerginApi: public QObject
*/
QVariant extractServerErrorValue( const QByteArray &data, const QString &key );
/**
* Extracts detail (message) of an error json. If its not json or detail cannot be parsed, the whole data are return;
* \param data Data received from mergin server on a request failed.
*/
QString extractServerErrorMsg( const QByteArray &data );
/**
* Returns a temporary project path.
* \param projectFullName
*/
QString getTempProjectDir( const QString &projectFullName );

/** Creates a request to get project details (list of project files).
*/
QNetworkReply *getProjectInfo( const QString &projectFullName, bool withAuth = true );

//! Called when pull of project data has finished to finalize things and emit sync finished signal
void finalizeProjectPull( const QString &projectFullName );

Expand Down Expand Up @@ -798,6 +795,10 @@ class MerginApi: public QObject

bool projectFileHasBeenUpdated( const ProjectDiff &diff );

void updateProjectMetadataRoleReplyFinished();

bool updateCachedProjectRole( const QString &projectFullName, const QString &newRole );

QNetworkAccessManager mManager;
QString mApiRoot;
LocalProjectsManager &mLocalProjects;
Expand All @@ -808,6 +809,15 @@ class MerginApi: public QObject
MerginSubscriptionInfo *mSubscriptionInfo; //owned by this (qml grouped-properties)
MerginUserAuth *mUserAuth; //owned by this (qml grouped-properties)

enum CustomAttribute
{
AttrProjectFullName = QNetworkRequest::User,
AttrTempFileName = QNetworkRequest::User + 1,
AttrWorkspaceName = QNetworkRequest::User + 2,
AttrAcceptFlag = QNetworkRequest::User + 3,
AttrCachedRole = QNetworkRequest::User + 4
};

Transactions mTransactionalStatus; //projectFullname -> transactionStatus
static const QSet<QString> sIgnoreExtensions;
static const QSet<QString> sIgnoreImageExtensions;
Expand Down

1 comment on commit eabfc85

@inputapp-bot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iOS - version 24.12.696811 just submitted!

Please sign in to comment.