1.10 beta

This commit is contained in:
RainLoop Team 2016-05-02 23:42:29 +03:00
parent 116de6fd45
commit ecf23a4f6d
27 changed files with 259 additions and 158 deletions

View file

@ -204,6 +204,7 @@ class AbstractApp extends AbstractBoot
const const
kn = require('Knoin/Knoin'), kn = require('Knoin/Knoin'),
mobile = Settings.appSettingsGet('mobile'),
inIframe = !!Settings.appSettingsGet('inIframe') inIframe = !!Settings.appSettingsGet('inIframe')
; ;
@ -219,7 +220,7 @@ class AbstractApp extends AbstractBoot
window.close(); window.close();
} }
customLogoutLink = customLogoutLink || (admin ? Links.rootAdmin() : Links.rootUser()); customLogoutLink = customLogoutLink || (admin ? Links.rootAdmin(mobile) : Links.rootUser(mobile));
if (logout && window.location.href !== customLogoutLink) if (logout && window.location.href !== customLogoutLink)
{ {

View file

@ -49,8 +49,8 @@ class Links
/** /**
* @return {string} * @return {string}
*/ */
rootUser() { rootUser(mobile = false) {
return './'; return mobile ? './?/Mobile/' : './';
} }
/** /**

View file

@ -32,8 +32,8 @@
LanguageStore.prototype.populate = function () LanguageStore.prototype.populate = function ()
{ {
var var
aLanguages = Settings.settingsGet('Languages'), aLanguages = Settings.appSettingsGet('languages'),
aLanguagesAdmin = Settings.settingsGet('LanguagesAdmin') aLanguagesAdmin = Settings.appSettingsGet('languagesAdmin')
; ;
this.languages(Utils.isArray(aLanguages) ? aLanguages : []); this.languages(Utils.isArray(aLanguages) ? aLanguages : []);

View file

@ -26,7 +26,7 @@
ThemeStore.prototype.populate = function () ThemeStore.prototype.populate = function ()
{ {
var aThemes = Settings.settingsGet('Themes'); var aThemes = Settings.appSettingsGet('themes');
this.themes(Utils.isArray(aThemes) ? aThemes : []); this.themes(Utils.isArray(aThemes) ? aThemes : []);
this.theme(Settings.settingsGet('Theme')); this.theme(Settings.settingsGet('Theme'));

View file

@ -37,3 +37,10 @@
} }
} }
} }
html.rl-mobile {
.b-languages-content .lang-item {
width: calc(~'100% - 40px');
}
}

View file

@ -175,9 +175,14 @@ html.rl-no-preview-pane {
} }
.listSearchDesc { .listSearchDesc {
font-size: 20px; font-size: 18px;
padding: 20px; padding: 15px;
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
html.rl-mobile &{
font-size: 16px;
padding: 12px;
}
} }
.listThreadUidDesc { .listThreadUidDesc {

View file

@ -81,6 +81,10 @@ select {
padding: 4px 9px; padding: 4px 9px;
} }
.btn.btn-thin-2 {
padding: 4px 7px;
}
.btn.btn-nowrap { .btn.btn-nowrap {
white-space: nowrap; white-space: nowrap;
} }
@ -412,3 +416,24 @@ html.rl-mobile {
} }
} }
} }
.close-input-wrp {
display: inline-block;
position: relative;
input {
padding-right: 15px;
}
.close {
position: absolute;
right: 0;
top: 5px;
margin: 0 7px;
z-index: 100;
vertical-align: middle;
opacity: .4;
&:hover {
opacity: .6;
}
}
}

View file

@ -198,6 +198,7 @@
this.submitRequest(true); this.submitRequest(true);
var var
self = this,
sPassword = this.password(), sPassword = this.password(),
fLoginRequest = _.bind(function (sPassword) { fLoginRequest = _.bind(function (sPassword) {
@ -212,9 +213,11 @@
{ {
this.additionalCode(''); this.additionalCode('');
this.additionalCode.visibility(true); this.additionalCode.visibility(true);
this.additionalCode.focused(true);
this.submitRequest(false); this.submitRequest(false);
_.delay(function(){
self.additionalCode.focused(true);
}, 100);
} }
else if (oData.Admin) else if (oData.Admin)
{ {
@ -400,7 +403,7 @@
self = this, self = this,
sSignMeLocal = Local.get(Enums.ClientSideKeyName.LastSignMe), sSignMeLocal = Local.get(Enums.ClientSideKeyName.LastSignMe),
sSignMe = (Settings.settingsGet('SignMe') || 'unused').toLowerCase(), sSignMe = (Settings.settingsGet('SignMe') || 'unused').toLowerCase(),
sJsHash = Settings.settingsGet('JsHash'), sJsHash = Settings.appSettingsGet('jsHash'),
fSocial = function (iErrorCode) { fSocial = function (iErrorCode) {
iErrorCode = Utils.pInt(iErrorCode); iErrorCode = Utils.pInt(iErrorCode);
if (0 === iErrorCode) if (0 === iErrorCode)

View file

@ -1,8 +1,8 @@
{ {
"name": "RainLoop", "name": "RainLoop",
"title": "RainLoop Webmail", "title": "RainLoop Webmail",
"version": "1.9.5", "version": "1.10.0",
"release": "420", "release": "100",
"description": "Simple, modern & fast web-based email client", "description": "Simple, modern & fast web-based email client",
"homepage": "http://rainloop.net", "homepage": "http://rainloop.net",
"main": "gulpfile.js", "main": "gulpfile.js",

View file

@ -2357,30 +2357,30 @@ END;
} }
/** /**
* @param string $sData * @param string $sData
* @param string $sKey * @param string $sKey
* *
* @return string * @return string
*/ */
public static function Hmac($sData, $sKey) public static function Hmac($sData, $sKey)
{ {
if (\function_exists('hash_hmac')) if (\function_exists('hash_hmac'))
{ {
return \hash_hmac('md5', $sData, $sKey); return \hash_hmac('md5', $sData, $sKey);
} }
$iLen = 64; $iLen = 64;
if ($iLen < \strlen($sKey)) if ($iLen < \strlen($sKey))
{ {
$sKey = \pack('H*', \md5($sKey)); $sKey = \pack('H*', \md5($sKey));
} }
$sKey = \str_pad($sKey, $iLen, \chr(0x00)); $sKey = \str_pad($sKey, $iLen, \chr(0x00));
$sIpad = \str_pad('', $iLen, \chr(0x36)); $sIpad = \str_pad('', $iLen, \chr(0x36));
$sOpad = \str_pad('', $iLen, \chr(0x5c)); $sOpad = \str_pad('', $iLen, \chr(0x5c));
return \md5(($sKey ^ $sOpad).\pack('H*', \md5(($sKey ^ $sIpad).$sData))); return \md5(($sKey ^ $sOpad).\pack('H*', \md5(($sKey ^ $sIpad).$sData)));
} }
/** /**
* @param string $sDomain * @param string $sDomain

View file

@ -172,6 +172,16 @@ class ImapClient extends \MailSo\Net\NetClient
return $this; return $this;
} }
protected function _xor($string, $string2)
{
$result = '';
$size = strlen($string);
for ($i=0; $i<$size; $i++) {
$result .= chr(ord($string[$i]) ^ ord($string2[$i]));
}
return $result;
}
/** /**
* @param string $sLogin * @param string $sLogin
* @param string $sPassword * @param string $sPassword
@ -204,7 +214,6 @@ class ImapClient extends \MailSo\Net\NetClient
try try
{ {
$bUseAuthCramMd5IfSupported = false; // TODO
if ($bUseAuthCramMd5IfSupported && $this->IsSupported('AUTH=CRAM-MD5')) if ($bUseAuthCramMd5IfSupported && $this->IsSupported('AUTH=CRAM-MD5'))
{ {
$this->SendRequest('AUTHENTICATE', array('CRAM-MD5')); $this->SendRequest('AUTHENTICATE', array('CRAM-MD5'));
@ -222,10 +231,20 @@ class ImapClient extends \MailSo\Net\NetClient
} }
} }
if ($oContinuationResponse && false) if ($oContinuationResponse && !empty($oContinuationResponse->ResponseList[1]))
{ {
// TODO $sTiken = @\base64_decode($oContinuationResponse->ResponseList[1]);
$this->Logger()->WriteDump($aResponse); $this->oLogger->Write('tiket: '.$sTiken);
$sToken = \base64_encode($sLogin.' '.\MailSo\Base\Utils::Hmac($sPassword, $sTiken));
if ($this->oLogger)
{
$this->oLogger->AddSecret($sToken);
}
$this->sendRaw($sToken, true, '*******');
$this->parseResponseWithValidation();
} }
else else
{ {
@ -234,6 +253,12 @@ class ImapClient extends \MailSo\Net\NetClient
\MailSo\Log\Enumerations\Type::NOTICE, true); \MailSo\Log\Enumerations\Type::NOTICE, true);
} }
} }
else
{
$this->writeLogException(
new \MailSo\Imap\Exceptions\LoginException(),
\MailSo\Log\Enumerations\Type::NOTICE, true);
}
} }
else if ($bUseAuthPlainIfSupported && $this->IsSupported('AUTH=PLAIN')) else if ($bUseAuthPlainIfSupported && $this->IsSupported('AUTH=PLAIN'))
{ {

View file

@ -1716,10 +1716,6 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
$sLanguageAdmin = $oConfig->Get('webmail', 'language_admin', 'en'); $sLanguageAdmin = $oConfig->Get('webmail', 'language_admin', 'en');
$sTheme = $oConfig->Get('webmail', 'theme', 'Default'); $sTheme = $oConfig->Get('webmail', 'theme', 'Default');
$aResult['Themes'] = $this->GetThemes($bMobile);
$aResult['Languages'] = $this->GetLanguages(false);
$aResult['LanguagesAdmin'] = $this->GetLanguages(true);
$aResult['AllowLanguagesOnSettings'] = (bool) $oConfig->Get('webmail', 'allow_languages_on_settings', true); $aResult['AllowLanguagesOnSettings'] = (bool) $oConfig->Get('webmail', 'allow_languages_on_settings', true);
$aResult['AllowLanguagesOnLogin'] = (bool) $oConfig->Get('login', 'allow_languages_on_login', true); $aResult['AllowLanguagesOnLogin'] = (bool) $oConfig->Get('login', 'allow_languages_on_login', true);
$aResult['AttachmentLimit'] = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 10)) * 1024 * 1024; $aResult['AttachmentLimit'] = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 10)) * 1024 * 1024;
@ -8960,7 +8956,7 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
} }
return \in_array($sTheme, $this->GetThemes($bMobile)) ? return \in_array($sTheme, $this->GetThemes($bMobile)) ?
$sTheme : $this->Config()->Get('themes', 'default', 'Default'); $sTheme : $this->Config()->Get('themes', 'default', $bMobile ? 'Mobile' : 'Default');
} }
/** /**
@ -9039,17 +9035,21 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
* *
* @return array * @return array
*/ */
public function GetThemes($bMobile = false) public function GetThemes($bMobile = false, $bIncludeMobile = true)
{ {
if ($bMobile) if ($bMobile)
{ {
return array('Mobile'); return array('Mobile');
} }
static $aCache = null; static $aCache = array('full' => null, 'mobile' => null);
if (\is_array($aCache)) if ($bIncludeMobile && \is_array($aCache['full']))
{ {
return $aCache; return $aCache['full'];
}
else if ($bIncludeMobile && \is_array($aCache['mobile']))
{
return $aCache['mobile'];
} }
$bClear = false; $bClear = false;
@ -9065,21 +9065,18 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
{ {
if ('.' !== $sFile{0} && \is_dir($sDir.'/'.$sFile) && \file_exists($sDir.'/'.$sFile.'/styles.less')) if ('.' !== $sFile{0} && \is_dir($sDir.'/'.$sFile) && \file_exists($sDir.'/'.$sFile.'/styles.less'))
{ {
if ('Default' !== $sFile && 'Clear' !== $sFile) if ('Default' === $sFile)
{
$bDefault = true;
}
else if ('Clear' === $sFile)
{
$bClear = true;
}
else if ($bIncludeMobile || 'Mobile' !== $sFile)
{ {
$sList[] = $sFile; $sList[] = $sFile;
} }
else
{
if ('Default' === $sFile)
{
$bDefault = true;
}
else if ('Clear' === $sFile)
{
$bClear = true;
}
}
} }
} }
@closedir($rDirH); @closedir($rDirH);
@ -9117,7 +9114,7 @@ NewThemeLink IncludeCss LoadingDescriptionEsc TemplatesLink LangLink IncludeBack
\array_push($sList, 'Clear'); \array_push($sList, 'Clear');
} }
$aCache = $sList; $aCache[$bIncludeMobile ? 'full' : 'mobile'] = $sList;
return $sList; return $sList;
} }

