Activate simple Nextcloud directory selector popup #96

This commit is contained in:
the-djmaze 2022-10-19 10:15:03 +02:00
parent 5abc6a3034
commit f53dab1baa
5 changed files with 131 additions and 66 deletions

View file

@ -19,9 +19,9 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
$this->addHook('filter.app-data', 'FilterAppData'); $this->addHook('filter.app-data', 'FilterAppData');
$this->addJs('js/message.js'); $this->addJs('js/message.js');
$this->addJs('js/webdav.js');
$this->addHook('json.attachments', 'DoAttachmentsActions'); $this->addHook('json.attachments', 'DoAttachmentsActions');
$this->addJsonHook('NextcloudSaveMsg', 'NextcloudSaveMsg'); $this->addJsonHook('NextcloudSaveMsg', 'NextcloudSaveMsg');
$this->addTemplate('templates/PopupsNextcloudFiles.html'); $this->addTemplate('templates/PopupsNextcloudFiles.html');
} }
} }
@ -60,8 +60,14 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
public function NextcloudSaveMsg() : array public function NextcloudSaveMsg() : array
{ {
$sSaveFolder = \ltrim($this->jsonParam('folder', ''), '/');
$aValues = \RainLoop\Utils::DecodeKeyValuesQ($this->jsonParam('msgHash', '')); $aValues = \RainLoop\Utils::DecodeKeyValuesQ($this->jsonParam('msgHash', ''));
if (!empty($aValues['Folder']) && !empty($aValues['Uid'])) { $aResult = [
'folder' => '',
'filename' => '',
'success' => false
];
if ($sSaveFolder && !empty($aValues['Folder']) && !empty($aValues['Uid'])) {
$oActions = \RainLoop\Api::Actions(); $oActions = \RainLoop\Api::Actions();
$oMailClient = $oActions->MailClient(); $oMailClient = $oActions->MailClient();
if (!$oMailClient->IsLoggined()) { if (!$oMailClient->IsLoggined()) {
@ -69,17 +75,20 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
$oAccount->ImapConnectAndLoginHelper($oActions->Plugins(), $oMailClient, $oActions->Config()); $oAccount->ImapConnectAndLoginHelper($oActions->Plugins(), $oMailClient, $oActions->Config());
} }
$sSaveFolder = $this->Config()->Get('plugin', 'save_folder', '') ?: 'Emails'; $sSaveFolder = $sSaveFolder ?: 'Emails';
$oFiles = \OCP\Files::getStorage('files'); $oFiles = \OCP\Files::getStorage('files');
if ($oFiles && \method_exists($oFiles, 'file_put_contents')) { if ($oFiles) {
$oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder); $oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder);
} }
$aResult['folder'] = $sSaveFolder;
$sFilename = $sSaveFolder . '/' . ($this->jsonParam('filename', '') ?: \date('YmdHis')) . '.eml'; $sFilename = $sSaveFolder . '/' . ($this->jsonParam('filename', '') ?: \date('YmdHis')) . '.eml';
$aResult['folder'] = $sFilename;
$oMailClient->MessageMimeStream( $oMailClient->MessageMimeStream(
function ($rResource) use ($oFiles, $sFilename) { function ($rResource) use ($oFiles, $sFilename, $aResult) {
if (\is_resource($rResource)) { if (\is_resource($rResource)) {
$oFiles->file_put_contents($sFilename, $rResource); $aResult['success'] = $oFiles->file_put_contents($sFilename, $rResource);
} }
}, },
(string) $aValues['Folder'], (string) $aValues['Folder'],
@ -88,7 +97,7 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
); );
} }
return $this->jsonResponse(__FUNCTION__, true); return $this->jsonResponse(__FUNCTION__, $aResult);
} }
public function DoAttachmentsActions(\SnappyMail\AttachmentsAction $data) public function DoAttachmentsActions(\SnappyMail\AttachmentsAction $data)
@ -96,7 +105,8 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
if (static::isLoggedIn() && 'nextcloud' === $data->action) { if (static::isLoggedIn() && 'nextcloud' === $data->action) {
$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 = $this->Config()->Get('plugin', 'save_folder', '') ?: 'Attachments'; $sSaveFolder = \ltrim($this->jsonParam('NcFolder', ''), '/');
$sSaveFolder = $sSaveFolder ?: $this->Config()->Get('plugin', 'save_folder', '') ?: '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) {
@ -105,14 +115,10 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
if (!empty($sSavedFileHash)) { if (!empty($sSavedFileHash)) {
$fFile = $data->filesProvider->GetFile($data->account, $sSavedFileHash, 'rb'); $fFile = $data->filesProvider->GetFile($data->account, $sSavedFileHash, 'rb');
if (\is_resource($fFile)) { if (\is_resource($fFile)) {
$sSavedFileNameFull = \MailSo\Base\Utils::SmartFileExists($sSaveFolder.'/'.$sSavedFileName, function ($sPath) use ($oFiles) { $sSavedFileNameFull = static::SmartFileExists($sSaveFolder.'/'.$sSavedFileName, $oFiles);
return $oFiles->file_exists($sPath);
});
if (!$oFiles->file_put_contents($sSavedFileNameFull, $fFile)) { if (!$oFiles->file_put_contents($sSavedFileNameFull, $fFile)) {
$data->result = false; $data->result = false;
} }
if (\is_resource($fFile)) { if (\is_resource($fFile)) {
\fclose($fFile); \fclose($fFile);
} }
@ -193,4 +199,33 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
->SetDefaultValue(true) ->SetDefaultValue(true)
); );
} }
private static function SmartFileExists(string $sFilePath, $oFiles) : string
{
$sFilePath = \str_replace('\\', '/', \trim($sFilePath));
if (!$oFiles->file_exists($sFilePath)) {
return $sFilePath;
}
$aFileInfo = \pathinfo($sFilePath);
$iIndex = 0;
while (true) {
++$iIndex;
$sFilePathNew = $aFileInfo['dirname'].'/'.
\preg_replace('/\(\d{1,2}\)$/', '', $aFileInfo['filename']).
' ('.$iIndex.')'.
(empty($aFileInfo['extension']) ? '' : '.'.$aFileInfo['extension'])
;
if (!$oFiles->file_exists($sFilePathNew)) {
return $sFilePathNew;
}
if (10 < $iIndex) {
break;
}
}
return $sFilePath;
}
} }

