Merge pull request #1247 from SergeyMosin/some-improvements

Some improvements
This commit is contained in:
the-djmaze 2023-10-01 11:13:55 +02:00 committed by GitHub
commit 4cc1e8429e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 64 additions and 14 deletions

View file

@ -116,7 +116,8 @@ export const FileType = {
Spreadsheet: 'spreadsheet', Spreadsheet: 'spreadsheet',
Presentation: 'presentation', Presentation: 'presentation',
Certificate: 'certificate', Certificate: 'certificate',
Archive: 'archive' Archive: 'archive',
Calendar: 'calendar'
}; };
export const FileInfo = { export const FileInfo = {
@ -190,6 +191,9 @@ export const FileInfo = {
case 'eml' == ext || ['message/delivery-status', 'message/rfc822'].includes(mimeType): case 'eml' == ext || ['message/delivery-status', 'message/rfc822'].includes(mimeType):
result = FileType.Eml; result = FileType.Eml;
break; break;
case 'ics' == ext || mimeType == 'text/calendar':
result = FileType.Calendar;
break;
case 'text' == mimeTypeParts[0] || 'txt' == ext || 'log' == ext: case 'text' == mimeTypeParts[0] || 'txt' == ext || 'log' == ext:
result = FileType.Text; result = FileType.Text;
break; break;
@ -240,6 +244,7 @@ export const FileInfo = {
case FileType.Certificate: case FileType.Certificate:
case FileType.Spreadsheet: case FileType.Spreadsheet:
case FileType.Presentation: case FileType.Presentation:
case FileType.Calendar:
return result + '-' + fileType; return result + '-' + fileType;
} }
return result; return result;

View file

@ -165,7 +165,9 @@ export class EmailAddressesComponent {
_parseInput(force) { _parseInput(force) {
let val = this.input.value; let val = this.input.value;
if ((force || val.includes(',') || val.includes(';')) && this._parseValue(val)) { if ((force || val.includes(',') || val.includes(';')
|| (val.charAt(val.length-1)===' ' && this._simpleEmailMatch(val)))
&& this._parseValue(val)) {
this.input.value = ''; this.input.value = '';
} }
this._resizeInput(); this._resizeInput();
@ -284,6 +286,13 @@ export class EmailAddressesComponent {
} }
} }
_simpleEmailMatch(value) {
// A very SIMPLE test to check if the value might be an email
const val = value.trim();
return /^[^@]*<[^\s@]{1,128}@[^\s@]{1,256}\.[\w]{2,32}>$/g.test(val)
|| /^[^\s@]{1,128}@[^\s@]{1,256}\.[\w]{2,32}$/g.test(val);
}
_renderTags() { _renderTags() {
let self = this; let self = this;
[...self.ul.children].forEach(node => node !== self.inputCont && node.remove()); [...self.ul.children].forEach(node => node !== self.inputCont && node.remove());

View file

@ -493,6 +493,19 @@ export class ComposePopupView extends AbstractViewPopup {
|| getNotification(Notifications.CantSendMessage)); || getNotification(Notifications.CantSendMessage));
} }
} else { } else {
if (arrayLength(this.aDraftInfo) > 0) {
const flag = {
'reply': '\\answered',
'forward': '$forwarded'
}[this.aDraftInfo[0]];
if (flag) {
const aFlags = MessageUserStore.message().flags();
if (aFlags.indexOf(flag) === -1) {
aFlags.push(flag);
MessageUserStore.message().flags(aFlags);
}
}
}
this.close(); this.close();
} }
setFolderETag(this.draftsFolder(), ''); setFolderETag(this.draftsFolder(), '');

View file

