Add an internal link share to the share dialog

Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
This commit is contained in:
Claudio Cambra 2022-11-04 19:30:22 +01:00
parent d0d16e4ef1
commit 59d84759e4
No known key found for this signature in database
GPG key ID: C839200C384636B0
5 changed files with 60 additions and 7 deletions

View file

@ -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)

View file

@ -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"));

View file

@ -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.

View file

@ -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;

View file

@ -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,