diff --git a/plugins/nextcloud/index.php b/plugins/nextcloud/index.php
index cdf60d4ad..3aad81154 100644
--- a/plugins/nextcloud/index.php
+++ b/plugins/nextcloud/index.php
@@ -160,7 +160,7 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
{
if (!$bAdmin && \is_array($aResult)) {
$sUID = \OC::$server->getUserSession()->getUser()->getUID();
- $sWebDAV = \OC::$server->getURLGenerator()->linkTo('', 'remote.php') . '/dav/';
+ $sWebDAV = \OC::$server->getURLGenerator()->linkTo('', 'remote.php') . '/dav';
// $sWebDAV = \OCP\Util::linkToRemote('dav');
$aResult['Nextcloud'] = [
'UID' => $sUID,
diff --git a/plugins/nextcloud/js/composer.js b/plugins/nextcloud/js/composer.js
index 45068cac5..b53611dc2 100644
--- a/plugins/nextcloud/js/composer.js
+++ b/plugins/nextcloud/js/composer.js
@@ -7,33 +7,30 @@
view.nextcloudAttach = () => {
rl.nextcloud.selectFiles().then(files => {
files && files.forEach(file => {
- let attachment = view.addAttachmentHelper(
- Jua?.randomId(),
- file.name.replace(/^.*\/([^/]+)$/, '$1'),
- file.size
- );
- attachment
- .waiting(false)
- .uploading(true)
- .complete(false);
+ if (file.name) {
+ let attachment = view.addAttachmentHelper(
+ Jua?.randomId(),
+ file.name.replace(/^.*\/([^/]+)$/, '$1'),
+ file.size
+ );
- rl.pluginRemoteRequest(
- (iError, data) => {
- attachment
- .uploading(false)
- .complete(true);
- if (iError) {
- attachment.error(data?.Result?.error || 'failed');
- } else {
- attachment.tempName(data.Result.tempName);
+ rl.pluginRemoteRequest(
+ (iError, data) => {
+ attachment.uploading(false).complete(true);
+ if (iError) {
+ attachment.error(data?.Result?.error || 'failed');
+ } else {
+ attachment.tempName(data.Result.tempName);
+ }
+ },
+ 'NextcloudAttachFile',
+ {
+ 'file': file.name
}
- },
- 'NextcloudAttachFile',
- {
- 'file': file.name
- }
- );
-
+ );
+ } else if (file.url) {
+ view.oEditor.editor.squire.makeLink(file.url);
+ }
});
});
};
diff --git a/plugins/nextcloud/js/webdav.js b/plugins/nextcloud/js/webdav.js
index 684ce1cba..f9c107b26 100644
--- a/plugins/nextcloud/js/webdav.js
+++ b/plugins/nextcloud/js/webdav.js
@@ -1,36 +1,77 @@
(rl => {
const
- namespace = 'DAV:',
+ nsDAV = 'DAV:',
+ nsNC = 'http://nextcloud.org/ns',
+ nsOC = 'http://owncloud.org/ns',
+ nsOCS = 'http://open-collaboration-services.org/ns',
nsCalDAV = 'urn:ietf:params:xml:ns:caldav',
+ OC = () => parent.OC,
+
+ // Nextcloud 19 deprecated generateUrl, but screw `import { generateUrl } from "@nextcloud/router"`
+ generateUrl = path => OC().webroot + (OC().config.modRewriteWorking ? '' : '/index.php') + path,
+ generateRemoteUrl = path => location.protocol + '//' + location.host + generateUrl(path),
+
+// shareTypes = {0 = user, 1 = group, 3 = public link}
+
propfindFiles = `
-
-
-
+
+
+
-
-
-`,
+
+
+
+
+
+
+
+
+
+
+`,
+/*
+
+
+ video/mp4
+ RGDNVW
+ 3963036
+ 19
+ []
+
+ 3
+
+
+ HTTP/1.1 200 OK
+
+
+
+
+
+ HTTP/1.1 404 Not Found
+
+*/
propfindCal = `
-
-
-
-
-
-
-`,
+
+
+
+
+
+
+`,
xmlParser = new DOMParser(),
pathRegex = /.*\/remote.php\/dav\/[^/]+\/[^/]+/g,
- getDavElementsByTagName = (parent, localName) => parent.getElementsByTagNameNS(namespace, localName),
+ getElementsByTagName = (parent, namespace, localName) => parent.getElementsByTagNameNS(namespace, localName),
+ getDavElementsByTagName = (parent, localName) => getElementsByTagName(parent, nsDAV, localName),
getDavElementByTagName = (parent, localName) => getDavElementsByTagName(parent, localName)?.item(0),
getElementByTagName = (parent, localName) => +parent.getElementsByTagName(localName)?.item(0),
davFetch = (mode, path, options) => {
- if (!parent.OC.requestToken) {
+ if (!OC().requestToken) {
return Promise.reject(new Error('OC.requestToken missing'));
}
let cfg = rl.settings.get('Nextcloud');
@@ -41,7 +82,7 @@ const
credentials: 'same-origin',
headers: {}
}, options);
- options.headers.requesttoken = parent.OC.requestToken;
+ options.headers.requesttoken = OC().requestToken;
// cfg.UID = document.head.dataset.user
return fetch(cfg.WebDAV + '/' + mode + '/' + cfg.UID + path, options);
},
@@ -51,7 +92,7 @@ const
createDirectory = path => davFetchFiles(path, { method: 'MKCOL' }),
fetchFiles = path => {
- if (!parent.OC.requestToken) {
+ if (!OC().requestToken) {
return Promise.reject(new Error('OC.requestToken missing'));
}
return davFetchFiles(path, {
@@ -85,6 +126,7 @@ const
}
} else {
elem.isFile = true;
+ elem.id = e.getElementsByTagNameNS(nsOC, 'fileid')?.item(0)?.textContent;
elem.size = getDavElementByTagName(e, 'getcontentlength')?.textContent
|| getElementByTagName(e, 'oc:size')?.textContent;
}
@@ -110,12 +152,12 @@ const
summary.dataset.icon = '📁';
if (!view.files()) {
let btn = document.createElement('button');
- btn.item_name = item.name;
btn.name = 'select';
btn.textContent = 'select';
btn.className = 'button-vue';
btn.style.marginLeft = '1em';
summary.append(btn);
+ summary.item_name = item.name;
}
details.append(summary);
details.append(ul);
@@ -127,17 +169,33 @@ const
if (view.files()) {
items.forEach(item => {
if (item.isFile) {
- // TODO show files
let li = document.createElement('li'),
btn = document.createElement('button');
- btn.item = item;
+
+ li.item = item;
+ li.textContent = item.name.replace(/^.*\/([^/]+)$/, '$1');
+ li.dataset.icon = '🗎';
+
btn.name = 'select';
btn.textContent = 'select';
btn.className = 'button-vue';
btn.style.marginLeft = '1em';
- li.textContent = item.name.replace(/^.*\/([^/]+)$/, '$1');
- li.dataset.icon = '🗎';
li.append(btn);
+
+ btn = document.createElement('button');
+ btn.name = 'share-internal';
+ btn.textContent = '🔗 internal';
+ btn.className = 'button-vue';
+ btn.style.marginLeft = '1em';
+ li.append(btn);
+/*
+ btn = document.createElement('button');
+ btn.name = 'share-public';
+ btn.textContent = '🔗 public';
+ btn.className = 'button-vue';
+ btn.style.marginLeft = '1em';
+ li.append(btn);
+*/
parent.append(li);
}
});
@@ -150,8 +208,8 @@ const
btn.name = 'create';
btn.textContent = 'create & select';
btn.className = 'button-vue';
- btn.item_name = path;
btn.input = input;
+ li.item_path = path;
li.append(input);
li.append(btn);
parent.append(li);
@@ -171,13 +229,50 @@ class NextcloudFilesPopupView extends rl.pluginPopupView {
this.tree.addEventListener('click', event => {
let el = event.target;
if (el.matches('button')) {
+ let parent = el.parentNode;
if ('select' == el.name) {
- this.select = this.files() ? [el.item] : el.item_name;
+ this.select = this.files() ? [parent.item] : parent.item_name;
this.close();
+ } else if ('share-internal' == el.name) {
+ this.select = [{url:generateRemoteUrl(`/f/${parent.item.id}`)}];
+ this.close();
+ } else if ('share-public' == el.name) {
+/*
+ if (3 == share-type) {
+ GET generateUrl(`/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json&path=${encodeURIComponent(parent.item.name)}&reshares=true`);
+ } else {
+ POST generateUrl(`/ocs/v2.php/apps/files_sharing/api/v1/shares`)
+ > {"path":"/Nextcloud intro.mp4","shareType":3,"attributes":"[]"}
+ < {"ocs":{"meta":{"status":"ok","statuscode":200,"message":"OK"},
+ "data":{
+ "id":"2",
+ "share_type":3,
+ "permissions":17,
+ "token":"7GK9mL9LCTseSgK",
+ "path":"\/Nextcloud intro.mp4",
+ "item_type":"file",
+ "mimetype":"video\/mp4",
+ "storage":1,
+ "item_source":20,
+ "file_source":20,
+ "file_parent":2,
+ "file_target":"\/Nextcloud intro.mp4",
+ "password":null,
+ "url":"https:\/\/example.com\/index.php\/s\/7GK9mL9LCTseSgK",
+ "mail_send":1,
+ "hide_download":0,
+ "attributes":null
+ }}}
+ GET /index.php/s/7GK9mL9LCTseSgK
+ PUT /ocs/v2.php/apps/files_sharing/api/v1/shares/2
+ > {"expireDate":"\"2022-11-29T23:00:00.000Z\""}
+ > {"password":"ABC09"}
+ }
+*/
} else if ('create' == el.name) {
let name = el.input.value.replace(/[|\\?*<":>+[]\/&\s]/g, '');
if (name.length) {
- name = el.item_name + '/' + name;
+ name = parent.item_path + '/' + name;
createDirectory(name).then(response => {
if (response.status == 201) {
this.select = name;