mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-07 16:37:02 +03:00
Attach Nextcloud files to mail #569
This commit is contained in:
parent
2ede940aa7
commit
30c2371b9a
5 changed files with 119 additions and 23 deletions
|
|
@ -4,7 +4,7 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
{
|
{
|
||||||
const
|
const
|
||||||
NAME = 'Nextcloud',
|
NAME = 'Nextcloud',
|
||||||
VERSION = '2.4',
|
VERSION = '2.6',
|
||||||
RELEASE = '2022-10-19',
|
RELEASE = '2022-10-19',
|
||||||
CATEGORY = 'Integrations',
|
CATEGORY = 'Integrations',
|
||||||
DESCRIPTION = 'Integrate with Nextcloud v20+',
|
DESCRIPTION = 'Integrate with Nextcloud v20+',
|
||||||
|
|
@ -18,10 +18,15 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
$this->addHook('main.fabrica', 'MainFabrica');
|
$this->addHook('main.fabrica', 'MainFabrica');
|
||||||
$this->addHook('filter.app-data', 'FilterAppData');
|
$this->addHook('filter.app-data', 'FilterAppData');
|
||||||
|
|
||||||
$this->addJs('js/message.js');
|
|
||||||
$this->addJs('js/webdav.js');
|
$this->addJs('js/webdav.js');
|
||||||
|
|
||||||
|
$this->addJs('js/message.js');
|
||||||
$this->addHook('json.attachments', 'DoAttachmentsActions');
|
$this->addHook('json.attachments', 'DoAttachmentsActions');
|
||||||
$this->addJsonHook('NextcloudSaveMsg', 'NextcloudSaveMsg');
|
$this->addJsonHook('NextcloudSaveMsg', 'NextcloudSaveMsg');
|
||||||
|
$this->addJsonHook('NextcloudAttachFile', 'NextcloudAttachFile');
|
||||||
|
|
||||||
|
$this->addJs('js/composer.js');
|
||||||
|
|
||||||
$this->addTemplate('templates/PopupsNextcloudFiles.html');
|
$this->addTemplate('templates/PopupsNextcloudFiles.html');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -58,6 +63,30 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
public function NextcloudAttachFile() : array
|
||||||
|
{
|
||||||
|
$aResult = [
|
||||||
|
'success' => false,
|
||||||
|
'tempName' => ''
|
||||||
|
];
|
||||||
|
$sFile = $this->jsonParam('file', '');
|
||||||
|
$oFiles = \OCP\Files::getStorage('files');
|
||||||
|
if ($oFiles && $oFiles->is_file($sFile) && $fp = $oFiles->fopen($sFile, 'rb')) {
|
||||||
|
$oActions = \RainLoop\Api::Actions();
|
||||||
|
$oAccount = $oActions->getAccountFromToken();
|
||||||
|
if ($oAccount) {
|
||||||
|
$sSavedName = 'nextcloud-file-' . \sha1($sFile . \microtime());
|
||||||
|
if (!$oActions->FilesProvider()->PutFile($oAccount, $sSavedName, $fp)) {
|
||||||
|
$aResult['error'] = 'failed';
|
||||||
|
} else {
|
||||||
|
$aResult['tempName'] = $sSavedName;
|
||||||
|
$aResult['success'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->jsonResponse(__FUNCTION__, $aResult);
|
||||||
|
}
|
||||||
|
|
||||||
public function NextcloudSaveMsg() : array
|
public function NextcloudSaveMsg() : array
|
||||||
{
|
{
|
||||||
$sSaveFolder = \ltrim($this->jsonParam('folder', ''), '/');
|
$sSaveFolder = \ltrim($this->jsonParam('folder', ''), '/');
|
||||||
|
|
@ -106,7 +135,7 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
$oFiles = \OCP\Files::getStorage('files');
|
$oFiles = \OCP\Files::getStorage('files');
|
||||||
if ($oFiles && \method_exists($oFiles, 'file_put_contents')) {
|
if ($oFiles && \method_exists($oFiles, 'file_put_contents')) {
|
||||||
$sSaveFolder = \ltrim($this->jsonParam('NcFolder', ''), '/');
|
$sSaveFolder = \ltrim($this->jsonParam('NcFolder', ''), '/');
|
||||||
$sSaveFolder = $sSaveFolder ?: $this->Config()->Get('plugin', 'save_folder', '') ?: 'Attachments';
|
$sSaveFolder = $sSaveFolder ?: 'Attachments';
|
||||||
$oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder);
|
$oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder);
|
||||||
$data->result = true;
|
$data->result = true;
|
||||||
foreach ($data->items as $aItem) {
|
foreach ($data->items as $aItem) {
|
||||||
|
|
@ -192,8 +221,6 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||||
protected function configMapping() : array
|
protected function configMapping() : array
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
\RainLoop\Plugins\Property::NewInstance('save_folder')->SetLabel('Save Folder')
|
|
||||||
->SetDefaultValue('Attachments'),
|
|
||||||
\RainLoop\Plugins\Property::NewInstance('suggestions')->SetLabel('Suggestions')
|
\RainLoop\Plugins\Property::NewInstance('suggestions')->SetLabel('Suggestions')
|
||||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||||
->SetDefaultValue(true)
|
->SetDefaultValue(true)
|
||||||
|
|
|
||||||
51
plugins/nextcloud/js/composer.js
Normal file
51
plugins/nextcloud/js/composer.js
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
(rl => {
|
||||||
|
// if (rl.settings.get('Nextcloud'))
|
||||||
|
|
||||||
|
addEventListener('rl-view-model.create', e => {
|
||||||
|
if ('PopupsCompose' === e.detail.viewModelTemplateID) {
|
||||||
|
let view = e.detail;
|
||||||
|
view.nextcloudAttach = () => {
|
||||||
|
rl.ncFiles.selectFiles().then(files => {
|
||||||
|
files.forEach(file => {
|
||||||
|
let id = Jua?.randomId() || file.etag,
|
||||||
|
attachment = view.addAttachmentHelper(
|
||||||
|
id.etag,
|
||||||
|
file.name.replace(/^.*\/([^/]+)$/, '$1'),
|
||||||
|
file.size
|
||||||
|
);
|
||||||
|
attachment
|
||||||
|
.waiting(false)
|
||||||
|
.uploading(true)
|
||||||
|
.complete(false);
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let template = document.getElementById('PopupsCompose');
|
||||||
|
const uploadBtn = template.content.querySelector('#composeUploadButton');
|
||||||
|
if (uploadBtn) {
|
||||||
|
uploadBtn.after(Element.fromHTML('<a class="btn fontastic"'
|
||||||
|
+ ' data-bind="click: nextcloudAttach" data-i18n="[title]NEXTCLOUD/ATTACH_FILES">◦◯◦</a>'));
|
||||||
|
}
|
||||||
|
|
||||||
|
})(window.rl);
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
(rl => {
|
(rl => {
|
||||||
|
// if (rl.settings.get('Nextcloud'))
|
||||||
|
|
||||||
addEventListener('rl-view-model.create', e => {
|
addEventListener('rl-view-model.create', e => {
|
||||||
if ('MailMessageView' === e.detail.viewModelTemplateID) {
|
if ('MailMessageView' === e.detail.viewModelTemplateID) {
|
||||||
|
|
|
||||||
|
|
@ -109,28 +109,26 @@
|
||||||
{
|
{
|
||||||
if (items.length) {
|
if (items.length) {
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
if (item.isFile) {
|
if (!item.isFile) {
|
||||||
if (view.files()) {
|
|
||||||
// TODO show files
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let li = document.createElement('li'),
|
let li = document.createElement('li'),
|
||||||
details = document.createElement('details'),
|
details = document.createElement('details'),
|
||||||
summary = document.createElement('summary'),
|
summary = document.createElement('summary'),
|
||||||
ul = document.createElement('ul'),
|
ul = document.createElement('ul');
|
||||||
btn = document.createElement('button');
|
|
||||||
btn.item_name = item.name;
|
|
||||||
details.addEventListener('toggle', () => {
|
details.addEventListener('toggle', () => {
|
||||||
if (!ul.children.length) {
|
ul.children.length
|
||||||
fetchFiles(propertyRequestBody, item.name).then(items => buildTree(view, ul, items, item.name));
|
|| fetchFiles(propertyRequestBody, item.name).then(items => buildTree(view, ul, items, item.name));
|
||||||
}
|
|
||||||
});
|
});
|
||||||
summary.textContent = '📁 ' + item.name.replace(/^.*\/([^/]+)$/, '$1');
|
summary.textContent = item.name.replace(/^.*\/([^/]+)$/, '$1');
|
||||||
btn.name = 'select';
|
summary.dataset.icon = '📁';
|
||||||
btn.textContent = 'select';
|
if (!view.files()) {
|
||||||
btn.className = 'button-vue';
|
let btn = document.createElement('button');
|
||||||
btn.style.marginLeft = '1em';
|
btn.item_name = item.name;
|
||||||
summary.append(btn);
|
btn.name = 'select';
|
||||||
|
btn.textContent = 'select';
|
||||||
|
btn.className = 'button-vue';
|
||||||
|
btn.style.marginLeft = '1em';
|
||||||
|
summary.append(btn);
|
||||||
|
}
|
||||||
details.append(summary);
|
details.append(summary);
|
||||||
details.append(ul);
|
details.append(ul);
|
||||||
// a.append('- ' + item.name.replace(/^\/+/, ''));
|
// a.append('- ' + item.name.replace(/^\/+/, ''));
|
||||||
|
|
@ -138,6 +136,24 @@
|
||||||
parent.append(li);
|
parent.append(li);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (view.files()) {
|
||||||
|
items.forEach(item => {
|
||||||
|
if (item.isFile) {
|
||||||
|
// TODO show files
|
||||||
|
let li = document.createElement('li'),
|
||||||
|
btn = document.createElement('button');
|
||||||
|
btn.item = item;
|
||||||
|
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);
|
||||||
|
parent.append(li);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!view.files()) {
|
if (!view.files()) {
|
||||||
let li = document.createElement('li'),
|
let li = document.createElement('li'),
|
||||||
|
|
@ -168,7 +184,7 @@
|
||||||
let el = event.target;
|
let el = event.target;
|
||||||
if (el.matches('button')) {
|
if (el.matches('button')) {
|
||||||
if ('select' == el.name) {
|
if ('select' == el.name) {
|
||||||
this.select = el.item_name;
|
this.select = this.files() ? [el.item] : el.item_name;
|
||||||
this.close();
|
this.close();
|
||||||
} else if ('create' == el.name) {
|
} else if ('create' == el.name) {
|
||||||
let name = el.input.value.replace(/[|\\?*<":>+[]\/&\s]/g, '');
|
let name = el.input.value.replace(/[|\\?*<":>+[]\/&\s]/g, '');
|
||||||
|
|
|
||||||
|
|
@ -3,3 +3,4 @@ SAVE_ATTACHMENTS = "Save in Nextcloud"
|
||||||
SAVE_EML = "Save as .eml in Nextcloud"
|
SAVE_EML = "Save as .eml in Nextcloud"
|
||||||
SELECT_FOLDER = "Select folder"
|
SELECT_FOLDER = "Select folder"
|
||||||
SELECT_FILES = "Select file(s)"
|
SELECT_FILES = "Select file(s)"
|
||||||
|
ATTACH_FILES = "Attach Nextcloud files"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue