Cleanup more CSS and JS

and merge/cleanup/redesign composer attachments
This commit is contained in:
djmaze 2021-02-22 15:16:33 +01:00
parent fe45179847
commit e52b9abc61
23 changed files with 156 additions and 293 deletions

View file

@ -405,13 +405,7 @@ class AppUser extends AbstractApp {
prom prom
.then((value) => !!value) .then((value) => !!value)
.then(callback) .then(callback)
.catch(() => { .catch(() => callback && setTimeout(() => callback(false), 1));
setTimeout(() => {
if (callback) {
callback(false); // eslint-disable-line callback-return
}
}, 1);
});
} }
} }

View file

@ -133,7 +133,7 @@ export const FileInfo = {
getContentType: fileName => { getContentType: fileName => {
fileName = fileName.toLowerCase().trim(); fileName = fileName.toLowerCase().trim();
if ('winmail.dat' === fileName) { if ('winmail.dat' === fileName) {
return 'application/ms-tnef'; return app + 'ms-tnef';
} }
let ext = fileName.split('.').pop(); let ext = fileName.split('.').pop();
if (/^(txt|text|def|list|in|ini|log|sql|cfg|conf|asc)$/.test(ext)) if (/^(txt|text|def|list|in|ini|log|sql|cfg|conf|asc)$/.test(ext))
@ -171,49 +171,42 @@ export const FileInfo = {
let result = FileType.Unknown; let result = FileType.Unknown;
const mimeTypeParts = mimeType.split('/'), const mimeTypeParts = mimeType.split('/'),
type = mimeTypeParts[1].replace('x-','').replace('-compressed',''), type = mimeTypeParts[1].replace('x-','').replace('-compressed',''),
match = str => type.includes(str); match = str => mimeType.includes(str),
archive = /^(zip|7z|tar|rar|gzip|bzip|bzip2)$/;
switch (true) { switch (true) {
case 'image' === mimeTypeParts[0] || ['png', 'jpg', 'jpeg', 'gif', 'webp'].includes(ext): case 'image' == mimeTypeParts[0] || ['png', 'jpg', 'jpeg', 'gif', 'webp'].includes(ext):
result = FileType.Image; result = FileType.Image;
break; break;
case 'audio' === mimeTypeParts[0] || ['mp3', 'ogg', 'oga', 'wav'].includes(ext): case 'audio' == mimeTypeParts[0] || ['mp3', 'ogg', 'oga', 'wav'].includes(ext):
result = FileType.Audio; result = FileType.Audio;
break; break;
case 'video' === mimeTypeParts[0] || ['mkv', 'avi'].includes(ext): case 'video' == mimeTypeParts[0] || 'mkv' == ext || 'avi' == ext:
result = FileType.Video; result = FileType.Video;
break; break;
case ['php', 'js', 'css'].includes(ext): case ['php', 'js', 'css'].includes(ext):
result = FileType.Code; result = FileType.Code;
break; break;
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 'text/html' === mimeType || ['html'].includes(ext): case 'text/html' == mimeType || 'html' == ext:
result = FileType.Html; result = FileType.Html;
break; break;
case 'text' === mimeTypeParts[0] || ['txt', 'log'].includes(ext): case 'text' == mimeTypeParts[0] || 'txt' == ext || 'log' == ext:
result = FileType.Text; result = FileType.Text;
break; break;
case [ case archive.test(type) || archive.test(ext):
'zip',
'7z',
'tar',
'rar',
'gzip',
'bzip',
'bzip2'
].includes(type) || ['zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2'].includes(ext):
result = FileType.Archive; result = FileType.Archive;
break; break;
case 'pdf' == type || 'pdf' == ext: case 'pdf' == type || 'pdf' == ext:
result = FileType.Pdf; result = FileType.Pdf;
break; break;
case ['application/pgp-signature', 'application/pgp-keys'].includes(mimeType) || case [app+'pgp-signature', app+'pgp-keys'].includes(mimeType) ||
['asc', 'pem', 'ppk'].includes(ext): ['asc', 'pem', 'ppk'].includes(ext):
result = FileType.Certificate; result = FileType.Certificate;
break; break;
case ['application/pkcs7-signature'].includes(mimeType) || 'p7s' == ext: case [app+'pkcs7-signature'].includes(mimeType) || 'p7s' == ext:
result = FileType.CertificateBin; result = FileType.CertificateBin;
break; break;
case match(msOffice+'.wordprocessingml') || match(openDoc+'.text') || match('vnd.ms-word') case match(msOffice+'.wordprocessingml') || match(openDoc+'.text') || match('vnd.ms-word')
@ -228,6 +221,7 @@ export const FileInfo = {
break; break;
// no default // no default
} }
return cache[key] = result; return cache[key] = result;
}, },
@ -270,10 +264,11 @@ export const FileInfo = {
result[0] += '-chart-graph'; result[0] += '-chart-graph';
break; break;
case FileType.Pdf: case FileType.Pdf:
result['icon-none', 'pdf']; result = ['icon-none', 'pdf'];
break; break;
// no default // no default
} }
return result; return result;
}, },

View file

@ -1,8 +1,18 @@
const config = { export function createCKEditor(element)
{
const language = (rl.settings.get('Language') || 'en').toLowerCase(),
htmlEditorLangsMap = {
'ar_sa': 'ar-sa',
'pt_br': 'pt-br',
'zh_cn': 'zh-cn',
};
const editor = CKEDITOR.appendTo(element, {
title: false, title: false,
stylesSet: false, stylesSet: false,
customConfig: '', // customConfig: '',
contentsCss: '', // contentsCss: '',
toolbarGroups: [ toolbarGroups: [
{ name: 'spec' }, { name: 'spec' },
{ name: 'styles' }, { name: 'styles' },
@ -15,8 +25,9 @@ const config = {
{ name: 'others' } { name: 'others' }
], ],
removePlugins: 'liststyle', removePlugins: 'liststyle' + (rl.settings.app('allowHtmlEditorBitiButtons') ? '' : ',bidi'),
removeButtons: 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll', removeButtons: 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll'
+ (rl.settings.app('allowHtmlEditorSourceButton') ? '' : ',Source'),
removeDialogTabs: 'link:advanced;link:target;image:advanced;images:advanced', removeDialogTabs: 'link:advanced;link:target;image:advanced;images:advanced',
extraPlugins: 'plain,signature', extraPlugins: 'plain,signature',
@ -25,61 +36,29 @@ const config = {
extraAllowedContent: true, extraAllowedContent: true,
fillEmptyBlocks: false, fillEmptyBlocks: false,
ignoreEmptyParagraph: true, // ignoreEmptyParagraph: true,
disableNativeSpellChecker: false, disableNativeSpellChecker: false,
colorButton_enableAutomatic: false, colorButton_enableAutomatic: false,
colorButton_enableMore: true, // colorButton_enableMore: true,
font_defaultLabel: 'Arial', font_defaultLabel: 'Arial',
fontSize_defaultLabel: '13', fontSize_defaultLabel: '13',
fontSize_sizes: '10/10px;12/12px;13/13px;14/14px;16/16px;18/18px;20/20px;24/24px;28/28px;36/36px;48/48px' fontSize_sizes: '10/10px;12/12px;13/13px;14/14px;16/16px;18/18px;20/20px;24/24px;28/28px;36/36px;48/48px',
},
htmlEditorLangsMap = { enterMode: CKEDITOR.ENTER_BR,
'ar_sa': 'ar-sa', shiftEnterMode: CKEDITOR.ENTER_P,
'pt_br': 'pt-br', language: htmlEditorLangsMap[language] || language.substr(0,2)
'zh_cn': 'zh-cn', });
};
export function createCKEditor(element)
{
const language = (rl.settings.get('Language') || 'en').toLowerCase(),
noSource = !rl.settings.app('allowHtmlEditorSourceButton'),
noBidi = !rl.settings.app('allowHtmlEditorBitiButtons');
if (!config.__cfgInited) {
config.__cfgInited = true;
if (noSource) {
config.removeButtons += ',Source';
}
if (noBidi) {
config.removePlugins += ',bidi';
}
}
config.enterMode = CKEDITOR.ENTER_BR;
config.shiftEnterMode = CKEDITOR.ENTER_P;
config.language = htmlEditorLangsMap[language] || language.substr(0,2);
if (CKEDITOR.env) {
CKEDITOR.env.isCompatible = true;
}
const editor = CKEDITOR.appendTo(element, config);
editor.on('key', event => !(event && event.data && 'Tab' == event.data.key)); editor.on('key', event => !(event && event.data && 'Tab' == event.data.key));
if (window.FileReader) {
editor.on('drop', event => { editor.on('drop', event => {
if (0 < event.data.dataTransfer.getFilesCount()) { const dt = event.data.dataTransfer,
const file = event.data.dataTransfer.getFile(0); id = dt.id,
if (file && event.data.dataTransfer.id && file.type && file.type.match(/^image/i)) { file = dt.getFilesCount() ? dt.getFile(0) : 0;
const id = event.data.dataTransfer.id, if (file && id && file.type && file.type.match(/^image/i)) {
imageId = `[img=${id}]`, const imageId = `[img=${id}]`,
reader = new FileReader(); reader = new FileReader();
reader.onloadend = () => { reader.onloadend = () => {
@ -92,11 +71,9 @@ export function createCKEditor(element)
reader.readAsDataURL(file); reader.readAsDataURL(file);
event.data.dataTransfer.setData('text/html', imageId); dt.setData('text/html', imageId);
}
} }
}); });
}
return editor; return editor;
} }

View file

@ -51,22 +51,11 @@
.attachmentIconParent { .attachmentIconParent {
position: relative; position: absolute;
height: 56px; height: 56px;
width: 60px; width: 60px;
background: none; background: none;
text-align: center;
.iconPreview, .iconBG, .iconMain, .iconProgress {
position: absolute;
top: 0;
left: 0;
display: inline-block;
width: 100%;
height: 100%;
}
.iconProgress { .iconProgress {
background: #eee; background: #eee;
@ -75,21 +64,15 @@
.iconBG { .iconBG {
font-size: 18px; font-size: 18px;
text-align: center;
color: #999; color: #999;
font-weight: bold; font-weight: bold;
line-height: 55px; line-height: 55px;
text-shadow: 0 1px 0 #fff;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8);
} }
.iconPreview { .iconPreview {
display: none; display: none;
background: #555;
background-image: none;
background: rgba(0, 0, 0, .5) !important; background: rgba(0, 0, 0, .5) !important;
color: #fff; color: #fff;
text-shadow: 0 1px 0 #000; text-shadow: 0 1px 0 #000;
} }
@ -111,20 +94,15 @@
} }
.attachmentIcon { .attachmentIcon {
margin: 6px 0 0 13px; margin: 6px 0 0;
font-size: 36px; font-size: 36px;
width: 36px; width: 36px;
height: 36px; height: 36px;
color: #aaa; color: #aaa;
}
.attachmentIcon {
&.icon-none { &.icon-none {
display: none; display: none;
} }
&.icon-file-certificate {
margin-left: 15px;
}
} }
.attachmentIconText { .attachmentIconText {
@ -134,7 +112,6 @@
height: 56px; height: 56px;
color: #aaa; color: #aaa;
line-height: 56px; line-height: 56px;
text-align: center;
font-style: normal; font-style: normal;
} }
@ -146,45 +123,22 @@
} }
*/ */
.attachmentIconParent.hasPreview:hover { .showPreview, .showPreplay,
.iconPreview { .attachmentIconParent.hasPreview:hover .iconMain,
display: inline-block; .attachmentIconParent.hasPreplay:hover .iconMain,
} .attachmentIconParent.hasPreview .hidePreview,
.iconMain { .attachmentIconParent.hasPreplay .hidePreview {
display: none; display: none;
} }
}
.attachmentIconParent.hasPreplay:hover { .attachmentIconParent.hasPreview:hover .iconPreview,
.iconPreview { .attachmentIconParent.hasPreplay:hover .iconPreview {
display: inline-block; display: inline-block;
} }
.iconMain {
display: none;
}
}
.showPreview, .showPreplay { .attachmentIconParent.hasPreview .showPreview,
display: none; .attachmentIconParent.hasPreplay .showPreview {
display: inline;
cursor: pointer; cursor: pointer;
} }
.attachmentIconParent.hasPreview {
.showPreview {
display: inline;
}
.hidePreview {
display: none;
}
}
.attachmentIconParent.hasPreplay {
.showPreplay {
display: inline;
}
.hidePreview {
display: none;
}
}
} }

View file

@ -43,7 +43,6 @@
.b-header-toolbar { .b-header-toolbar {
height: 40px;
color: #fff; color: #fff;
background-color: rgba(0,0,0,0.8); background-color: rgba(0,0,0,0.8);

View file

@ -7,7 +7,7 @@
cursor: text; cursor: text;
font-size: 90%; font-size: 90%;
list-style: none; list-style: none;
margin: 0 5px 0 0; margin: 0;
padding: 0; padding: 0;
transition: border linear .2s, box-shadow linear .2s; transition: border linear .2s, box-shadow linear .2s;
} }

View file

@ -64,7 +64,7 @@
} }
} }
.b-list-delimiter { hr {
margin: 10px; margin: 10px;
border-top: 0 solid #000; border-top: 0 solid #000;
border-bottom: 1px solid #999; border-bottom: 1px solid #999;
@ -175,10 +175,6 @@
.e-collapsed-sign { .e-collapsed-sign {
cursor: pointer; cursor: pointer;
width: 22px;
height: 30px;
line-height: 30px;
text-align: center;
vertical-align: inherit; vertical-align: inherit;
} }
} }

