diff --git a/dev/Admin/General.js b/dev/Admin/General.js index 08c9ce5cc..21c471c73 100644 --- a/dev/Admin/General.js +++ b/dev/Admin/General.js @@ -30,12 +30,21 @@ function AdminGeneral() }; }); }); + + this.mainLanguageFullName = ko.computed(function () { + return Utils.convertLangName(this.mainLanguage()); + }, this); this.languagesOptions = ko.computed(function () { return _.map(oData.languages(), function (sLanguage) { + var + sName = Utils.convertLangName(sLanguage), + sEn = Utils.convertLangName(sLanguage, true) + ; + return { 'optValue': sLanguage, - 'optText': Utils.convertLangName(sLanguage) + 'optText': sName + (sEn !== sName ? ' (' + sEn + ')' : '') }; }); }); @@ -120,3 +129,8 @@ AdminGeneral.prototype.onBuild = function () }, 50); }; + +AdminGeneral.prototype.selectLanguage = function () +{ + kn.showScreenPopup(PopupsLanguagesViewModel); +}; diff --git a/dev/Boots/RainLoopApp.js b/dev/Boots/RainLoopApp.js index 071d4769b..a95f2f0b3 100644 --- a/dev/Boots/RainLoopApp.js +++ b/dev/Boots/RainLoopApp.js @@ -570,7 +570,7 @@ RainLoopApp.prototype.bootstart = function () bTwitter = this.settingsGet('AllowTwitterSocial') ; - if (!this.settingsGet('RemoteChangePassword')) + if (!this.settingsGet('AllowChangePassword')) { Utils.removeSettingsViewModel(SettingsChangePasswordScreen); } diff --git a/dev/Common/Utils.js b/dev/Common/Utils.js index c427f2af0..07339f4b8 100644 --- a/dev/Common/Utils.js +++ b/dev/Common/Utils.js @@ -1187,11 +1187,13 @@ Utils.microtime = function () /** * * @param {string} sLanguage + * @param {boolean=} bEng = false * @return {string} */ -Utils.convertLangName = function (sLanguage) +Utils.convertLangName = function (sLanguage, bEng) { - return Utils.i18n('LANGS_NAMES/LANG_' + sLanguage.toUpperCase().replace(/[^a-zA-Z0-9]+/, '_'), null, sLanguage); + return Utils.i18n('LANGS_NAMES' + (true === bEng ? '_EN' : '') + '/LANG_' + + sLanguage.toUpperCase().replace(/[^a-zA-Z0-9]+/, '_'), null, sLanguage); }; /** diff --git a/dev/Storages/WebMailData.js b/dev/Storages/WebMailData.js index c36b8edb8..96c43494a 100644 --- a/dev/Storages/WebMailData.js +++ b/dev/Storages/WebMailData.js @@ -34,14 +34,14 @@ function WebMailDataStorage() this.devPassword = ''; this.accountEmail = ko.observable(''); - this.accountLogin = ko.observable(''); + this.accountIncLogin = ko.observable(''); + this.accountOutLogin = ko.observable(''); this.projectHash = ko.observable(''); this.threading = ko.observable(false); this.lastFoldersHash = ''; this.remoteSuggestions = false; - this.remoteChangePassword = false; // system folders this.sentFolder = ko.observable(''); @@ -389,7 +389,8 @@ WebMailDataStorage.prototype.populateDataOnStart = function() AbstractData.prototype.populateDataOnStart.call(this); this.accountEmail(RL.settingsGet('Email')); - this.accountLogin(RL.settingsGet('Login')); + this.accountIncLogin(RL.settingsGet('IncLogin')); + this.accountOutLogin(RL.settingsGet('OutLogin')); this.projectHash(RL.settingsGet('ProjectHash')); this.displayName(RL.settingsGet('DisplayName')); @@ -399,7 +400,6 @@ WebMailDataStorage.prototype.populateDataOnStart = function() this.lastFoldersHash = RL.local().get(Enums.ClientSideKeyName.FoldersLashHash) || ''; this.remoteSuggestions = !!RL.settingsGet('RemoteSuggestions'); - this.remoteChangePassword = !!RL.settingsGet('RemoteChangePassword'); this.devEmail = RL.settingsGet('DevEmail'); this.devLogin = RL.settingsGet('DevLogin'); diff --git a/dev/Styles/AdminGeneral.less b/dev/Styles/AdminGeneral.less index 5b8845153..8d1ec89ec 100644 --- a/dev/Styles/AdminGeneral.less +++ b/dev/Styles/AdminGeneral.less @@ -1,4 +1,11 @@ - -.b-admin-general { -} - + +.b-admin-general { + .flag-selector { + padding-top: 5px; + } + + .flag-name { + border-bottom: 1px dashed #555; + } +} + diff --git a/dev/Styles/Languages.less b/dev/Styles/Languages.less index ed8340af6..21f5c0fee 100644 --- a/dev/Styles/Languages.less +++ b/dev/Styles/Languages.less @@ -3,11 +3,11 @@ &.modal { z-index: 1103; - width: 520px; + width: 500px; } &.exp { - width: 521px; + width: 501px; } .modal-header { @@ -18,7 +18,7 @@ display: inline-block; padding: 5px 15px; margin: 2px 5px; - width: 200px; + width: 180px; background-color: #fff; text-align: left; diff --git a/dev/ViewModels/PopupsLanguagesViewModel.js b/dev/ViewModels/PopupsLanguagesViewModel.js index b5a0eb3eb..b4d92c186 100644 --- a/dev/ViewModels/PopupsLanguagesViewModel.js +++ b/dev/ViewModels/PopupsLanguagesViewModel.js @@ -11,26 +11,40 @@ function PopupsLanguagesViewModel() this.exp = ko.observable(false); this.languages = ko.computed(function () { - var sCurrent = RL.data().mainLanguage(); return _.map(RL.data().languages(), function (sLanguage) { return { 'key': sLanguage, - 'selected': sLanguage === sCurrent, + 'selected': ko.observable(false), 'fullName': Utils.convertLangName(sLanguage) }; }); }); + + RL.data().mainLanguage.subscribe(function () { + this.resetMainLanguage(); + }, this); } Utils.extendAsViewModel('PopupsLanguagesViewModel', PopupsLanguagesViewModel); +PopupsLanguagesViewModel.prototype.languageEnName = function (sLanguage) +{ + return Utils.convertLangName(sLanguage, true); +}; + +PopupsLanguagesViewModel.prototype.resetMainLanguage = function () +{ + var sCurrent = RL.data().mainLanguage(); + _.each(this.languages(), function (oItem) { + oItem['selected'](oItem['key'] === sCurrent); + }); +}; + PopupsLanguagesViewModel.prototype.onShow = function () { -// var self = this; -// _.defer(function () { -// self.exp(true); -// }); this.exp(true); + + this.resetMainLanguage(); }; PopupsLanguagesViewModel.prototype.onHide = function () diff --git a/package.json b/package.json index b9c16d071..e02b4c9a7 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "RainLoop", "title": "RainLoop Webmail", - "version": "1.4.0", - "release": "511", + "version": "1.4.1", + "release": "512", "description": "Simple, modern & fast web-based email client", "homepage": "http://rainloop.net", "main": "Gruntfile.js", diff --git a/rainloop/v/0.0.0/app/i18n/langs.ini b/rainloop/v/0.0.0/app/i18n/langs.ini index 81ae34610..2f3274ae3 100644 --- a/rainloop/v/0.0.0/app/i18n/langs.ini +++ b/rainloop/v/0.0.0/app/i18n/langs.ini @@ -4,36 +4,85 @@ LANG_EN_US = "English (US)" LANG_EN_GB = "English (UK)" LANG_EN_CA = "English (Canadian)" -LANG_NL = "Nederlands (Dutch)" -LANG_NL_NL = "Nederlands (Dutch)" +LANG_NL = "Nederlands" +LANG_NL_NL = "Nederlands" -LANG_RU = "Русский (Russian)" -LANG_RU_RU = "Русский (Russian)" +LANG_RU = "Русский" +LANG_RU_RU = "Русский" -LANG_DE = "Deutsch (German)" -LANG_DE_DE = "Deutsch (German)" +LANG_DE = "Deutsch" +LANG_DE_DE = "Deutsch" -LANG_FR = "Français (French)" +LANG_FR = "Français" LANG_FR_FR = "Français (France)" LANG_FR_CA = "Français (Canada)" -LANG_PT = "Português (Portugal)" +LANG_PT = "Português" LANG_PT_PT = "Português (Portugal)" LANG_PT_BR = "Português (Brasil)" -LANG_ES = "Español (Spanish)" +LANG_ES = "Español" LANG_ES_ES = "Español (España)" -LANG_ES_LA = "Español (Spanish)" +LANG_ES_LA = "Español" -LANG_IT = "Italiano (Italian)" -LANG_IT_IT = "Italiano (Italian)" +LANG_IT = "Italiano" +LANG_IT_IT = "Italiano" -LANG_LV = "Latviešu (Latvian)" -LANG_LV_LV = "Latviešu (Latvian)" +LANG_LV = "Latviešu" +LANG_LV_LV = "Latviešu" -LANG_IS = "Íslenska (Icelandic)" -LANG_IS_IS = "Íslenska (Icelandic)" +LANG_IS = "Íslenska" +LANG_IS_IS = "Íslenska" -LANG_JA = "日本語 (Japanese)" -LANG_JP = "日本語 (Japanese)" -LANG_JA_JP = "日本語 (Japanese)" +LANG_JA = "日本語" +LANG_JP = "日本語" +LANG_JA_JP = "日本語" + +LANG_ZH_TW = "中文(台灣)" +LANG_ZH_CN = "中文(简体)" +LANG_ZH_HK = "中文(香港)" + +[LANGS_NAMES_EN] +LANG_EN = "English" +LANG_EN_US = "English (US)" +LANG_EN_GB = "English (UK)" +LANG_EN_CA = "English (Canadian)" + +LANG_NL = "Dutch" +LANG_NL_NL = "Dutch" + +LANG_RU = "Russian" +LANG_RU_RU = "Russian" + +LANG_DE = "German" +LANG_DE_DE = "German" + +LANG_FR = "French" +LANG_FR_FR = "French (France)" +LANG_FR_CA = "France (Canada)" + +LANG_PT = "Portuguese" +LANG_PT_PT = "Portuguese (Portugal)" +LANG_PT_BR = "Portuguese (Brazil)" + +LANG_ES = "Spanish" +LANG_ES_ES = "Spanish" +LANG_ES_LA = "Spanish" + +LANG_IT = "Italian" +LANG_IT_IT = "Italian" + +LANG_LV = "Latvian" +LANG_LV_LV = "Latvian" + +LANG_IS = "Icelandic" +LANG_IS_IS = "Icelandic" + +LANG_JA = "Japanese" +LANG_JP = "Japanese" +LANG_JA_JP = "Japanese" + +LANG_CN = "Chinese" +LANG_ZH_TW = "Traditional Chinese (Taiwan)" +LANG_ZH_CN = "Simplified Chinese (China)" +LANG_ZH_HK = "Traditional Chinese (Hong Kong)" \ No newline at end of file diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Imap/FetchResponse.php b/rainloop/v/0.0.0/app/libraries/MailSo/Imap/FetchResponse.php index 3b932d24f..c0b415ce6 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Imap/FetchResponse.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Imap/FetchResponse.php @@ -23,17 +23,17 @@ class FetchResponse * * @param \MailSo\Imap\Response $oImapResponse */ - private function __construct(&$oImapResponse) + private function __construct($oImapResponse) { - $this->oImapResponse =& $oImapResponse; + $this->oImapResponse = $oImapResponse; $this->aEnvelopeCache = null; } /** - * @param \MailSo\Imap\Response &$oImapResponse + * @param \MailSo\Imap\Response $oImapResponse * @return \MailSo\Imap\FetchResponse */ - public static function NewInstance(&$oImapResponse) + public static function NewInstance($oImapResponse) { return new self($oImapResponse); } @@ -133,22 +133,22 @@ class FetchResponse * * @return mixed */ - public function &GetFetchValue($sFetchItemName) + public function GetFetchValue($sFetchItemName) { $mReturn = null; $bNextIsValue = false; if (Enumerations\FetchType::INDEX === $sFetchItemName) { - $mReturn =& $this->oImapResponse->ResponseList[1]; + $mReturn = $this->oImapResponse->ResponseList[1]; } else { - foreach ($this->oImapResponse->ResponseList[3] as &$mItem) + foreach ($this->oImapResponse->ResponseList[3] as $mItem) { if ($bNextIsValue) { - $mReturn =& $mItem; + $mReturn = $mItem; break; } @@ -176,7 +176,7 @@ class FetchResponse if (isset($this->oImapResponse->ResponseList[3]) && \is_array($this->oImapResponse->ResponseList[3])) { - foreach ($this->oImapResponse->ResponseList[3] as &$mItem) + foreach ($this->oImapResponse->ResponseList[3] as $mItem) { if ($bNextIsValue) { diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php b/rainloop/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php index 3f7efd830..ffe624e95 100644 --- a/rainloop/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php +++ b/rainloop/v/0.0.0/app/libraries/MailSo/Imap/ImapClient.php @@ -898,7 +898,7 @@ class ImapClient extends \MailSo\Net\NetClient $aReturn = array(); $oImapResponse = null; - foreach ($aResult as &$oImapResponse) + foreach ($aResult as $oImapResponse) { if (FetchResponse::IsValidFetchImapResponse($oImapResponse)) { @@ -1089,13 +1089,13 @@ class ImapClient extends \MailSo\Net\NetClient private function validateThreadItem($aValue) { $mResult = false; - if (is_numeric($aValue)) + if (\is_numeric($aValue)) { $mResult = (int) $aValue; } - else if (is_array($aValue)) + else if (\is_array($aValue)) { - if (1 === count($aValue) && is_numeric($aValue[0])) + if (1 === count($aValue) && \is_numeric($aValue[0])) { $mResult = (int) $aValue[0]; } diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Account.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Account.php index 04d1ce09d..90a57f9d6 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Account.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Account.php @@ -93,12 +93,40 @@ class Account return 0 < \strlen($this->sParentEmail) ? $this->sParentEmail : $this->sEmail; } + /** + * @return string + */ + public function IncLogin() + { + $sLogin = $this->sLogin; + if ($this->oDomain->IncShortLogin()) + { + $sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($this->sLogin); + } + + return $sLogin; + } + + /** + * @return string + */ + public function OutLogin() + { + $sLogin = $this->sLogin; + if ($this->oDomain->OutShortLogin()) + { + $sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($this->sLogin); + } + + return $sLogin; + } + /** * @return string */ public function Login() { - return $this->sLogin; + return $this->IncLogin(); } /** diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php index 260567045..819a73ccf 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php @@ -291,7 +291,7 @@ class Actions if ($oAccount) { $sFileName = \str_replace('{user:email}', \strtolower($oAccount->Email()), $sFileName); - $sFileName = \str_replace('{user:login}', $oAccount->Login(), $sFileName); + $sFileName = \str_replace('{user:login}', $oAccount->IncLogin(), $sFileName); $sFileName = \str_replace('{user:domain}', \strtolower($oAccount->Domain()->Name()), $sFileName); } @@ -876,7 +876,7 @@ class Actions 'AllowThemes' => (bool) $oConfig->Get('webmail', 'allow_themes', true), 'AllowCustomTheme' => (bool) $oConfig->Get('webmail', 'allow_custom_theme', true), 'SuggestionsLimit' => (int) $oConfig->Get('labs', 'suggestions_limit', 50), - 'RemoteChangePassword' => false, + 'AllowChangePassword' => false, 'ContactsIsSupported' => (bool) $this->ContactsProvider()->IsSupported(), 'ContactsIsAllowed' => (bool) $this->ContactsProvider()->IsActive(), 'JsHash' => \md5(\RainLoop\Utils::GetConnectionToken()), @@ -898,11 +898,12 @@ class Actions $oAccount = $this->getAccountFromToken(false); if ($oAccount instanceof \RainLoop\Account) { - $aResult['Email'] = $oAccount->Email(); - $aResult['Login'] = $oAccount->Login(); $aResult['Auth'] = true; + $aResult['Email'] = $oAccount->Email(); + $aResult['IncLogin'] = $oAccount->IncLogin(); + $aResult['OutLogin'] = $oAccount->OutLogin(); $aResult['AccountHash'] = $oAccount->Hash(); - $aResult['RemoteChangePassword'] = $this->ChangePasswordProvider()->PasswordChangePossibility($oAccount); + $aResult['AllowChangePassword'] = $this->ChangePasswordProvider()->PasswordChangePossibility($oAccount); $oSettings = $this->SettingsProvider()->Load($oAccount); } @@ -1198,15 +1199,9 @@ class Actions try { - $sLogin = $oAccount->Login(); - if ($oAccount->Domain()->IncShortLogin()) - { - $sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($sLogin); - } - $this->MailClient() ->Connect($oAccount->Domain()->IncHost(), $oAccount->Domain()->IncPort(), $oAccount->Domain()->IncSecure()) - ->Login($sLogin, $oAccount->Password()) + ->Login($oAccount->IncLogin(), $oAccount->Password()) ; } catch (\RainLoop\Exceptions\ClientException $oException) @@ -1631,15 +1626,19 @@ class Actions */ public function DoAppDelayStart() { + $this->Plugins()->RunHook('service.app-delay-start-begin'); + \RainLoop\Utils::UpdateConnectionToken(); $bMainCache = false; $bFilesCache = false; $bActivity = false; $bPing = false; + $bReHash = false; $iOneDay1 = 60 * 60 * 23; $iOneDay2 = 60 * 60 * 25; + $iOneDay3 = $iOneDay2 * 2; $sTimers = $this->StorageProvider()->Get(null, \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, 'Cache/Timers', ''); @@ -1650,6 +1649,7 @@ class Actions $iFilesCacheTime = !empty($aTimers[1]) && \is_numeric($aTimers[1]) ? (int) $aTimers[1] : 0; $iActivityTime = !empty($aTimers[2]) && \is_numeric($aTimers[2]) ? (int) $aTimers[2] : 0; $iPingTime = !empty($aTimers[3]) && \is_numeric($aTimers[3]) ? (int) $aTimers[3] : 0; + $iReHashTime = !empty($aTimers[4]) && \is_numeric($aTimers[4]) ? (int) $aTimers[4] : 0; if (0 === $iMainCacheTime || $iMainCacheTime + $iOneDay1 < \time()) { @@ -1675,13 +1675,19 @@ class Actions $iPingTime = \time(); } - if ($bMainCache || $bFilesCache || $bActivity || $bPing) + if (0 === $iReHashTime || $iReHashTime + $iOneDay3 < \time()) + { + $bReHash = true; + $iReHashTime = \time(); + } + + if ($bMainCache || $bFilesCache || $bActivity || $bPing || $bReHash) { if (!$this->StorageProvider()->Put(null, \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY, 'Cache/Timers', \implode(',', array($iMainCacheTime, $iFilesCacheTime, $iActivityTime, $iPingTime)))) { - $bMainCache = $bFilesCache = $bActivity = $bPing = false; + $bMainCache = $bFilesCache = $bActivity = $bPing = $bReHash = false; } } @@ -1711,6 +1717,15 @@ class Actions $this->KeenIO('Ping'); } + if ($bReHash) + { + $sHash = \RainLoop\Utils::PathMD5(APP_VERSION_ROOT_PATH); + $this->Logger()->Write('App Hash: '.$sHash); + @\file_put_contents(APP_DATA_FOLDER_PATH.'HASH', $sHash); + } + + $this->Plugins()->RunHook('service.app-delay-start-end'); + return $this->TrueResponse(__FUNCTION__); } @@ -3704,9 +3719,8 @@ class Actions 'Secure' => $oAccount->Domain()->OutSecure(), 'UseAuth' => $oAccount->Domain()->OutAuth(), 'From' => empty($sFrom) ? $oAccount->Email() : $sFrom, - 'Login' => $oAccount->Login(), + 'Login' => $oAccount->OutLogin(), 'Password' => $oAccount->Password(), - 'UseShortLogin' => $oAccount->Domain()->OutShortLogin(), 'HiddenRcpt' => array() ); @@ -3727,13 +3741,7 @@ class Actions { if ($aSmtpCredentials['UseAuth']) { - $sLogin = $aSmtpCredentials['Login']; - if ($aSmtpCredentials['UseShortLogin']) - { - $sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($sLogin); - } - - $oSmtpClient->Login($sLogin, $aSmtpCredentials['Password']); + $oSmtpClient->Login($aSmtpCredentials['Login'], $aSmtpCredentials['Password']); } } @@ -4953,7 +4961,7 @@ class Actions { $this->MailClient() ->Connect($oAccount->Domain()->IncHost(), $oAccount->Domain()->IncPort(), $oAccount->Domain()->IncSecure()) - ->Login($oAccount->Login(), $oAccount->Password(), !!$this->Config()->Get('labs', 'use_imap_auth_plain')) + ->Login($oAccount->IncLogin(), $oAccount->Password(), !!$this->Config()->Get('labs', 'use_imap_auth_plain')) ; } catch (\MailSo\Net\Exceptions\ConnectionException $oException) @@ -5175,6 +5183,7 @@ class Actions private function setupInformation() { $aResult = array( + 'hash' => \file_exists(APP_DATA_FOLDER_PATH.'HASH') ? @\file_get_contents(APP_DATA_FOLDER_PATH.'HASH') : '', 'version-full' => APP_VERSION, ); diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php index 596a20506..69dfa4f6f 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Service.php @@ -178,11 +178,18 @@ class Service $bCached = true; } + $sAppHash = ''; + if (\file_exists(APP_DATA_FOLDER_PATH.'HASH')) + { + $sAppHash = @\file_get_contents(APP_DATA_FOLDER_PATH.'HASH'); + } + $sResult .= ''; } diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Social.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Social.php index 1781c8bdf..dff1e7971 100644 --- a/rainloop/v/0.0.0/app/libraries/RainLoop/Social.php +++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Social.php @@ -377,7 +377,7 @@ class Social { $aUserData = array( 'Email' => $oAccount->Email(), - 'Login' => $oAccount->Login(), + 'Login' => $oAccount->IncLogin(), 'Password' => $oAccount->Password() ); @@ -489,7 +489,7 @@ class Social { $aUserData = array( 'Email' => $oAccount->Email(), - 'Login' => $oAccount->Login(), + 'Login' => $oAccount->IncLogin(), 'Password' => $oAccount->Password() ); @@ -652,7 +652,7 @@ class Social $aUserData = array( 'Email' => $oAccount->Email(), - 'Login' => $oAccount->Login(), + 'Login' => $oAccount->IncLogin(), 'Password' => $oAccount->Password() ); diff --git a/rainloop/v/0.0.0/app/templates/Views/AdminSettingsGeneral.html b/rainloop/v/0.0.0/app/templates/Views/AdminSettingsGeneral.html index 8df69a67f..511ad71fe 100644 --- a/rainloop/v/0.0.0/app/templates/Views/AdminSettingsGeneral.html +++ b/rainloop/v/0.0.0/app/templates/Views/AdminSettingsGeneral.html @@ -22,6 +22,29 @@
General
+
+ +
+ +
+
+
+ +
+ +
+
+
-
- -
-
-
-
-
-
- -
- -
-
-
-
-