@ -1,7 +1,7 @@
import ko from 'ko'; import ko from 'ko';
import { ScopeFolderList, ScopeMessageList } from 'Common/Enums'; import { ScopeFolderList, ScopeMessageList } from 'Common/Enums';
import { addShortcut, stopEvent } from 'Common/Globals'; import { addShortcut, leftPanelDisabled, stopEvent } from 'Common/Globals';
import { mailBox, settings } from 'Common/Links'; import { mailBox, settings } from 'Common/Links';
//import { setFolderETag } from 'Common/Cache'; //import { setFolderETag } from 'Common/Cache';
import { addComputablesTo } from 'External/ko'; import { addComputablesTo } from 'External/ko';
@ -21,6 +21,7 @@ import { ContactsPopupView } from 'View/Popup/Contacts';
import { ComposePopupView } from 'View/Popup/Compose'; import { ComposePopupView } from 'View/Popup/Compose';
import { setExpandedFolder, foldersFilter } from 'Model/FolderCollection'; import { setExpandedFolder, foldersFilter } from 'Model/FolderCollection';
import { ThemeStore } from '../../../Stores/Theme';
export class MailFolderList extends AbstractViewLeft { export class MailFolderList extends AbstractViewLeft {
constructor() { constructor() {
@ -112,6 +113,9 @@ export class MailFolderList extends AbstractViewLeft {
search = 'unseen'; search = 'unseen';
} }
hasher.setHash(mailBox(folder.fullNameHash, 1, search)); hasher.setHash(mailBox(folder.fullNameHash, 1, search));
// in mobile mode hide the panel when a folder is clicked
ThemeStore.isMobile() && leftPanelDisabled()===false && leftPanelDisabled(true);
} }
AppUserStore.focusedState(ScopeMessageList); AppUserStore.focusedState(ScopeMessageList);

View file

@ -86,7 +86,8 @@ class Application extends App implements IBootstrap
// https://github.com/nextcloud/server/issues/36083#issuecomment-1387370634 // https://github.com/nextcloud/server/issues/36083#issuecomment-1387370634
// \OC::$server->getSession()['snappymail-password'] = ''; // \OC::$server->getSession()['snappymail-password'] = '';
SnappyMailHelper::loadApp(); SnappyMailHelper::loadApp();
\RainLoop\Api::Actions()->Logout(true); // \RainLoop\Api::Actions()->Logout(true);
\RainLoop\Api::Actions()->DoLogout();
}); });
// https://github.com/nextcloud/impersonate/issues/179 // https://github.com/nextcloud/impersonate/issues/179

View file