View file

@ -288,9 +288,10 @@ Enables caching in the system'),
), ),
'labs' => array( 'labs' => array(
'ignore_folders_subscription' => array(false, 'allow_mobile_version' => array(true,
'Experimental settings. Handle with care. 'Experimental settings. Handle with care.
'), '),
'ignore_folders_subscription' => array(false),
'check_new_password_strength' => array(true), 'check_new_password_strength' => array(true),
'update_channel' => array('stable'), 'update_channel' => array('stable'),
'allow_gravatar' => array(true), 'allow_gravatar' => array(true),

View file

@ -151,10 +151,16 @@ class Service
} }
} }
$oMobileDetect = new \Detection\MobileDetect(); $bMobile = false;
$bMobileDevice = $oMobileDetect->isMobile() && !$oMobileDetect->isTablet(); $bMobileDevice = false;
$bMobile = (0 < \count($aPaths) && !empty($aPaths[0]) && 'mobile' === \strtolower($aPaths[0])); if ($this->oActions->Config()->Get('labs', 'allow_mobile_version', false))
{
$oMobileDetect = new \Detection\MobileDetect();
$bMobileDevice = $oMobileDetect->isMobile() && !$oMobileDetect->isTablet();
$bMobile = (0 < \count($aPaths) && !empty($aPaths[0]) && 'mobile' === \strtolower($aPaths[0]));
}
if ($bIndex && !$bMobile) if ($bIndex && !$bMobile)
{ {
@ -310,6 +316,9 @@ class Service
'folderSpecLimit' => (int) $oConfig->Get('labs', 'folders_spec_limit', 50), 'folderSpecLimit' => (int) $oConfig->Get('labs', 'folders_spec_limit', 50),
'faviconStatus' => (bool) $oConfig->Get('labs', 'favicon_status', true), 'faviconStatus' => (bool) $oConfig->Get('labs', 'favicon_status', true),
'listPermanentFiltered' => '' !== \trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', '')), 'listPermanentFiltered' => '' !== \trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', '')),
'themes' => $this->oActions->GetThemes($bMobile, false),
'languages' => $this->oActions->GetLanguages(false),
'languagesAdmin' => $this->oActions->GetLanguages(true),
'attachmentsActions' => $aAttachmentsActions, 'attachmentsActions' => $aAttachmentsActions,
'rsaPublicKey' => $sRsaPublicKey 'rsaPublicKey' => $sRsaPublicKey
), $bAdmin ? array( ), $bAdmin ? array(

View file

@ -2,10 +2,10 @@ it_IT:
LOGIN: LOGIN:
LABEL_LOGIN: "Nome utente" LABEL_LOGIN: "Nome utente"
LABEL_PASSWORD: "Password" LABEL_PASSWORD: "Password"
BUTTON_LOGIN: "Accedi al pannello di amministrazione" BUTTON_LOGIN: "Accedi all'amministrazione"
TOP_PANEL: TOP_PANEL:
LABEL_PREMIUM: "Premium" LABEL_PREMIUM: "Premium"
LABEL_ADMIN_PANEL: "Pannello di amministrazione" LABEL_ADMIN_PANEL: "Amministrazione"
TABS_LABELS: TABS_LABELS:
LABEL_GENERAL_NAME: "Generali" LABEL_GENERAL_NAME: "Generali"
LABEL_LOGIN_NAME: "Accesso" LABEL_LOGIN_NAME: "Accesso"

View file

@ -215,6 +215,7 @@ pl_PL:
BUTTON_CLOSE: "Zamknij" BUTTON_CLOSE: "Zamknij"
BUTTON_ADD: "Dodaj" BUTTON_ADD: "Dodaj"
BUTTON_UPDATE: "Zaktualizuj" BUTTON_UPDATE: "Zaktualizuj"
NEW_DOMAIN_DESC: "Konfiguracja tej domeny pozwala na pracę <br />z adresami email: <i>%NAME%</i>"
WHITE_LIST_ALERT: | WHITE_LIST_ALERT: |
Lista użytkowników domeny, którzy mogą uzyskać dostęp poprzez tego klienta. Lista użytkowników domeny, którzy mogą uzyskać dostęp poprzez tego klienta.
Użyj spacji do rozdzielenia. Użyj spacji do rozdzielenia.
@ -294,6 +295,7 @@ pl_PL:
DEMO_SEND_MESSAGE_ERROR: "Ze względów bezpieczeństwa, to konto nie posiada zezwolenia na wysyłanie wiadomości na zewnętrzne adresy e-mail!" DEMO_SEND_MESSAGE_ERROR: "Ze względów bezpieczeństwa, to konto nie posiada zezwolenia na wysyłanie wiadomości na zewnętrzne adresy e-mail!"
DEMO_ACCOUNT_ERROR: "Ze względów bezpieczeństwa, to konto nie posiada uprawnień do wykonania tego zadania!" DEMO_ACCOUNT_ERROR: "Ze względów bezpieczeństwa, to konto nie posiada uprawnień do wykonania tego zadania!"
ACCOUNT_ALREADY_EXISTS: "To konto już istnieje" ACCOUNT_ALREADY_EXISTS: "To konto już istnieje"
ACCOUNT_DOES_NOT_EXIST: "Konto nie istnieje"
MAIL_SERVER_ERROR: "Wystąpił błąd podczas dostępu do serwera" MAIL_SERVER_ERROR: "Wystąpił błąd podczas dostępu do serwera"
INVALID_INPUT_ARGUMENT: "Niepoprawny argument wejścia" INVALID_INPUT_ARGUMENT: "Niepoprawny argument wejścia"
UNKNOWN_ERROR: "Nieznany błąd" UNKNOWN_ERROR: "Nieznany błąd"

View file

@ -50,6 +50,7 @@ it_IT:
FOLDER_LIST: FOLDER_LIST:
BUTTON_COMPOSE: "Scrivi messaggio" BUTTON_COMPOSE: "Scrivi messaggio"
BUTTON_CONTACTS: "Contatti" BUTTON_CONTACTS: "Contatti"
BUTTON_NEW_MESSAGE: "Nuovo messaggio"
INBOX_NAME: "Posta in arrivo" INBOX_NAME: "Posta in arrivo"
STARRED_NAME: "Preferiti" STARRED_NAME: "Preferiti"
SENT_NAME: "Posta inviata" SENT_NAME: "Posta inviata"

View file

@ -50,7 +50,9 @@ pl_PL:
FOLDER_LIST: FOLDER_LIST:
BUTTON_COMPOSE: "Utwórz" BUTTON_COMPOSE: "Utwórz"
BUTTON_CONTACTS: "Kontakty" BUTTON_CONTACTS: "Kontakty"
BUTTON_NEW_MESSAGE: "Nowa wiadomość"
INBOX_NAME: "Odebrane" INBOX_NAME: "Odebrane"
STARRED_NAME: "Oznaczone gwiazdką"
SENT_NAME: "Wysłane" SENT_NAME: "Wysłane"
DRAFTS_NAME: "Wersje robocze" DRAFTS_NAME: "Wersje robocze"
SPAM_NAME: "Wiadomości śmieci - SPAM" SPAM_NAME: "Wiadomości śmieci - SPAM"
@ -299,7 +301,7 @@ pl_PL:
BUTTON_SIGN_AND_ENCRYPT: "Podpisz i szyfruj" BUTTON_SIGN_AND_ENCRYPT: "Podpisz i szyfruj"
POPUPS_MESSAGE_OPEN_PGP: POPUPS_MESSAGE_OPEN_PGP:
TITLE_MESSAGE_OPEN_PGP: "OpenPGP Decrypt" TITLE_MESSAGE_OPEN_PGP: "OpenPGP Decrypt"
LABEL_KEY: "Private Key" LABEL_KEY: "Klucz prywatny"
LABEL_PASSWORD: "Password" LABEL_PASSWORD: "Password"
BUTTON_DECRYPT: "Decrypt" BUTTON_DECRYPT: "Decrypt"
POPUPS_TWO_FACTOR_TEST: POPUPS_TWO_FACTOR_TEST:
@ -619,6 +621,7 @@ pl_PL:
NO_PRIVATE_KEY_FOUND: "Nie znaleziono klucza prywatnego" NO_PRIVATE_KEY_FOUND: "Nie znaleziono klucza prywatnego"
NO_PRIVATE_KEY_FOUND_FOR: "Nie znaleziono klucza prywatnego dla adresu: \"%EMAIL%\"" NO_PRIVATE_KEY_FOUND_FOR: "Nie znaleziono klucza prywatnego dla adresu: \"%EMAIL%\""
ADD_A_PUBLICK_KEY: "Dodaj klucz publiczny" ADD_A_PUBLICK_KEY: "Dodaj klucz publiczny"
SELECT_A_PRIVATE_KEY: "Wybierz klucz prywatny"
UNVERIFIRED_SIGNATURE: "Niezweryfikowana" UNVERIFIRED_SIGNATURE: "Niezweryfikowana"
DECRYPTION_ERROR: "Błąd deszyfrowania OpenPGP" DECRYPTION_ERROR: "Błąd deszyfrowania OpenPGP"
GOOD_SIGNATURE: "Podpisana przez: %USER%" GOOD_SIGNATURE: "Podpisana przez: %USER%"

View file

@ -17,6 +17,9 @@ ru_RU:
BUTTON_SETTINGS: "Настройки" BUTTON_SETTINGS: "Настройки"
BUTTON_HELP: "Помощь" BUTTON_HELP: "Помощь"
BUTTON_LOGOUT: "Выйти" BUTTON_LOGOUT: "Выйти"
MOBILE:
BUTTON_MOBILE_VERSION: "Мобильная версия"
BUTTON_DESKTOP_VERSION: "Полная версия"
SEARCH: SEARCH:
MAIN_INPUT_PLACEHOLDER: "Поиск писем" MAIN_INPUT_PLACEHOLDER: "Поиск писем"
TITLE_ADV: "Расширенный поиск писем" TITLE_ADV: "Расширенный поиск писем"

View file

@ -17,6 +17,9 @@ uk_UA:
BUTTON_SETTINGS: "Налаштування" BUTTON_SETTINGS: "Налаштування"
BUTTON_HELP: "Допомога" BUTTON_HELP: "Допомога"
BUTTON_LOGOUT: "Вийти" BUTTON_LOGOUT: "Вийти"
MOBILE:
BUTTON_MOBILE_VERSION: "Мобільна версія"
BUTTON_DESKTOP_VERSION: "Повна версія"
SEARCH: SEARCH:
MAIN_INPUT_PLACEHOLDER: "Пошук листів" MAIN_INPUT_PLACEHOLDER: "Пошук листів"
TITLE_ADV: "Розширений пошук листів" TITLE_ADV: "Розширений пошук листів"

View file

@ -4,12 +4,12 @@
<div class="toolbar"> <div class="toolbar">
<div class="btn-toolbar"> <div class="btn-toolbar">
<div class="btn-group" data-bind="visible: mobile && leftPanelDisabled()"> <div class="btn-group" data-bind="visible: mobile && leftPanelDisabled()">
<a class="btn single" data-bind="click: showLeft"> <a class="btn btn-thin-2 single" data-bind="click: showLeft">
<i class="icon-right-middle"></i> <i class="icon-right-middle"></i>
</a> </a>
</div> </div>
<div class="btn-group" data-bind="visible: mobile && !leftPanelDisabled()" style="margin-left: -1px"> <div class="btn-group" data-bind="visible: mobile && !leftPanelDisabled()" style="margin-left: -1px">
<a class="btn single" data-bind="click: hideLeft"> <a class="btn btn-thin-2 single" data-bind="click: hideLeft">
<i class="icon-left-middle"></i> <i class="icon-left-middle"></i>
</a> </a>
</div> </div>
@ -141,9 +141,12 @@
<div class="second-toolbar thm-message-list-top-toolbar"> <div class="second-toolbar thm-message-list-top-toolbar">
<div class="form-inline"> <div class="form-inline">
<div class="input-append pull-right" data-bind="visible: allowSearch"> <div class="input-append pull-right" data-bind="visible: allowSearch">
<input type="search" class="i18n span4 inputSearch" tabindex="-1" <div class="close-input-wrp">
placeholder="Search" autocorrect="off" autocapitalize="off" <a class="close" data-bind="click: cancelSearch, visible: '' !== messageListSearchDesc()">&times;</a>
data-i18n="[placeholder]SEARCH/MAIN_INPUT_PLACEHOLDER" data-bind="value: inputProxyMessageListSearch, onEnter: searchEnterAction, hasfocus: inputMessageListSearchFocus" /> <input type="search" class="i18n span4 inputSearch" tabindex="-1"
placeholder="Search" autocorrect="off" autocapitalize="off"
data-i18n="[placeholder]SEARCH/MAIN_INPUT_PLACEHOLDER" data-bind="value: inputProxyMessageListSearch, onEnter: searchEnterAction, hasfocus: inputMessageListSearchFocus" />
</div>
<a class="btn buttonMoreSearch" data-bind="visible: allowSearchAdv, click: advancedSearchClick"> <a class="btn buttonMoreSearch" data-bind="visible: allowSearchAdv, click: advancedSearchClick">
<span class="caret"></span> <span class="caret"></span>
</a> </a>
@ -162,7 +165,6 @@
<span class="i18n" data-i18n="MESSAGE_LIST/BACK_TO_MESSAGE_LIST"></span> <span class="i18n" data-i18n="MESSAGE_LIST/BACK_TO_MESSAGE_LIST"></span>
</div> </div>
<div class="listSearchDesc" data-bind="visible: '' !== messageListSearchDesc()"> <div class="listSearchDesc" data-bind="visible: '' !== messageListSearchDesc()">
<a class="close-custom" data-bind="click: cancelSearch">&times;</a>
<span data-bind="text: messageListSearchDesc"></span> <span data-bind="text: messageListSearchDesc"></span>
</div> </div>
<div class="listDragOver" data-bind="css: {'viewAppendArea': dragOver() && '' === messageListError() && !popupVisibility(), 'dragOverEnter': dragOverEnter }, initDom: dragOverArea"> <div class="listDragOver" data-bind="css: {'viewAppendArea': dragOver() && '' === messageListError() && !popupVisibility(), 'dragOverEnter': dragOverEnter }, initDom: dragOverArea">

View file

@ -74,7 +74,7 @@
<nobr> <nobr>
<div class="btn-group pull-right" style="margin-right: -8px;"> <div class="btn-group pull-right" style="margin-right: -8px;">
<div class="btn-group pull-right" data-bind="registrateBootstrapDropdown: true, visible: allowComposer || allowMessageListActions || allowMessageActions"> <div class="btn-group pull-right" data-bind="registrateBootstrapDropdown: true, visible: allowComposer || allowMessageListActions || allowMessageActions">
<a class="btn btn-thin btn-transparent last btn-dark-disabled-border dropdown-toggle buttonMore" id="more-view-dropdown-id" href="#" tabindex="-1" data-toggle="dropdown" data-tooltip-join="bottom" style="margin-left: -1px;" data-bind="command: messageVisibilityCommand, tooltip: 'MESSAGE/BUTTON_MORE', css: {'first': !allowComposer}"> <a class="btn btn-thin-2 btn-transparent last btn-dark-disabled-border dropdown-toggle buttonMore" id="more-view-dropdown-id" href="#" tabindex="-1" data-toggle="dropdown" data-tooltip-join="bottom" style="margin-left: -4px; margin-right: 2px" data-bind="command: messageVisibilityCommand, tooltip: 'MESSAGE/BUTTON_MORE', css: {'first': !allowComposer}">
<span data-bind="visible: !allowComposer" class="icon-ellipsis-alt"></span> <span data-bind="visible: !allowComposer" class="icon-ellipsis-alt"></span>
<span data-bind="visible: allowComposer" class="caret"></span> <span data-bind="visible: allowComposer" class="caret"></span>
</a> </a>
@ -183,15 +183,15 @@
</div> </div>
</ul> </ul>
</div> </div>
<a class="btn btn-thin btn-transparent first btn-dark-disabled-border buttonReply pull-right" data-tooltip-join="bottom" <a class="btn btn-thin-2 btn-transparent first btn-dark-disabled-border buttonReply pull-right" data-tooltip-join="bottom"
data-bind="visible: 'reply' === lastReplyAction() && allowComposer, command: replyCommand, tooltip: 'MESSAGE/BUTTON_REPLY'"> data-bind="visible: 'reply' === lastReplyAction() && allowComposer, command: replyCommand, tooltip: 'MESSAGE/BUTTON_REPLY'">
<i class="icon-reply"></i> <i class="icon-reply"></i>
</a> </a>
<a class="btn btn-thin btn-transparent first btn-dark-disabled-border buttonReplyAll pull-right" data-tooltip-join="bottom" <a class="btn btn-thin-2 btn-transparent first btn-dark-disabled-border buttonReplyAll pull-right" data-tooltip-join="bottom"
data-bind="visible: 'replyall' === lastReplyAction() && allowComposer, command: replyAllCommand, tooltip: 'MESSAGE/BUTTON_REPLY_ALL'"> data-bind="visible: 'replyall' === lastReplyAction() && allowComposer, command: replyAllCommand, tooltip: 'MESSAGE/BUTTON_REPLY_ALL'">
<i class="icon-reply-all"></i> <i class="icon-reply-all"></i>
</a> </a>
<a class="btn btn-thin btn-transparent first btn-dark-disabled-border buttonForward pull-right" data-tooltip-join="bottom" <a class="btn btn-thin-2 btn-transparent first btn-dark-disabled-border buttonForward pull-right" data-tooltip-join="bottom"
data-bind="visible: 'forward' === lastReplyAction() && allowComposer, command: forwardCommand, tooltip: 'MESSAGE/BUTTON_FORWARD'"> data-bind="visible: 'forward' === lastReplyAction() && allowComposer, command: forwardCommand, tooltip: 'MESSAGE/BUTTON_FORWARD'">
<i class="icon-forward"></i> <i class="icon-forward"></i>
</a> </a>

View file

@ -18,7 +18,7 @@
<a class="btn btn-danger button-delete button-delete-transitions" data-bind="command: deleteCommand"> <a class="btn btn-danger button-delete button-delete-transitions" data-bind="command: deleteCommand">
<i class="icon-trash icon-white"></i> <i class="icon-trash icon-white"></i>
</a> </a>
<span class="saved-text" data-bind="text: savedTimeText"></span> <span class="saved-text hide-on-mobile" data-bind="text: savedTimeText"></span>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div> <div>

View file

@ -8,80 +8,76 @@
</h3> </h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row" style="margin-top: 10px;"> <div class="form-horizontal" data-bind="visible: capaTwoFactor" style="margin-top: 10px;">
<div class="control-group" data-bind="visible: twoFactorStatus">
<div class="form-horizontal" data-bind="visible: capaTwoFactor"> <div class="controls">
<div class="control-group" data-bind="visible: twoFactorStatus"> <div style="display: inline-block" data-tooltip-join="top" data-bind="tooltip: viewTwoFactorEnableTooltip">
<div class="controls"> <div data-bind="component: {
<div style="display: inline-block" data-tooltip-join="top" data-bind="tooltip: viewTwoFactorEnableTooltip"> name: 'Checkbox',
<div data-bind="component: { params: {
name: 'Checkbox', label: 'POPUPS_TWO_FACTOR_CFG/LABEL_ENABLE_TWO_FACTOR',
params: { enable: twoFactorAllowedEnable,
label: 'POPUPS_TWO_FACTOR_CFG/LABEL_ENABLE_TWO_FACTOR', value: viewEnable,
enable: twoFactorAllowedEnable, inline: true
value: viewEnable, }
inline: true }"></div>
} </div>
}"></div> &nbsp;&nbsp;&nbsp;
<span class="i18n g-ui-link" data-bind="click: testTwoFactor, visible: twoFactorStatus"
data-i18n="POPUPS_TWO_FACTOR_CFG/LINK_TEST"></span>
</div>
</div>
<div class="control-group">
<label class="control-label">
<span class="i18n" data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_USER"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<strong><span data-bind="text: viewUser"></span></strong>
<div style="padding-top: 15px;" data-bind="visible: lock">
<blockquote>
<p class="muted i18n width100-on-mobile" style="width: 550px" data-i18n="POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_REQUIRE_DESC"></p>
</blockquote>
</div>
</div>
</div>
<div class="control-group" data-bind="visible: '' === viewSecret() && twoFactorStatus() && !clearing()">
<div class="controls" style="padding-top: 5px;">
<strong data-bind="visible: secreting">...</strong>
<span class="g-ui-link i18n" data-bind="click: showSecret, visible: !secreting()"
data-i18n="POPUPS_TWO_FACTOR_CFG/BUTTON_SHOW_SECRET"></span>
</div>
</div>
<div class="control-group" data-bind="visible: '' !== viewSecret()">
<label class="control-label">
<span class="i18n" data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_SECRET"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<strong data-bind="text: viewSecret"></strong>
&nbsp;&nbsp;
<span class="g-ui-link i18n" data-bind="click: hideSecret" data-i18n="POPUPS_TWO_FACTOR_CFG/BUTTON_HIDE_SECRET"></span>
<br />
<br />
<blockquote>
<p class="muted i18n width100-on-mobile" style="width: 550px" data-i18n="POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_DESC"></p>
</blockquote>
<!-- ko if: '' !== viewUrl() -->
<img style="margin-left: -7px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII=" data-bind="attr: {'src': viewUrl}" />
<!-- /ko -->
</div>
</div>
<div class="control-group" data-bind="visible: '' !== viewBackupCodes()">
<label class="control-label">
<span class="i18n" data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_BACKUP_CODES"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<pre data-bind="text: viewBackupCodes" style="width: 230px; word-break: break-word;"></pre>
<br />
<blockquote>
<p class="muted i18n width100-on-mobile" style="width: 550px" data-i18n="POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_BACKUP_CODES_DESC"></p>
</blockquote>
</div>
</div>
</div> </div>
&nbsp;&nbsp;&nbsp;
<span class="i18n g-ui-link" data-bind="click: testTwoFactor, visible: twoFactorStatus"
data-i18n="POPUPS_TWO_FACTOR_CFG/LINK_TEST"></span>
</div>
</div>
<div class="control-group">
<label class="control-label">
<span class="i18n" data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_USER"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<strong><span data-bind="text: viewUser"></span></strong>
<div style="padding-top: 15px;" data-bind="visible: lock">
<blockquote>
<p class="muted i18n" style="width: 550px" data-i18n="POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_REQUIRE_DESC"></p>
</blockquote>
</div>
</div>
</div>
<div class="control-group" data-bind="visible: '' === viewSecret() && twoFactorStatus() && !clearing()">
<div class="controls" style="padding-top: 5px;">
<strong data-bind="visible: secreting">...</strong>
<span class="g-ui-link i18n" data-bind="click: showSecret, visible: !secreting()"
data-i18n="POPUPS_TWO_FACTOR_CFG/BUTTON_SHOW_SECRET"></span>
</div>
</div>
<div class="control-group" data-bind="visible: '' !== viewSecret()">
<label class="control-label">
<span class="i18n" data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_SECRET"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<strong data-bind="text: viewSecret"></strong>
&nbsp;&nbsp;
<span class="g-ui-link i18n" data-bind="click: hideSecret" data-i18n="POPUPS_TWO_FACTOR_CFG/BUTTON_HIDE_SECRET"></span>
<br />
<br />
<blockquote>
<p class="muted i18n" style="width: 550px" data-i18n="POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_DESC"></p>
</blockquote>
<!-- ko if: '' !== viewUrl() -->
<img style="margin-left: -7px;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII=" data-bind="attr: {'src': viewUrl}" />
<!-- /ko -->
</div>
</div>
<div class="control-group" data-bind="visible: '' !== viewBackupCodes()">
<label class="control-label">
<span class="i18n" data-i18n="POPUPS_TWO_FACTOR_CFG/LABEL_TWO_FACTOR_BACKUP_CODES"></span>
</label>
<div class="controls" style="padding-top: 5px;">
<pre data-bind="text: viewBackupCodes" style="width: 230px; word-break: break-word;"></pre>
<br />
<blockquote>
<p class="muted i18n" style="width: 550px" data-i18n="POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_BACKUP_CODES_DESC"></p>
</blockquote>
</div>
</div>
</div>
</div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a class="btn pull-left" data-bind="visible: lock, click: logout"> <a class="btn pull-left" data-bind="visible: lock, click: logout">

