cozy-sharing 30.1.1 → 30.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/components/FederatedFolder/DumbFederatedFolderModal.js +9 -3
- package/dist/components/FederatedFolder/FederatedFolderModal.js +9 -3
- package/dist/components/ShareByLink.js +115 -54
- package/dist/components/ShareDialogCozyToCozy.js +18 -3
- package/dist/components/ShareDialogOnlyByLink.js +6 -2
- package/dist/components/ShareModal/ShareModal.js +6 -5
- package/dist/components/ShareModal.js +13 -3
- package/dist/components/ShareModal.spec.js +4 -4
- package/dist/components/ShareRestrictionModal/ShareRestrictionModal.js +51 -64
- package/dist/components/ShareRestrictionModal/helpers.js +61 -12
- package/dist/components/SharedDrive/DumbSharedDriveModal.js +9 -3
- package/dist/components/SharedDrive/SharedDriveEditModal.js +14 -3
- package/dist/components/SharedFolder/DumbBatchSharedFolderModal.js +12 -4
- package/package.json +2 -2
- package/src/components/FederatedFolder/DumbFederatedFolderModal.jsx +8 -2
- package/src/components/FederatedFolder/FederatedFolderModal.jsx +11 -2
- package/src/components/ShareByLink.jsx +66 -25
- package/src/components/ShareDialogCozyToCozy.jsx +17 -2
- package/src/components/ShareDialogOnlyByLink.jsx +5 -1
- package/src/components/ShareModal/ShareModal.jsx +4 -2
- package/src/components/ShareModal.jsx +10 -0
- package/src/components/ShareModal.spec.js +7 -3
- package/src/components/ShareRestrictionModal/ShareRestrictionModal.jsx +42 -38
- package/src/components/ShareRestrictionModal/helpers.js +23 -4
- package/src/components/SharedDrive/DumbSharedDriveModal.jsx +8 -2
- package/src/components/SharedDrive/SharedDriveEditModal.jsx +20 -2
- package/src/components/SharedFolder/DumbBatchSharedFolderModal.jsx +10 -2
|
@@ -91,96 +91,83 @@ export var ShareRestrictionModal = function ShareRestrictionModal(_ref) {
|
|
|
91
91
|
|
|
92
92
|
var handleClick = /*#__PURE__*/function () {
|
|
93
93
|
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
94
|
-
var
|
|
95
|
-
|
|
94
|
+
var permsPromise, urlPromise;
|
|
96
95
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
97
96
|
while (1) switch (_context.prev = _context.next) {
|
|
98
97
|
case 0:
|
|
99
|
-
setLoading(true); //
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
_context.next = 13;
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
98
|
+
setLoading(true); // The clipboard write must be initiated synchronously within the click
|
|
99
|
+
// handler for Safari to honor the user gesture; we pass a pending blob
|
|
100
|
+
// whose content resolves after the permission round-trip.
|
|
105
101
|
|
|
106
|
-
|
|
107
|
-
_context.next = 5;
|
|
108
|
-
return createPermissions({
|
|
102
|
+
permsPromise = hasSharingLink ? updatePermissions({
|
|
109
103
|
file: file,
|
|
110
104
|
t: t,
|
|
111
|
-
|
|
105
|
+
dateToggle: dateToggle,
|
|
106
|
+
selectedDate: selectedDate,
|
|
107
|
+
passwordToggle: passwordToggle,
|
|
112
108
|
password: password,
|
|
113
109
|
editingRights: editingRights,
|
|
114
110
|
documentType: documentType,
|
|
115
|
-
|
|
116
|
-
showAlert: showAlert
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
case 5:
|
|
120
|
-
_yield$createPermissi2 = _context.sent;
|
|
121
|
-
perms = _yield$createPermissi2.data;
|
|
122
|
-
url = generateWebLink({
|
|
123
|
-
cozyUrl: client.getStackClient().uri,
|
|
124
|
-
searchParams: [['sharecode', perms.attributes.shortcodes.code]],
|
|
125
|
-
pathname: '/public',
|
|
126
|
-
slug: getAppSlugFromDocumentType({
|
|
127
|
-
documentType: documentType
|
|
128
|
-
}),
|
|
129
|
-
subDomainType: client.capabilities.flat_subdomains ? 'flat' : 'nested'
|
|
130
|
-
});
|
|
131
|
-
_context.next = 10;
|
|
132
|
-
return copyToClipboard(url, {
|
|
133
|
-
t: t,
|
|
111
|
+
updateDocumentPermissions: updateDocumentPermissions,
|
|
134
112
|
showAlert: showAlert
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
onClose();
|
|
139
|
-
_context.next = 22;
|
|
140
|
-
break;
|
|
113
|
+
}).then(function (_ref3) {
|
|
114
|
+
var _ref4 = _slicedToArray(_ref3, 1),
|
|
115
|
+
perms = _ref4[0].data;
|
|
141
116
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
return updatePermissions({
|
|
117
|
+
return perms;
|
|
118
|
+
}) : createPermissions({
|
|
145
119
|
file: file,
|
|
146
120
|
t: t,
|
|
147
|
-
|
|
148
|
-
selectedDate: selectedDate,
|
|
149
|
-
passwordToggle: passwordToggle,
|
|
121
|
+
ttl: makeTTL(dateToggle && selectedDate),
|
|
150
122
|
password: password,
|
|
151
123
|
editingRights: editingRights,
|
|
152
124
|
documentType: documentType,
|
|
153
|
-
|
|
125
|
+
shareByLink: shareByLink,
|
|
154
126
|
showAlert: showAlert
|
|
127
|
+
}).then(function (_ref5) {
|
|
128
|
+
var perms = _ref5.data;
|
|
129
|
+
return perms;
|
|
155
130
|
});
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
documentType: documentType
|
|
167
|
-
}),
|
|
168
|
-
subDomainType: client.capabilities.flat_subdomains ? 'flat' : 'nested'
|
|
131
|
+
urlPromise = permsPromise.then(function (perms) {
|
|
132
|
+
return generateWebLink({
|
|
133
|
+
cozyUrl: client.getStackClient().uri,
|
|
134
|
+
searchParams: [['sharecode', perms.attributes.shortcodes.code]],
|
|
135
|
+
pathname: '/public',
|
|
136
|
+
slug: getAppSlugFromDocumentType({
|
|
137
|
+
documentType: documentType
|
|
138
|
+
}),
|
|
139
|
+
subDomainType: client.capabilities.flat_subdomains ? 'flat' : 'nested'
|
|
140
|
+
});
|
|
169
141
|
});
|
|
170
|
-
_context.next =
|
|
171
|
-
return copyToClipboard(
|
|
142
|
+
_context.next = 5;
|
|
143
|
+
return copyToClipboard(urlPromise, {
|
|
172
144
|
t: t,
|
|
173
145
|
showAlert: showAlert
|
|
174
146
|
});
|
|
175
147
|
|
|
176
|
-
case
|
|
148
|
+
case 5:
|
|
149
|
+
_context.prev = 5;
|
|
150
|
+
_context.next = 8;
|
|
151
|
+
return permsPromise;
|
|
152
|
+
|
|
153
|
+
case 8:
|
|
154
|
+
_context.next = 14;
|
|
155
|
+
break;
|
|
156
|
+
|
|
157
|
+
case 10:
|
|
158
|
+
_context.prev = 10;
|
|
159
|
+
_context.t0 = _context["catch"](5);
|
|
160
|
+
setLoading(false);
|
|
161
|
+
return _context.abrupt("return");
|
|
162
|
+
|
|
163
|
+
case 14:
|
|
177
164
|
onClose();
|
|
178
165
|
|
|
179
|
-
case
|
|
166
|
+
case 15:
|
|
180
167
|
case "end":
|
|
181
168
|
return _context.stop();
|
|
182
169
|
}
|
|
183
|
-
}, _callee);
|
|
170
|
+
}, _callee, null, [[5, 10]]);
|
|
184
171
|
}));
|
|
185
172
|
|
|
186
173
|
return function handleClick() {
|
|
@@ -189,7 +176,7 @@ export var ShareRestrictionModal = function ShareRestrictionModal(_ref) {
|
|
|
189
176
|
}();
|
|
190
177
|
|
|
191
178
|
var handleRevokeLink = /*#__PURE__*/function () {
|
|
192
|
-
var
|
|
179
|
+
var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
|
193
180
|
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
194
181
|
while (1) switch (_context2.prev = _context2.next) {
|
|
195
182
|
case 0:
|
|
@@ -214,7 +201,7 @@ export var ShareRestrictionModal = function ShareRestrictionModal(_ref) {
|
|
|
214
201
|
}));
|
|
215
202
|
|
|
216
203
|
return function handleRevokeLink() {
|
|
217
|
-
return
|
|
204
|
+
return _ref6.apply(this, arguments);
|
|
218
205
|
};
|
|
219
206
|
}();
|
|
220
207
|
|
|
@@ -115,11 +115,19 @@ export var generateShareLinkFromFile = function generateShareLinkFromFile(_ref3)
|
|
|
115
115
|
});
|
|
116
116
|
};
|
|
117
117
|
/**
|
|
118
|
-
* Copy a
|
|
118
|
+
* Copy a value to the clipboard.
|
|
119
119
|
*
|
|
120
|
-
*
|
|
120
|
+
* Accepts a resolved string or a `Promise<string>`. The promise form is
|
|
121
|
+
* required when the value depends on a prior async step (e.g. creating a
|
|
122
|
+
* sharing link) from within a click handler: Safari drops the user-gesture
|
|
123
|
+
* context across any `await`, so `navigator.clipboard.writeText` called after
|
|
124
|
+
* an awaited call throws `NotAllowedError`. Passing a pending blob to
|
|
125
|
+
* `ClipboardItem` lets the clipboard API be invoked synchronously while the
|
|
126
|
+
* content is resolved later.
|
|
127
|
+
*
|
|
128
|
+
* @param {string | Promise<string>} value - Value to copy
|
|
121
129
|
* @param {object} [options]
|
|
122
|
-
* @param {
|
|
130
|
+
* @param {Function} options.t - Translation function
|
|
123
131
|
* @param {Function} options.showAlert - Function to display an alert
|
|
124
132
|
*/
|
|
125
133
|
|
|
@@ -128,6 +136,7 @@ export var copyToClipboard = /*#__PURE__*/function () {
|
|
|
128
136
|
var _ref5,
|
|
129
137
|
t,
|
|
130
138
|
showAlert,
|
|
139
|
+
blobPromise,
|
|
131
140
|
_args2 = arguments;
|
|
132
141
|
|
|
133
142
|
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
@@ -144,33 +153,73 @@ export var copyToClipboard = /*#__PURE__*/function () {
|
|
|
144
153
|
|
|
145
154
|
case 3:
|
|
146
155
|
_context2.prev = 3;
|
|
147
|
-
|
|
156
|
+
|
|
157
|
+
if (!(typeof value === 'string')) {
|
|
158
|
+
_context2.next = 9;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
_context2.next = 7;
|
|
148
163
|
return navigator.clipboard.writeText(value);
|
|
149
164
|
|
|
150
|
-
case
|
|
165
|
+
case 7:
|
|
166
|
+
_context2.next = 21;
|
|
167
|
+
break;
|
|
168
|
+
|
|
169
|
+
case 9:
|
|
170
|
+
if (!(typeof ClipboardItem !== 'undefined')) {
|
|
171
|
+
_context2.next = 15;
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
blobPromise = Promise.resolve(value).then(function (text) {
|
|
176
|
+
return new Blob([text], {
|
|
177
|
+
type: 'text/plain'
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
_context2.next = 13;
|
|
181
|
+
return navigator.clipboard.write([new ClipboardItem({
|
|
182
|
+
'text/plain': blobPromise
|
|
183
|
+
})]);
|
|
184
|
+
|
|
185
|
+
case 13:
|
|
186
|
+
_context2.next = 21;
|
|
187
|
+
break;
|
|
188
|
+
|
|
189
|
+
case 15:
|
|
190
|
+
_context2.t0 = navigator.clipboard;
|
|
191
|
+
_context2.next = 18;
|
|
192
|
+
return value;
|
|
193
|
+
|
|
194
|
+
case 18:
|
|
195
|
+
_context2.t1 = _context2.sent;
|
|
196
|
+
_context2.next = 21;
|
|
197
|
+
return _context2.t0.writeText.call(_context2.t0, _context2.t1);
|
|
198
|
+
|
|
199
|
+
case 21:
|
|
151
200
|
showAlert({
|
|
152
201
|
message: t('copyReminderContent.success'),
|
|
153
202
|
severity: 'success',
|
|
154
203
|
variant: 'filled'
|
|
155
204
|
});
|
|
156
|
-
_context2.next =
|
|
205
|
+
_context2.next = 28;
|
|
157
206
|
break;
|
|
158
207
|
|
|
159
|
-
case
|
|
160
|
-
_context2.prev =
|
|
161
|
-
_context2.
|
|
208
|
+
case 24:
|
|
209
|
+
_context2.prev = 24;
|
|
210
|
+
_context2.t2 = _context2["catch"](3);
|
|
162
211
|
showAlert({
|
|
163
212
|
message: t('copyReminderContent.error'),
|
|
164
213
|
severity: 'error',
|
|
165
214
|
variant: 'filled'
|
|
166
215
|
});
|
|
167
|
-
log.error("Error in 'copyToClipboard' function when trying to copy to clipboard", _context2.
|
|
216
|
+
log.error("Error in 'copyToClipboard' function when trying to copy to clipboard", _context2.t2);
|
|
168
217
|
|
|
169
|
-
case
|
|
218
|
+
case 28:
|
|
170
219
|
case "end":
|
|
171
220
|
return _context2.stop();
|
|
172
221
|
}
|
|
173
|
-
}, _callee2, null, [[3,
|
|
222
|
+
}, _callee2, null, [[3, 24]]);
|
|
174
223
|
}));
|
|
175
224
|
|
|
176
225
|
return function copyToClipboard(_x2) {
|
|
@@ -20,7 +20,9 @@ export var DumbSharedDriveModal = withLocales(function (_ref) {
|
|
|
20
20
|
onRename = _ref.onRename,
|
|
21
21
|
_ref$showNameField = _ref.showNameField,
|
|
22
22
|
showNameField = _ref$showNameField === void 0 ? true : _ref$showNameField,
|
|
23
|
-
sharingLink = _ref.sharingLink
|
|
23
|
+
sharingLink = _ref.sharingLink,
|
|
24
|
+
autoOpenShareRestriction = _ref.autoOpenShareRestriction,
|
|
25
|
+
showGenerateLinkButton = _ref.showGenerateLinkButton;
|
|
24
26
|
|
|
25
27
|
var _useI18n = useI18n(),
|
|
26
28
|
t = _useI18n.t;
|
|
@@ -48,7 +50,9 @@ export var DumbSharedDriveModal = withLocales(function (_ref) {
|
|
|
48
50
|
cancelLabel: t('SharedDrive.sharedDriveModal.cancel'),
|
|
49
51
|
createLabel: t('SharedDrive.sharedDriveModal.create'),
|
|
50
52
|
shareLabel: t('FederatedFolder.share'),
|
|
51
|
-
saveLabel: t('SharedDrive.sharedDriveModal.save')
|
|
53
|
+
saveLabel: t('SharedDrive.sharedDriveModal.save'),
|
|
54
|
+
autoOpenShareRestriction: autoOpenShareRestriction,
|
|
55
|
+
showGenerateLinkButton: showGenerateLinkButton
|
|
52
56
|
});
|
|
53
57
|
});
|
|
54
58
|
DumbSharedDriveModal.propTypes = {
|
|
@@ -67,6 +71,8 @@ DumbSharedDriveModal.propTypes = {
|
|
|
67
71
|
onShare: PropTypes.func.isRequired,
|
|
68
72
|
onRename: PropTypes.func,
|
|
69
73
|
showNameField: PropTypes.bool,
|
|
70
|
-
sharingLink: PropTypes.string
|
|
74
|
+
sharingLink: PropTypes.string,
|
|
75
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
76
|
+
showGenerateLinkButton: PropTypes.bool
|
|
71
77
|
};
|
|
72
78
|
export default DumbSharedDriveModal;
|
|
@@ -16,7 +16,9 @@ export var SharedDriveEditModal = withLocales(function (_ref) {
|
|
|
16
16
|
recipients = _ref.recipients,
|
|
17
17
|
onShare = _ref.onShare,
|
|
18
18
|
onRevoke = _ref.onRevoke,
|
|
19
|
-
onClose = _ref.onClose
|
|
19
|
+
onClose = _ref.onClose,
|
|
20
|
+
autoOpenShareRestriction = _ref.autoOpenShareRestriction,
|
|
21
|
+
showGenerateLinkButton = _ref.showGenerateLinkButton;
|
|
20
22
|
var client = useClient();
|
|
21
23
|
|
|
22
24
|
var _useI18n = useI18n(),
|
|
@@ -91,9 +93,18 @@ export var SharedDriveEditModal = withLocales(function (_ref) {
|
|
|
91
93
|
onShare: onShare,
|
|
92
94
|
sharedDriveName: name,
|
|
93
95
|
handleSharedDriveNameChange: handleNameChange,
|
|
94
|
-
onRename: onRename
|
|
96
|
+
onRename: onRename,
|
|
97
|
+
autoOpenShareRestriction: autoOpenShareRestriction,
|
|
98
|
+
showGenerateLinkButton: showGenerateLinkButton
|
|
95
99
|
});
|
|
96
100
|
});
|
|
97
101
|
SharedDriveEditModal.propTypes = {
|
|
98
|
-
|
|
102
|
+
document: PropTypes.object,
|
|
103
|
+
sharing: PropTypes.object,
|
|
104
|
+
recipients: PropTypes.array,
|
|
105
|
+
onShare: PropTypes.func.isRequired,
|
|
106
|
+
onRevoke: PropTypes.func.isRequired,
|
|
107
|
+
onClose: PropTypes.func.isRequired,
|
|
108
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
109
|
+
showGenerateLinkButton: PropTypes.bool
|
|
99
110
|
};
|
|
@@ -36,7 +36,9 @@ export var DumbBatchSharedFolderModal = withLocales(function (_ref) {
|
|
|
36
36
|
saveLabel = _ref.saveLabel,
|
|
37
37
|
sharingDesc = _ref.sharingDesc,
|
|
38
38
|
_ref$showShareByEmail = _ref.showShareByEmail,
|
|
39
|
-
showShareByEmail = _ref$showShareByEmail === void 0 ? true : _ref$showShareByEmail
|
|
39
|
+
showShareByEmail = _ref$showShareByEmail === void 0 ? true : _ref$showShareByEmail,
|
|
40
|
+
autoOpenShareRestriction = _ref.autoOpenShareRestriction,
|
|
41
|
+
showGenerateLinkButton = _ref.showGenerateLinkButton;
|
|
40
42
|
var hasRecipients = Boolean(recipients === null || recipients === void 0 ? void 0 : recipients.length); // Determine action buttons based on modal mode
|
|
41
43
|
|
|
42
44
|
var actionButtons = function () {
|
|
@@ -56,7 +58,9 @@ export var DumbBatchSharedFolderModal = withLocales(function (_ref) {
|
|
|
56
58
|
return /*#__PURE__*/React.createElement(ShareByLink, {
|
|
57
59
|
link: sharingLink,
|
|
58
60
|
document: document,
|
|
59
|
-
documentType: "Files"
|
|
61
|
+
documentType: "Files",
|
|
62
|
+
showGenerateLinkButton: showGenerateLinkButton,
|
|
63
|
+
autoOpenShareRestriction: autoOpenShareRestriction
|
|
60
64
|
});
|
|
61
65
|
}
|
|
62
66
|
|
|
@@ -64,7 +68,9 @@ export var DumbBatchSharedFolderModal = withLocales(function (_ref) {
|
|
|
64
68
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ShareByLink, {
|
|
65
69
|
link: sharingLink,
|
|
66
70
|
document: document,
|
|
67
|
-
documentType: "Files"
|
|
71
|
+
documentType: "Files",
|
|
72
|
+
showGenerateLinkButton: showGenerateLinkButton,
|
|
73
|
+
autoOpenShareRestriction: autoOpenShareRestriction
|
|
68
74
|
}), /*#__PURE__*/React.createElement(Button, {
|
|
69
75
|
variant: "primary",
|
|
70
76
|
label: shareLabel,
|
|
@@ -165,7 +171,9 @@ DumbBatchSharedFolderModal.propTypes = {
|
|
|
165
171
|
shareLabel: PropTypes.string,
|
|
166
172
|
saveLabel: PropTypes.string,
|
|
167
173
|
sharingDesc: PropTypes.string,
|
|
168
|
-
showShareByEmail: PropTypes.bool
|
|
174
|
+
showShareByEmail: PropTypes.bool,
|
|
175
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
176
|
+
showGenerateLinkButton: PropTypes.bool
|
|
169
177
|
};
|
|
170
178
|
DumbBatchSharedFolderModal.defaultProps = {
|
|
171
179
|
sharingDesc: ''
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cozy-sharing",
|
|
3
|
-
"version": "30.
|
|
3
|
+
"version": "30.2.1",
|
|
4
4
|
"description": "Provides sharing login for React applications.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"author": "Cozy",
|
|
@@ -84,5 +84,5 @@
|
|
|
84
84
|
"sideEffects": [
|
|
85
85
|
"*.css"
|
|
86
86
|
],
|
|
87
|
-
"gitHead": "
|
|
87
|
+
"gitHead": "4658ed10da57999de9a4cbef4887582ac10019db"
|
|
88
88
|
}
|
|
@@ -20,7 +20,9 @@ export const DumbFederatedFolderModal = withLocales(
|
|
|
20
20
|
onClose,
|
|
21
21
|
onShare,
|
|
22
22
|
sharingLink,
|
|
23
|
-
showShareByEmail
|
|
23
|
+
showShareByEmail,
|
|
24
|
+
autoOpenShareRestriction,
|
|
25
|
+
showGenerateLinkButton
|
|
24
26
|
}) => {
|
|
25
27
|
const { t } = useI18n()
|
|
26
28
|
return (
|
|
@@ -42,6 +44,8 @@ export const DumbFederatedFolderModal = withLocales(
|
|
|
42
44
|
addButtonLabel={t('FederatedFolder.add')}
|
|
43
45
|
shareLabel={t('FederatedFolder.share')}
|
|
44
46
|
showShareByEmail={showShareByEmail}
|
|
47
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
48
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
45
49
|
/>
|
|
46
50
|
)
|
|
47
51
|
}
|
|
@@ -60,7 +64,9 @@ DumbFederatedFolderModal.propTypes = {
|
|
|
60
64
|
onClose: PropTypes.func.isRequired,
|
|
61
65
|
onShare: PropTypes.func.isRequired,
|
|
62
66
|
sharingLink: PropTypes.string,
|
|
63
|
-
showShareByEmail: PropTypes.bool
|
|
67
|
+
showShareByEmail: PropTypes.bool,
|
|
68
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
69
|
+
showGenerateLinkButton: PropTypes.bool
|
|
64
70
|
}
|
|
65
71
|
|
|
66
72
|
export default DumbFederatedFolderModal
|
|
@@ -17,7 +17,12 @@ import {
|
|
|
17
17
|
} from '../SharedDrive/helpers'
|
|
18
18
|
|
|
19
19
|
export const FederatedFolderModal = withLocales(
|
|
20
|
-
({
|
|
20
|
+
({
|
|
21
|
+
onClose,
|
|
22
|
+
document: existingDocument,
|
|
23
|
+
autoOpenShareRestriction,
|
|
24
|
+
showGenerateLinkButton
|
|
25
|
+
}) => {
|
|
21
26
|
const client = useClient()
|
|
22
27
|
const { t } = useI18n()
|
|
23
28
|
const {
|
|
@@ -159,6 +164,8 @@ export const FederatedFolderModal = withLocales(
|
|
|
159
164
|
onShare={onShare}
|
|
160
165
|
sharingLink={sharingLink}
|
|
161
166
|
showShareByEmail={!isSharedDrive}
|
|
167
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
168
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
162
169
|
/>
|
|
163
170
|
)
|
|
164
171
|
}
|
|
@@ -166,7 +173,9 @@ export const FederatedFolderModal = withLocales(
|
|
|
166
173
|
|
|
167
174
|
FederatedFolderModal.propTypes = {
|
|
168
175
|
onClose: PropTypes.func.isRequired,
|
|
169
|
-
document: PropTypes.object.isRequired
|
|
176
|
+
document: PropTypes.object.isRequired,
|
|
177
|
+
autoOpenShareRestriction: PropTypes.bool,
|
|
178
|
+
showGenerateLinkButton: PropTypes.bool
|
|
170
179
|
}
|
|
171
180
|
|
|
172
181
|
export default FederatedFolderModal
|
|
@@ -18,7 +18,13 @@ import {
|
|
|
18
18
|
} from './ShareRestrictionModal/helpers'
|
|
19
19
|
import { useSharingContext } from '../hooks/useSharingContext'
|
|
20
20
|
|
|
21
|
-
const ShareByLink = ({
|
|
21
|
+
const ShareByLink = ({
|
|
22
|
+
link,
|
|
23
|
+
document,
|
|
24
|
+
documentType,
|
|
25
|
+
showGenerateLinkButton = false,
|
|
26
|
+
autoOpenShareRestriction = false
|
|
27
|
+
}) => {
|
|
22
28
|
const { t } = useI18n()
|
|
23
29
|
const { isMobile } = useBreakpoints()
|
|
24
30
|
const { showAlert } = useAlert()
|
|
@@ -27,8 +33,9 @@ const ShareByLink = ({ link, document, documentType }) => {
|
|
|
27
33
|
const [isGenerating, setIsGenerating] = useState(false)
|
|
28
34
|
|
|
29
35
|
const canShare = typeof navigator?.share === 'function'
|
|
30
|
-
const
|
|
31
|
-
const
|
|
36
|
+
const showGenerateButton = showGenerateLinkButton && !link
|
|
37
|
+
const showCopyAndSendButtons = !showGenerateButton && isMobile && canShare
|
|
38
|
+
const showOnlyCopyButton = !showGenerateButton && (!isMobile || !canShare)
|
|
32
39
|
const isFederated = flag('drive.federated-shared-folder.enabled')
|
|
33
40
|
|
|
34
41
|
const [isEditDialogOpen, toggleEditDialogOpen] = useReducer(
|
|
@@ -36,6 +43,14 @@ const ShareByLink = ({ link, document, documentType }) => {
|
|
|
36
43
|
false
|
|
37
44
|
)
|
|
38
45
|
|
|
46
|
+
const showGenericError = () => {
|
|
47
|
+
showAlert({
|
|
48
|
+
message: t(`${documentType}.share.error.generic`),
|
|
49
|
+
severity: 'error',
|
|
50
|
+
variant: 'filled'
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
|
|
39
54
|
const handleGenerateLink = async () => {
|
|
40
55
|
setIsGenerating(true)
|
|
41
56
|
try {
|
|
@@ -60,18 +75,40 @@ const ShareByLink = ({ link, document, documentType }) => {
|
|
|
60
75
|
}
|
|
61
76
|
|
|
62
77
|
const generateLinkAndCopyLinkToClipboard = async () => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
78
|
+
if (link) {
|
|
79
|
+
await copyToClipboard(link, { t, showAlert })
|
|
80
|
+
return
|
|
66
81
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
82
|
+
// Safari: the clipboard API must be invoked synchronously within the
|
|
83
|
+
// click handler, so we pass the pending link to `copyToClipboard`.
|
|
84
|
+
// The resolved URL is captured here so we can branch on success after
|
|
85
|
+
// the copy has completed, without re-awaiting the promise.
|
|
86
|
+
let generatedLink = null
|
|
87
|
+
await copyToClipboard(
|
|
88
|
+
handleGenerateLink().then(generated => {
|
|
89
|
+
generatedLink = generated
|
|
90
|
+
if (!generated) throw new Error('link-generation-failed')
|
|
91
|
+
return generated
|
|
92
|
+
}),
|
|
93
|
+
{ t, showAlert }
|
|
94
|
+
)
|
|
95
|
+
if (!generatedLink) {
|
|
96
|
+
showGenericError()
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
if (autoOpenShareRestriction) {
|
|
100
|
+
toggleEditDialogOpen()
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const generateLinkSilently = async () => {
|
|
105
|
+
const generated = await handleGenerateLink()
|
|
106
|
+
if (!generated) {
|
|
107
|
+
showGenericError()
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
if (autoOpenShareRestriction) {
|
|
111
|
+
toggleEditDialogOpen()
|
|
75
112
|
}
|
|
76
113
|
}
|
|
77
114
|
|
|
@@ -81,11 +118,7 @@ const ShareByLink = ({ link, document, documentType }) => {
|
|
|
81
118
|
linkToShare = await handleGenerateLink()
|
|
82
119
|
}
|
|
83
120
|
if (!linkToShare) {
|
|
84
|
-
|
|
85
|
-
message: t(`${documentType}.share.error.generic`),
|
|
86
|
-
severity: 'error',
|
|
87
|
-
variant: 'filled'
|
|
88
|
-
})
|
|
121
|
+
showGenericError()
|
|
89
122
|
return
|
|
90
123
|
}
|
|
91
124
|
|
|
@@ -100,11 +133,7 @@ const ShareByLink = ({ link, document, documentType }) => {
|
|
|
100
133
|
} catch (error) {
|
|
101
134
|
// Don't show error when user cancels the share dialog
|
|
102
135
|
if (error.name !== 'AbortError') {
|
|
103
|
-
|
|
104
|
-
message: t(`${documentType}.share.error.generic`),
|
|
105
|
-
severity: 'error',
|
|
106
|
-
variant: 'filled'
|
|
107
|
-
})
|
|
136
|
+
showGenericError()
|
|
108
137
|
}
|
|
109
138
|
}
|
|
110
139
|
}
|
|
@@ -144,6 +173,16 @@ const ShareByLink = ({ link, document, documentType }) => {
|
|
|
144
173
|
busy={isGenerating}
|
|
145
174
|
/>
|
|
146
175
|
)}
|
|
176
|
+
{showGenerateButton && (
|
|
177
|
+
<Button
|
|
178
|
+
label={t(`${documentType}.share.shareByLink.create`)}
|
|
179
|
+
variant="secondary"
|
|
180
|
+
size="medium"
|
|
181
|
+
startIcon={<Icon icon={LinkIcon} />}
|
|
182
|
+
onClick={generateLinkSilently}
|
|
183
|
+
busy={isGenerating}
|
|
184
|
+
/>
|
|
185
|
+
)}
|
|
147
186
|
{isEditDialogOpen && (
|
|
148
187
|
<ShareRestrictionModal file={document} onClose={toggleEditDialogOpen} />
|
|
149
188
|
)}
|
|
@@ -154,7 +193,9 @@ const ShareByLink = ({ link, document, documentType }) => {
|
|
|
154
193
|
ShareByLink.propTypes = {
|
|
155
194
|
link: PropTypes.string,
|
|
156
195
|
document: PropTypes.object.isRequired,
|
|
157
|
-
documentType: PropTypes.string.isRequired
|
|
196
|
+
documentType: PropTypes.string.isRequired,
|
|
197
|
+
showGenerateLinkButton: PropTypes.bool,
|
|
198
|
+
autoOpenShareRestriction: PropTypes.bool
|
|
158
199
|
}
|
|
159
200
|
|
|
160
201
|
export default ShareByLink
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import cx from 'classnames'
|
|
2
|
-
import React from 'react'
|
|
2
|
+
import React, { useMemo } from 'react'
|
|
3
3
|
|
|
4
4
|
import Typography from 'cozy-ui/transpiled/react/Typography'
|
|
5
5
|
import useBreakpoints from 'cozy-ui/transpiled/react/providers/Breakpoints'
|
|
@@ -111,17 +111,32 @@ const SharingTitleFunction = ({ documentType, document }) =>
|
|
|
111
111
|
*/
|
|
112
112
|
const ShareDialogCozyToCozy = ({
|
|
113
113
|
showShareByLink,
|
|
114
|
+
showGenerateLinkButton,
|
|
115
|
+
autoOpenShareRestriction,
|
|
114
116
|
documentType,
|
|
115
117
|
document,
|
|
116
118
|
...props
|
|
117
119
|
}) => {
|
|
120
|
+
const dialogActionsOnShare = useMemo(() => {
|
|
121
|
+
if (!showShareByLink) return null
|
|
122
|
+
const BoundShareByLink = dialogActionProps => (
|
|
123
|
+
<DumbShareByLink
|
|
124
|
+
{...dialogActionProps}
|
|
125
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
126
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
127
|
+
/>
|
|
128
|
+
)
|
|
129
|
+
BoundShareByLink.displayName = 'BoundShareByLink'
|
|
130
|
+
return BoundShareByLink
|
|
131
|
+
}, [showShareByLink, showGenerateLinkButton, autoOpenShareRestriction])
|
|
132
|
+
|
|
118
133
|
return (
|
|
119
134
|
<ShareDialogTwoStepsConfirmationContainer
|
|
120
135
|
{...props}
|
|
121
136
|
documentType={documentType}
|
|
122
137
|
document={document}
|
|
123
138
|
dialogContentOnShare={SharingContent}
|
|
124
|
-
dialogActionsOnShare={
|
|
139
|
+
dialogActionsOnShare={dialogActionsOnShare}
|
|
125
140
|
dialogTitleOnShare={SharingTitleFunction({ documentType, document })}
|
|
126
141
|
disableGutters
|
|
127
142
|
/>
|
|
@@ -19,7 +19,9 @@ const ShareDialogOnlyByLink = ({
|
|
|
19
19
|
documentType,
|
|
20
20
|
link,
|
|
21
21
|
onClose,
|
|
22
|
-
permissions
|
|
22
|
+
permissions,
|
|
23
|
+
showGenerateLinkButton,
|
|
24
|
+
autoOpenShareRestriction
|
|
23
25
|
}) => {
|
|
24
26
|
const { t } = useI18n()
|
|
25
27
|
const { isMobile } = useBreakpoints()
|
|
@@ -62,6 +64,8 @@ const ShareDialogOnlyByLink = ({
|
|
|
62
64
|
link={link}
|
|
63
65
|
document={document}
|
|
64
66
|
documentType={documentType}
|
|
67
|
+
showGenerateLinkButton={showGenerateLinkButton}
|
|
68
|
+
autoOpenShareRestriction={autoOpenShareRestriction}
|
|
65
69
|
/>
|
|
66
70
|
</div>
|
|
67
71
|
</>
|