View file

@ -309,6 +309,7 @@ html.rl-no-preview-pane {
} }
} }
html.rl-mobile #rl-left > .resizer,
html.rl-side-preview-pane:not(.rl-mobile) #rl-right .resizer { html.rl-side-preview-pane:not(.rl-mobile) #rl-right .resizer {
display: none !important; display: none !important;
} }

View file

@ -344,11 +344,6 @@ html.rl-no-preview-pane {
margin-right: 2px; margin-right: 2px;
border: 1px solid #ccc; border: 1px solid #ccc;
[class^="icon-"],
[class*=" icon-"] {
font-size: 14px;
}
&:hover { &:hover {
background-color: #aaa; background-color: #aaa;
border-color: #666; border-color: #666;

View file

@ -1,8 +1,4 @@
label {
cursor: pointer;
}
label.inline, span.inline { label.inline, span.inline {
display: inline-block; display: inline-block;
} }
@ -49,12 +45,6 @@ label.inline, span.inline {
box-shadow: none !important; box-shadow: none !important;
opacity: .6; opacity: .6;
[class^="icon-"] {
width: 19px;
height: 19px;
font-size: 19px;
}
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
@ -65,9 +55,6 @@ label.inline, span.inline {
.caret { .caret {
border-top-color: #BD362F; border-top-color: #BD362F;
} }
[class^="icon-"]:before {
color: #BD362F;
}
} }
.dropdown-menu * + .dividerbar { .dropdown-menu * + .dividerbar {
@ -86,10 +73,6 @@ label.inline, span.inline {
.caret { .caret {
border-top-color: #BD362F; border-top-color: #BD362F;
} }
[class^="icon-"]:before {
color: #BD362F;
}
} }
.alert a { .alert a {

View file

@ -19,34 +19,11 @@
} }
} }
.iconsize20 { /* .b-contacts-content .b-view-content */
font-size: 20px;
}
.iconsize24 { .iconsize24 {
font-size: 24px; font-size: 24px;
} }
/* White icons with optional class, or on hover/active states of certain elements */
.icon-white,
.nav > .active > a > [class^="icon-"],
.nav > .active > a > [class*=" icon-"] {
color: #fff;
}
.g-ui-menu .e-item:hover [class^="icon-"],
.g-ui-menu .e-item:hover [class*=" icon-"] {
color: #fff;
}
.icon-none {
background-image: none !important;
}
.iconcolor-display-none {
display: none;
}
.iconcolor-green { .iconcolor-green {
color: green; color: green;
} }
@ -69,25 +46,21 @@
border: 3px solid #aaa; border: 3px solid #aaa;
border-top-color: #333; border-top-color: #333;
border-radius: 100%; border-radius: 100%;
&.big {
height: 13px;
width: 13px;
margin: -1px -2px;
} }
&.white, &.icon-white { .btn-success .icon-spinner {
border-color: #fff; border-color: #fff;
border-top-color: #999; border-top-color: #999;
&.animated { &.animated {
border-color: transparent; border-color: transparent;
border-top-color: #fff; border-top-color: #fff;
} }
} }
.btn-large .icon-spinner {
height: 13px;
width: 13px;
margin: -1px -2px;
} }
.icon-spinner:not(.not-animated) { .icon-spinner:not(.not-animated) {

View file

@ -174,7 +174,7 @@ class MessageViewMailBoxUserView extends AbstractViewRight {
viewFromDkimStatusIconClass:() => { viewFromDkimStatusIconClass:() => {
switch (this.viewFromDkimData()[0]) { switch (this.viewFromDkimData()[0]) {
case 'none': case 'none':
return 'icon-none iconcolor-display-none'; return '';
case 'pass': case 'pass':
return 'icon-ok iconcolor-green'; return 'icon-ok iconcolor-green';
default: default:

View file

@ -102,7 +102,7 @@
<div class="control-group"> <div class="control-group">
<div class="controls"> <div class="controls">
<a class="btn" data-bind="command: saveNewAdminPasswordCommand, css: { 'btn-success': adminPasswordUpdateSuccess, 'btn-danger': adminPasswordUpdateError }"> <a class="btn" data-bind="command: saveNewAdminPasswordCommand, css: { 'btn-success': adminPasswordUpdateSuccess, 'btn-danger': adminPasswordUpdateError }">
<i class="fontastic" data-bind="css: {'icon-white': adminPasswordUpdateSuccess() || adminPasswordUpdateError() }">🔑</i> <i class="fontastic">🔑</i>
<span data-i18n="TAB_SECURITY/BUTTON_UPDATE_PASSWORD"></span> <span data-i18n="TAB_SECURITY/BUTTON_UPDATE_PASSWORD"></span>
</a> </a>
</div> </div>

View file

@ -1,19 +0,0 @@
<li class="attachmentItem clearfix" data-bind="attr: { 'title': title }, css: { 'waiting': waiting, 'error': '' !== error() }">
<div class="attachmentIconParent pull-left">
<div class="iconMain">
<i class="attachmentIcon attachmentMainIcon" data-bind="css: iconClass(), visible: !uploading() || 0 === progress()"></i>
<i class="attachmentIconText attachmentMainIconText" data-bind="text: iconText(), visible: !uploading() || 0 === progress()"></i>
</div>
<div class="iconProgress" data-bind="attr: { 'style': progressStyle }, visible: uploading"></div>
<div class="iconBG" data-bind="text: progressText, visible: uploading"></div>
</div>
<div class="attachmentNameParent">
<button type="button" class="close pull-right" style="margin-top:-4px;" data-bind="click: cancel">×</button>
<div style="white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">
<span class="attachmentName" data-bind="text: fileName"></span>&nbsp;
</div>
<div>
<span class="attachmentSize" data-bind="text: friendlySize"></span>&nbsp;
</div>
</div>
</li>

View file

@ -10,7 +10,7 @@
<div class="content"> <div class="content">
<div class="content-wrapper"> <div class="content-wrapper">
<div class="b-folders-system" data-bind="template: { name: 'MailFolderListSystemItem', foreach: folderListSystem }"></div> <div class="b-folders-system" data-bind="template: { name: 'MailFolderListSystemItem', foreach: folderListSystem }"></div>
<hr class="b-list-delimiter" /> <hr/>
<div class="b-folders-user" data-bind="template: { name: 'MailFolderListItem', foreach: folderList }"></div> <div class="b-folders-user" data-bind="template: { name: 'MailFolderListItem', foreach: folderList }"></div>
<div class="move-action-content-wrapper" data-bind="visible: moveAction"></div> <div class="move-action-content-wrapper" data-bind="visible: moveAction"></div>
</div> </div>

View file

@ -193,7 +193,7 @@
</div> </div>
</div> </div>
<div id="messagesDragImage"><span class="text"></span>&nbsp;<i class="icon-mail icon-white"></i></div> <div id="messagesDragImage"><span class="text"></span>&nbsp;<i class="icon-mail"></i></div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -169,13 +169,11 @@
<div> <div>
<div style="overflow: hidden;"> <div style="overflow: hidden;">
<div class="informationShort" data-bind="event: { 'dblclick': toggleFullScreen }"> <div class="informationShort" data-bind="event: { 'dblclick': toggleFullScreen }">
<span>
<span class="from" data-bind="html: viewFromShort, title: viewFrom"></span> <span class="from" data-bind="html: viewFromShort, title: viewFrom"></span>
<span data-bind="visible: viewFromDkimVisibility"> <span data-bind="visible: viewFromDkimVisibility">
&nbsp; &nbsp;
<i data-bind="css: viewFromDkimStatusIconClass, title: viewFromDkimStatusTitle"></i> <i data-bind="css: viewFromDkimStatusIconClass, title: viewFromDkimStatusTitle"></i>
</span> </span>
</span>
<span data-bind="visible: 0 < viewTimeStamp()"> <span data-bind="visible: 0 < viewTimeStamp()">
(<time class="date" data-moment-format="FULL" data-bind="moment: viewTimeStamp"></time>) (<time class="date" data-moment-format="FULL" data-bind="moment: viewTimeStamp"></time>)
</span> </span>

View file

@ -1,11 +1,11 @@
<div class="modal fade b-compose" data-bind="modal: modalVisibility, css: {'loading': saving() || sending()}"> <div class="modal fade b-compose" data-bind="modal: modalVisibility, css: {'loading': saving() || sending()}">
<div class="modal-header b-header-toolbar g-ui-user-select-none"> <div class="modal-header b-header-toolbar g-ui-user-select-none">
<a class="btn btn-large button-send" data-bind="command: sendCommand, tooltipErrorTip: sendErrorDesc, css: {'btn-success': sendButtonSuccess, 'btn-danger': sendError, 'btn-warning': sendSuccessButSaveError }"> <a class="btn button-send" data-bind="command: sendCommand, tooltipErrorTip: sendErrorDesc, css: {'btn-success': sendButtonSuccess, 'btn-danger': sendError, 'btn-warning': sendSuccessButSaveError }">
<i class="icon-white" data-bind="css: {'icon-paper-plane': !sending(), 'icon-spinner big': sending()}"></i> <i data-bind="css: {'icon-paper-plane': !sending(), 'icon-spinner': sending()}"></i>
<span class="hide-mobile" data-i18n="COMPOSE/BUTTON_SEND"></span> <span class="hide-mobile" data-i18n="COMPOSE/BUTTON_SEND"></span>
</a> </a>
<a class="btn button-save" data-bind="visible: allowFolders, command: saveCommand, tooltipErrorTip: savedErrorDesc, css: {'btn-danger': savedError }"> <a class="btn button-save" data-bind="visible: allowFolders, command: saveCommand, tooltipErrorTip: savedErrorDesc, css: {'btn-danger': savedError }">
<i class="fontastic" data-bind="css: {'icon-spinner': saving(), 'icon-white': savedError()}">💾</i> <i class="fontastic" data-bind="css: {'icon-spinner': saving()}">💾</i>
<span class="hide-mobile" data-i18n="GLOBAL/SAVE"></span> <span class="hide-mobile" data-i18n="GLOBAL/SAVE"></span>
</a> </a>
@ -13,7 +13,7 @@
<a class="minimize-custom" data-bind="click: skipCommand, tooltip: 'COMPOSE/BUTTON_MINIMIZE'"></a> <a class="minimize-custom" data-bind="click: skipCommand, tooltip: 'COMPOSE/BUTTON_MINIMIZE'"></a>
<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="fontastic icon-white">🗑</i> <i class="fontastic">🗑</i>
</a> </a>
<span class="saved-text hide-mobile" data-bind="text: savedTimeText"></span> <span class="saved-text hide-mobile" data-bind="text: savedTimeText"></span>
</div> </div>
@ -155,7 +155,7 @@
<b data-bind="text: attachmentsCount"></b> <b data-bind="text: attachmentsCount"></b>
&nbsp;&nbsp; &nbsp;&nbsp;
</span> </span>
<i data-bind="css: { 'icon-attachment': 0 === attachmentsInProcessCount(), 'icon-spinner': 0 < attachmentsInProcessCount(), 'icon-white': 0 < attachmentsInErrorCount() }"></i> <i data-bind="css: { 'icon-attachment': 0 === attachmentsInProcessCount(), 'icon-spinner': 0 < attachmentsInProcessCount()}"></i>
</button> </button>
</div> </div>
</div> </div>
@ -180,7 +180,27 @@
<div class="b-attachment-place" data-bind="visible: addAttachmentEnabled() && dragAndDropEnabled() && dragAndDropVisible(), initDom: composeUploaderDropPlace, css: {'dragAndDropOver': dragAndDropOver}"> <div class="b-attachment-place" data-bind="visible: addAttachmentEnabled() && dragAndDropEnabled() && dragAndDropVisible(), initDom: composeUploaderDropPlace, css: {'dragAndDropOver': dragAndDropOver}">
<span data-i18n="COMPOSE/ATTACH_DROP_FILES_DESC"></span> <span data-i18n="COMPOSE/ATTACH_DROP_FILES_DESC"></span>
</div> </div>
<ul class="attachmentList" data-bind="template: { name: 'ComposeAttachment', foreach: attachments }"></ul> <ul class="attachmentList" data-bind="foreach: attachments">
<li class="attachmentItem" data-bind="attr: { 'title': title }, css: { 'waiting': waiting, 'error': '' !== error() }">
<div class="attachmentIconParent">
<div class="iconMain">
<i class="attachmentIcon attachmentMainIcon" data-bind="css: iconClass(), visible: !uploading() || 0 === progress()"></i>
<i class="attachmentIconText attachmentMainIconText" data-bind="text: iconText(), visible: !uploading() || 0 === progress()"></i>
</div>
<div class="iconProgress" data-bind="attr: { 'style': progressStyle }, visible: uploading"></div>
<div class="iconBG" data-bind="text: progressText, visible: uploading"></div>
</div>
<div class="attachmentNameParent">
<button type="button" class="close pull-right" style="margin-top:-4px;" data-bind="click: cancel">×</button>
<div style="white-space: nowrap; text-overflow: ellipsis; overflow: hidden;">
<span class="attachmentName" data-bind="text: fileName"></span>&nbsp;
</div>
<div>
<span class="attachmentSize" data-bind="text: friendlySize"></span>&nbsp;
</div>
</div>
</li>
</ul>
<div class="no-attachments-desc" data-bind="visible: 0 === attachments().length"> <div class="no-attachments-desc" data-bind="visible: 0 === attachments().length">
<span data-i18n="COMPOSE/NO_ATTACHMENTS_HERE_DESC"></span> <span data-i18n="COMPOSE/NO_ATTACHMENTS_HERE_DESC"></span>
</div> </div>

View file

@ -14,7 +14,7 @@
<div class="btn-group"> <div class="btn-group">
<a class="btn btn-success button-new-message" data-bind="command: newMessageCommand"> <a class="btn btn-success button-new-message" data-bind="command: newMessageCommand">
<i class="icon-mail icon-white"></i> <i class="icon-mail"></i>
</a> </a>
</div> </div>

View file

@ -21,7 +21,7 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a class="btn" data-bind="command: testCodeCommand, css: { 'btn-success': true === codeStatus(), 'btn-danger': false === codeStatus() }"> <a class="btn" data-bind="command: testCodeCommand, css: { 'btn-success': true === codeStatus(), 'btn-danger': false === codeStatus() }">
<i data-bind="css: {'icon-ok': !testing(), 'icon-spinner': testing(), 'icon-white': true === codeStatus() || false === codeStatus() }"></i> <i data-bind="css: {'icon-ok': !testing(), 'icon-spinner': testing()}"></i>
<span data-i18n="GLOBAL/TEST"></span> <span data-i18n="GLOBAL/TEST"></span>
</a> </a>
</div> </div>

View file

@ -128,7 +128,7 @@
}"></div> }"></div>
&nbsp; &nbsp;
<span data-bind="visible: isDesktopNotificationDenied" style="color: #999" data-i18n="SETTINGS_GENERAL/LABEL_CHROME_NOTIFICATION_DESC_DENIED"></span> <span data-bind="visible: isDesktopNotificationDenied" style="color: #999" data-i18n="SETTINGS_GENERAL/LABEL_CHROME_NOTIFICATION_DESC_DENIED"></span>
<span class="fontastic iconsize20" data-bind="click: testSystemNotification" style="color:green;cursor:pointer">▶️</span> <span class="fontastic" data-bind="click: testSystemNotification" style="color:green;cursor:pointer">▶️</span>
</div> </div>
<div> <div>
<div data-bind="component: { <div data-bind="component: {
@ -140,7 +140,7 @@
} }
}"></div> }"></div>
&nbsp; &nbsp;
<span class="fontastic iconsize20" data-bind="click: testSoundNotification" style="color:green;cursor:pointer">▶️</span> <span class="fontastic" data-bind="click: testSoundNotification" style="color:green;cursor:pointer">▶️</span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -19,6 +19,7 @@ fieldset {
// Groups of fields with labels on top (legends) // Groups of fields with labels on top (legends)
legend { legend {
cursor: pointer;
display: block; display: block;
width: 100%; width: 100%;
padding: 0; padding: 0;

View file

@ -5,18 +5,14 @@
// Base classes // Base classes
.badge { .badge {
font-size: @baseFontSize * .846;
font-weight: bold;
line-height: 14px; // ensure proper line-height if floated
color: @white;
vertical-align: baseline;
white-space: nowrap;
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
background-color: @grayLight; background-color: @grayLight;
}
.badge {
padding: 1px 9px 2px;
border-radius: 9px; border-radius: 9px;
color: @white;
font-size: 80%;
min-width: 1em;
padding: 1px 4px;
text-align: center;
text-shadow: 0 -1px 0 rgba(0,0,0,.25);
} }
// Hover state, but only for links // Hover state, but only for links