View file

@ -13,16 +13,16 @@
<!-- /ko --> <!-- /ko -->
</div> </div>
</div> </div>
<div class="b-content show-on-panel-disabled" data-bind="click: function () { leftPanelDisabled(false); }"></div> <div class="b-content show-on-panel-disabled" data-bind="click: function () { leftPanelDisabled(false); }"></div>
<div class="b-footer"> <div class="b-footer">
<nobr> <nobr>
<div class="btn-toolbar"> <div class="btn-toolbar">
<div class="btn-group"> <div class="btn-group">
<a class="btn single buttonResize" data-bind="click: function () { leftPanelDisabled(!leftPanelDisabled()); }"> <a class="btn single buttonResize" data-bind="click: function () { leftPanelDisabled(!leftPanelDisabled()); }">
<i data-bind="css: {'icon-resize-out': leftPanelDisabled(), 'icon-resize-in': !leftPanelDisabled()}"></i> <i data-bind="css: {'icon-resize-out': leftPanelDisabled(), 'icon-resize-in': !leftPanelDisabled()}"></i>
</a> </a>
</div> </div>
</div> </div>
</nobr> </nobr>
</div> </div>
</div> </div>

View file

@ -2,12 +2,12 @@
<div class="b-toolbar" style="padding-left: 0"> <div class="b-toolbar" style="padding-left: 0">
<div class="btn-toolbar" style="margin-top: 2px;"> <div class="btn-toolbar" style="margin-top: 2px;">
<div class="btn-group" data-bind="visible: mobile && leftPanelDisabled()"> <div class="btn-group" data-bind="visible: mobile && leftPanelDisabled()">
<a class="btn single" data-bind="click: showLeft"> <a class="btn btn-thin-2 single" data-bind="click: showLeft">
<i class="icon-right-middle"></i> <i class="icon-right-middle"></i>
</a> </a>
</div> </div>
<div class="btn-group" data-bind="visible: mobile && !leftPanelDisabled()" style="margin-left: -1px"> <div class="btn-group" data-bind="visible: mobile && !leftPanelDisabled()" style="margin-left: -1px">
<a class="btn single" data-bind="click: hideLeft"> <a class="btn btn-thin-2 single" data-bind="click: hideLeft">
<i class="icon-left-middle"></i> <i class="icon-left-middle"></i>
</a> </a>
</div> </div>

View file

@ -0,0 +1,18 @@
.b-login-content .loginFormWrapper {
width: 90%;
.wrapper {
padding: 30px 30px 10px 30px;
}
}
.thm-login {
width: 100% !important;
width: calc(~'100% - 60px') !important;
max-width: 303px !important;
box-shadow: 0 1px 4px #ccc !important;
box-shadow: 0 1px 5px rgba(0,0,0,.2) !important;
box-shadow: 0 0 0 1px rgba(0,0,0,.04),0 1px 5px rgba(0,0,0,.1) !important;
}