View file

@ -1,12 +1,5 @@
(rl => { (rl => {
function browseFiles(path = '/')
{
rl.ncFiles.getDirectoryContents(path).then(elemList => {
console.dir(elemList);
}).catch(err => console.error(err))
}
addEventListener('rl-view-model.create', e => { addEventListener('rl-view-model.create', e => {
if ('MailMessageView' === e.detail.viewModelTemplateID) { if ('MailMessageView' === e.detail.viewModelTemplateID) {
let view = e.detail; let view = e.detail;
@ -19,48 +12,49 @@
.filter(v => v); .filter(v => v);
if (hashes.length) { if (hashes.length) {
view.saveNextcloudLoading(true); view.saveNextcloudLoading(true);
rl.fetchJSON('./?/Json/&q[]=/0/', {}, { rl.ncFiles.selectFolder().then(folder => {
Action: 'AttachmentsActions', if (folder) {
Do: 'nextcloud', rl.fetchJSON('./?/Json/&q[]=/0/', {}, {
Hashes: hashes Action: 'AttachmentsActions',
}) Do: 'nextcloud',
.then(result => { Hashes: hashes,
view.saveNextcloudLoading(false); NcFolder: folder
if (result?.Result) { })
// success .then(result => {
} else { view.saveNextcloudLoading(false);
view.saveNextcloudError(true); if (result?.Result) {
// success
} else {
view.saveNextcloudError(true);
}
})
.catch(() => {
view.saveNextcloudLoading(false);
view.saveNextcloudError(true);
});
} }
})
.catch(() => {
view.saveNextcloudLoading(false);
view.saveNextcloudError(true);
}); });
} }
}; };
view.nextcloudSaveMsg = () => { view.nextcloudSaveMsg = () => {
let msg = view.message(); rl.ncFiles.selectFolder().then(folder => {
let msg = view.message();
/** folder && rl.pluginRemoteRequest(
* TODO: op select screen to show browseFiles result (iError, data) => {
* Then the user can select which Nextcloud folder to save to console.dir({
*/ iError:iError,
// browseFiles(); data:data
});
rl.pluginRemoteRequest( },
(iError, data) => { 'NextcloudSaveMsg',
console.dir({ {
iError:iError, 'msgHash': msg.requestHash,
data:data 'folder': folder,
}); 'filename': msg.subject()
}, }
'NextcloudSaveMsg', );
{ });
'msgHash': msg.requestHash,
'filename': msg.subject()
}
);
}; };
} }
}); });

View file

@ -96,14 +96,39 @@
}); });
} }
onShow(files, fResolve) { onBuild(dom) {
this.files(!!files); this.tree = dom.querySelector('#sm-nc-files-tree');
this.fResolve = fResolve; this.tree.addEventListener('click', event => {
let li = event.target.closest('li');
if (li.item_name) {
this.close();
this.fResolve(li.item_name);
}
});
} }
select() { // Happens after showModal()
this.close(); beforeShow(files, fResolve) {
this.fResolve(this.folder()); this.files(!!files);
this.fResolve = fResolve;
this.tree.innerHTML = '';
fetchFiles(propertyRequestBody, '/').then(items => {
items.forEach(item => {
if (item.isFile) {
if (files) {
// TODO show files
}
} else {
let li = document.createElement('li'),
a = document.createElement('a');
li.item_name = item.name;
a.append('- ' + item.name.replace(/^\/+/, ''));
li.append(a);
this.tree.append(li);
}
});
}).catch(err => console.error(err))
} }
onClose() { onClose() {
@ -111,6 +136,14 @@
this.fResolve(); this.fResolve();
return false; return false;
} }
/*
onShow() {} // Happens after showModal()
beforeShow() {} // Happens before showModal()
afterShow() {} // Happens after showModal() animation transitionend
onHide() {} // Happens before animation transitionend
afterHide() {} // Happens after animation transitionend
close() {}
*/
} }
rl.ncFiles = new class { rl.ncFiles = new class {

View file

@ -1,3 +1,5 @@
[NEXTCLOUD] [NEXTCLOUD]
SAVE_ATTACHMENTS = "Save in Nextcloud" SAVE_ATTACHMENTS = "Save in Nextcloud"
SAVE_EML = "Save as .eml in Nextcloud" SAVE_EML = "Save as .eml in Nextcloud"
SELECT_FOLDER = "Select folder"
SELECT_FILES = "Select file(s)"

View file

@ -1,12 +1,13 @@
<header> <header>
<a class="close" href="#" data-bind="click: close">×</a> <a class="close" href="#" data-bind="click: close">×</a>
<h3 data-i18n="NEXTCLOUD/BROWSE"></h3> <h3 data-i18n="NEXTCLOUD/SELECT_FOLDER" data-bind="hidden:files"></h3>
<h3 data-i18n="NEXTCLOUD/SELECT_FILES" data-bind="visible:files"></h3>
</header> </header>
<div class="modal-body form-horizontal"> <div class="modal-body form-horizontal">
<!--
TODO: built tree of directories and optional files TODO: built tree of directories and optional files
In case of directories: radiobutton to select one OR click selects In case of directories: radiobutton to select one OR click selects
In case of files: checkbox to select (multiple) In case of files: checkbox to select (multiple)
-->
<ul id="sm-nc-files-tree"></ul>
</div> </div>
<footer>
<a class="btn" data-bind="command: select" data-i18n="NEXTCLOUD/SELECT"></a>
</footer>