@ -80,7 +80,9 @@ class SnappyMailHelper
if ($doLogin && $aCredentials[1] && $aCredentials[2]) { if ($doLogin && $aCredentials[1] && $aCredentials[2]) {
try { try {
$oActions->Logger()->AddSecret($aCredentials[2]); $oActions->Logger()->AddSecret($aCredentials[2]);
$oAccount = $oActions->LoginProcess($aCredentials[1], $aCredentials[2], false);
$bSignMe = $oConfig->Get('login', 'sign_me_auto', \RainLoop\Enumerations\SignMeType::DEFAULT_OFF) === \RainLoop\Enumerations\SignMeType::DEFAULT_ON;
$oAccount = $oActions->LoginProcess($aCredentials[1], $aCredentials[2], $bSignMe);
if ($oAccount) { if ($oAccount) {
$oActions->Plugins()->RunHook('login.success', array($oAccount)); $oActions->Plugins()->RunHook('login.success', array($oAccount));
$oActions->SetAuthToken($oAccount); $oActions->SetAuthToken($oAccount);

View file

@ -679,16 +679,17 @@ class Actions
'contactsAllowed' => $this->AddressBookProvider($oAccount)->IsActive(), 'contactsAllowed' => $this->AddressBookProvider($oAccount)->IsActive(),
'allowSpellcheck' => $oConfig->Get('defaults', 'allow_spellcheck', false),
'ViewHTML' => (bool) $oConfig->Get('defaults', 'view_html', true), 'ViewHTML' => (bool) $oConfig->Get('defaults', 'view_html', true),
'ViewImages' => $oConfig->Get('defaults', 'view_images', 'ask'), 'ViewImages' => $oConfig->Get('defaults', 'view_images', 'ask'),
'ViewImagesWhitelist' => '', 'ViewImagesWhitelist' => '',
'RemoveColors' => (bool) $oConfig->Get('defaults', 'remove_colors', false), 'RemoveColors' => (bool) $oConfig->Get('defaults', 'remove_colors', false),
'AllowStyles' => false, 'AllowStyles' => false,
'ListInlineAttachments' => false, 'ListInlineAttachments' => false,
'CollapseBlockquotes' => true, 'CollapseBlockquotes' => $oConfig->Get('defaults', 'collapse_blockquotes', true),
'MaxBlockquotesLevel' => 0, 'MaxBlockquotesLevel' => 0,
'simpleAttachmentsList' => false, 'simpleAttachmentsList' => false,
'listGrouped' => false, 'listGrouped' => $oConfig->Get('defaults', 'mail_list_grouped', false),
'MessagesPerPage' => (int) $oConfig->Get('webmail', 'messages_per_page', 25), 'MessagesPerPage' => (int) $oConfig->Get('webmail', 'messages_per_page', 25),
'MessageReadDelay' => (int) $oConfig->Get('webmail', 'message_read_delay', 5), 'MessageReadDelay' => (int) $oConfig->Get('webmail', 'message_read_delay', 5),
'MsgDefaultAction' => (int) $oConfig->Get('defaults', 'msg_default_action', 1), 'MsgDefaultAction' => (int) $oConfig->Get('defaults', 'msg_default_action', 1),
@ -773,7 +774,7 @@ class Actions
$aResult['requireTLS'] = (bool) $oSettings->GetConf('requireTLS', false); $aResult['requireTLS'] = (bool) $oSettings->GetConf('requireTLS', false);
$aResult['pgpSign'] = (bool) $oSettings->GetConf('pgpSign', false); $aResult['pgpSign'] = (bool) $oSettings->GetConf('pgpSign', false);
$aResult['pgpEncrypt'] = (bool) $oSettings->GetConf('pgpEncrypt', false); $aResult['pgpEncrypt'] = (bool) $oSettings->GetConf('pgpEncrypt', false);
$aResult['allowSpellcheck'] = (bool) $oSettings->GetConf('allowSpellcheck', false); $aResult['allowSpellcheck'] = (bool) $oSettings->GetConf('allowSpellcheck', $aResult['allowSpellcheck']);
// $aResult['allowCtrlEnterOnCompose'] = (bool) $oSettings->GetConf('allowCtrlEnterOnCompose', true); // $aResult['allowCtrlEnterOnCompose'] = (bool) $oSettings->GetConf('allowCtrlEnterOnCompose', true);
$aResult['ViewHTML'] = (bool)$oSettings->GetConf('ViewHTML', $aResult['ViewHTML']); $aResult['ViewHTML'] = (bool)$oSettings->GetConf('ViewHTML', $aResult['ViewHTML']);

View file

@ -139,7 +139,14 @@ trait UserAuth
$this->imapConnect($oAccount, true); $this->imapConnect($oAccount, true);
if ($bMainAccount) { if ($bMainAccount) {
$bSignMe && $this->SetSignMeToken($oAccount); if($bSignMe){
// SetAuthToken token needs to be called before SetSignMeToken
// because $_COOKIE['smctoken'] is used by Crypt::Passphrase.
// If the $_COOKIE['smctoken'] is not set then SetSignMeToken
// throws an exception
$this->SetAuthToken($oAccount);
$this->SetSignMeToken($oAccount);
}
$this->StorageProvider()->Put($oAccount, StorageType::SESSION, Utils::GetSessionToken(), 'true'); $this->StorageProvider()->Put($oAccount, StorageType::SESSION, Utils::GetSessionToken(), 'true');
} }

View file

@ -301,10 +301,13 @@ Values:
"match" - whitelist or ask "match" - whitelist or ask
"always" - show always'), "always" - show always'),
'contacts_autosave' => array(true), 'contacts_autosave' => array(true),
'mail_use_threads' => array(false), 'mail_list_grouped' => array(false),
'mail_use_threads' => array(false),
'allow_draft_autosave' => array(true), 'allow_draft_autosave' => array(true),
'mail_reply_same_folder' => array(false), 'mail_reply_same_folder' => array(false),
'msg_default_action' => array(1, '1 - reply, 2 - reply all'), 'msg_default_action' => array(1, '1 - reply, 2 - reply all'),
'collapse_blockquotes' => array(true),
'allow_spellcheck' => array(false)
), ),
'logs' => array( 'logs' => array(

View file

@ -83,7 +83,7 @@ class Cookies
if ($cookie_remove) { if ($cookie_remove) {
\header_remove('Set-Cookie'); \header_remove('Set-Cookie');
foreach ($cookies as $cookie) { foreach ($cookies as $cookie) {
\header($cookie); \header($cookie,false);
} }
} }
@ -118,14 +118,14 @@ class Cookies
foreach (\str_split($sValue, $iMaxSize) as $i => $sPart) { foreach (\str_split($sValue, $iMaxSize) as $i => $sPart) {
$sCookieName = $i ? "{$sName}~{$i}" : $sName; $sCookieName = $i ? "{$sName}~{$i}" : $sName;
Log::debug('COOKIE', "set {$sCookieName}"); Log::debug('COOKIE', "set {$sCookieName}");
static::_set($sCookieName, $sPart, $iExpire); static::_set($sCookieName, $sPart, $iExpire, $httponly);
} }
// Delete unused old 4K split cookie parts // Delete unused old 4K split cookie parts
foreach (\array_keys($_COOKIE) as $sCookieName) { foreach (\array_keys($_COOKIE) as $sCookieName) {
$aSplit = \explode('~', $sCookieName); $aSplit = \explode('~', $sCookieName);
if (isset($aSplit[1]) && $aSplit[0] == $sName && $aSplit[1] > $i) { if (isset($aSplit[1]) && $aSplit[0] == $sName && $aSplit[1] > $i) {
Log::debug('COOKIE', "unset {$sCookieName}"); Log::debug('COOKIE', "unset {$sCookieName}");
static::_set($sCookieName, '', 0); static::_set($sCookieName, '', 0, $httponly);
} }
} }
} }

View file

@ -254,6 +254,7 @@
"TITLE_UPDATE_IDENTITY": "Update Identity?", "TITLE_UPDATE_IDENTITY": "Update Identity?",
"BUTTON_ADD_IDENTITY": "Add", "BUTTON_ADD_IDENTITY": "Add",
"BUTTON_UPDATE_IDENTITY": "Update", "BUTTON_UPDATE_IDENTITY": "Update",
"LABEL_SIGNATURE_ADD": "Add/Edit signature",
"LABEL_SIGNATURE_INSERT_BEFORE": "Insert this signature before quoted text in replies" "LABEL_SIGNATURE_INSERT_BEFORE": "Insert this signature before quoted text in replies"
}, },
"POPUPS_CREATE_FOLDER": { "POPUPS_CREATE_FOLDER": {

View file

@ -130,7 +130,7 @@
<tr> <tr>
<td data-i18n="GLOBAL/SUBJECT"></div> <td data-i18n="GLOBAL/SUBJECT"></div>
<td> <td>
<input type="text" name="subject" autocomplete="off" data-bind="textInput: subject"> <input type="text" name="subject" autocomplete="off" data-bind="textInput: subject, attr:{spellcheck:allowSpellcheck()?'true':'false'}">
</td> </td>
</tr> </tr>
</table> </table>

View file

@ -52,6 +52,7 @@
</div> </div>
<hr> <hr>
<div class="control-group g-ui-user-select-none"> <div class="control-group g-ui-user-select-none">
<h4 data-i18n="POPUPS_IDENTITY/LABEL_SIGNATURE_ADD"></h4>
<div data-bind="component: { <div data-bind="component: {
name: 'Checkbox', name: 'Checkbox',
params: { params: {

View file

@ -106,3 +106,6 @@
.icon-check-mark-circle-two::before { .icon-check-mark-circle-two::before {
content: "\e073"; content: "\e073";
} }
.icon-file-calendar::before {
content: "📅";
}