mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-25 06:25:56 +03:00
Add an internal link share to the share dialog
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
This commit is contained in:
parent
d0d16e4ef1
commit
59d84759e4
5 changed files with 60 additions and 7 deletions
|
@ -53,6 +53,7 @@ GridLayout {
|
||||||
|
|
||||||
readonly property bool isLinkShare: model.shareType === ShareModel.ShareTypeLink
|
readonly property bool isLinkShare: model.shareType === ShareModel.ShareTypeLink
|
||||||
readonly property bool isPlaceholderLinkShare: model.shareType === ShareModel.ShareTypePlaceholderLink
|
readonly property bool isPlaceholderLinkShare: model.shareType === ShareModel.ShareTypePlaceholderLink
|
||||||
|
readonly property bool isInternalLinkShare: model.shareType === ShareModel.ShareTypeInternalLink
|
||||||
|
|
||||||
readonly property string text: model.display ?? ""
|
readonly property string text: model.display ?? ""
|
||||||
readonly property string detailText: model.detailText ?? ""
|
readonly property string detailText: model.detailText ?? ""
|
||||||
|
@ -183,7 +184,7 @@ GridLayout {
|
||||||
icon.width: 16
|
icon.width: 16
|
||||||
icon.height: 16
|
icon.height: 16
|
||||||
|
|
||||||
visible: root.isLinkShare
|
visible: root.isLinkShare || root.isInternalLinkShare
|
||||||
enabled: visible
|
enabled: visible
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -210,7 +211,7 @@ GridLayout {
|
||||||
|
|
||||||
imageSource: "image://svgimage-custom-color/more.svg/" + Style.ncTextColor
|
imageSource: "image://svgimage-custom-color/more.svg/" + Style.ncTextColor
|
||||||
|
|
||||||
visible: !root.isPlaceholderLinkShare
|
visible: !root.isPlaceholderLinkShare && !root.isInternalLinkShare
|
||||||
enabled: visible
|
enabled: visible
|
||||||
|
|
||||||
onClicked: root.rootStackView.push(shareDetailsPageComponent, {}, StackView.PushTransition)
|
onClicked: root.rootStackView.push(shareDetailsPageComponent, {}, StackView.PushTransition)
|
||||||
|
|
|
@ -24,7 +24,8 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static const QString placeholderLinkShareId = QStringLiteral("__placeholderLinkShareId__");
|
static const auto placeholderLinkShareId = QStringLiteral("__placeholderLinkShareId__");
|
||||||
|
static const auto internalLinkShareId = QStringLiteral("__internalLinkShareId__");
|
||||||
|
|
||||||
QString createRandomPassword()
|
QString createRandomPassword()
|
||||||
{
|
{
|
||||||
|
@ -129,6 +130,11 @@ QVariant ShareModel::data(const QModelIndex &index, const int role) const
|
||||||
return startOfExpireDayUTC.toMSecsSinceEpoch();
|
return startOfExpireDayUTC.toMSecsSinceEpoch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (share->getShareType() == Share::TypeInternalLink) {
|
||||||
|
switch(role) {
|
||||||
|
case LinkRole:
|
||||||
|
return _privateLinkUrl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(role) {
|
switch(role) {
|
||||||
|
@ -190,6 +196,8 @@ void ShareModel::resetData()
|
||||||
_sharePath.clear();
|
_sharePath.clear();
|
||||||
_maxSharingPermissions = {};
|
_maxSharingPermissions = {};
|
||||||
_numericFileId.clear();
|
_numericFileId.clear();
|
||||||
|
_privateLinkUrl.clear();
|
||||||
|
_filelockState = {};
|
||||||
_manager.clear();
|
_manager.clear();
|
||||||
_shares.clear();
|
_shares.clear();
|
||||||
_fetchOngoing = false;
|
_fetchOngoing = false;
|
||||||
|
@ -256,12 +264,19 @@ void ShareModel::updateData()
|
||||||
_sharePath,
|
_sharePath,
|
||||||
Share::TypePlaceholderLink));
|
Share::TypePlaceholderLink));
|
||||||
|
|
||||||
|
_internalLinkShare.reset(new Share(_accountState->account(),
|
||||||
|
internalLinkShareId,
|
||||||
|
_accountState->account()->id(),
|
||||||
|
_accountState->account()->davDisplayName(),
|
||||||
|
_sharePath,
|
||||||
|
Share::TypeInternalLink));
|
||||||
|
|
||||||
auto job = new PropfindJob(_accountState->account(), _sharePath);
|
auto job = new PropfindJob(_accountState->account(), _sharePath);
|
||||||
job->setProperties(
|
job->setProperties(
|
||||||
QList<QByteArray>()
|
QList<QByteArray>()
|
||||||
<< "https://open-collaboration-services.org/ns:share-permissions"
|
<< "http://open-collaboration-services.org/ns:share-permissions"
|
||||||
<< "https://owncloud.org/ns:fileid" // numeric file id for fallback private link generation
|
<< "http://owncloud.org/ns:fileid" // numeric file id for fallback private link generation
|
||||||
<< "https://owncloud.org/ns:privatelink");
|
<< "http://owncloud.org/ns:privatelink");
|
||||||
job->setTimeout(10 * 1000);
|
job->setTimeout(10 * 1000);
|
||||||
connect(job, &PropfindJob::result, this, &ShareModel::slotPropfindReceived);
|
connect(job, &PropfindJob::result, this, &ShareModel::slotPropfindReceived);
|
||||||
connect(job, &PropfindJob::finishedWithError, this, [&](const QNetworkReply *reply) {
|
connect(job, &PropfindJob::finishedWithError, this, [&](const QNetworkReply *reply) {
|
||||||
|
@ -359,6 +374,8 @@ void ShareModel::slotPropfindReceived(const QVariantMap &result)
|
||||||
qCInfo(lcShareModel) << "Received numeric file id for" << _sharePath << numericFileId;
|
qCInfo(lcShareModel) << "Received numeric file id for" << _sharePath << numericFileId;
|
||||||
_privateLinkUrl = _accountState->account()->deprecatedPrivateLinkUrl(numericFileId).toString(QUrl::FullyEncoded);
|
_privateLinkUrl = _accountState->account()->deprecatedPrivateLinkUrl(numericFileId).toString(QUrl::FullyEncoded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setupInternalLinkShare();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareModel::slotSharesFetched(const QList<SharePtr> &shares)
|
void ShareModel::slotSharesFetched(const QList<SharePtr> &shares)
|
||||||
|
@ -384,6 +401,21 @@ void ShareModel::slotSharesFetched(const QList<SharePtr> &shares)
|
||||||
handlePlaceholderLinkShare();
|
handlePlaceholderLinkShare();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShareModel::setupInternalLinkShare()
|
||||||
|
{
|
||||||
|
if (!_accountState ||
|
||||||
|
_accountState->account().isNull() ||
|
||||||
|
_localPath.isEmpty() ||
|
||||||
|
_privateLinkUrl.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
beginInsertRows({}, _shares.count(), _shares.count());
|
||||||
|
_shares.append(_internalLinkShare);
|
||||||
|
endInsertRows();
|
||||||
|
Q_EMIT internalLinkReady();
|
||||||
|
}
|
||||||
|
|
||||||
void ShareModel::slotAddShare(const SharePtr &share)
|
void ShareModel::slotAddShare(const SharePtr &share)
|
||||||
{
|
{
|
||||||
if (share.isNull()) {
|
if (share.isNull()) {
|
||||||
|
@ -508,6 +540,8 @@ QString ShareModel::displayStringForShare(const SharePtr &share) const
|
||||||
return displayString;
|
return displayString;
|
||||||
} else if (share->getShareType() == Share::TypePlaceholderLink) {
|
} else if (share->getShareType() == Share::TypePlaceholderLink) {
|
||||||
return tr("Link share");
|
return tr("Link share");
|
||||||
|
} else if (share->getShareType() == Share::TypeInternalLink) {
|
||||||
|
return tr("Internal link");
|
||||||
} else if (share->getShareWith()) {
|
} else if (share->getShareWith()) {
|
||||||
return share->getShareWith()->format();
|
return share->getShareWith()->format();
|
||||||
}
|
}
|
||||||
|
@ -521,6 +555,8 @@ QString ShareModel::iconUrlForShare(const SharePtr &share) const
|
||||||
const auto iconsPath = QStringLiteral("image://svgimage-custom-color/");
|
const auto iconsPath = QStringLiteral("image://svgimage-custom-color/");
|
||||||
|
|
||||||
switch(share->getShareType()) {
|
switch(share->getShareType()) {
|
||||||
|
case Share::TypeInternalLink:
|
||||||
|
return QString(iconsPath + QStringLiteral("external.svg"));
|
||||||
case Share::TypePlaceholderLink:
|
case Share::TypePlaceholderLink:
|
||||||
case Share::TypeLink:
|
case Share::TypeLink:
|
||||||
return QString(iconsPath + QStringLiteral("public.svg"));
|
return QString(iconsPath + QStringLiteral("public.svg"));
|
||||||
|
|
|
@ -74,6 +74,7 @@ public:
|
||||||
ShareTypeCircle = Share::TypeCircle,
|
ShareTypeCircle = Share::TypeCircle,
|
||||||
ShareTypeRoom = Share::TypeRoom,
|
ShareTypeRoom = Share::TypeRoom,
|
||||||
ShareTypePlaceholderLink = Share::TypePlaceholderLink,
|
ShareTypePlaceholderLink = Share::TypePlaceholderLink,
|
||||||
|
ShareTypeInternalLink = Share::TypeInternalLink,
|
||||||
};
|
};
|
||||||
Q_ENUM(ShareType);
|
Q_ENUM(ShareType);
|
||||||
|
|
||||||
|
@ -109,6 +110,7 @@ signals:
|
||||||
void fetchOngoingChanged();
|
void fetchOngoingChanged();
|
||||||
void hasInitialShareFetchCompletedChanged();
|
void hasInitialShareFetchCompletedChanged();
|
||||||
void shareesChanged();
|
void shareesChanged();
|
||||||
|
void internalLinkReady();
|
||||||
|
|
||||||
void serverError(const int code, const QString &message);
|
void serverError(const int code, const QString &message);
|
||||||
void passwordSetError(const QString &shareId, const int code, const QString &message);
|
void passwordSetError(const QString &shareId, const int code, const QString &message);
|
||||||
|
@ -157,6 +159,7 @@ private slots:
|
||||||
void updateData();
|
void updateData();
|
||||||
void initShareManager();
|
void initShareManager();
|
||||||
void handlePlaceholderLinkShare();
|
void handlePlaceholderLinkShare();
|
||||||
|
void setupInternalLinkShare();
|
||||||
|
|
||||||
void slotPropfindReceived(const QVariantMap &result);
|
void slotPropfindReceived(const QVariantMap &result);
|
||||||
void slotServerError(const int code, const QString &message);
|
void slotServerError(const int code, const QString &message);
|
||||||
|
@ -183,6 +186,7 @@ private:
|
||||||
bool _fetchOngoing = false;
|
bool _fetchOngoing = false;
|
||||||
bool _hasInitialShareFetchCompleted = false;
|
bool _hasInitialShareFetchCompleted = false;
|
||||||
SharePtr _placeholderLinkShare;
|
SharePtr _placeholderLinkShare;
|
||||||
|
SharePtr _internalLinkShare;
|
||||||
|
|
||||||
// DO NOT USE QSHAREDPOINTERS HERE.
|
// DO NOT USE QSHAREDPOINTERS HERE.
|
||||||
// QSharedPointers MUST NOT be used with pointers already assigned to other shared pointers.
|
// QSharedPointers MUST NOT be used with pointers already assigned to other shared pointers.
|
||||||
|
|
|
@ -73,12 +73,23 @@ bool SortedShareModel::lessThan(const QModelIndex &sourceLeft, const QModelIndex
|
||||||
const auto leftShareType = leftShare->getShareType();
|
const auto leftShareType = leftShare->getShareType();
|
||||||
|
|
||||||
// Placeholder link shares always go at top
|
// Placeholder link shares always go at top
|
||||||
if(leftShareType == Share::TypePlaceholderLink) {
|
if (leftShareType == Share::TypePlaceholderLink) {
|
||||||
return true;
|
return true;
|
||||||
|
} else if (leftShareType == Share::TypeInternalLink) {
|
||||||
|
// Internal links always at bottom
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto rightShareType = rightShare->getShareType();
|
const auto rightShareType = rightShare->getShareType();
|
||||||
|
|
||||||
|
// Placeholder link shares always go at top
|
||||||
|
if (rightShareType == Share::TypePlaceholderLink) {
|
||||||
|
return false;
|
||||||
|
} else if (rightShareType == Share::TypeInternalLink) {
|
||||||
|
// Internal links always at bottom
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// We want to place link shares at the top
|
// We want to place link shares at the top
|
||||||
if (leftShareType == Share::TypeLink && rightShareType != Share::TypeLink) {
|
if (leftShareType == Share::TypeLink && rightShareType != Share::TypeLink) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -52,6 +52,7 @@ public:
|
||||||
* Need to be in sync with Sharee::Type
|
* Need to be in sync with Sharee::Type
|
||||||
*/
|
*/
|
||||||
enum ShareType {
|
enum ShareType {
|
||||||
|
TypeInternalLink = -2,
|
||||||
TypePlaceholderLink = -1,
|
TypePlaceholderLink = -1,
|
||||||
TypeUser = Sharee::User,
|
TypeUser = Sharee::User,
|
||||||
TypeGroup = Sharee::Group,
|
TypeGroup = Sharee::Group,
|
||||||
|
|
Loading…
Reference in a new issue