diff options
Diffstat (limited to 'webapp')
73 files changed, 2159 insertions, 1548 deletions
diff --git a/webapp/Makefile b/webapp/Makefile index 99f896e53..88ee625a4 100644 --- a/webapp/Makefile +++ b/webapp/Makefile @@ -1,4 +1,4 @@ -.PHONY: build test +.PHONY: build test run clean test: @echo Checking for style guide compliance @@ -12,7 +12,20 @@ test: touch $@ -build: .npminstall - @echo Building mattermost web client +build: | .npminstall test + @echo Building mattermost Webapp npm run build + +run: .npminstall + @echo Running mattermost Webapp for development + + npm run run + + +clean: + @echo Cleaning Webapp + + rm -rf dist + rm -rf node_modules + rm .npminstall diff --git a/webapp/components/center_panel.jsx b/webapp/components/center_panel.jsx index 17e5e43d9..6c156f2a8 100644 --- a/webapp/components/center_panel.jsx +++ b/webapp/components/center_panel.jsx @@ -120,7 +120,10 @@ export default class CenterPanel extends React.Component { id='app-content' className='app__content' > - <div id='channel-header'> + <div + id='channel-header' + className='channel-header' + > <ChannelHeader user={this.state.user} /> diff --git a/webapp/components/code_preview.jsx b/webapp/components/code_preview.jsx new file mode 100644 index 000000000..e769ae590 --- /dev/null +++ b/webapp/components/code_preview.jsx @@ -0,0 +1,101 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import $ from 'jquery'; +import * as syntaxHightlighting from 'utils/syntax_hightlighting.jsx'; +import Constants from 'utils/constants.jsx'; +import FileInfoPreview from './file_info_preview.jsx'; + +import React from 'react'; + +export default class CodePreview extends React.Component { + constructor(props) { + super(props); + + this.updateStateFromProps = this.updateStateFromProps.bind(this); + this.handleReceivedError = this.handleReceivedError.bind(this); + this.handleReceivedCode = this.handleReceivedCode.bind(this); + + this.state = { + code: '', + lang: '', + loading: true, + success: true + }; + } + + componentDidMount() { + this.updateStateFromProps(this.props); + } + + componentWillReceiveProps(nextProps) { + if (this.props.fileUrl !== nextProps.fileUrl) { + this.updateStateFromProps(nextProps); + } + } + + updateStateFromProps(props) { + var usedLanguage = syntaxHightlighting.getLang(props.filename); + + if (!usedLanguage || props.fileInfo.size > Constants.CODE_PREVIEW_MAX_FILE_SIZE) { + this.setState({code: '', lang: '', loading: false, success: false}); + return; + } + + this.setState({code: '', lang: usedLanguage, loading: true}); + + $.ajax({ + async: true, + url: props.fileUrl, + type: 'GET', + error: this.handleReceivedError, + success: this.handleReceivedCode + }); + } + + handleReceivedCode(data) { + const parsed = syntaxHightlighting.formatCode(this.state.lang, data, this.props.filename); + this.setState({code: parsed, loading: false, success: true}); + } + + handleReceivedError() { + this.setState({loading: false, success: false}); + } + + static support(filename) { + return typeof syntaxHightlighting.getLang(filename) !== 'undefined'; + } + + render() { + if (this.state.loading) { + return ( + <div className='view-image__loading'> + <img + className='loader-image' + src='/static/images/load.gif' + /> + </div> + ); + } + + if (!this.state.success) { + return ( + <FileInfoPreview + filename={this.props.filename} + fileUrl={this.props.fileUrl} + fileInfo={this.props.fileInfo} + formatMessage={this.props.formatMessage} + /> + ); + } + + return <div dangerouslySetInnerHTML={{__html: this.state.code}}/>; + } +} + +CodePreview.propTypes = { + filename: React.PropTypes.string.isRequired, + fileUrl: React.PropTypes.string.isRequired, + fileInfo: React.PropTypes.object.isRequired, + formatMessage: React.PropTypes.func.isRequired +}; diff --git a/webapp/components/more_channels.jsx b/webapp/components/more_channels.jsx index fc047eaff..d0eeec1ef 100644 --- a/webapp/components/more_channels.jsx +++ b/webapp/components/more_channels.jsx @@ -160,7 +160,7 @@ export default class MoreChannels extends React.Component { return ( <div - className='modal fade' + className='modal fade more-channel__modal' id='more_channels' ref='modal' tabIndex='-1' diff --git a/webapp/components/new_channel_modal.jsx b/webapp/components/new_channel_modal.jsx index 628687f27..f69eeed49 100644 --- a/webapp/components/new_channel_modal.jsx +++ b/webapp/components/new_channel_modal.jsx @@ -38,7 +38,7 @@ class NewChannelModal extends React.Component { } componentDidMount() { if (Utils.isBrowserIE()) { - $('body').addClass('browser--IE'); + $('body').addClass('browser--ie'); } } handleSubmit(e) { diff --git a/webapp/components/popover_list_members.jsx b/webapp/components/popover_list_members.jsx index 81760eb6e..7d048019c 100644 --- a/webapp/components/popover_list_members.jsx +++ b/webapp/components/popover_list_members.jsx @@ -158,6 +158,7 @@ export default class PopoverListMembers extends React.Component { <Popover ref='memebersPopover' title={title} + className='member-list__popover' id='member-list-popover' > <div className='more-modal__list'>{popoverHtml}</div> diff --git a/webapp/components/suggestion/command_provider.jsx b/webapp/components/suggestion/command_provider.jsx index 36860fa66..204f52483 100644 --- a/webapp/components/suggestion/command_provider.jsx +++ b/webapp/components/suggestion/command_provider.jsx @@ -37,9 +37,9 @@ CommandSuggestion.propTypes = { }; export default class CommandProvider { - handlePretextChanged(suggestionId, pretext) { + handlePretextChanged(suggestionId, pretext, channelId) { if (pretext.startsWith('/')) { - AsyncClient.getSuggestedCommands(pretext, suggestionId, CommandSuggestion); + AsyncClient.getSuggestedCommands(pretext, channelId, suggestionId, CommandSuggestion); } } } diff --git a/webapp/components/suggestion/suggestion_box.jsx b/webapp/components/suggestion/suggestion_box.jsx index e3ec63194..97c6c6cd9 100644 --- a/webapp/components/suggestion/suggestion_box.jsx +++ b/webapp/components/suggestion/suggestion_box.jsx @@ -111,7 +111,7 @@ export default class SuggestionBox extends React.Component { handlePretextChanged(pretext) { for (const provider of this.props.providers) { - provider.handlePretextChanged(this.suggestionId, pretext); + provider.handlePretextChanged(this.suggestionId, pretext, this.props.channelId); } } @@ -160,6 +160,7 @@ SuggestionBox.propTypes = { value: React.PropTypes.string.isRequired, onUserInput: React.PropTypes.func, providers: React.PropTypes.arrayOf(React.PropTypes.object), + channelId: React.PropTypes.string, // explicitly name any input event handlers we override and need to manually call onChange: React.PropTypes.func, diff --git a/webapp/components/textbox.jsx b/webapp/components/textbox.jsx index 1a395072e..952026ed5 100644 --- a/webapp/components/textbox.jsx +++ b/webapp/components/textbox.jsx @@ -224,6 +224,7 @@ export default class Textbox extends React.Component { style={{visibility: this.state.preview ? 'hidden' : 'visible'}} listComponent={SuggestionList} providers={this.suggestionProviders} + channelId={this.props.channelId} /> <div ref='preview' diff --git a/webapp/components/user_settings/manage_command_hooks.jsx b/webapp/components/user_settings/manage_command_hooks.jsx index ce353ad64..9703664cc 100644 --- a/webapp/components/user_settings/manage_command_hooks.jsx +++ b/webapp/components/user_settings/manage_command_hooks.jsx @@ -4,9 +4,13 @@ import LoadingScreen from '../loading_screen.jsx'; import * as Client from 'utils/client.jsx'; +import * as Utils from 'utils/utils.jsx'; +import Constants from 'utils/constants.jsx'; import {intlShape, injectIntl, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl'; +const PreReleaseFeatures = Constants.PRE_RELEASE_FEATURES; + const holders = defineMessages({ requestTypePost: { id: 'user.settings.cmds.request_type_post', @@ -59,6 +63,7 @@ export default class ManageCommandCmds extends React.Component { this.getCmds = this.getCmds.bind(this); this.addNewCmd = this.addNewCmd.bind(this); this.emptyCmd = this.emptyCmd.bind(this); + this.updateExternalManagement = this.updateExternalManagement.bind(this); this.updateTrigger = this.updateTrigger.bind(this); this.updateURL = this.updateURL.bind(this); this.updateMethod = this.updateMethod.bind(this); @@ -99,7 +104,7 @@ export default class ManageCommandCmds extends React.Component { addNewCmd(e) { e.preventDefault(); - if (this.state.cmd.trigger === '' || this.state.cmd.url === '') { + if (this.state.cmd.url === '' || (this.state.cmd.trigger === '' && !this.state.external_management)) { return; } @@ -189,6 +194,12 @@ export default class ManageCommandCmds extends React.Component { ); } + updateExternalManagement(e) { + var cmd = this.state.cmd; + cmd.external_management = e.target.checked; + this.setState(cmd); + } + updateTrigger(e) { var cmd = this.state.cmd; cmd.trigger = e.target.value; @@ -270,11 +281,26 @@ export default class ManageCommandCmds extends React.Component { ); } + let slashCommandAutocompleteDiv; + if (Utils.isFeatureEnabled(PreReleaseFeatures.SLASHCMD_AUTOCMP)) { + slashCommandAutocompleteDiv = ( + <div className='padding-top x2'> + <strong> + <FormattedMessage + id='user.settings.cmds.external_management' + defaultMessage='External management: ' + /> + </strong><span className='word-break--all'>{cmd.external_management ? this.props.intl.formatMessage(holders.autocompleteYes) : this.props.intl.formatMessage(holders.autocompleteNo)}</span> + </div> + ); + } + cmds.push( <div key={cmd.id} className='webhook__item webcmd__item' > + {slashCommandAutocompleteDiv} {triggerDiv} <div className='padding-top x2 webcmd__url'> <strong> @@ -416,43 +442,115 @@ export default class ManageCommandCmds extends React.Component { </div> ); - const disableButton = this.state.cmd.trigger === '' || this.state.cmd.url === ''; + const disableButton = this.state.cmd.url === '' || (this.state.cmd.trigger === '' && !this.state.external_management); - return ( - <div key='addCommandCmd'> - <FormattedHTMLMessage - id='user.settings.cmds.add_desc' - defaultMessage='Create slash commands to send events to external integrations and receive a response. For example typing `/patient Joe Smith` could bring back search results from your internal health records management system for the name “Joe Smith”. Please see <a href="http://docs.mattermost.com/developer/slash-commands.html">Slash commands documentation</a> for detailed instructions. View all slash commands configured on this team below.' - /> - <div><label className='control-label padding-top x2'> - <FormattedMessage - id='user.settings.cmds.add_new' - defaultMessage='Add a new command' - /> - </label></div> - <div className='padding-top divider-light'></div> - <div className='padding-top'> + let triggerInput; + if (!this.state.cmd.external_management) { + triggerInput = ( + <div className='padding-top x2'> + <label className='control-label'> + <FormattedMessage + id='user.settings.cmds.trigger' + defaultMessage='Command Trigger Word: ' + /> + </label> + <div className='padding-top'> + <input + ref='trigger' + className='form-control' + value={this.state.cmd.trigger} + onChange={this.updateTrigger} + placeholder={this.props.intl.formatMessage(holders.addTriggerPlaceholder)} + /> + </div> + <div className='padding-top'> + <FormattedMessage + id='user.settings.cmds.trigger_desc' + defaultMessage='Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug' + /> + </div> + </div> + ); + } + let slashCommandAutocompleteCheckbox; + if (Utils.isFeatureEnabled(PreReleaseFeatures.SLASHCMD_AUTOCMP)) { + slashCommandAutocompleteCheckbox = ( + <div className='padding-top x2'> + <label className='control-label'> + <FormattedMessage + id='user.settings.cmds.external_management' + defaultMessage='External management: ' + /> + </label> + <div className='padding-top'> + <div className='checkbox'> + <label> + <input + type='checkbox' + checked={this.state.cmd.external_management} + onChange={this.updateExternalManagement} + /> + <FormattedMessage + id='user.settings.cmds.slashCmd_autocmp' + defaultMessage='Enable external application to offer autocomplete' + /> + </label> + </div> + </div> + </div> + + ); + } + + let autoCompleteSettings; + if (!this.state.cmd.external_management) { + autoCompleteSettings = ( + <div> <div className='padding-top x2'> <label className='control-label'> <FormattedMessage - id='user.settings.cmds.trigger' - defaultMessage='Command Trigger Word: ' + id='user.settings.cmds.auto_complete' + defaultMessage='Autocomplete: ' + /> + </label> + <div className='padding-top'> + <div className='checkbox'> + <label> + <input + type='checkbox' + checked={this.state.cmd.auto_complete} + onChange={this.updateAutoComplete} + /> + <FormattedMessage + id='user.settings.cmds.auto_complete_help' + defaultMessage=' Show this command in the autocomplete list.' + /> + </label> + </div> + </div> + </div> + + <div className='padding-top x2'> + <label className='control-label'> + <FormattedMessage + id='user.settings.cmds.auto_complete_hint' + defaultMessage='Autocomplete Hint: ' /> </label> <div className='padding-top'> <input - ref='trigger' + ref='autoCompleteHint' className='form-control' - value={this.state.cmd.trigger} - onChange={this.updateTrigger} - placeholder={this.props.intl.formatMessage(holders.addTriggerPlaceholder)} + value={this.state.cmd.auto_complete_hint} + onChange={this.updateAutoCompleteHint} + placeholder={this.props.intl.formatMessage(holders.addAutoCompleteHintPlaceholder)} /> </div> <div className='padding-top'> <FormattedMessage - id='user.settings.cmds.trigger_desc' - defaultMessage='Examples: /patient, /client, /employee Reserved: /echo, /join, /logout, /me, /shrug' + id='user.settings.cmds.auto_complete_hint_desc' + defaultMessage='Optional hint in the autocomplete list about parameters needed for command.' /> </div> </div> @@ -460,6 +558,76 @@ export default class ManageCommandCmds extends React.Component { <div className='padding-top x2'> <label className='control-label'> <FormattedMessage + id='user.settings.cmds.auto_complete_desc' + defaultMessage='Autocomplete Description: ' + /> + </label> + <div className='padding-top'> + <input + ref='autoCompleteDesc' + className='form-control' + value={this.state.cmd.auto_complete_desc} + onChange={this.updateAutoCompleteDesc} + placeholder={this.props.intl.formatMessage(holders.addAutoCompleteDescPlaceholder)} + /> + </div> + <div className='padding-top'> + <FormattedMessage + id='user.settings.cmds.auto_complete_desc_desc' + defaultMessage='Optional short description of slash command for the autocomplete list.' + /> + </div> + </div> + + <div className='padding-top x2'> + <label className='control-label'> + <FormattedMessage + id='user.settings.cmds.display_name' + defaultMessage='Descriptive Label: ' + /> + </label> + <div className='padding-top'> + <input + ref='displayName' + className='form-control' + value={this.state.cmd.display_name} + onChange={this.updateDisplayName} + placeholder={this.props.intl.formatMessage(holders.addDisplayNamePlaceholder)} + /> + </div> + <div className='padding-top'> + <FormattedMessage + id='user.settings.cmds.cmd_display_name' + defaultMessage='Brief description of slash command to show in listings.' + /> + </div> + {addError} + </div> + </div> + ); + } + + return ( + <div key='addCommandCmd'> + <FormattedHTMLMessage + id='user.settings.cmds.add_desc' + defaultMessage='Create slash commands to send events to external integrations and receive a response. For example typing `/patient Joe Smith` could bring back search results from your internal health records management system for the name “Joe Smith”. Please see <a href="http://docs.mattermost.com/developer/slash-commands.html">Slash commands documentation</a> for detailed instructions. View all slash commands configured on this team below.' + /> + <div><label className='control-label padding-top x2'> + <FormattedMessage + id='user.settings.cmds.add_new' + defaultMessage='Add a new command' + /> + </label></div> + <div className='padding-top divider-light'></div> + <div className='padding-top'> + + {slashCommandAutocompleteCheckbox} + {triggerInput} + + <div className='padding-top x2'> + <label className='control-label'> + <FormattedMessage id='user.settings.cmds.url' defaultMessage='Request URL: ' /> @@ -560,102 +728,7 @@ export default class ManageCommandCmds extends React.Component { </div> </div> - <div className='padding-top x2'> - <label className='control-label'> - <FormattedMessage - id='user.settings.cmds.auto_complete' - defaultMessage='Autocomplete: ' - /> - </label> - <div className='padding-top'> - <div className='checkbox'> - <label> - <input - type='checkbox' - checked={this.state.cmd.auto_complete} - onChange={this.updateAutoComplete} - /> - <FormattedMessage - id='user.settings.cmds.auto_complete_help' - defaultMessage=' Show this command in the autocomplete list.' - /> - </label> - </div> - </div> - </div> - - <div className='padding-top x2'> - <label className='control-label'> - <FormattedMessage - id='user.settings.cmds.auto_complete_hint' - defaultMessage='Autocomplete Hint: ' - /> - </label> - <div className='padding-top'> - <input - ref='autoCompleteHint' - className='form-control' - value={this.state.cmd.auto_complete_hint} - onChange={this.updateAutoCompleteHint} - placeholder={this.props.intl.formatMessage(holders.addAutoCompleteHintPlaceholder)} - /> - </div> - <div className='padding-top'> - <FormattedMessage - id='user.settings.cmds.auto_complete_hint_desc' - defaultMessage='Optional hint in the autocomplete list about parameters needed for command.' - /> - </div> - </div> - - <div className='padding-top x2'> - <label className='control-label'> - <FormattedMessage - id='user.settings.cmds.auto_complete_desc' - defaultMessage='Autocomplete Description: ' - /> - </label> - <div className='padding-top'> - <input - ref='autoCompleteDesc' - className='form-control' - value={this.state.cmd.auto_complete_desc} - onChange={this.updateAutoCompleteDesc} - placeholder={this.props.intl.formatMessage(holders.addAutoCompleteDescPlaceholder)} - /> - </div> - <div className='padding-top'> - <FormattedMessage - id='user.settings.cmds.auto_complete_desc_desc' - defaultMessage='Optional short description of slash command for the autocomplete list.' - /> - </div> - </div> - - <div className='padding-top x2'> - <label className='control-label'> - <FormattedMessage - id='user.settings.cmds.display_name' - defaultMessage='Descriptive Label: ' - /> - </label> - <div className='padding-top'> - <input - ref='displayName' - className='form-control' - value={this.state.cmd.display_name} - onChange={this.updateDisplayName} - placeholder={this.props.intl.formatMessage(holders.addDisplayNamePlaceholder)} - /> - </div> - <div className='padding-top'> - <FormattedMessage - id='user.settings.cmds.cmd_display_name' - defaultMessage='Brief description of slash command to show in listings.' - /> - </div> - {addError} - </div> + {autoCompleteSettings} <div className='padding-top x2 padding-bottom'> <a diff --git a/webapp/components/user_settings/user_settings_advanced.jsx b/webapp/components/user_settings/user_settings_advanced.jsx index 7c496f57b..40897e8c9 100644 --- a/webapp/components/user_settings/user_settings_advanced.jsx +++ b/webapp/components/user_settings/user_settings_advanced.jsx @@ -51,6 +51,10 @@ const holders = defineMessages({ EMBED_TOGGLE: { id: 'user.settings.advance.embed_toggle', defaultMessage: 'Show toggle for all embed previews' + }, + SLASHCMD_AUTOCMP: { + id: 'user.settings.advance.slashCmd_autocmp', + defaultMessage: 'Enable external application to offer slash command autocomplete' } }); diff --git a/webapp/components/user_settings/user_settings_display.jsx b/webapp/components/user_settings/user_settings_display.jsx index 58d4493cb..3299588f7 100644 --- a/webapp/components/user_settings/user_settings_display.jsx +++ b/webapp/components/user_settings/user_settings_display.jsx @@ -195,7 +195,7 @@ export default class UserSettingsDisplay extends React.Component { const showUsername = ( <FormattedMessage id='user.settings.display.showUsername' - defaultMessage='Show username (team default)' + defaultMessage='Show username (default)' /> ); const showNickname = ( diff --git a/webapp/components/view_image.jsx b/webapp/components/view_image.jsx index e739fca30..7572f88ae 100644 --- a/webapp/components/view_image.jsx +++ b/webapp/components/view_image.jsx @@ -7,6 +7,7 @@ import * as Client from 'utils/client.jsx'; import * as Utils from 'utils/utils.jsx'; import AudioVideoPreview from './audio_video_preview.jsx'; import Constants from 'utils/constants.jsx'; +import CodePreview from './code_preview.jsx'; import FileInfoPreview from './file_info_preview.jsx'; import FileStore from 'stores/file_store.jsx'; import ViewImagePopoverBar from './view_image_popover_bar.jsx'; @@ -254,6 +255,15 @@ class ViewImageModal extends React.Component { formatMessage={this.props.intl.formatMessage} /> ); + } else if (CodePreview.support(filename)) { + content = ( + <CodePreview + filename={filename} + fileUrl={fileUrl} + fileInfo={fileInfo} + formatMessage={this.props.intl.formatMessage} + /> + ); } else { content = ( <FileInfoPreview @@ -311,18 +321,19 @@ class ViewImageModal extends React.Component { <Modal show={this.props.show} onHide={this.props.onModalDismissed} - className='image_modal' + className='modal-image' dialogClassName='modal-image' > <Modal.Body - modalClassName='image-body' + modalClassName='modal-image__body' onClick={this.props.onModalDismissed} > <div - className={'image-wrapper'} + className={'modal-image__wrapper'} onClick={this.props.onModalDismissed} > <div + className='modal-back' onMouseEnter={this.onMouseEnterImage} onMouseLeave={this.onMouseLeaveImage} onClick={(e) => e.stopPropagation()} diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json index 437271633..42e23b8e5 100644 --- a/webapp/i18n/en.json +++ b/webapp/i18n/en.json @@ -1126,6 +1126,7 @@ "tutorial_tip.seen": "Seen this before? ", "upload_overlay.info": "Drop a file to upload it.", "user.settings.advance.embed_preview": "Show preview snippet of links below message", + "user.settings.advance.slashCmd_autocmp": "Enable external application to offer slash command autocomplete", "user.settings.advance.embed_toggle": "Show toggle for all embed previews", "user.settings.advance.enabled": "enabled", "user.settings.advance.feature": " Feature ", @@ -1173,6 +1174,7 @@ "user.settings.cmds.url_desc": "The callback URL to receive the HTTP POST or GET event request when the slash command is run.", "user.settings.cmds.username": "Response Username: ", "user.settings.cmds.username_desc": "Choose a username override for responses for this slash command. Usernames can consist of up to 22 characters consisting of lowercase letters, numbers and they symbols \"-\", \"_\", and \".\" .", + "user.settings.cmds.slashCmd_autocmp": "Enable external application to offer autocomplete", "user.settings.custom_theme.awayIndicator": "Away Indicator", "user.settings.custom_theme.buttonBg": "Button BG", "user.settings.custom_theme.buttonColor": "Button Text", @@ -1209,7 +1211,7 @@ "user.settings.display.preferTime": "Select how you prefer time displayed.", "user.settings.display.showFullname": "Show first and last name", "user.settings.display.showNickname": "Show nickname if one exists, otherwise show first and last name", - "user.settings.display.showUsername": "Show username (team default)", + "user.settings.display.showUsername": "Show username (default)", "user.settings.display.teammateDisplay": "Teammate Name Display", "user.settings.display.theme.customTheme": "Custom Theme", "user.settings.display.theme.describe": "Open to manage your theme", diff --git a/webapp/i18n/pt.json b/webapp/i18n/pt.json index 0d8e5f4cb..17ffe1b16 100644 --- a/webapp/i18n/pt.json +++ b/webapp/i18n/pt.json @@ -1174,7 +1174,7 @@ "user.settings.display.preferTime": "Selecione como você prefere que a hora seja mostrada.", "user.settings.display.showFullname": "Mostrar primeiro e último nome", "user.settings.display.showNickname": "Mostras apelidos se um existir, caso contrário mostrar o primeiro e último nome", - "user.settings.display.showUsername": "Mostrar nome de usuário (equipe padrão)", + "user.settings.display.showUsername": "Mostrar nome de usuário (padrão)", "user.settings.display.teammateDisplay": "Nome de Exibição da Equipe de Trabalho", "user.settings.display.theme.customTheme": "Tema Customizado", "user.settings.display.theme.describe": "Abrir para gerenciar seu tema", @@ -1313,4 +1313,4 @@ "web.footer.terms": "Termos", "web.header.back": "Voltar", "web.root.singup_info": "Toda comunicação em um só lugar, pesquisável e acessível em qualquer lugar" -}
\ No newline at end of file +} diff --git a/webapp/package.json b/webapp/package.json index 0d88a6212..25003114e 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -31,7 +31,7 @@ "babel-loader": "6.2.4", "babel-plugin-transform-runtime": "6.6.0", "babel-polyfill": "6.7.2", - "babel-preset-es2015": "6.6.0", + "babel-preset-es2015-webpack": "6.4.0", "babel-preset-react": "6.5.0", "babel-preset-stage-0": "6.5.0", "eslint": "2.2.0", @@ -39,6 +39,7 @@ "exports-loader": "0.6.3", "extract-text-webpack-plugin": "1.0.1", "file-loader": "0.8.5", + "url-loader": "0.5.7", "html-loader": "0.4.3", "copy-webpack-plugin": "1.1.1", "css-loader": "0.23.1", @@ -52,6 +53,7 @@ }, "scripts": { "check": "eslint --ext \".jsx\" --ignore-pattern node_modules --quiet .", - "build": "webpack --progress" + "build": "webpack --optimize-dedupe", + "run": "webpack --progress" } } diff --git a/webapp/root.jsx b/webapp/root.jsx index 8ebe51bd2..2ce220f1d 100644 --- a/webapp/root.jsx +++ b/webapp/root.jsx @@ -3,11 +3,11 @@ import $ from 'jquery'; -import 'sass/styles.scss'; import 'bootstrap/dist/css/bootstrap.css'; import 'jasny-bootstrap/dist/css/jasny-bootstrap.css'; import 'bootstrap-colorpicker/dist/css/bootstrap-colorpicker.css'; import 'google-fonts/google-fonts.css'; +import 'sass/styles.scss'; import React from 'react'; import ReactDOM from 'react-dom'; diff --git a/webapp/sass/base/_structure.scss b/webapp/sass/base/_structure.scss index 56888f8dc..217488334 100644 --- a/webapp/sass/base/_structure.scss +++ b/webapp/sass/base/_structure.scss @@ -6,22 +6,24 @@ body { } body { - width: 100%; - height: 100%; background: $bg--gray; + height: 100%; position: relative; + width: 100%; +} - &.sticky { - background: $bg--white; +.sticky { + background: $white; - > .container-fluid { - overflow: auto; - } + > .container-fluid { + overflow: auto; + } - .inner-wrap { - > .row.content { - min-height: 100%; + .inner-wrap { + > .row { + &.content { margin-bottom: -89px; + min-height: 100%; } } } @@ -30,9 +32,11 @@ body { .inner-wrap { height: 100%; - > .row.main { - height: 100%; - position: relative; + > .row { + &.main { + height: 100%; + position: relative; + } } } diff --git a/webapp/sass/base/_typography.scss b/webapp/sass/base/_typography.scss index 676a2c405..f5795d862 100644 --- a/webapp/sass/base/_typography.scss +++ b/webapp/sass/base/_typography.scss @@ -6,20 +6,20 @@ strong { } a { + color: $primary-color; cursor: pointer; text-decoration: none; word-break: break-word; - color: $color--primary; -} -a:focus, -a:hover { - color: $color--primary--hover; + &:focus, + &:hover { + color: $primary-color--hover; + } } body { + @include font-smoothing; font-family: 'Open Sans', sans-serif; - -webkit-font-smoothing: antialiased; } .word-break--all { diff --git a/webapp/sass/components/_alerts.scss b/webapp/sass/components/_alerts.scss index 49ca3e8af..cb4c9c9e1 100644 --- a/webapp/sass/components/_alerts.scss +++ b/webapp/sass/components/_alerts.scss @@ -1,13 +1,13 @@ @charset 'UTF-8'; .alert { - padding: 8px 12px; @include border-radius($border-rad); + padding: 8px 12px; } .alert--confirm { display: inline-block; float: left; - padding: 4px 10px; margin: 1px 0 0 10px; -}
\ No newline at end of file + padding: 4px 10px; +} diff --git a/webapp/sass/components/_buttons.scss b/webapp/sass/components/_buttons.scss index bb8efbb14..efef11ce9 100644 --- a/webapp/sass/components/_buttons.scss +++ b/webapp/sass/components/_buttons.scss @@ -5,19 +5,19 @@ @include border-radius($border-rad); &.btn-primary { + background: $primary-color; border-color: transparent; - background: $color--primary; &:hover, &:focus, &:active { - background: $color--primary--hover; + background: $primary-color--hover; } } &.btn-inactive { + background: $light-gray; border-color: transparent; - background: #707070; - color: #fff; + color: $white; } } diff --git a/webapp/sass/components/_emoticons.scss b/webapp/sass/components/_emoticons.scss index 661b25d94..80a800863 100644 --- a/webapp/sass/components/_emoticons.scss +++ b/webapp/sass/components/_emoticons.scss @@ -1,27 +1,27 @@ @charset 'UTF-8'; .emoticon { - width: 1.5em; - height: 1.5em; + background-size: contain; display: inline-block; + height: 1.5em; margin-bottom: .25em; - background-size: contain; + width: 1.5em; } .emoticon-suggestion { @include clearfix; - width: 100%; - height: 30px; cursor: pointer; font-size: 13px; + height: 30px; line-height: 30px; + width: 100%; } .emoticon-suggestion__image { - width: 20px; height: 20px; margin: 6px 6px 0 5px; padding: 0; text-align: center; vertical-align: top; + width: 20px; } diff --git a/webapp/sass/components/_error-bar.scss b/webapp/sass/components/_error-bar.scss index 2b74a33ae..cda7d25bd 100644 --- a/webapp/sass/components/_error-bar.scss +++ b/webapp/sass/components/_error-bar.scss @@ -1,29 +1,28 @@ @charset 'UTF-8'; .error-bar { - background-color: #09f; - text-align: center; - position: relative; - color: #fff; + background-color: darken($primary-color, 5%); + color: $white; + padding: 5px 30px; position: absolute; + text-align: center; top: 0; width: 100%; z-index: 9999; - padding: 5px 30px; &__close { - position: absolute; - right: 0; - top: 0; - color: #fff; + color: $white; + font-family: 'Open Sans', sans-serif; font-size: 20px; font-weight: 600; - text-decoration: none; padding: 0 10px; - font-family: 'Open Sans', sans-serif; + position: absolute; + right: 0; + text-decoration: none; + top: 0; &:hover { - color: #fff; + color: $white; text-decoration: none; } } diff --git a/webapp/sass/components/_files.scss b/webapp/sass/components/_files.scss index b9e2b5f7d..5522c6db8 100644 --- a/webapp/sass/components/_files.scss +++ b/webapp/sass/components/_files.scss @@ -1,27 +1,31 @@ @charset 'UTF-8'; .file-preview__container { - position: relative; + height: 100px; margin: 1px 0 10px; - width: 100%; max-height: 100px; - height: 100px; - white-space: nowrap; overflow-x: auto; overflow-y: hidden; + position: relative; + white-space: nowrap; + width: 100%; } .file-preview { + @include clearfix; + border: 1px solid $light-gray; display: inline-block; - width: 120px; height: 100px; margin: 0 0 0 10px; position: relative; - border: 1px solid #ddd; - @include clearfix; + width: 120px; - &:hover .file-preview__remove:after { - @include opacity(1); + &:hover { + .file-preview__remove { + &:after { + @include opacity(1); + } + } } &:first-child { @@ -29,13 +33,13 @@ } .spinner { - position: absolute; - top: 50%; + height: 32px; left: 50%; margin-left: -16px; margin-top: -16px; + position: absolute; + top: 50%; width: 32px; - height: 32px; } } @@ -46,14 +50,15 @@ } .file-preview__remove { - position: absolute; - width: 100%; height: 100%; left: 0; + position: absolute; top: 0; + width: 100%; &:after { - background: rgba(0, 0, 0, .4); + @include opacity(0); + @include alpha-property(background, $black, .4); content: ''; height: 100%; left: 0; @@ -61,33 +66,31 @@ position: absolute; top: 0; width: 100%; - @include opacity(0); } i { - top: 5px; - right: 5px; - position: absolute; - color: #fff; + color: $white; cursor: pointer; - z-index: 5; opacity: inherit; - text-shadow: 0 0px 3px #444; - text-shadow: 0 0px 3px rgba(0, 0, 0, .7); + position: absolute; + right: 5px; + text-shadow: 0 0 3px alpha-color($black, .7); + top: 5px; + z-index: 5; } } .image-comment { background-position: left top; background-repeat: no-repeat; - width: 300px; height: 300px; + width: 300px; } .file-icon { - width: 100%; height: 100%; + width: 100%; &.audio { @include file-icon('../images/icons/audio.png'); @@ -131,36 +134,30 @@ } .post-image__column { - position: relative; - width: 240px; - height: 100px; + border: 1px solid alpha-color($black, .2); float: left; + height: 100px; margin: 5px 10px 5px 0; - border: 1px solid lightgrey; - - a { - text-decoration: none; - color: grey; - } + position: relative; + width: 240px; } .post-image__load { + background-position: center; + background-repeat: no-repeat; + background-size: 20px 20px; height: 100%; width: 100%; - background-size: 20px 20px; - background-repeat: no-repeat; - background-position: center; - background-image: url('~images/load.gif'); } .post-image { - width: 100%; - height: 100%; - background-color: #fff; + background-color: $white; background-repeat: no-repeat; + height: 100%; overflow: hidden; position: relative; text-align: center; + width: 100%; &.small { background-position: center; @@ -170,60 +167,59 @@ background-position: top left; } - .spinner.file__loading { - position: absolute; - left: 50%; - margin-left: -16px; - top: 50%; - margin-top: -16px; + .spinner { + .file__loading { + left: 50%; + margin-left: -16px; + margin-top: -16px; + position: absolute; + top: 50%; + } } .file__loaded { max-width: initial; + &.landscape, &.quadrat { height: 100px; } + &.portrait { width: 120px; } } - - &:hover .file-playback__controls.stop { - @include opacity(1); - } } .post-image__thumbnail { + @include cursor(zoom-in); float: left; - width: 50%; height: 100%; - cursor: zoom-in; - cursor: -webkit-zoom-in; + width: 50%; } .post-image__details { - float: left; @include clearfix; - word-break: break-word; - width: 50%; - height: 100%; - background: white; - border-left: 1px solid #ddd; + background: $white; + border-left: 1px solid $light-gray; + color: alpha-color($black, .8); + float: left; font-size: 13px; + height: 100%; padding: 7px; - color: #333; + width: 50%; + word-break: break-word; .post-image__name { - margin-bottom: 3px; display: block; + margin-bottom: 3px; } .post-image__download { + @include opacity(.7); + cursor: pointer; display: inline-block; padding-right: 7px; - cursor: pointer; - @include opacity(.7); } .post-image__type { @@ -231,57 +227,56 @@ } .post-image__size { - margin-left: 4px; @include opacity(.6); + margin-left: 4px; } } .file-details__container { @include display-flex; - display: -ms-flexbox; + background: $white; .file-details { - width: 320px; height: 270px; padding: 14px; text-align: left; vertical-align: top; + width: 320px; .file-details__name { - color: #333; + color: alpha-color($black, .9); font-size: 16px; } .file-details__info { - color: grey; + color: alpha-color($black, .5); } } + .file-details__preview { - width: 320px; + border-right: 1px solid $light-gray; height: 270px; - border-right: 1px solid #ddd; vertical-align: center; + width: 320px; // helper to center the image icon in the preview window .file-details__preview-helper { - height: 100%; display: inline-block; + height: 100%; vertical-align: middle; } } } .file-playback__controls { - position: absolute; - right: 5px; + @include single-transition(opacity, .6s); bottom: 0; - font-size: 22px; cursor: pointer; - z-index: 2; - -webkit-transition: opacity .6s; - -moz-transition: opacity .6s; - -o-transition: opacity .6s; + font-size: 22px; + position: absolute; + right: 5px; transition: opacity .6s; + z-index: 2; &.stop { @include opacity(0); @@ -289,6 +284,6 @@ } .view-image__loading { - background: black; + background: $black; min-height: 100px; } diff --git a/webapp/sass/components/_inputs.scss b/webapp/sass/components/_inputs.scss index 5e3311182..42ab56128 100644 --- a/webapp/sass/components/_inputs.scss +++ b/webapp/sass/components/_inputs.scss @@ -15,12 +15,21 @@ &.no-resize { resize: none; } + + &[disabled], + [readonly] { + @include alpha-property(background, $white, .1); + color: inherit; + cursor: auto; + } } -.form-control[disabled], -.form-control[readonly], -fieldset[disabled] .form-control { - cursor: auto; - background: rgba(#fff, .1); - color: inherit; +fieldset { + &[disabled] { + .form-control { + @include alpha-property(background, $white, .1); + color: inherit; + cursor: auto; + } + } } diff --git a/webapp/sass/components/_links.scss b/webapp/sass/components/_links.scss index f31008b4f..3d7472670 100644 --- a/webapp/sass/components/_links.scss +++ b/webapp/sass/components/_links.scss @@ -1,23 +1,22 @@ @charset 'UTF-8'; a { + color: $primary-color; cursor: pointer; text-decoration: none; word-break: break-word; - color: $color--primary; -} -a:focus, -a:hover { - color: $color--primary--hover; + &:hover, + &:focus { + color: $primary-color--hover; + } } -.text-danger, -a.text-danger { - color: #e05f5d; +.text-danger { + color: desaturate($red, 20%); &:hover, &:focus { - color: #e05f5d; + color: desaturate($red, 20%); } } diff --git a/webapp/sass/components/_mentions.scss b/webapp/sass/components/_mentions.scss index 98efc599d..98ae7d320 100644 --- a/webapp/sass/components/_mentions.scss +++ b/webapp/sass/components/_mentions.scss @@ -1,24 +1,24 @@ @charset 'UTF-8'; .mention { - color: #fff; - background: $color--primary; + @include border-radius(3px); + background: $primary-color; + color: $white; + padding-bottom: 2px; position: relative; z-index: 10; - padding-bottom: 2px; - @include border-radius(3px); } .mentions__name { - position: relative; - width: 100%; + cursor: pointer; + font-size: 13px; height: 36px; - padding: 2px; - z-index: 101; line-height: 36px; - font-size: 13px; - cursor: pointer; + padding: 2px; + position: relative; white-space: nowrap; + width: 100%; + z-index: 101; .mention-align { @include clearfix; @@ -28,29 +28,29 @@ } .mention__image { - margin-right: 6px; - height: 32px; - width: 32px; - line-height: 36px; + @include border-radius(32px); display: block; font-size: 20px; + height: 32px; + line-height: 36px; + margin-right: 6px; text-align: center; - @include border-radius(32px); + width: 32px; .mention--align { + display: inline-block; max-width: 80%; overflow: hidden; - display: inline-block; - white-space: nowrap; text-overflow: ellipsis; + white-space: nowrap; } } .mention__fullname { - color: grey; + color: $dark-gray; padding-left: 10px; } .mention--highlight { - background-color: #fff2bb; + background-color: $yellow; } diff --git a/webapp/sass/components/_modal.scss b/webapp/sass/components/_modal.scss index a8e8a99f7..94378aabe 100644 --- a/webapp/sass/components/_modal.scss +++ b/webapp/sass/components/_modal.scss @@ -1,12 +1,24 @@ @charset 'UTF-8'; -#channel_members_modal .modal-body { - min-height: 110px; +.browser--ie { + .modal { + .modal-dialog { + @include translateY(0); + } + } } .modal-body { - padding: 20px 15px; overflow: auto; + padding: 20px 15px; + + .edit-modal-body { + overflow: visible; + + .suggestion-list__content { + max-height: 150px; + } + } } .more-table { @@ -15,27 +27,23 @@ } .modal { + color: alpha-color($black, .9); width: 100%; - color: #333; - body.browser--IE & { - .modal-dialog { - @include translateY(0); - } - } - - &.image_modal { - .modal-backdrop.in { - @include opacity(.7); + &.modal-image { + .modal-backdrop { + &.in { + @include opacity(.7); + } } } .custom-textarea { + border-color: $light-gray; color: inherit; - border-color: #ccc; &:focus { - border-color: #ccc; + border-color: $light-gray; box-shadow: none; } } @@ -44,15 +52,15 @@ font-size: 13px; &.btn-default { - border: none; background: transparent; + border: none; } } .info__label { font-weight: 600; - text-align: right; padding-right: 0; + text-align: right; } .team-member-list { @@ -60,21 +68,21 @@ } .remove__member { + color: $dark-gray; float: right; - color: #999; font-size: 20px; line-height: 0; padding: 6px; &:hover { - color: #e56565; + color: $red; } } .modal-dialog { - max-width: 95%; margin-left: auto; margin-right: auto; + max-width: 95%; } .modal-push-down { @@ -82,51 +90,51 @@ } .modal-next-bar { + height: 100%; position: absolute; - top: 0px; right: 0; - height: 100%; + top: 0; } .modal-header { - border-radius: 0; - background: $color--primary; - color: #fff; - padding: 15px 15px 11px; - border: 1px solid #ddd; - min-height: 56px; + @include border-radius(0); @include clearfix; + background: $primary-color; + border: 1px solid $light-gray; + color: $white; + min-height: 56px; + padding: 15px 15px 11px; .modal-title { + color: $bg--gray; float: left; font-size: 17px; line-height: 27px; - color: #f4f4f4; .name { + color: $white; font-weight: 600; - color: #fff; } } .modal-action { - padding: 0; margin: 0; + padding: 0; } - button.close { - color: #fff; + .close { @include opacity(1); - z-index: 5; - width: 30px; + @include single-transition(all, .25s, ease-in); + color: $white; height: 30px; line-height: 30px; - @include single-transition(all, .25s, ease-in); position: absolute; right: 10px; + width: 30px; + z-index: 5; &:hover { - background: rgba(0, 0, 0, .1); + @include alpha-property(background, $black, .1); } span { @@ -149,8 +157,8 @@ } .no-channel-message { - text-align: center; padding: 2em 1em; + text-align: center; .primary-message { font-size: 1.25em; @@ -168,46 +176,46 @@ } .modal-chevron-icon { - top: 50%; font-size: 120%; + top: 50%; } .modal-prev-bar { - position: absolute; - top: 0px; - left: 0; height: 100%; + left: 0; + position: absolute; + top: 0; } - &#more_channels { + &.more-channel__modal { .modal-body { padding: 0; } } .modal-image { - position: relative; - width: 100%; height: 100%; margin: 0 auto; max-width: 100%; + position: relative; + width: 100%; .modal-body { @include clearfix; - height: 100%; display: table; + height: 100%; + max-height: 100%; table-layout: fixed; width: 100%; - max-height: 100%; } - .image-wrapper { - position: relative; - max-width: 90%; + .modal-image__wrapper { @include border-radius(3px); display: table-cell; - vertical-align: middle; + max-width: 90%; + position: relative; text-align: center; + vertical-align: middle; width: 100%; &:hover { @@ -215,33 +223,31 @@ } &.default { - width: 100%; height: 80%; + width: 100%; } audio, canvas, progress, video { - max-width: 100%; - height: auto; display: block; + height: auto; + max-width: 100%; } .modal-close { - background: url('../images/close.png') no-repeat; + @include single-transition(opacity, .6s); @include background-size(100% 100%); - width: 37px; + @include opacity(0); + background-image: url('../images/close.png'); + cursor: pointer; height: 37px; position: absolute; right: -13px; top: -13px; - @include opacity(0); - -webkit-transition: opacity .6s; - -moz-transition: opacity .6s; - -o-transition: opacity .6s; transition: opacity .6s; - cursor: pointer; + width: 37px; z-index: 9999; &.modal-close--show { @@ -250,99 +256,109 @@ } > div { + display: inline-block; min-height: 100px; min-width: 320px; - background: #fff; - display: inline-block; position: relative; + } - &:hover .file-playback__controls.stop { - @include opacity(1); - } + code { + min-height: 130px; + min-width: 330px; + } + + pre, code { + display: inline-block; + } + + .post-body--code { + max-height: calc(100vh - 80px); + max-width: calc(100vw - 80px); + overflow: auto; } img { - max-width: 100%; max-height: 100%; + max-width: 100%; } - .spinner.file__loading { - z-index: 2; - position: absolute; - left: 50%; - margin-left: -16px; - top: 50%; - margin-top: -16px; + .spinner { + .file__loading { + left: 50%; + margin-left: -16px; + margin-top: -16px; + position: absolute; + top: 50%; + z-index: 2; + } } } .modal-content { + background: alpha-color($black, 0); + border: none; box-shadow: none; - background: rgba(0, 0, 0, 0); - width: 100%; height: 100%; padding: 0; - border: none; + width: 100%; } - .image-body { - vertical-align: middle; + .modal-image__body { display: table-cell; - text-align: center; height: 100%; + overflow: visible; padding: 0; position: relative; - overflow: visible; + text-align: center; + vertical-align: middle; } .image-control { - width: 50px; - height: 45px; + background: url('../images/prev.png') left no-repeat; float: left; - background: url(../images/prev.png) left no-repeat; - top: 50%; - position: relative; + height: 45px; margin-top: -23px; + position: relative; + top: 50%; + width: 50px; + &.image-next { + background: url('../images/next.png') left no-repeat; float: right; - background: url(../images/next.png) left no-repeat; } } .loader-image { - position: absolute; - top: 0; bottom: 0; left: 0; - right: 0; margin: auto; + position: absolute; + right: 0; + top: 0; } .loader-percent { - position: absolute; - top: 55px; bottom: 0; + color: $dark-gray; + height: 20px; left: 0; - right: 0; margin: auto; - color: grey; - height: 20px; + position: absolute; + right: 0; + top: 55px; } .modal-button-bar { - position: absolute; - bottom: -40px; - left: 0px; - right: 0px; - background-color: #222; + @include single-transition(opacity, .6s); @include border-radius(0 0 3px 3px); @include opacity(0); - -webkit-transition: opacity .6s; - -moz-transition: opacity .6s; - -o-transition: opacity .6s; - transition: opacity .6s; + background-color: $black; + bottom: -40px; + left: 0; line-height: 40px; padding: 0 10px; + position: absolute; + right: 0; &.footer--show { @include opacity(1); @@ -356,10 +372,10 @@ } .text { - vertical-align: middle; bottom: 0; - color: white; + color: $white; margin-left: 5px; + vertical-align: middle; } .public-link { @@ -376,11 +392,12 @@ } .row--invite { - margin-right: 40px; @include clearfix; + margin-right: 40px; .col-sm-6 { padding: 0 0 0 15px; + &:first-child { padding-left: 0; } @@ -389,26 +406,26 @@ .more-modal { .user-list { - overflow-y: auto; - overflow-x: hidden; margin-top: 10px; + overflow-x: hidden; + overflow-y: auto; position: relative; } .modal-body { - padding: 10px 0 20px; overflow-x: hidden; + padding: 10px 0 20px; } .filter-row { - margin: 10px 0; @include clearfix; + margin: 10px 0; } .member-count { - margin-top: 5px; - float: right; @include opacity(.8); + float: right; + margin-top: 5px; } .more-purpose { @@ -416,21 +433,13 @@ } } -.modal-body.edit-modal-body { - overflow: visible; - - .suggestion-list__content { - max-height: 150px; - } -} - .more-modal__list { - overflow: auto; display: flex; flex-direction: column; + overflow: auto; .popover & { - font-size: 0.95em; + font-size: .95em; .more-modal__row { padding: 5px 10px; @@ -442,9 +451,9 @@ } .more-modal__image { + @include border-radius(60px); flex-grow: 0; flex-shrink: 0; - @include border-radius(60px); margin-right: 8px; } @@ -462,33 +471,33 @@ } .more-modal__name { - font-weight: 600; font-size: .95em; - white-space: nowrap; + font-weight: 600; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } .more-modal__description { @include opacity(.7); display: block; - white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } .more-modal__row { + border-bottom: 1px solid; display: flex; padding: 8px 15px; - border-bottom: 1px solid; } p { + @include opacity(.8); font-size: .9em; + margin: 5px 0; overflow: hidden; text-overflow: ellipsis; - @include opacity(.8); - margin: 5px 0; } } diff --git a/webapp/sass/components/_oauth.scss b/webapp/sass/components/_oauth.scss index cd8382a5c..04840457c 100644 --- a/webapp/sass/components/_oauth.scss +++ b/webapp/sass/components/_oauth.scss @@ -1,18 +1,18 @@ @charset 'UTF-8'; .prompt { - background: #fff; - border: 1px solid #ddd; - padding: 1em 2em 0; + background: $white; + border: 1px solid $light-gray; margin: 50px auto; max-width: 90%; + padding: 1em 2em 0; width: 600px; .prompt__heading { + display: table; font-size: em(20px); line-height: normal; margin: 1em 0; - display: table; width: 100%; > div { @@ -26,13 +26,13 @@ } .prompt__allow { - margin: 1em 0; font-size: em(24px); + margin: 1em 0; } .prompt__buttons { - text-align: right; - border-top: 1px solid #ddd; + border-top: 1px solid $dark-gray; padding: 1.5em 0; + text-align: right; } } diff --git a/webapp/sass/components/_popover.scss b/webapp/sass/components/_popover.scss index de66b67a7..0b2769f77 100644 --- a/webapp/sass/components/_popover.scss +++ b/webapp/sass/components/_popover.scss @@ -3,32 +3,38 @@ .popover { @include border-radius($border-rad); - color: #333; + color: lighten($black, 25%); &.bottom, &.right, &.top, &.left { - > .arrow:after { - border-color: transparent; + > .arrow { + &:after { + border-color: transparent; + } } } .popover-title { - background: rgba(black, .05); + background: alpha-color($black, .05); padding: 8px 10px; } .popover-content { - p:last-child { - margin-bottom: 5px; + p { + &:last-child { + margin-bottom: 5px; + } } } } -.channel-header__info .popover-content { - max-height: 250px; - overflow: auto; +.channel-header__info { + .popover-content { + max-height: 250px; + overflow: auto; + } } .user-popover { @@ -36,32 +42,35 @@ display: inline-block; } -.code-popover .popover-content { - padding: 5px; +.code-popover { + .popover-content { + padding: 5px; + } } .user-popover__image { - margin: 0 0 10px; @include border-radius(128px); + margin: 0 0 10px; } .user-popover__email { + display: block; max-width: 200px; overflow: hidden; text-overflow: ellipsis; - display: block; } .search-help-popover { - visibility: hidden; - max-width: none; - width: 100%; - top: 36px; @include single-transition(opacity, .3s, ease-in); font-size: em(13px); + max-width: none; + top: 36px; + visibility: hidden; + width: 100%; &.autocomplete { display: block; + .popover-content { padding: 10px; position: relative; @@ -69,65 +78,68 @@ } .search-autocomplete__divider { - margin: 10px 0 5px; line-height: 21px; + margin: 10px 0 5px; position: relative; + &:first-child { margin-top: 5px; } - span { + + > span { + background: $white; display: inline-block; padding-right: 10px; - background: #fff; - z-index: 5; position: relative; + z-index: 5; } + &:before { + @include opacity(.2); + background: $dark-gray; content: ''; - position: absolute; - width: 100%; height: 1px; - background: #ddd; - top: 10px; left: 0; - @include opacity(.2); + position: absolute; + top: 10px; + width: 100%; } } .search-autocomplete__item { + @include border-radius(2px); cursor: pointer; - padding: 6px 8px; margin: 3px 0 0 5px; - @include border-radius(2px); - white-space: nowrap; overflow: hidden; + padding: 6px 8px; text-overflow: ellipsis; + white-space: nowrap; &:hover { - background: rgba(black, .1); + background: alpha-color($black, .1); } &.selected { - background: rgba(black, .2); + background: alpha-color($black, .2); } .fa { - margin-right: 5px; @include opacity(.5); + margin-right: 5px; } .profile-img { - margin-top: -1px; height: 16px; margin-right: 6px; + margin-top: -1px; width: 16px; } } &.bottom > .arrow { - top: -18px; border-width: 9px; left: 30px; + top: -18px; } .popover-content { @@ -142,9 +154,11 @@ ul { padding-left: 17px; + span { @include opacity(.8); } + strong, b { @include opacity(1); @@ -156,25 +170,28 @@ } &.visible { - visibility: visible; @include opacity(1); + visibility: visible; } } -#member-list-popover { +.member-list__popover { max-width: initial; + .popover-content { - position: relative; + max-height: 350px; padding: 0; + position: relative; width: 260px; - max-height: 350px; + .text-nowrap { + font-size: 13px; + line-height: 26px; + overflow: hidden; padding: 6px 10px; width: 100%; - overflow: hidden; - line-height: 26px; - font-size: 13px; } + .more__name { margin-left: 6px; max-width: 140px; diff --git a/webapp/sass/components/_scrollbar.scss b/webapp/sass/components/_scrollbar.scss index 4ecb38b1f..0bb0e7e21 100644 --- a/webapp/sass/components/_scrollbar.scss +++ b/webapp/sass/components/_scrollbar.scss @@ -1,28 +1,25 @@ @charset 'UTF-8'; -::-webkit-scrollbar -{ - width: 8px; /* for vertical scrollbars */ - height: 8px; /* for horizontal scrollbars */ +::-webkit-scrollbar { + height: 8px; // for horizontal scrollbars + width: 8px; // for vertical scrollbars } -::-webkit-scrollbar-track -{ - background: rgba(0, 0, 0, 0.1); +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, .1); } -::-webkit-scrollbar-thumb -{ +::-webkit-scrollbar-thumb { @include border-radius($border-rad * 2); - background: rgba(0, 0, 0, 0.4); + background: rgba(0, 0, 0, .4); } -body{ - scrollbar-face-color: rgba(0, 0, 0, 0.1); - scrollbar-shadow-color: #2D2C4D; - scrollbar-highlight-color:#7D7E94; +body { scrollbar-3dlight-color: #7D7E94; - scrollbar-darkshadow-color: #2D2C4D; - scrollbar-track-color: rgba(0, 0, 0, 0.1); scrollbar-arrow-color: #C1C1D1; + scrollbar-darkshadow-color: #2D2C4D; + scrollbar-face-color: rgba(0, 0, 0, .1); + scrollbar-highlight-color: #7D7E94; + scrollbar-shadow-color: #2D2C4D; + scrollbar-track-color: rgba(0, 0, 0, .1); }
\ No newline at end of file diff --git a/webapp/sass/components/_search.scss b/webapp/sass/components/_search.scss index faf0b8177..499c4fad4 100644 --- a/webapp/sass/components/_search.scss +++ b/webapp/sass/components/_search.scss @@ -1,15 +1,19 @@ @charset 'UTF-8'; -#channel-header .search-bar__container { - padding: 0 9px 0 3px; +.channel-header { + .search-bar__container { + padding: 0 9px 0 3px; + } } .search-bar__container { - padding: 12px 8px 0 0; @include flex(0 0 56px); + padding: 12px 8px 0 0; - .sidebar--right.move--left & { - padding-right: 42px; + .sidebar--right { + &.move--left & { + padding-right: 42px; + } } } @@ -18,62 +22,60 @@ } .search__clear { + @include single-transition(all, .2s, linear); + @include translateX(60px); + cursor: pointer; display: none; - position: absolute; - right: 0; line-height: 45px; margin-right: 13px; - @include single-transition(all, .2s, linear); - @include translateX(60px); + position: absolute; + right: 0; z-index: 5; - cursor: pointer; } .search-item-snippet { @include clearfix; text-overflow: ellipsis; + + ul, + ol { + padding-left: 20px; + } } .sidebar__collapse { + @include single-transition(all, .2s, linear); + @include translateX(0); cursor: pointer; - z-index: 5; - fill: #fff; - position: absolute; - left: 0; + display: none; + fill: $white; font-size: 35px; - width: 49px; - @include single-transition(all, .2s, linear); - @include translateX(0px); - text-align: center; - padding-left: 1px; + left: 0; line-height: 40px; - display: none; -} - -.search-item-snippet { - ul, - ol { - padding-left: 20px; - } + padding-left: 1px; + position: absolute; + text-align: center; + width: 49px; + z-index: 5; } .sidebar__search-icon { - position: absolute; - top: 15px; - margin-left: 10px; - font-size: 14px; @include opacity(.5); + color: $dark-gray; display: none; - color: #777; + font-size: 14px; + margin-left: 10px; + position: absolute; + top: 15px; } .search__form { position: relative; .search-bar__container & { - margin: 0; - border: 1px solid #ddd; @include border-radius(2px); + border: 1px solid $light-gray; + margin: 0; width: 300px; } @@ -82,21 +84,21 @@ } .search-bar { + box-shadow: none; height: 40px; padding-right: 30px; - box-shadow: none; .search-bar__container & { - height: 30px; border: none; + height: 30px; } } .glyphicon-refresh-animate { - top: 27px; + color: $dark-gray; position: absolute; right: 27px; - color: #999; + top: 27px; .search-bar__container & { right: 7px; @@ -106,30 +108,29 @@ } .search-items-container { - position: relative; - overflow: auto; - -webkit-overflow-scrolling: touch; @include flex(1 1 auto); + -webkit-overflow-scrolling: touch; height: calc(100% - 56px); + overflow: auto; padding-top: 10px; + position: relative; } .search-results-header { + border-bottom: $border-gray; + color: #999999; font-size: 1em; - text-transform: uppercase; - color: #999; font-weight: 400; - color: #888; height: 44px; line-height: 44px; - padding: 0 10px 0 10px; - border-bottom: $border-gray; + padding: 0 10px; + text-transform: uppercase; } .search-item__container { .post { - padding: 0 1em 1em; margin: 0; + padding: 0 1em 1em; &:first-child { border: none; @@ -137,17 +138,17 @@ .search-channel__name { font-weight: 600; - margin: 0 0 10px 0; + margin: 0 0 10px; } } } .search-item__jump { + @include opacity(.8); + font-size: 13px; position: absolute; right: 0; - top: 0px; - font-size: 13px; - @include opacity(.8); + top: 0; &:hover { @include opacity(1); @@ -155,9 +156,9 @@ } .search-item__comment { + margin-right: 35px; position: absolute; right: 0; - margin-right: 35px; top: 0; } @@ -171,5 +172,5 @@ } .search-highlight { - background-color: #fff2bb; + background-color: $yellow; } diff --git a/webapp/sass/components/_suggestion-list.scss b/webapp/sass/components/_suggestion-list.scss index 125a3cf32..0100026ca 100644 --- a/webapp/sass/components/_suggestion-list.scss +++ b/webapp/sass/components/_suggestion-list.scss @@ -1,9 +1,9 @@ @charset 'UTF-8'; .suggestion-list { + @extend %popover-box-shadow; width: 100%; z-index: 100; - @extend %popover-box-shadow; } .suggestion-list--top { @@ -11,31 +11,31 @@ } .suggestion-list__content { - width: 100%; - max-height: 292px; - background-color: #fff; + background-color: $white; border: $border-gray; + max-height: 292px; overflow-x: hidden; overflow-y: scroll; + width: 100%; .command { - position: relative; - width: 100%; + border-bottom: 1px solid $light-gray; + font-size: .95em; line-height: 24px; padding: 5px 10px 8px; + position: relative; + width: 100%; z-index: 101; - font-size: .95em; - border-bottom: 1px solid #ddd; .command__desc { - margin-left: 5px; @include opacity(.5); line-height: normal; + margin-left: 5px; } } } .suggestion-list__content--top { - position: absolute; bottom: 0; + position: absolute; } diff --git a/webapp/sass/components/_tooltip.scss b/webapp/sass/components/_tooltip.scss index 44c10edb9..5e71e3a7b 100644 --- a/webapp/sass/components/_tooltip.scss +++ b/webapp/sass/components/_tooltip.scss @@ -2,9 +2,9 @@ .tooltip { .tooltip-inner { - word-break: break-word; font-size: 13px; - padding: 3px 10px 4px; font-weight: 500; + padding: 3px 10px 4px; + word-break: break-word; } } diff --git a/webapp/sass/components/_tutorial.scss b/webapp/sass/components/_tutorial.scss index f15919009..6545d7764 100644 --- a/webapp/sass/components/_tutorial.scss +++ b/webapp/sass/components/_tutorial.scss @@ -1,72 +1,76 @@ @charset 'UTF-8'; .tip-backdrop { - background: rgba(black, .5); + background: alpha-color($black, .5); + height: 100%; + left: 0; position: absolute; top: 0; - left: 0; width: 100%; - height: 100%; z-index: 999; } .tip-overlay { - width: 350px; - max-width: 90%; - position: absolute; - background-color: #fff; @include border-radius(3px); + background-color: $white; + max-width: 90%; padding: 20px; + position: absolute; + width: 350px; z-index: 1000; .arrow { + border-color: transparent; + border-style: solid; border-width: 10px; - position: absolute; display: block; - width: 0; height: 0; - border-color: transparent; - border-style: solid; + position: absolute; + width: 0; } &.tip-overlay--sidebar { - max-width: 75%; margin: 50px 0 0 10px; + max-width: 75%; min-height: 330px; + .tutorial__footer { - position: absolute; - width: 100%; bottom: 20px; left: 0; padding: 0 20px; + position: absolute; + width: 100%; } + .arrow { - top: 80px; + border-left-width: 0; + border-right-color: $white; left: -10px; margin-top: -10px; - border-left-width: 0; - border-right-color: #fff; + top: 80px; } } &.tip-overlay--header { margin: 10px 0 0 10px; + .arrow { - top: 15px; - left: -10px; border-left-width: 0; - border-right-color: #fff; + border-right-color: $white; + left: -10px; + top: 15px; } } &.tip-overlay--chat { margin-top: -10px; + .arrow { - left: 50%; - margin-left: -10px; border-bottom-width: 0; - border-top-color: #fff; + border-top-color: $white; bottom: -10px; + left: 50%; + margin-left: -10px; } } @@ -86,18 +90,18 @@ } .btn { - background: #ccc; - color: #fff; @include border-radius(3px); + background: alpha-color($black, .3); border: none; + color: $white; margin: 10px 0; &:hover, &:active, &:focus { - color: #fff; + background: alpha-color($black, .4); border: none; - background: #bbb; + color: $white; } } @@ -110,81 +114,88 @@ } .tutorial__circles { - margin: 1.5em 0px -1.7em -4px; + margin: 1.5em 0 -1.7em -4px; .circle { - width: 7px; height: 7px; margin: 0 4px; + width: 7px; } } } .tip-button { - z-index: 998; + cursor: pointer; + position: relative; right: -10px; top: -10px; - position: relative; - cursor: pointer; + z-index: 998; } .tip-div { position: absolute; - top: 0px; - right: 0px; + right: 0; + top: 0; &.tip-overlay--header { - top: 21px; right: 2px; + top: 21px; + .tip-button { @include opacity(.8); } } &.tip-overlay--sidebar { - left: 0; @include opacity(.8); + left: 0; top: -9px; } } .tutorial-steps__container { - text-align: center; - width: 100%; display: table; height: 100%; + text-align: center; + width: 100%; + .tutorial__content { display: table-cell; - vertical-align: middle; - padding-bottom: 100px; padding: 20px 40px 40px; + vertical-align: middle; + .tutorial__steps { - position: relative; + display: inline-block; + margin-bottom: 50px; max-width: 310px; min-height: 370px; - margin-bottom: 50px; + position: relative; text-align: left; - display: inline-block; } } + .tutorial__footer { - position: absolute; bottom: 0; + position: absolute; } + h1 { font-size: em(40px); - margin: -20px 0 30px; font-weight: 600; + margin: -20px 0 30px; } + h3 { font-size: em(24px); - margin-bottom: 30px; font-weight: 600; + margin-bottom: 30px; } + .tutorial__circles { - position: absolute; bottom: 40px; + position: absolute; } + .tutorial-skip { margin-left: 13px; } @@ -192,17 +203,19 @@ .tutorial__circles { margin: 2em 0; + .circle { - width: 9px; - height: 9px; @include border-radius(9px); @include opacity(.2); - background: #000; + background: $black; display: inline-block; + height: 9px; margin: 0 5px; + width: 9px; + &.active { - background: $color--primary; @include opacity(1); + background: $primary-color; } } } diff --git a/webapp/sass/components/_videos.scss b/webapp/sass/components/_videos.scss index 91db750bd..e009e6538 100644 --- a/webapp/sass/components/_videos.scss +++ b/webapp/sass/components/_videos.scss @@ -1,65 +1,68 @@ @charset 'UTF-8'; .video-div { - position: relative; - max-width: 480px; margin-bottom: 8px; + max-width: 480px; + position: relative; + .video-thumbnail { - max-width: 100%; height: auto; + max-width: 100%; } + .block { - background-color: rgba(0,0,0,.5); + background-color: alpha-color($black, .5); border-radius: 10px; + height: 150px; + left: 50%; + margin: -75px 0 0 -100px; position: absolute; top: 50%; - left: 50%; - margin-top: -100px; width: 200px; - margin: -75px 0 0 -100px; - height: 150px; } } .video-type { @include opacity(.8); font-size: 15px; - margin: 0px; - padding: 0px; + margin: 0; + padding: 0; } .video-title { font-size: 15px; margin-top: 3px; } + .play-button { - width: 100px; + @include border-radius(14px); + border: 4px solid alpha-color($white, .4); height: 100px; position: absolute; - top: 26px; right: 51px; - border: 4px solid; - border-color: rgba(255,255,255,.4); - border-radius: 14px; -} -.play-button span { - position: absolute; - top: 10px; - left: 20px; - width: 0; - height: 0; - border-top: 36px solid transparent; - border-bottom: 36px solid transparent; - border-left: 60px solid rgba(255,255,255,.4); + top: 26px; + width: 100px; + + span { + border-bottom: 36px solid transparent; + border-left: 60px solid alpha-color($white, .4); + border-top: 36px solid transparent; + height: 0; + left: 20px; + position: absolute; + top: 10px; + width: 0; + } } .img-div { -moz-force-broken-image-icon: 1; - position: relative; - max-width: 450px; - max-height: 500px; - margin-bottom: 8px; border-radius: 5px; + margin-bottom: 8px; + max-height: 500px; + max-width: 450px; + position: relative; + &.placeholder { height: 500px; } diff --git a/webapp/sass/layout/_content.scss b/webapp/sass/layout/_content.scss index 71bef0d7f..bbc09a80e 100644 --- a/webapp/sass/layout/_content.scss +++ b/webapp/sass/layout/_content.scss @@ -15,21 +15,22 @@ } .app__content { + @include display-flex; + @include flex-direction(column); + background: $white; height: 100%; - padding-top: 50px; margin-left: 220px; + padding-top: 50px; position: relative; - background: #fff; - @include display-flex; - @include flex-direction(column); .channel__wrap & { padding-top: 0; } } + #post-create { @include flex(0 0 auto); - background: #fff; + background: $white; width: 100%; z-index: 3; } @@ -37,12 +38,12 @@ #archive-link-home { @include flex(0 0 auto); cursor: pointer; - padding: 10px 20px; font-size: 13px; + padding: 10px 20px; .fa { - font-size: 11px; @include opacity(.7); + font-size: 11px; } a { @@ -50,36 +51,6 @@ } } -.post-list { - .new-messages-hr { - margin-top: 5px; - margin-bottom: 0px; - border: 0; - border-top: 1px solid #f80; - } - - .new-messages-text { - margin-top: 2px; - margin-bottom: 5px; - color: #f80; - text-align: center; - } -} - -.new-messages-hr { - margin-top: 5px; - margin-bottom: 0px; - border: 0; - border-top: 1px solid #f80; -} - -.new-messages-text { - margin-top: 2px; - margin-bottom: 5px; - color: #f80; - text-align: center; -} - .delete-message-text { margin-top: 10px; } diff --git a/webapp/sass/layout/_footer.scss b/webapp/sass/layout/_footer.scss index 5624e6376..36f1fbc70 100644 --- a/webapp/sass/layout/_footer.scss +++ b/webapp/sass/layout/_footer.scss @@ -1,22 +1,22 @@ @charset 'UTF-8'; .footer-pane { - background: #eee; + background: $light-gray; padding-bottom: 1em; .footer-link { padding: 0 1.5em; &.copyright { - color: #999; + color: $dark-gray; padding-right: 0; } } .footer-site-name { - padding: 1.5em 0 1em; font-size: 14px; font-weight: bold; + padding: 1.5em 0 1em; text-transform: uppercase; } } diff --git a/webapp/sass/layout/_forms.scss b/webapp/sass/layout/_forms.scss index 1f51603cc..259beeb57 100644 --- a/webapp/sass/layout/_forms.scss +++ b/webapp/sass/layout/_forms.scss @@ -6,32 +6,32 @@ } .form__label { - text-align: left; - padding-right: 3px; - font-weight: 600; font-size: 1.1em; + font-weight: 600; + padding-right: 3px; + text-align: left; &.light { - font-weight: normal; - color: #999; + color: $dark-gray; font-size: 1.05em; font-style: italic; + font-weight: normal; padding-top: 2px; } } .input__help { + @include opacity(.8); color: inherit; margin: 10px 0 0 10px; word-break: break-word; - @include opacity(.8); &.dark { @include opacity(1); } &.error { - color: #a94442; + color: darken($red, 20%); } } @@ -49,13 +49,9 @@ } .help-block { + color: $dark-gray; font-size: .95em; margin: 10px 0 0; - color: #999; -} - -.disabled-input { - background-color: #ddd !important; } .form-group { diff --git a/webapp/sass/layout/_headers.scss b/webapp/sass/layout/_headers.scss index 0a6b9f920..9b631d00f 100644 --- a/webapp/sass/layout/_headers.scss +++ b/webapp/sass/layout/_headers.scss @@ -1,6 +1,6 @@ @charset 'UTF-8'; -#channel-header { +.channel-header { @include flex(0 0 56px); } @@ -15,8 +15,8 @@ } .header-dropdown__icon { - font-size: 11px; color: inherit; + font-size: 11px; top: 3px; } @@ -31,12 +31,12 @@ word-break: break-word; &.dropdown { + float: left; max-width: 100%; padding-right: 1em; - float: left; .header-dropdown__icon { - color: #777; + color: $dark-gray; } a { @@ -49,10 +49,11 @@ } &.description { - overflow: hidden; - text-overflow: ellipsis; margin-top: 2px; max-height: 45px; + overflow: hidden; + text-overflow: ellipsis; + .markdown-inline-img { max-height: 45px; } @@ -65,14 +66,14 @@ } .channel-intro { + border-bottom: 1px solid $light-gray; margin: 0 auto 35px; - padding: 0 1em 5px; max-width: 1000px; - border-bottom: 1px solid lightgrey; + padding: 0 1em 5px; .intro-links { - margin: 0 1.5em 10px 0; display: inline-block; + margin: 0 1.5em 10px 0; .fa { margin-right: 5px; @@ -80,28 +81,30 @@ } .channel-intro-profile { - margin-top: 5px; margin-left: 63px; + margin-top: 5px; } .channel-intro-img { float: left; + img { @include border-radius(100px); } } .channel-intro__title { - font-weight: 600; font-size: 20px; + font-weight: 600; margin-bottom: 15px; } .channel-intro__content { - background: #f7f7f7; - padding: 10px 15px; @include border-radius(3px); + background: $bg--gray; + padding: 10px 15px; } + .channel-intro-text { margin-top: 35px; } @@ -111,28 +114,28 @@ .sidebar--left, .sidebar--menu { .team__header { - position: relative; - padding: 9px 10px; @include legacy-pie-clearfix; + padding: 9px 10px; + position: relative; &:before { @include single-transition(all, .05s, linear); - content: ''; background: none; - top: 0; - left: 0; - width: 100%; + content: ''; height: 100%; + left: 0; position: absolute; + top: 0; + width: 100%; } &:hover { &:before { - background: rgba(black, .1); + @include alpha-property(background, $black, .1); } .user__name { - color: #fff; + color: $white; } .navbar-right { @@ -145,95 +148,88 @@ .navbar-right { font-size: .85em; position: absolute; - top: 10px; right: 22px; + top: 10px; z-index: 5; .dropdown-toggle { + @include opacity(.8); @include single-transition(all, .1s, linear); padding: 10px; - @include opacity(.8); } .dropdown-menu { - li a { + a { + overflow: hidden; padding: 3px 20px; text-overflow: ellipsis; - overflow: hidden; } } .dropdown__icon { - fill: #fff; + fill: $white; } } - .settings__link a:hover, - a:visited, - a:link, - a:active { - text-decoration: none; - } - .user__picture { - width: 36px; - height: 36px; - float: left; @include border-radius(36px); + float: left; + height: 36px; margin-right: 6px; + width: 36px; } .header__info { - color: #fff; @include clearfix; + color: $white; padding-left: 2px; - z-index: 1; position: relative; + z-index: 1; } .team__name, .user__name { display: block; - font-weight: 600; font-size: 16px; + font-weight: 600; max-width: 85%; overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; } .team__name { + float: left; line-height: 22px; margin-top: -2px; - float: left; } .user__name { @include single-transition(all, .1s, linear); + @include alpha-property(color, $white, .8); font-size: 14px; - line-height: 18px; font-weight: 400; - color: #eee; - color: rgba(#fff, .8); + line-height: 18px; } > .nav { > li { > a { + background: none; float: right; - background: none !important; padding: 2px; + } - &.dropdown-toggle { - line-height: 1.8; - font-size: 1em; - color: #fff; - } + .dropdown-toggle { + color: $white; + font-size: 1em; + line-height: 1.8; } } } } + .search__clear { display: none; } @@ -250,27 +246,29 @@ } .channel-header { - width: 100%; border-left: none; font-size: 14px; line-height: 56px; + width: 100%; #member_popover { - width: 50px; - color: #999; + color: #999999; cursor: pointer; + width: 50px; .fa { - margin-left: 4px; font-size: 16px; + margin-left: 4px; } } &.alt { margin: 0; + th { font-weight: normal !important; } + td { border: none; } @@ -278,37 +276,39 @@ th { text-align: center; + &:first-child { - text-align: left !important; border-left: none; - width: 100%; padding-left: 1em; + text-align: left !important; + width: 100%; } + &:last-child { width: 8.9%; } } td { - padding: 5px 25px 5px !important; font-size: 13px; + padding: 5px 25px 5px !important; text-align: center !important; + &:first-child { text-align: left !important; } } .heading { - margin: 0; - color: #555; + color: #555555; + display: inline-block; font-size: 1.3em; font-weight: 600; + margin: 0 4px 0 0; + max-width: 100%; overflow: hidden; text-overflow: ellipsis; - max-width: 100%; - display: inline-block; vertical-align: middle; - margin-right: 4px; } .caret { @@ -318,13 +318,13 @@ .more { color: #81848b; display: inline-block; - vertical-align: top; - text-transform: capitalize; font-size: 13px; + text-transform: capitalize; + vertical-align: top; } .disabled { - color: #999; + color: #999999; } } @@ -342,11 +342,11 @@ .channel-header__links { font-family: 'Open Sans', sans-serif; + font-size: 22px; height: 30px; - width: 24px; line-height: 26px; margin-right: 9px; - font-size: 22px; + width: 24px; .channel__wrap.move--left & { position: absolute; @@ -355,14 +355,15 @@ } > a { - color: inherit; - text-decoration: none; @include opacity(.6); @include single-transition(all, .1s, ease-in); + color: inherit; + text-decoration: none; &:hover { @include opacity(1); } + &:focus { color: inherit; } diff --git a/webapp/sass/layout/_markdown.scss b/webapp/sass/layout/_markdown.scss index 307060ac3..b9acd8b5b 100644 --- a/webapp/sass/layout/_markdown.scss +++ b/webapp/sass/layout/_markdown.scss @@ -16,43 +16,77 @@ #post-list { .markdown-inline-img { -moz-force-broken-image-icon: 1; - max-height: 500px; height: 500px; + max-height: 500px; } } .post-body--code { + overflow-x: auto; + overflow-y: hidden; position: relative; pre { - margin-bottom: 0; - word-break: normal; - overflow: auto; - word-wrap: normal; + border: 1px solid rgba(221,221,221,0.2); + border-radius: .25em; + margin: 0; + padding: 0px; + text-align: left; + white-space: nowrap; + } + + code { + border: none; + white-space: pre; + } + + td { + padding: 0 .5em; + vertical-align: top; + } + + &:hover .post-body--code__language { + @include opacity(1); } } .post-body--code__language { - -webkit-transform: translate3d(0,0,0); + @include opacity(0); + @include translate3d(0, 0, 0); + background: #21586d; + border-radius: 0 .25em; + color: $white; + padding: 4px 10px 5px; position: absolute; - top: 0; right: 0; - color: #fff; - background: #21586d; - padding: 4px 10px 5px 10px; - font-size: 13px; - opacity: .7; + top: 0; + -webkit-transition: opacity 0.6s; + -moz-transition: opacity 0.6s; + -o-transition: opacity 0.6s; + transition: opacity 0.6s; z-index: 5; } +.post-body--code__lineno { + border-right: 1px solid #aaa; + color: #aaa; + margin-right: .5em; + text-align: right; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} + .post__body { hr { - height: 4px; - padding: 0; - margin: 15px 0 16px; + @include opacity(.2); background-color: #e7e7e7; border: 0 none; - @include opacity(.2); + height: 4px; + margin: 15px 0 16px; + padding: 0; } code { @@ -67,50 +101,53 @@ } .markdown__table { - background: #fff; + background: $white; margin: 5px 0 10px; th, td { - padding: 6px 13px; border: 1px solid #ddd; + padding: 6px 13px; } tbody tr { - background: #fff; + background: $white; &:nth-child(2n) { background-color: #f8f8f8; } } } + blockquote { border: none; - position: relative; font-size: 16px; - padding: 10px 10px 10px 38px; margin-bottom: 0; + padding: 10px 10px 10px 38px; + position: relative; &:before { + @include opacity(.6); + content: '\f10d'; + display: inline-block; font-family: FontAwesome; - font-weight: normal; + font-size: 20px; font-style: normal; - display: inline-block; - text-decoration: inherit; - content: '\f10d'; + font-weight: normal; left: 8px; - top: 5px; position: absolute; - font-size: 20px; - @include opacity(.6); + text-decoration: inherit; + top: 5px; } } + pre { - border: none; - margin: 5px 0; color: inherit; + margin: 5px 0; + padding: 0; } + code { - background: #fff; + background: $white; color: inherit; } diff --git a/webapp/sass/layout/_navigation.scss b/webapp/sass/layout/_navigation.scss index 65c62cb17..87e4b4d27 100644 --- a/webapp/sass/layout/_navigation.scss +++ b/webapp/sass/layout/_navigation.scss @@ -7,14 +7,14 @@ #navbar { input { - margin: 0px 5px 0px 2px; + margin: 0 5px 0 2px; } .navbar-default { - position: absolute; + background: $primary-color; border: none; min-height: 45px; - background: $color--primary; + position: absolute; .navbar-nav { > li { @@ -30,19 +30,19 @@ } .navbar-toggle { - width: 43px; - float: left; border-color: transparent; border-radius: 0; + fill: $white; + float: left; + height: 44px; + line-height: 48px; margin: 0; padding: 0 10px; - line-height: 48px; - height: 44px; + width: 43px; z-index: 5; - fill: #fff; .icon-bar { - background: #fff; + background: $white; width: 21px; } @@ -51,7 +51,7 @@ } .icon--white { - color: #fff; + color: $white; } &:hover, @@ -62,16 +62,16 @@ } .navbar-brand { - padding: 0 .5em; - height: 45px; - line-height: 45px; float: none; font-size: 16px; + height: 45px; + line-height: 45px; + padding: 0 .5em; .heading { - margin-right: 3px; + color: $white; font-weight: 600; - color: #fff; + margin-right: 3px; } .header-dropdown__icon { @@ -79,36 +79,36 @@ } .dropdown-toggle { - color: #fff; + color: $white; } .description { + color: $white; display: inline-block; margin-right: .5em; - color: #fff; &.info-popover { - width: 19px; - height: 19px; - background: url('../images/info__icon.png'); @include background-size(100% 100%); - vertical-align: middle; - top: -1px; - position: relative; + background: url('../images/info__icon.png'); cursor: pointer; + height: 19px; + position: relative; + top: -1px; + vertical-align: middle; + width: 19px; } } } } .sidebar-channel { - white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; span { - white-space: nowrap; margin-left: 2px; + white-space: nowrap; } } @@ -117,11 +117,13 @@ } .more-channel-table { - width: 100%; border: 1px solid #dbdbdc; + width: 100%; + td { padding: 7px; } + button { width: 110px; } @@ -129,9 +131,9 @@ } .badge-notify { - background: red; - position: absolute; + background: $red; left: 4px; + position: absolute; top: 3px; z-index: 100; } diff --git a/webapp/sass/layout/_post-right.scss b/webapp/sass/layout/_post-right.scss index 595577564..529f73995 100644 --- a/webapp/sass/layout/_post-right.scss +++ b/webapp/sass/layout/_post-right.scss @@ -27,8 +27,8 @@ .post { &.post--root { - padding-bottom: 1.2em; border-bottom: 1px solid #ddd; + padding-bottom: 1.2em; .post__body { background: transparent !important; @@ -37,8 +37,8 @@ .post__header { .col__reply { - top: 0; text-align: right; + top: 0; } } @@ -48,13 +48,13 @@ } hr { - margin-bottom: 0; border: none; + margin-bottom: 0; } .post-create__container { - width: 100%; margin-top: 10px; + width: 100%; .textarea-wrapper { min-height: 100px; @@ -70,48 +70,46 @@ .msg-typing { @include opacity(.7); + display: block; float: left; - margin-top: 3px; font-size: 13px; - line-height: 20px; - min-width: 1px; - display: block; height: 20px; + line-height: 20px; + margin-top: 3px; max-width: 230px; + min-width: 1px; } .post-create-footer { - width: 100%; padding: 5px 0 10px; + width: 100%; } .post-right-comments-upload-in-progress { - padding: 6px 0; color: #a8adb7; margin-right: 10px; + padding: 6px 0; } } } + .post-right-header { - font-size: 1em; - text-transform: uppercase; + border-bottom: $border-gray; color: #999; + font-size: 1em; font-weight: 400; - color: #888; height: 39px; padding: 10px 10px 0 15px; - border-bottom: $border-gray; + text-transform: uppercase; } .post-right-root-container { - padding: 5px 10px; border-bottom: $border-gray; -} + padding: 5px 10px; -.post-right-root-container { ul { - padding-left: 0; margin-bottom: 2px; + padding-left: 0; } } @@ -131,19 +129,19 @@ } .post-right-create-comment-container { - padding: 5px; - margin-bottom: 18px; - position: absolute; bottom: 0; left: 0; + margin-bottom: 18px; + padding: 5px; + position: absolute; width: 100%; } .post-right__scroll { - position: relative; - overflow: auto; - -webkit-overflow-scrolling: touch; @include flex(1 1 auto); + -webkit-overflow-scrolling: touch; + overflow: auto; + position: relative; .file-preview__container { margin-top: 5px; diff --git a/webapp/sass/layout/_post.scss b/webapp/sass/layout/_post.scss index ce055035d..9d5be239a 100644 --- a/webapp/sass/layout/_post.scss +++ b/webapp/sass/layout/_post.scss @@ -1,19 +1,20 @@ @charset 'UTF-8'; .custom-textarea { - white-space: pre-wrap; - word-wrap: break-word; background: transparent; - border: 1px solid #ccc; - position: absolute; - top: 0px; + border: 1px solid #cccccc; height: auto; - resize: none; line-height: 20px; min-height: 36px; overflow-x: hidden; + position: absolute; + resize: none; + top: 0px; + white-space: pre-wrap; + word-wrap: break-word; + &:focus { - border-color: #ccc; + border-color: #cccccc; box-shadow: none; } } @@ -24,23 +25,23 @@ } .textarea-div { - white-space: pre-wrap; - word-wrap: normal; + border: 0; color: rgba(0,0,0,0); - position: absolute; - top: 0px; - word-break: break-word; + height: auto; left: 1px; line-height: 20px; min-height: 36px; - height: auto; - border: 0; + position: absolute; + top: 0px; + white-space: pre-wrap; + word-break: break-word; + word-wrap: normal; } body.ios { .textarea-div { - padding: 7px 17px 7px 15px; -webkit-overflow-scrolling: auto; + padding: 7px 17px 7px 15px; } } @@ -49,133 +50,146 @@ body.ios { } .textarea-wrapper { + min-height: 36px; position: relative; + .textbox-preview-area { + box-shadow: none; + left: 0; position: absolute; - z-index: 2; top: 0; - left: 0; - box-shadow: none; white-space: normal; + z-index: 2; } + .help__text { - right: 0; - position: absolute; - z-index: 3; bottom: -23px; - font-size: 13px; cursor: pointer; + font-size: 13px; + position: absolute; + right: 0; + z-index: 3; } + .textbox-preview-link { margin-right: 8px; } - min-height: 36px; } .help_format_text { - display: none !important; - position: absolute; + @include opacity(0); + @include single-transition(all .2s ease); bottom: -23px; - left: 0px; + display: none !important; + font-size: .85em; + left: 0; overflow: hidden; + position: absolute; text-overflow: ellipsis; - font-size: .85em; - @include opacity(0); - @include single-transition(all .2s ease); b, i, code { margin-right: 3px; } + .textbox-preview-link { - font-size: 13px; cursor: pointer; + font-size: 13px; margin-left: 15px; } } .date-separator, .new-separator { - text-align: center; height: 2em; margin: 0; position: relative; + text-align: center; z-index: 0; + &:before, &:after { content: ''; + display: none; height: 1em; - position: absolute; left: 0; + position: absolute; width: 100%; - display: none; } + &:before { bottom: 0; } + &:after { top: 0; } + &.hovered--after { &:before { background: #f5f5f5; display: block; } } + &.hovered--before { &:after { background: #f5f5f5; display: block; } } + .separator__hr { - border-color: #ccc; + border-color: #cccccc; margin: 0; position: relative; - z-index: 5; top: 1em; + z-index: 5; } + .separator__text { - line-height: 2em; - color: #555; - background: #fff; + @include border-radius(50px); + background: #ffffff; + color: #555555; display: inline-block; - padding: 0 1em; + font-size: 13px; font-weight: 700; - @include border-radius(50px); + line-height: 2em; + padding: 0 1em; position: relative; z-index: 5; - font-size: 13px; } } + .new-separator { .separator__hr { border-color: #ffaf53; } + .separator__text { - color: #f80; + color: #ff8800; font-weight: normal; } } .file-overlay { + color: #ffffff; + font-size: em(20px); + font-weight: 600; + height: 100%; + left: 0; position: absolute; + text-align: center; top: 0; - left: 0; width: 100%; - height: 100%; - text-align: center; - color: #fff; - font-size: em(20px); - font-weight: 600; z-index: 6; .overlay__indent { - background-color: rgba(0, 0, 0, .6); - position: relative; - height: 100%; @include clearfix; + @include alpha-property(background-color, $black, .6); + height: 100%; + position: relative; } &.center-file-overlay { @@ -186,11 +200,13 @@ body.ios { &.right-file-overlay { font-size: em(18px); + .overlay__circle { - width: 300px; height: 300px; margin: -150px 0 0 -150px; + width: 300px; } + .overlay__files { margin: 60px auto 15px; width: 150px; @@ -198,16 +214,15 @@ body.ios { } .overlay__circle { - background: #111; - background: rgba(black, .7); - width: 370px; + @include border-radius(500px); + @include alpha-property(background, $black, .7); height: 370px; + left: 50%; margin: -185px 0 0 -185px; - @include border-radius(500px); + pointer-events: none; position: absolute; top: 50%; - left: 50%; - pointer-events: none; + width: 370px; } .overlay__files { @@ -216,11 +231,11 @@ body.ios { } .overlay__logo { - position: absolute; - left: 50%; + @include opacity(.3); bottom: 30px; + left: 50%; margin-left: -50px; - @include opacity(.3); + position: absolute; } .fa { @@ -232,62 +247,64 @@ body.ios { #post-list { @include flex(1 1 auto); - position: relative; - overflow-y: hidden; height: 100%; + overflow-y: hidden; + position: relative; .inactive { display: none; } .post-list-holder-by-time { - background: #fff; + -webkit-overflow-scrolling: touch; + background: #ffffff; + height: 100%; overflow-y: scroll; - width: 100%; padding: 1em 0 0; position: absolute; - height: 100%; - -webkit-overflow-scrolling: touch; + width: 100%; + &.active { display: inline; } } .more-messages-text { - margin: 5px 0 10px; - display: block; - text-align: center; - outline: none; border: none; + display: block; font-size: 13px; + margin: 5px 0 10px; + outline: none; + text-align: center; } + .beginning-messages-text { - margin-top: 2px; - margin-bottom: 5px; + color: grey; display: block; + margin-bottom: 5px; + margin-top: 2px; text-align: center; - color: grey; } } .post-list__timestamp { - position: absolute; - top: 8px; - left: 50%; - z-index: 50; - width: 120px; - text-align: center; - background: $color--primary; - color: #fff; @include border-radius(3px); - font-size: 12px; - line-height: 25px; - margin-left: -60px; - -webkit-font-smoothing: initial; + @include opacity(0); @include single-transition(all, .6s, ease); @include translateY(-45px); - @include opacity(0); + @include font-smoothing(initial); + background: $primary-color; + color: $white; display: none; + font-size: 12px; + left: 50%; + line-height: 25px; + margin-left: -60px; + position: absolute; + text-align: center; + top: 8px; + width: 120px; + z-index: 50; &.scrolling { @include translateY(0); @@ -296,147 +313,162 @@ body.ios { } .post-list__arrows { + @include opacity(0); + @include single-transition(all, .6s); background-repeat: no-repeat; - width: 40px; - height: 40px; - text-align: center; - fill: #444; - position: absolute; bottom: 0; + display: none; + fill: #444444; + height: 40px; left: 9px; + position: absolute; + text-align: center; + width: 40px; z-index: 50; - @include opacity(0); - @include single-transition(all, .6s); - display: none; svg { color: inherit; - width: 28px; height: 28px; + width: 28px; } &.scrolling { - display: block; @include opacity(1); + display: block; } } .post-create__container { form { - width: 100%; - padding: .5em 14px 0; margin: 0 auto; max-width: 1028px; + padding: .5em 14px 0; + width: 100%; } + .post-create-body { - position: relative; padding: 0 0 2px; + position: relative; + .post-body__cell { - vertical-align: top; position: relative; + vertical-align: top; + &.scroll { .btn-file { right: 15px; } + .custom-textarea { padding-right: 43px; } } } + .send-button { - display: none; + @include single-transition(all, .15s); cursor: pointer; - padding-right: 4px; - width: 45px; - height: 37px; + display: none; font-size: 18px; + height: 37px; line-height: 37px; - vertical-align: bottom; + padding-right: 4px; text-align: center; - @include single-transition(all, .15s); + vertical-align: bottom; + width: 45px; + &:active { @include opacity(.75); } } + .custom-textarea { - padding-top: 8px; - padding-right: 28px; - max-height: 162px !important; line-height: 1.5; + max-height: 162px !important; + padding-right: 28px; + padding-top: 8px; } + .textarea-div { - padding-top: 8px; - padding-right: 30px; + line-height: 1.5; max-height: 163px !important; overflow: auto; - line-height: 1.5; + padding-right: 30px; + padding-top: 8px; } + .btn-file { - right: 0; - position: absolute; - top: 1px; - color: #444; @include opacity(.5); @include single-transition(all, .15s); + color: #444444; font-size: 16px; padding: 7px 9px 6px; + position: absolute; + right: 0; + top: 1px; + &:hover, &:active { @include opacity(.9); box-shadow: none; } } + textarea { box-shadow: none; } } + .post-create-footer { @include clearfix; - padding: 3px 0 0 0; font-size: 13px; + padding: 3px 0 0 0; .control-label { font-weight: normal; margin-bottom: 0; - top: -5px; position: relative; + top: -5px; } } + .msg-typing { - display: block; @include opacity(.7); - white-space: nowrap; + display: block; + font-size: .95em; + height: 20px; margin-bottom: 5px; overflow: hidden; - font-size: .95em; text-overflow: ellipsis; - height: 20px; + white-space: nowrap; } } .post-list__table { display: table; + height: 100%; + min-height: 100%; table-layout: fixed; width: 100%; - min-height: 100%; - height: 100%; + .post-list__content { display: table-cell; vertical-align: bottom; + .dropdown-menu { &.bottom { - top: auto; bottom: 25px; + top: auto; } } } } .post { - word-wrap: break-word; + @include legacy-pie-clearfix; + max-width: 100%; padding: 8px .5em 0 1em; position: relative; - max-width: 100%; - @include legacy-pie-clearfix; + word-wrap: break-word; &:hover { .dropdown, @@ -445,6 +477,7 @@ body.ios { .post__remove { visibility: visible; } + .permalink-icon { visibility: visible; } @@ -455,9 +488,9 @@ body.ios { } p { - margin: 0; - line-height: 1.6em; font-size: .97em; + line-height: 1.6em; + margin: 0; white-space: pre-wrap; &:last-child { @@ -488,8 +521,8 @@ body.ios { } .post__header { - margin: 0; height: 0; + margin: 0; .col__name { display: none; @@ -501,20 +534,13 @@ body.ios { } .post__time { - top: 24px; - } - - .post__time { - font: normal normal normal FontAwesome; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - position: absolute; - top: -2px; - left: -7px; + @include opacity(0); font-size: 11px; + left: -7px; line-height: 37px; - @include opacity(0); + position: absolute; + text-rendering: auto; + top: -2px; } } @@ -528,11 +554,9 @@ body.ios { display: none; } } - } - &.post--comment { .post__body { - border-left: 4px solid #ddd; + border-left: 4px solid #dddddd; } } } @@ -562,12 +586,12 @@ body.ios { } .post__content { + display: table; margin: 0 auto; - position: relative; max-width: 1000px; - display: table; - width: 100%; + position: relative; table-layout: fixed; + width: 100%; > div { display: table-cell; @@ -576,9 +600,9 @@ body.ios { } .post__header { - padding: 0; list-style: none; margin-bottom: 2px; + padding: 0; li { display: inline-block; @@ -586,12 +610,12 @@ body.ios { } .col__name { - margin-right: 7px; font-weight: 600; + margin-right: 7px; .user-popover { - max-width: 200px; @include clearfix; + max-width: 200px; text-overflow: ellipsis; white-space: nowrap; } @@ -601,8 +625,8 @@ body.ios { position: absolute; right: 0; top: 30px; - width: 65px; white-space: nowrap; + width: 65px; } .permalink-popover { @@ -616,27 +640,29 @@ body.ios { .btn { font-size: 13px; height: 30px; - padding: 0 8px; line-height: 30px; + padding: 0 8px; } } } .post__img { width: 46px; + img { - width: 36px; + @include border-radius(50px); height: 36px; vertical-align: inherit; - @include border-radius(50px); + width: 36px; } } .post__embed-container { + @include single-transition(max-height, .5, ease); display: block; max-height: 1000px; - transition: max-height .5s ease; overflow: hidden; + &[hidden] { max-height: 0; } @@ -644,15 +670,15 @@ body.ios { .dropdown { display: inline-block; - visibility: hidden; margin-right: 5px; top: -1px; + visibility: hidden; .dropdown-menu { - right: 0; left: auto; min-width: 130px; padding: 2px 0; + right: 0; li { display: block; @@ -667,27 +693,27 @@ body.ios { .post__dropdown { &:after { content: '[...]'; - top: -1px; position: relative; + top: -1px; } } .post__remove { - font-family: 'Open Sans', sans-serif; - position: relative; + @include opacity(.5); + color: inherit; display: inline-block; - vertical-align: top; - right: 15px; - top: -5px; + font-family: 'Open Sans', sans-serif; font-size: 20px; - width: 20px; + font-weight: 600; height: 20px; line-height: 20px; - font-weight: 600; - visibility: hidden; - color: inherit; - @include opacity(.5); + position: relative; + right: 15px; text-decoration: none; + top: -5px; + vertical-align: top; + visibility: hidden; + width: 20px; &:hover { @include opacity(.8); @@ -695,10 +721,10 @@ body.ios { } .post__body { - word-wrap: break-word; - padding: .2em .5em; @include legacy-pie-clearfix; + padding: .2em .5em; width: calc(100% - 75px); + word-wrap: break-word; p { margin: 0 0 .4em; @@ -725,6 +751,7 @@ body.ios { p { margin-bottom: 0; } + li ul, li ol { padding: 0 0 0 20px; @@ -745,8 +772,8 @@ body.ios { } li input[type='checkbox']:disabled { - vertical-align: top; cursor: default; + vertical-align: top; } } @@ -766,21 +793,21 @@ body.ios { } .post__link { - margin: 2px 0 5px; font-size: 13px; - text-overflow: ellipsis; + margin: 2px 0 5px; overflow: hidden; + text-overflow: ellipsis; white-space: nowrap; } .post__embed-visibility { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; cursor: pointer; + display: inline-block; font: normal normal normal 14px/1 FontAwesome; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; margin: 5px 0 10px; - display: inline-block; + text-rendering: auto; &:hover { text-decoration: none; @@ -807,8 +834,8 @@ body.ios { .post-loading-gif { height: 10px; - width: 10px; margin-top: 6px; + width: 10px; } .post-fail { @@ -816,12 +843,12 @@ body.ios { } .post-waiting { - color: #999; + color: #999999; } .permalink-icon { + color: $primary-color; display: inline-block; - color: $color--primary; visibility: hidden; } @@ -830,16 +857,16 @@ body.ios { margin-right: 6px; visibility: hidden; svg { - width: 18px; - top: 3px; fill: inherit; position: relative; + top: 3px; + width: 18px; } } .comment-icon__container { - fill: $color--primary; display: inline-block; + fill: $primary-color; visibility: hidden; &:focus { @@ -857,10 +884,10 @@ body.ios { .comment-icon { display: inline-block; - top: 2px; - position: relative; - margin-right: 3px; fill: inherit; + margin-right: 3px; + position: relative; + top: 2px; } path { @@ -869,28 +896,30 @@ body.ios { } .web-embed-data { - padding: 2px 0 0 10px; - background: #f9f9f9; - background: rgba(0, 0, 0, .05); @include border-radius(2px); + @include alpha-property(background, $black, 0.05); height: 50px; overflow: hidden; + padding: 2px 0 0 10px; text-overflow: ellipsis; + .embed-title { - margin: 3px 0 1px; - color: #555; + color: #555555; font-weight: 600; - white-space: nowrap; - text-overflow: ellipsis; + margin: 3px 0 1px; overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } + .embed-description { + color: #888888; margin: 0; - white-space: nowrap; - text-overflow: ellipsis; overflow: hidden; - color: #888; + text-overflow: ellipsis; + white-space: nowrap; } + .embed-link { display: none; } @@ -898,89 +927,104 @@ body.ios { } .bot-indicator { + border-radius: 2px; font-family: inherit; font-size: 11px; - padding: 2px 4px; - border-radius: 2px; font-weight: 600; margin: 0 0 0 -4px; + padding: 2px 4px; } .attachment { .attachment__content { - border-width: 1px; - border-style: solid; border-radius: 4px; - padding: 2px 5px; + border-style: solid; + border-width: 1px; margin: 0 0 5px 0; + padding: 2px 5px; } + .attachment__thumb-pretext { - border: 0 none; background: transparent; + border: none; + margin-left: 5px; } + .attachment__container { - border-left-width: 4px; border-left-style: solid; + border-left-width: 4px; padding: 2px 0 2px 10px; + &.attachment__container--good { border-left-color: #00c100; } + &.attachment__container--warning { border-left-color: #dede01; } + &.attachment__container--danger { border-left-color: #e40303; } } + .attachment__body { float: left; - width: 80%; - padding-right: 5px; overflow-x: auto; overflow-y: hidden; + padding-right: 5px; + width: 80%; + &.attachment__body--no_thumb { width: 100%; } } + .attachment__text p:last-of-type { display: inline-block; } - .attachment__thumb-pretext { - margin-left: 5px; - } + .attachment__title { + font-size: 16px; + height: 22px; + line-height: 16px; margin: 5px 0; padding: 0; - line-height: 16px; - height: 22px; - font-size: 16px; + a { font-size: 16px; } } + .attachment__author-icon { @include border-radius(50px); + height: 14px; margin-right: 5px; width: 14px; - height: 14px; } + .attachment__image { - max-width: 100%; margin-bottom: 1em; + max-width: 100%; } + .attachment__thumb-container { - width: 20%; float: right; + width: 20%; + img { max-height: 75px; max-width: 100%; } } + .attachment___fields { width: 100%; + .attachment___field-caption { font-weight: 700; } + .attachment___field p { margin: 0; } @@ -992,6 +1036,6 @@ body.ios { } .permalink-popover { - min-width: 320px; margin-left: 50px !important; + min-width: 320px; } diff --git a/webapp/sass/layout/_sidebar-left.scss b/webapp/sass/layout/_sidebar-left.scss index ece054a15..4c65d0a65 100644 --- a/webapp/sass/layout/_sidebar-left.scss +++ b/webapp/sass/layout/_sidebar-left.scss @@ -1,86 +1,97 @@ @charset 'UTF-8'; .sidebar--left { + background: #fafafa; + border-right: $border-gray; + height: 100%; + left: 0; position: absolute; width: 220px; - left: 0; - height: 100%; - border-right: $border-gray; - background: #fafafa; z-index: 5; &.sidebar--padded { padding-top: 44px; } + .dropdown-menu { max-height: 400px; + max-width: 200px; overflow-x: hidden; overflow-y: auto; - max-width: 200px; width: 200px; } + .search__form { + display: none; margin: 0; padding: 1em 1em 0; - display: none; } + .badge { - background-color: $color--primary; + background-color: $primary-color; position: absolute; right: 10px; top: 5px; } + .status { + display: inline-block; + margin-right: 6px; position: relative; top: 1px; - margin-right: 6px; width: 12px; - display: inline-block; + svg { max-height: 14px; } + i, path, ellipse { @include opacity(.5); + &.online--icon, &.away--icon { @include opacity(1); } } + .fa-lock { margin-left: 1px; } + .fa-globe { - top: -1px; position: relative; + top: -1px; } } + .nav-pills__container { + -webkit-overflow-scrolling: touch; height: calc(100% - 80px); - position: relative; overflow: auto; - -webkit-overflow-scrolling: touch; + position: relative; } .nav-pills__unread-indicator { - position: absolute; - left: 0; - right: 0; - width: 72%; - color: #fff; - background: #2389d7; @include border-radius(50px); + background: #2389d7; + color: #ffffff; + font-size: 13.5px; + left: 0; margin: 0 auto; padding: 3px 0 4px; - font-size: 13.5px; + position: absolute; + right: 0; text-align: center; + width: 72%; z-index: 1; } .nav-pills__unread-indicator-top { top: 66px; } + .nav-pills__unread-indicator-bottom { bottom: 20px; } @@ -91,71 +102,83 @@ margin: 0; } } + li { > h4 { + color: #aaaaaa; font-size: 1em; - text-transform: uppercase; - margin: 1.1em 0 .5em; font-weight: 400; - color: #aaa; letter-spacing: -.3px; + margin: 1.1em 0 .5em; padding: 0 10px 0 15px; + text-transform: uppercase; } + > a { - padding: 3px 10px 3px 25px; - line-height: 1.5; border-radius: 0; - white-space: nowrap; + line-height: 1.5; overflow: hidden; + padding: 3px 10px 3px 25px; text-overflow: ellipsis; + white-space: nowrap; + &.has-badge { padding-right: 30px; } + &.has-close { padding-right: 30px; + &:hover { .btn-close { - display: block; @include opacity(.8); + display: block; } } + .btn-close { + @include opacity(0); + display: none; font-family: 'Open Sans', sans-serif; + font-size: 20px; + font-weight: 600; position: absolute; right: 15px; top: -1px; - font-size: 20px; - font-weight: 600; - @include opacity(0); - display: none; + &:hover { @include opacity(1); } } } + &.nav-more { text-decoration: underline; } + &.unread-title { font-weight: 600; } + } + &.active { a { &:before { + background: $black; content: ''; + height: 100%; + left: 0; position: absolute; top: 0; - left: 0; width: 5px; - height: 100%; - background: #000; } } + a, a:hover, a:focus { - background-color: rgba(black, .1); + @include alpha-property(background-color, $black, .1); border-radius: 0; font-weight: 400; position: relative; @@ -163,35 +186,37 @@ } } } + .modal-title { line-height: 2em; } .add-channel-btn { + color: #aaaaaa; float: right; - outline: none; + font-size: 22px; + font-weight: 700; + line-height: 18px; margin: -2px 0 0 0; - color: #aaa; + outline: none; padding: 0 5px; text-decoration: none; - font-size: 22px; - line-height: 18px; - font-weight: 700; + &:hover { - color: #666; + color: #666666; } } } .channel-loading-gif { height: 15px; - width: 15px; margin-top: 2px; + width: 15px; } .join-channel-loading-gif { - margin-top: 5px; - margin-left: 10px; height: 25px; + margin-left: 10px; + margin-top: 5px; width: 25px; } diff --git a/webapp/sass/layout/_sidebar-menu.scss b/webapp/sass/layout/_sidebar-menu.scss index 9438491f9..0cf60f328 100644 --- a/webapp/sass/layout/_sidebar-menu.scss +++ b/webapp/sass/layout/_sidebar-menu.scss @@ -1,69 +1,79 @@ @charset 'UTF-8'; .sidebar--menu { - position: absolute; - width: 220px; - right: 0; - height: 100%; - border-right: $border-gray; - padding: 0 0 2em 0; background: #fafafa; + border-right: $border-gray; display: none; + height: 100%; + padding: 0 0 2em; + position: absolute; + right: 0; + width: 220px; + .nav-pills__container { padding-top: 5px; } + .team__header { + @include legacy-pie-clearfix; display: none; padding: 0 15px; - @include legacy-pie-clearfix; + a { - color: #fff; + color: $white; } + .navbar-right { font-size: .85em; margin: 16px -5px 0; + .dropdown-toggle { padding: 0 10px; } + .dropdown-menu { li a { - padding: 3 20px; color: #555; + padding: 3 20px; } } + .dropdown__icon { - width: 4px; - height: 16px; @include background-size(100% 100%); display: inline-block; + height: 16px; + width: 4px; } } + .team__name { float: left; - line-height: 50px; - font-weight: 600; font-size: 1.2em; + font-weight: 600; + line-height: 50px; max-width: 80%; overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; } } + .nav { > li { > a { - font-size: 15px; background: none !important; color: inherit; + font-size: 15px; line-height: 40px; padding: 0 15px; + .fa, .glyphicon { - width: 25px; - text-align: center; left: -5px; position: relative; + text-align: center; + width: 25px; } } } diff --git a/webapp/sass/layout/_sidebar-right.scss b/webapp/sass/layout/_sidebar-right.scss index e1a7d7641..a7b631047 100644 --- a/webapp/sass/layout/_sidebar-right.scss +++ b/webapp/sass/layout/_sidebar-right.scss @@ -1,13 +1,13 @@ @charset 'UTF-8'; .sidebar--right { - position: fixed; - width: 400px; + @include translateX(400px); + background: $white; height: 100%; - right: 0px; padding: 0; - background: #fff; - @include translateX(400px); + position: fixed; + right: 0; + width: 400px; .post-body { img { @@ -26,39 +26,39 @@ } .sidebar--right__content { - height: 100%; @include display-flex; @include flex-direction(column); + height: 100%; } .sidebar--right__back { - color: inherit; @include opacity(.8); - width: 30px; - text-align: center; - margin: 0 0 0 -14px; - font-size: 13px; + color: inherit; display: inline-block; + font-size: 13px; + margin: 0 0 0 -14px; + text-align: center; + width: 30px; } .sidebar-right__body { + @include border-radius(2px 0 0 0); + @include display-flex; @include flex(1 1 auto); + @include flex-direction(column); border-left: $border-gray; border-top: $border-gray; - @include display-flex; - @include flex-direction(column); height: calc(100% - 56px); - @include border-radius(2px 0 0 0); } .sidebar__overlay { - width: 100%; - height: 100%; - background-color: yellow; @include opacity(.1); + background-color: $yellow; + height: 100%; + pointer-events: none; position: absolute; + width: 100%; z-index: 5; - pointer-events: none; } .input-group { @@ -66,17 +66,17 @@ } .sidebar--right__close { - margin: 11px 0 0 0; - width: 22px; - height: 22px; - opacity: .5; - font-size: 22px; - line-height: 0; + @include single-transition(all, .2s, ease-in); background: none; + border: none; float: right; + font-size: 22px; + height: 22px; + line-height: 0; + margin: 11px 0 0; + opacity: .5; outline: none; - border: none; - @include single-transition(all, .2s, ease-in); + width: 22px; &:hover, &:active { @@ -90,14 +90,14 @@ } .sidebar--right__header { - font-size: 1em; - text-transform: uppercase; + @include flex(0 0 44px); + border-bottom: $border-gray; color: inherit; + font-size: 1em; height: 44px; - padding: 0 1em; line-height: 44px; - @include flex(0 0 44px); - border-bottom: $border-gray; + padding: 0 1em; + text-transform: uppercase; } .sidebar--right__subheader { diff --git a/webapp/sass/layout/_webhooks.scss b/webapp/sass/layout/_webhooks.scss index d6e367218..ffd8dd7dc 100644 --- a/webapp/sass/layout/_webhooks.scss +++ b/webapp/sass/layout/_webhooks.scss @@ -1,11 +1,11 @@ @charset 'UTF-8'; .webhooks__container { - background: rgba(black, .1); - border: 1px solid; @include border-radius(3px); - padding: 0 13px 15px; + @include alpha-property(background, $black, .1); + border: 1px solid; margin-top: 10px; + padding: 0 13px 15px; } .webhook__item { @@ -19,16 +19,16 @@ } .webhook__remove { - position: absolute; - right: -7px; - top: 8px; - width: 30px; - height: 30px; + color: #e05f5d; font-size: 22px; font-weight: bold; + height: 30px; + position: absolute; + right: -7px; text-align: center; text-decoration: none; - color: #e05f5d; + top: 8px; + width: 30px; } .webhook__url { diff --git a/webapp/sass/responsive/_desktop.scss b/webapp/sass/responsive/_desktop.scss index dcabb807f..ccd6f0226 100644 --- a/webapp/sass/responsive/_desktop.scss +++ b/webapp/sass/responsive/_desktop.scss @@ -32,21 +32,23 @@ .tip-overlay { &.tip-overlay--chat { margin: -10px 0 0 -10px; + .arrow { - right: 15px; left: auto; + right: 15px; } } } + .inner-wrap { &.move--left { .file-overlay { font-size: em(18px); .overlay__circle { - width: 300px; height: 300px; margin: -150px 0 0 -150px; + width: 300px; } .overlay__files { @@ -62,4 +64,4 @@ .modal-lg { width: 700px; } -}
\ No newline at end of file +} diff --git a/webapp/sass/responsive/_mobile.scss b/webapp/sass/responsive/_mobile.scss index 4a1397143..53ea6d329 100644 --- a/webapp/sass/responsive/_mobile.scss +++ b/webapp/sass/responsive/_mobile.scss @@ -519,7 +519,7 @@ .search-bar__container { padding: 0; @include flex(0 0 44px); - background: $color--primary; + background: $primary-color; color: #fff; &.focused { @@ -756,9 +756,11 @@ .app__content { padding-top: 45px; margin: 0; + .channel__wrap & { padding-top: 45px; } + #channel-header { display: none; } @@ -775,11 +777,6 @@ .post-comments { padding: 9px 21px 10px 10px !important; } - - .post-image__column .post-image .file-playback__controls.stop, - .image-wrapper > a .file-playback__controls.stop { - @include opacity(1); - } } @media screen and (max-width: 640px) { diff --git a/webapp/sass/responsive/_tablet.scss b/webapp/sass/responsive/_tablet.scss index 14641cfa5..0a725a558 100644 --- a/webapp/sass/responsive/_tablet.scss +++ b/webapp/sass/responsive/_tablet.scss @@ -2,9 +2,9 @@ @media screen and (max-width: 960px) { .sidebar--right { - z-index: 5; - @include translateX(100%); @include single-transition(all, .5s, ease); + @include translateX(100%); + z-index: 5; &.move--left { @include translateX(0); @@ -32,4 +32,4 @@ .second-bar { display: none; } -}
\ No newline at end of file +} diff --git a/webapp/sass/routes/_access-history.scss b/webapp/sass/routes/_access-history.scss index 7ede7b085..ea66f5f00 100644 --- a/webapp/sass/routes/_access-history.scss +++ b/webapp/sass/routes/_access-history.scss @@ -2,9 +2,9 @@ .access-history__table { display: table; - width: 100%; - padding-top: 15px; line-height: 1.6; + padding-top: 15px; + width: 100%; &:first-child { padding: 0; @@ -16,8 +16,8 @@ } .access__date { - font-weight: 600; font-size: 15px; + font-weight: 600; width: 190px; } diff --git a/webapp/sass/routes/_activity-log.scss b/webapp/sass/routes/_activity-log.scss index 6e8d0a925..d3400e29a 100644 --- a/webapp/sass/routes/_activity-log.scss +++ b/webapp/sass/routes/_activity-log.scss @@ -1,36 +1,27 @@ @charset 'UTF-8'; -@keyframes highlight { - from { - background: rgba(yellow, .5); - } - to { - background: none; - } -} - .animation--highlight { &:before { - content: ''; animation: highlight 1.5s ease; + content: ''; + height: 100%; + left: 0; position: absolute; top: 0; - left: 0; width: 100%; - height: 100%; } } .activity-log__table { + border-top: 1px solid $light-gray; display: table; - width: 100%; line-height: 1.8; - border-top: 1px solid #ddd; padding: 15px 0; + width: 100%; &:first-child { - padding-top: 0; border: none; + padding-top: 0; } > div { @@ -49,6 +40,7 @@ .report__platform { font-size: 15px; font-weight: 600; + .fa { margin-right: 6px; } diff --git a/webapp/sass/routes/_admin-console.scss b/webapp/sass/routes/_admin-console.scss index aff1e8e8e..0b47e5ab6 100644 --- a/webapp/sass/routes/_admin-console.scss +++ b/webapp/sass/routes/_admin-console.scss @@ -15,26 +15,25 @@ } h3 { - font-weight: 600; border-bottom: 1px solid #ddd; - padding-bottom: .5em; + font-weight: 600; margin: 1em 0; + padding-bottom: .5em; } .table { - background: #fff; + background: $white; } .form-control { - background-color: #fff; + background-color: $white; border: 1px solid #ccc; color: #555; &:focus { + @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6)); border-color: #66afe9; outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6); } } @@ -42,7 +41,7 @@ color: #333; &.btn-primary { - background: #2389d7; + background: $primary-color; &:hover, &:focus, @@ -53,7 +52,7 @@ } .dropdown-menu { - background: #fff; + background: $white; border: 1px solid rgba(0,0,0,.15); color: inherit; } @@ -86,38 +85,38 @@ > h4 { background: #333; - padding: 10px 10px; margin: 1px 0 0; + padding: 10px; .menu-icon--right { - top: 6px; right: 12px; + top: 6px; } } } .menu-icon--right { - position: absolute; - right: 10px; - top: 3px; font-size: 18px; font-weight: 600; - width: 20px; height: 20px; line-height: 20px; + position: absolute; + right: 10px; text-align: center; + top: 3px; + width: 20px; .fa { + color: $white; font-size: 13px; - right: -2px; position: relative; - color: #fff; + right: -2px; } } &.nav__sub-menu { + @include font-smoothing(initial); background: #111; - -webkit-font-smoothing: auto; &.padded { padding: 5px 0; @@ -125,30 +124,31 @@ li { > a { - font-size: 13px; - padding: 5px 35px 5px 15px; background: transparent; color: #bbb; + font-size: 13px; + padding: 5px 35px 5px 15px; &:hover { - color: lighten($color--primary, 10); + color: lighten($primary-color, 10); } &.active { - color: #fff; + color: $white; font-weight: 600; } } .nav-more { - font-size: 13px; - padding: 5px 15px; background: transparent; color: #bbb; - display: block; cursor: pointer; + display: block; + font-size: 13px; + padding: 5px 15px; + &:hover { - color: lighten($color--primary, 10); + color: lighten($primary-color, 10); } } } @@ -166,13 +166,13 @@ } .log__panel { - overflow: scroll; - width: 100%; - height: 800px; + background-color: white; border: 1px solid #ddd; + height: 800px; margin-top: 10px; + overflow: scroll; padding: 5px; - background-color: white; + width: 100%; } .compliance__panel { @@ -199,10 +199,10 @@ color: #333; &.admin { - overflow: auto; background-color: #f1f1f1; - padding: 0 20px 20px; min-height: 600px; + overflow: auto; + padding: 0 20px 20px; } .wrapper--fixed { @@ -213,9 +213,9 @@ margin-top: 40px; .control-label { - text-align: left; - padding-right: 0; font-weight: 600; + padding-right: 0; + text-align: left; } .form-group { @@ -223,22 +223,25 @@ } .file__upload { - position: relative; - margin: 0 10px 10px 0; display: inline-block; + margin: 0 10px 10px 0; + position: relative; input { - position: absolute; @include opacity(0); - width: 100%; height: 100%; - z-index: 5; - top: 0; left: 0; + position: absolute; + top: 0; + width: 100%; + z-index: 5; } } .help-text { + color: #777; + margin: 10px 0 0 15px; + &.no-margin { margin: 0; } @@ -248,9 +251,6 @@ padding-left: 23px; } - margin: 10px 0 0 15px; - color: #777; - .help-link { margin-right: 5px; } @@ -262,10 +262,10 @@ .alert { display: inline-block; - padding: 5px 7px; margin: 1em 0 0; - top: 1px; + padding: 5px 7px; position: relative; + top: 1px; .fa { margin-right: 5px; @@ -274,11 +274,11 @@ } .banner { - background: #fff; + background: $white; border: 1px solid #ddd; - padding: .7em 1.5em; font-size: .95em; margin: 2em 0; + padding: .7em 1.5em; .banner__heading { font-size: 1.5em; @@ -295,19 +295,19 @@ .popover { border-radius: 3px; - width: 100%; font-size: .95em; + width: 100%; } .panel { - border: none; background-color: transparent; + border: none; } .panel-default { > .panel-heading { - padding: 10px 0; background-color: transparent; + padding: 10px 0; } .panel-body { @@ -324,9 +324,9 @@ line-height: 1.5; a { - text-decoration: none; - display: block; @include clearfix; + display: block; + text-decoration: none; &.collapsed { .fa-minus { @@ -339,10 +339,10 @@ } .fa { - font-size: 18px; + color: #aaa; float: right; + font-size: 18px; margin-top: 8px; - color: #aaa; } .fa-plus { diff --git a/webapp/sass/routes/_docs.scss b/webapp/sass/routes/_docs.scss index 24e96772b..9a205f8a2 100644 --- a/webapp/sass/routes/_docs.scss +++ b/webapp/sass/routes/_docs.scss @@ -5,15 +5,15 @@ padding-bottom: 20px; > div { - width: 1170px; margin: 0 auto; - padding: 0 15px; max-width: 100%; + padding: 0 15px; + width: 1170px; } h1.markdown__heading { border-bottom: 1px solid #ddd; - padding-bottom: 1rem; margin: 1em 0 1em; + padding-bottom: 1rem; } } diff --git a/webapp/sass/routes/_error-page.scss b/webapp/sass/routes/_error-page.scss index 8cd0716ca..438e60554 100644 --- a/webapp/sass/routes/_error-page.scss +++ b/webapp/sass/routes/_error-page.scss @@ -8,23 +8,23 @@ body { } .error__container { - max-width: 800px; - margin: 0 auto; + color: #555; display: table-cell; - vertical-align: top; + margin: 0 auto; + max-width: 800px; padding: 5em 0; text-align: left; - color: #555; + vertical-align: top; } .error__icon { - font-size: 4em; color: #ccc; + font-size: 4em; } h2 { - font-weight: 600; font-size: 1.5em; + font-weight: 600; margin: .8em 0 .5em; } diff --git a/webapp/sass/routes/_loading.scss b/webapp/sass/routes/_loading.scss index 8d6552957..39f37b1b3 100644 --- a/webapp/sass/routes/_loading.scss +++ b/webapp/sass/routes/_loading.scss @@ -4,32 +4,32 @@ .loading-screen { display: table; - width: 100%; height: 100%; padding: 60px; text-align: center; + width: 100%; .loading__content { display: table-cell; - vertical-align: middle; font-size: 0; + vertical-align: middle; h3 { + display: inline-block; font-size: 16px; font-weight: 400; - margin: 0 .2em 0; - display: inline-block; + margin: 0 .2em; } .round { - background-color: #444; - width: 4px; - height: 4px; + @include animation(move .75s infinite linear); + @include border-radius(10px); + background-color: #444444; display: inline-block; + height: 4px; margin: 0 2px; opacity: .1; - @include border-radius(10px); - @include animation(move .75s infinite linear); + width: 4px; } @for $i from 1 through 3 { @@ -42,6 +42,7 @@ from { opacity: 1; } + to { opacity: .1; } diff --git a/webapp/sass/routes/_settings.scss b/webapp/sass/routes/_settings.scss index 3c735be3c..1c3f2e308 100644 --- a/webapp/sass/routes/_settings.scss +++ b/webapp/sass/routes/_settings.scss @@ -2,41 +2,47 @@ .user-settings { min-height: 300px; + .table-responsive { - max-width: 560px; max-height: 300px; + max-width: 560px; } } .modal { .settings-modal { width: 800px; + .modal-back { - width: 50px; - height: 40px; - top: 12px; font-size: 27px; font-weight: normal; + height: 40px; + left: 0; line-height: 32px; position: absolute; - left: 0; text-align: center; + top: 12px; + width: 50px; + .fa { + height: 100%; + left: 0; line-height: inherit; position: absolute; width: 100%; - height: 100%; - left: 0; } } + .modal-body { - padding: 0; margin: 0 auto; min-height: calc(100% - 62px); + padding: 0; } + li { list-style: none; } + label { font-weight: 600; } @@ -44,87 +50,110 @@ .no-padding--left { padding-left: 0; } + .padding-top { padding-top: 7px; + &.x2 { padding-top: 14px; } + &.x3 { padding-top: 21px; } } + .padding-bottom { padding-bottom: 7px; + &.x2 { padding-bottom: 14px; } + &.x3 { padding-bottom: 21px; } + .control-label { font-weight: 600; + &.text-left { text-align: left; } } } + .profile-img { - width: 128px; height: 128px; + width: 128px; } + .settings-table { - max-width: 1000px; - margin: 0 auto; display: table; + margin: 0 auto; + max-width: 1000px; table-layout: fixed; width: 100%; + > div { display: table-cell; vertical-align: top; } + .nav { position: fixed; width: 179px; + &.position--top { top: 57px; } } + .security-links { margin-right: 20px; + .fa { margin-right: 6px; } } + .settings-links { width: 180px; } + .settings-content { - padding: 0px 20px 30px; + padding: 0 20px 30px; + .modal-header { display: none; } + .section-min { padding: 1em 0; margin-bottom: 0; cursor: pointer; position: relative; @include clearfix; + &:hover { background: #f9f9f9; } + &:hover .fa { display: inline-block; } + &:hover .section-edit { text-decoration: underline; } } .section-max { - background: rgba(black, .05); - padding: 1em 0 1.3em; - margin-bottom: 0; @include clearfix; + @include alpha-property(background, $black, .05); + margin-bottom: 0; + padding: 1em 0 1.3em; + .section-title { margin-bottom: 10px; } @@ -136,50 +165,54 @@ padding: 4px 5px; width: 40px; } + img { border: 1px solid rgba(black, .15); width: 29px; } } + .group--code { + select { + @include appearance(none); + appearance: none; padding-right: 25px; + + &::ms-expand { + display: none; + } } - select::-ms-expand { - display: none; - } + &:before { - pointer-events: none; - position: absolute; - top: 11px; - right: 50px; - z-index: 5; + @include font-smoothing; content: '\f0d7'; display: inline-block; font: normal normal normal 14px/1 FontAwesome; - font-size: inherit; + pointer-events: none; + position: absolute; + right: 50px; text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - select { - -moz-appearance: none; - -webkit-appearance: none; - appearance: none; + top: 11px; + z-index: 5; } } + .premade-themes { margin-bottom: 10px; + .theme-label { font-weight: 400; margin-top: 5px; } + img { border: 3px solid transparent; } + .active { img { - border-color: $color--primary; + border-color: $primary-color; } } } @@ -197,12 +230,12 @@ } .theme-elements__header { - margin: 10px 20px 0px 0; border-bottom: 1px solid #ccc; - padding: 5px 0 10px; + cursor: pointer; font-size: em(13.5px); font-weight: 600; - cursor: pointer; + margin: 10px 20px 0 0; + padding: 5px 0 10px; .fa-minus { display: none; @@ -212,39 +245,41 @@ .fa-minus { display: inline-block; } + .fa-plus { display: none; } } .header__icon { - float: right; @include opacity(.5); + float: right; } } .theme-elements__body { - padding-top: 5px; - display: none; + @include border-radius(0 0 3px 3px); @include legacy-pie-clearfix; - background: rgba(255, 255, 255, .05); - padding: 20px 0 0 20px; + @include alpha-property(background-color, $white, .05); + display: none; margin: 0 20px 0 0; - @include border-radius(0 0 3px 3px); + padding: 20px 0 0 20px; } .custom-label { - white-space: nowrap; - font-weight: normal; font-size: 12px; - width: 100%; + font-weight: normal; + margin-bottom: 0; overflow: hidden; text-overflow: ellipsis; - margin-bottom: 0; + white-space: nowrap; + width: 100%; } + .input-group-addon { background: transparent; } + .radio { label { font-weight: 600; @@ -253,32 +288,33 @@ } .section-title { - margin-bottom: 5px; font-weight: 600; + margin-bottom: 5px; padding-right: 50px; } .section-edit { - text-align: right; margin-bottom: 5px; + text-align: right; + .fa { - margin-right: 5px; - font-size: 12px; @include opacity(.5); display: none; + font-size: 12px; + margin-right: 5px; &.fa-chevron-down { - top: -1px; margin-right: 0; position: relative; + top: -1px; } } } .section-describe { - @include opacity(.7); - white-space: pre; @include clearfix; + @include opacity(.7); text-overflow: ellipsis; + white-space: pre; } .divider-dark { @@ -290,8 +326,8 @@ } .setting-list { - padding: 0; list-style-type: none; + padding: 0; } .setting-list__hint { @@ -305,68 +341,77 @@ .setting-list-item { margin-top: 7px; } + .has-error { color: #a94442; } .file-status { + color: #555; font-size: 13px; margin-top: 8px; - color: #555; } .confirm-import { - padding: 4px 10px; margin: 10px 0; + padding: 4px 10px; } } } } + .nav-pills { > li { margin: 0; + a { - padding: 8px 5px 8px 15px; border-radius: 0; color: #777; + padding: 8px 5px 8px 15px; } + .glyphicon { - width: 25px; top: 2px; + width: 25px; } + &:hover { a { - background-color: rgba(black, .1); + @include alpha-property(background-color, $black, .1); } } + &.active { a { - color: #111; background-color: #e1e1e1; + color: #111; + &:before { + background: $black; content: ''; + height: 100%; + left: 0; position: absolute; top: 0; - left: 0; width: 5px; - height: 100%; - background: #000; } } + a, a:hover, a:focus { - background-color: rgba(black, .1); + @include alpha-property(background-color, $black, .1); border-radius: 0; font-weight: 400; - position: relative; - white-space: nowrap; overflow: hidden; + position: relative; text-overflow: ellipsis; + white-space: nowrap; } } } } + h3 { font-size: em(20px); } @@ -391,13 +436,15 @@ .member-div { border-bottom: 1px solid lightgrey; - position: relative; - padding: 2px; margin: 0; + padding: 2px; + position: relative; width: 100%; + &:first-child { border-top: 1px solid lightgrey; } + .post-profile-img { @include border-radius(50px); margin-right: 8px; @@ -407,14 +454,14 @@ .member-role, .member-drop { .fa { - margin-right: 5px; @include opacity(.5); font-size: 12px; + margin-right: 5px; } .member-menu { - top: -50%; right: 110%; + top: -50%; } } @@ -425,13 +472,13 @@ } .member-menu { - right: 0px; left: auto; + right: 0; } .member-list { - width: 100%; overflow-x: visible; + width: 100%; } .member-page { diff --git a/webapp/sass/routes/_signup.scss b/webapp/sass/routes/_signup.scss index 53c59c222..09f8e4185 100644 --- a/webapp/sass/routes/_signup.scss +++ b/webapp/sass/routes/_signup.scss @@ -1,19 +1,19 @@ @charset 'UTF-8'; .signup-header { - width: 100%; + background: $bg--gray; line-height: 33px; padding: 0 1em .2em; - background: $bg--gray; + width: 100%; .fa { margin-right: 5px; } } .signup-team__container { - padding: 100px 0px 50px 0px; - max-width: 380px; margin: 0 auto; + max-width: 380px; + padding: 100px 0 50px; position: relative; &.padding--less { @@ -21,7 +21,7 @@ } .form-control:focus { - @include box-shadow(inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)); + @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6)); } h1, @@ -39,16 +39,16 @@ } h2 { + font-size: em(30px); font-weight: 600; - margin-bottom: .8em; letter-spacing: -.5px; - font-size: em(30px); + margin-bottom: .8em; } h3 { - font-weight: 600; - margin: 0 0 1.3em 0; font-size: 1.5em; + font-weight: 600; + margin: 0 0 1.3em; } h4 { @@ -66,7 +66,7 @@ } p { - color: #555; + color: #555555; line-height: 1.5; margin-bottom: 1em; } @@ -81,32 +81,32 @@ } .form-control { - text-align: left; display: table-cell; + text-align: left; width: 100%; } .input-group-addon { - text-align: left; - width: 50%; display: table-cell; overflow: hidden; + text-align: left; text-overflow: ellipsis; + width: 50%; } } } .inner__content { - padding: 0 1rem; margin: 30px 0 20px; + padding: 0 1rem; } .block--gray { + @include border-radius(3px); background: #f2f2f2; display: inline-block; - padding: .85em 1.2em; font-weight: 600; - @include border-radius(3px); + padding: .85em 1.2em; } form { @@ -114,32 +114,32 @@ } .signup-team-confirm__container { - padding: 100px 0px 100px 0px; + padding: 100px 0; } .signup-team-logo { display: none; + margin: 0 0 2em; width: 210px; - margin: 0 0 2em 0; } .signup-team-login { - padding-bottom: 10px; font-weight: 600; + padding-bottom: 10px; } .signup-team__name { - margin: .5em 0 0; font-size: 2.2em; font-weight: 600; + margin: .5em 0 0; padding-left: 1rem; } .signup-team__subdomain { - margin: .2em 0 1.2em; font-size: 1.5em; - padding-left: 1rem; font-weight: 300; + margin: .2em 0 1.2em; + padding-left: 1rem; text-transform: uppercase; } @@ -148,21 +148,21 @@ } .or__container { + background: #dddddd; height: 1px; - background: #ddd; - text-align: left; margin: 2em 0; + text-align: left; span { - width: 40px; - top: -10px; - position: relative; + background: #ffffff; + display: inline-block; font-size: 1.14286em; - line-height: 20px; font-weight: 600; - background: #fff; - display: inline-block; + line-height: 20px; + position: relative; text-align: center; + top: -10px; + width: 40px; } } @@ -177,9 +177,9 @@ .btn { font-size: 1em; - padding: em(7px) em(15px); font-weight: 600; margin-right: 5px; + padding: em(7px) em(15px); .fa { font-size: 17px; @@ -187,29 +187,29 @@ } .icon { - width: 18px; - height: 18px; - margin-right: 8px; @include background-size(100% 100%); display: inline-block; + height: 18px; + margin-right: 8px; + width: 18px; } &.btn-custom-login { + @include border-radius(2px); + color: $white; display: block; - min-width: 200px; - width: 200px; - padding: 0 1em; - margin: 1em 1rem; height: 40px; line-height: 34px; - color: #fff; - @include border-radius(2px); + margin: 1em 1rem; + min-width: 200px; + padding: 0 1em; + width: 200px; &.gitlab { - background: #548; + background: #554488; &:hover { - background: darken(#548, 10%); + background: darken(#554488, 10%); } span { @@ -250,10 +250,10 @@ } &.email { - background: #2389d7; + background: $primary-color; &:hover { - background: darken(#2389d7, 10%); + background: $primary-color--hover; } span { @@ -269,15 +269,15 @@ } &.btn-default { - color: #444; + color: #444444; } .glyphicon { &.glyphicon-ok, &.glyphicon-refresh { - margin-right: .5em; - left: -2px; font-size: .9em; + left: -2px; + margin-right: .5em; } &.glyphicon-chevron-right { @@ -296,28 +296,29 @@ .has-error { .control-label { - background: #f2f2f2; - padding: .7em 1em; @include border-radius(3px); - margin: 1em 0 0; + background: #f2f2f2; + color: #999999; font-size: 14px; font-weight: normal; - color: #999; + margin: 1em 0 0; + padding: .7em 1em; width: 100%; &:before { - @extend .fa; + @extend %font-awesome; + color: #aaaaaa; content: '\f071'; margin-right: 4px; - color: #aaa; } } } .reset-form { @include border-radius(3px); - position: relative; font-size: .95em; + position: relative; + p { color: inherit; } @@ -363,12 +364,12 @@ .black, &.black { - color: #000; + color: #000000; } } .color--light { - color: #777; + color: #777777; } .margin--extra { @@ -381,9 +382,10 @@ } .signup-team-all { - margin: 0 0 20px; - border: 1px solid #ddd; @include border-radius(2px); + border: 1px solid #dddddd; + margin: 0 0 20px; + .signup-team-dir { background: #fafafa; border-top: 1px solid #d5d5d5; @@ -395,25 +397,25 @@ a { color: inherit; display: block; - padding: 0 15px; - line-height: 3.5em; - height: 3.5em; font-size: 1.1em; + height: 3.5em; + line-height: 3.5em; + padding: 0 15px; } } .signup-team-dir__name { - white-space: nowrap; float: left; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; width: 90%; } .signup-team-dir__arrow { + color: #999999; float: right; font-size: .9em; - color: #999; line-height: 3.5em; } } diff --git a/webapp/sass/routes/_statistics.scss b/webapp/sass/routes/_statistics.scss index b48c137c3..797bc480b 100644 --- a/webapp/sass/routes/_statistics.scss +++ b/webapp/sass/routes/_statistics.scss @@ -2,45 +2,45 @@ .team_statistics { .total-count { + @include border-radius(3px); + background: $white; + border: 1px solid $light-gray; margin: 1em 0; text-align: center; - background: #fff; - border: 1px solid #ddd; width: 100%; - @include border-radius(3px); .title { + border-bottom: 1px solid $light-gray; + font-size: 13px; font-weight: 400; padding: 7px 10px; - border-bottom: 1px solid #ddd; text-align: left; - font-size: 13px; .fa { + color: #555555; float: right; - margin: 0px 0 0; - color: #555; font-size: 16px; + margin: 0; } } .content { + color: #555555; font-size: 30px; font-weight: 600; - color: #555; - padding: .3em 0 .35em; overflow: auto; + padding: .3em 0 .35em; } } .total-count--day { - width: 760px; - height: 275px; - border: 1px solid #ddd; - padding: 5px 10px 10px 10px; - margin: 10px 10px 10px 10px; - background: #fff; + background: $white; + border: 1px solid $light-gray; clear: both; + height: 275px; + margin: 10px; + padding: 5px 10px 10px; + width: 760px; > div { font-size: 18px; @@ -50,8 +50,8 @@ .recent-active-users { table { - width: 100%; table-layout: fixed; + width: 100%; } .content { @@ -68,14 +68,15 @@ } td { - font-weight: 400; - white-space: nowrap; - text-overflow: ellipsis; + @include clearfix; + border-left: 1px solid $light-gray; + border-top: 1px solid $light-gray; font-size: 13px; - border-left: 1px solid #ddd; - border-top: 1px solid #ddd; + font-weight: 400; padding: 5px 5px 6px; - @include clearfix; + text-overflow: ellipsis; + white-space: nowrap; + &:first-child { border-left: none; } diff --git a/webapp/sass/utils/_animations.scss b/webapp/sass/utils/_animations.scss index 767e30847..ffdbcb219 100644 --- a/webapp/sass/utils/_animations.scss +++ b/webapp/sass/utils/_animations.scss @@ -1,19 +1,21 @@ @charset 'UTF-8'; -@-webkit-keyframes spin2 { +@keyframes spin { from { - -webkit-transform: rotate(0deg); + transform: scale(1) rotate(0deg); } + to { - -webkit-transform: rotate(360deg); + transform: scale(1) rotate(360deg); } } -@keyframes spin { +@keyframes highlight { from { - transform: scale(1) rotate(0deg); + @include alpha-property(background, $yellow, .5); } + to { - transform: scale(1) rotate(360deg); + background: none; } } diff --git a/webapp/sass/utils/_functions.scss b/webapp/sass/utils/_functions.scss index 9013920fa..baedd72c5 100644 --- a/webapp/sass/utils/_functions.scss +++ b/webapp/sass/utils/_functions.scss @@ -4,6 +4,20 @@ @return #{$pixels/$context}em } +@function alpha-color($color, $amount) { + @return rgba($color, $amount) +} + %popover-box-shadow { @include box-shadow(rgba(black, .175) 1px -3px 12px); +} + +%font-awesome { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + transform: translate(0, 0); }
\ No newline at end of file diff --git a/webapp/sass/utils/_mixins.scss b/webapp/sass/utils/_mixins.scss index 28723e1a5..6e4488fca 100644 --- a/webapp/sass/utils/_mixins.scss +++ b/webapp/sass/utils/_mixins.scss @@ -1,8 +1,29 @@ @charset 'UTF-8'; @mixin file-icon($path) { - background: #fff url($path); + @include background-size(60px auto); + background-color: $white; + background-image: url($path); background-position: center; background-repeat: no-repeat; - @include background-size(60px auto); } + +@mixin alpha-property($property, $color, $opacity) { + #{$property}: rgba($color, $opacity); +} + +@mixin font-smoothing($value: antialiased) { + @if $value == antialiased { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + } + @else { + -webkit-font-smoothing: subpixel-antialiased; + -moz-osx-font-smoothing: auto; + } +} + +@mixin cursor($value) { + cursor: -webkit-$value; + cursor: zoom-$value; +}
\ No newline at end of file diff --git a/webapp/sass/utils/_module.scss b/webapp/sass/utils/_module.scss index e7f0c0c46..5dddcaef7 100644 --- a/webapp/sass/utils/_module.scss +++ b/webapp/sass/utils/_module.scss @@ -1,5 +1,5 @@ // Only for combining all the files in this folder @import 'variables'; -@import 'animations'; @import 'functions'; @import 'mixins'; +@import 'animations'; diff --git a/webapp/sass/utils/_variables.scss b/webapp/sass/utils/_variables.scss index 065c37a17..345ab11e8 100644 --- a/webapp/sass/utils/_variables.scss +++ b/webapp/sass/utils/_variables.scss @@ -1,10 +1,16 @@ @charset 'UTF-8'; // Color Variables -$color--primary: rgb(35, 137, 215); -$color--primary--hover: darken($color--primary, 10%); +$primary-color: rgb(35, 137, 215); +$primary-color--hover: darken($primary-color, 10%); $bg--gray: rgb(245, 245, 245); -$bg--white: rgb(255, 255, 255); +$white: rgb(255, 255, 255); +$black: rgb(0, 0, 0); +$red: rgb(229, 101, 101); +$yellow: rgb(255, 255, 0); +$light-gray: rgba(0, 0, 0, .06); +$gray: rgba(0, 0, 0, .3); +$dark-gray: rgba(0, 0, 0, .5); // Page Variables $border-gray: 1px solid #ddd; diff --git a/webapp/utils/async_client.jsx b/webapp/utils/async_client.jsx index d3f91bb0e..2392b50b9 100644 --- a/webapp/utils/async_client.jsx +++ b/webapp/utils/async_client.jsx @@ -781,12 +781,12 @@ export function savePreferences(preferences, success, error) { ); } -export function getSuggestedCommands(command, suggestionId, component) { - client.listCommands( +export function getSuggestedCommands(command, channelId, suggestionId, component) { + client.listCommands({command: command, channelId: channelId}, (data) => { var matches = []; data.forEach((cmd) => { - if (('/' + cmd.trigger).indexOf(command) === 0) { + if (('/' + cmd.trigger).indexOf(command) === 0 || cmd.external_management) { let s = '/' + cmd.trigger; let hint = ''; if (cmd.auto_complete_hint && cmd.auto_complete_hint.length !== 0) { diff --git a/webapp/utils/client.jsx b/webapp/utils/client.jsx index e29cf71d3..69bda4303 100644 --- a/webapp/utils/client.jsx +++ b/webapp/utils/client.jsx @@ -1031,12 +1031,13 @@ export function regenCommandToken(data, success, error) { }); } -export function listCommands(success, error) { +export function listCommands(data, success, error) { $.ajax({ url: '/api/v1/commands/list', dataType: 'json', contentType: 'application/json', - type: 'GET', + type: 'POST', + data: JSON.stringify(data), success, error: function onError(xhr, status, err) { var e = handleError('listCommands', xhr, status, err); diff --git a/webapp/utils/constants.jsx b/webapp/utils/constants.jsx index 0f7c9857d..4ee934e11 100644 --- a/webapp/utils/constants.jsx +++ b/webapp/utils/constants.jsx @@ -145,7 +145,7 @@ export default { PRESENTATION_TYPES: ['ppt', 'pptx'], SPREADSHEET_TYPES: ['xlsx', 'csv'], WORD_TYPES: ['doc', 'docx'], - CODE_TYPES: ['css', 'html', 'js', 'php', 'rb'], + CODE_TYPES: ['as', 'applescript', 'osascript', 'scpt', 'bash', 'sh', 'zsh', 'clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic', 'coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced', 'cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp', 'cs', 'csharp', 'css', 'd', 'di', 'dart', 'delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm', 'diff', 'django', 'jinja', 'dockerfile', 'docker', 'erl', 'f90', 'f95', 'fsharp', 'fs', 'gcode', 'nc', 'go', 'groovy', 'handlebars', 'hbs', 'html.hbs', 'html.handlebars', 'hs', 'hx', 'java', 'jsp', 'js', 'jsx', 'json', 'jl', 'kt', 'ktm', 'kts', 'less', 'lisp', 'lua', 'mk', 'mak', 'md', 'mkdown', 'mkd', 'matlab', 'm', 'mm', 'objc', 'obj-c', 'ml', 'perl', 'pl', 'php', 'php3', 'php4', 'php5', 'php6', 'ps', 'ps1', 'pp', 'py', 'gyp', 'r', 'ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb', 'rs', 'scala', 'scm', 'sld', 'scss', 'st', 'sql', 'swift', 'tex', 'vbnet', 'vb', 'bas', 'vbs', 'v', 'veo', 'xml', 'html', 'xhtml', 'rss', 'atom', 'xsl', 'plist', 'yaml'], PDF_TYPES: ['pdf'], PATCH_TYPES: ['patch'], ICON_FROM_TYPE: { @@ -515,30 +515,64 @@ export default { SPACE: 32, TAB: 9 }, + CODE_PREVIEW_MAX_FILE_SIZE: 500000, // 500 KB HighlightedLanguages: { - diff: 'Diff', - apache: 'Apache', - makefile: 'Makefile', - http: 'HTTP', - json: 'JSON', - markdown: 'Markdown', - javascript: 'JavaScript', - css: 'CSS', - nginx: 'nginx', - objectivec: 'Objective-C', - python: 'Python', - xml: 'XML', - perl: 'Perl', - bash: 'Bash', - php: 'PHP', - coffeescript: 'CoffeeScript', - cs: 'C#', - cpp: 'C++', - sql: 'SQL', - go: 'Go', - ruby: 'Ruby', - java: 'Java', - ini: 'ini' + actionscript: {name: 'ActionScript', extensions: ['as']}, + applescript: {name: 'AppleScript', extensions: ['applescript', 'osascript', 'scpt']}, + bash: {name: 'Bash', extensions: ['bash', 'sh', 'zsh']}, + clojure: {name: 'Clojure', extensions: ['clj', 'boot', 'cl2', 'cljc', 'cljs', 'cljs.hl', 'cljscm', 'cljx', 'hic']}, + coffeescript: {name: 'CoffeeScript', extensions: ['coffee', '_coffee', 'cake', 'cjsx', 'cson', 'iced']}, + cpp: {name: 'C/C++', extensions: ['cpp', 'c', 'cc', 'h', 'c++', 'h++', 'hpp']}, + cs: {name: 'C#', extensions: ['cs', 'csharp']}, + css: {name: 'CSS', extensions: ['css']}, + d: {name: 'D', extensions: ['d', 'di']}, + dart: {name: 'Dart', extensions: ['dart']}, + delphi: {name: 'Delphi', extensions: ['delphi', 'dpr', 'dfm', 'pas', 'pascal', 'freepascal', 'lazarus', 'lpr', 'lfm']}, + diff: {name: 'Diff', extensions: ['diff', 'patch']}, + django: {name: 'Django', extensions: ['django', 'jinja']}, + dockerfile: {name: 'Dockerfile', extensions: ['dockerfile', 'docker']}, + erlang: {name: 'Erlang', extensions: ['erl']}, + fortran: {name: 'Fortran', extensions: ['f90', 'f95']}, + fsharp: {name: 'F#', extensions: ['fsharp', 'fs']}, + gcode: {name: 'G-Code', extensions: ['gcode', 'nc']}, + go: {name: 'Go', extensions: ['go']}, + groovy: {name: 'Groovy', extensions: ['groovy']}, + handlebars: {name: 'Handlebars', extensions: ['handlebars', 'hbs', 'html.hbs', 'html.handlebars']}, + haskell: {name: 'Haskell', extensions: ['hs']}, + haxe: {name: 'Haxe', extensions: ['hx']}, + java: {name: 'Java', extensions: ['java', 'jsp']}, + javascript: {name: 'JavaScript', extensions: ['js', 'jsx']}, + json: {name: 'JSON', extensions: ['json']}, + julia: {name: 'Julia', extensions: ['jl']}, + kotlin: {name: 'Kotlin', extensions: ['kt', 'ktm', 'kts']}, + less: {name: 'Less', extensions: ['less']}, + lisp: {name: 'Lisp', extensions: ['lisp']}, + lua: {name: 'Lua', extensions: ['lua']}, + makefile: {name: 'Makefile', extensions: ['mk', 'mak']}, + markdown: {name: 'Markdown', extensions: ['md', 'mkdown', 'mkd']}, + matlab: {name: 'Matlab', extensions: ['matlab', 'm']}, + objectivec: {name: 'Objective C', extensions: ['mm', 'objc', 'obj-c']}, + ocaml: {name: 'OCaml', extensions: ['ml']}, + perl: {name: 'Perl', extensions: ['perl', 'pl']}, + php: {name: 'PHP', extensions: ['php', 'php3', 'php4', 'php5', 'php6']}, + powershell: {name: 'PowerShell', extensions: ['ps', 'ps1']}, + puppet: {name: 'Puppet', extensions: ['pp']}, + python: {name: 'Python', extensions: ['py', 'gyp']}, + r: {name: 'R', extensions: ['r']}, + ruby: {name: 'Ruby', extensions: ['ruby', 'rb', 'gemspec', 'podspec', 'thor', 'irb']}, + rust: {name: 'Rust', extensions: ['rs']}, + scala: {name: 'Scala', extensions: ['scala']}, + scheme: {name: 'Scheme', extensions: ['scm', 'sld']}, + scss: {name: 'SCSS', extensions: ['scss']}, + smalltalk: {name: 'Smalltalk', extensions: ['st']}, + sql: {name: 'SQL', extensions: ['sql']}, + swift: {name: 'Swift', extensions: ['swift']}, + tex: {name: 'TeX', extensions: ['tex']}, + vbnet: {name: 'VB.Net', extensions: ['vbnet', 'vb', 'bas']}, + vbscript: {name: 'VBScript', extensions: ['vbs']}, + verilog: {name: 'Verilog', extensions: ['v', 'veo']}, + xml: {name: 'HTML, XML', extensions: ['xml', 'html', 'xhtml', 'rss', 'atom', 'xsl', 'plist']}, + yaml: {name: 'YAML', extensions: ['yaml']} }, PostsViewJumpTypes: { BOTTOM: 1, @@ -561,6 +595,10 @@ export default { EMBED_TOGGLE: { label: 'embed_toggle', description: 'Show toggle for all embed previews' + }, + SLASHCMD_AUTOCMP: { + label: 'slashCmd_autocmp', + description: 'Enable external application to offer slash command autocomplete' } }, OVERLAY_TIME_DELAY: 400, diff --git a/webapp/utils/markdown.jsx b/webapp/utils/markdown.jsx index 635a39290..2cf1c5af0 100644 --- a/webapp/utils/markdown.jsx +++ b/webapp/utils/markdown.jsx @@ -1,65 +1,14 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import highlightJs from 'highlight.js/lib/highlight.js'; -import highlightJsDiff from 'highlight.js/lib/languages/diff.js'; -import highlightJsApache from 'highlight.js/lib/languages/apache.js'; -import highlightJsMakefile from 'highlight.js/lib/languages/makefile.js'; -import highlightJsHttp from 'highlight.js/lib/languages/http.js'; -import highlightJsJson from 'highlight.js/lib/languages/json.js'; -import highlightJsMarkdown from 'highlight.js/lib/languages/markdown.js'; -import highlightJsJavascript from 'highlight.js/lib/languages/javascript.js'; -import highlightJsCss from 'highlight.js/lib/languages/css.js'; -import highlightJsNginx from 'highlight.js/lib/languages/nginx.js'; -import highlightJsObjectivec from 'highlight.js/lib/languages/objectivec.js'; -import highlightJsPython from 'highlight.js/lib/languages/python.js'; -import highlightJsXml from 'highlight.js/lib/languages/xml.js'; -import highlightJsPerl from 'highlight.js/lib/languages/perl.js'; -import highlightJsBash from 'highlight.js/lib/languages/bash.js'; -import highlightJsPhp from 'highlight.js/lib/languages/php.js'; -import highlightJsCoffeescript from 'highlight.js/lib/languages/coffeescript.js'; -import highlightJsCs from 'highlight.js/lib/languages/cs.js'; -import highlightJsCpp from 'highlight.js/lib/languages/cpp.js'; -import highlightJsSql from 'highlight.js/lib/languages/sql.js'; -import highlightJsGo from 'highlight.js/lib/languages/go.js'; -import highlightJsRuby from 'highlight.js/lib/languages/ruby.js'; -import highlightJsJava from 'highlight.js/lib/languages/java.js'; -import highlightJsIni from 'highlight.js/lib/languages/ini.js'; - -highlightJs.registerLanguage('diff', highlightJsDiff); -highlightJs.registerLanguage('apache', highlightJsApache); -highlightJs.registerLanguage('makefile', highlightJsMakefile); -highlightJs.registerLanguage('http', highlightJsHttp); -highlightJs.registerLanguage('json', highlightJsJson); -highlightJs.registerLanguage('markdown', highlightJsMarkdown); -highlightJs.registerLanguage('javascript', highlightJsJavascript); -highlightJs.registerLanguage('css', highlightJsCss); -highlightJs.registerLanguage('nginx', highlightJsNginx); -highlightJs.registerLanguage('objectivec', highlightJsObjectivec); -highlightJs.registerLanguage('python', highlightJsPython); -highlightJs.registerLanguage('xml', highlightJsXml); -highlightJs.registerLanguage('perl', highlightJsPerl); -highlightJs.registerLanguage('bash', highlightJsBash); -highlightJs.registerLanguage('php', highlightJsPhp); -highlightJs.registerLanguage('coffeescript', highlightJsCoffeescript); -highlightJs.registerLanguage('cs', highlightJsCs); -highlightJs.registerLanguage('cpp', highlightJsCpp); -highlightJs.registerLanguage('sql', highlightJsSql); -highlightJs.registerLanguage('go', highlightJsGo); -highlightJs.registerLanguage('ruby', highlightJsRuby); -highlightJs.registerLanguage('java', highlightJsJava); -highlightJs.registerLanguage('ini', highlightJsIni); - import * as TextFormatting from './text_formatting.jsx'; import * as Utils from './utils.jsx'; +import * as syntaxHightlighting from './syntax_hightlighting.jsx'; import marked from 'marked'; import katex from 'katex'; import 'katex/dist/katex.min.css'; -import Constants from 'utils/constants.jsx'; -const HighlightedLanguages = Constants.HighlightedLanguages; - function markdownImageLoaded(image) { image.style.height = 'auto'; } @@ -110,31 +59,11 @@ class MattermostMarkdownRenderer extends marked.Renderer { this.formattingOptions = formattingOptions; } - code(code, language, escaped) { + code(code, language) { let usedLanguage = language || ''; usedLanguage = usedLanguage.toLowerCase(); - // treat html as xml to prevent injection attacks - if (usedLanguage === 'html') { - usedLanguage = 'xml'; - } - - if (HighlightedLanguages[usedLanguage]) { - const parsed = highlightJs.highlight(usedLanguage, code); - - return ( - '<div class="post-body--code">' + - '<span class="post-body--code__language">' + - HighlightedLanguages[usedLanguage] + - '</span>' + - '<pre>' + - '<code class="hljs">' + - parsed.value + - '</code>' + - '</pre>' + - '</div>' - ); - } else if (usedLanguage === 'tex' || usedLanguage === 'latex') { + if (usedLanguage === 'tex' || usedLanguage === 'latex') { try { const html = katex.renderToString(code, {throwOnError: false, displayMode: true}); @@ -144,13 +73,12 @@ class MattermostMarkdownRenderer extends marked.Renderer { } } - return ( - '<pre>' + - '<code class="hljs">' + - (escaped ? code : TextFormatting.sanitizeHtml(code)) + '\n' + - '</code>' + - '</pre>' - ); + // treat html as xml to prevent injection attacks + if (usedLanguage === 'html') { + usedLanguage = 'xml'; + } + + return syntaxHightlighting.formatCode(usedLanguage, code); } codespan(text) { diff --git a/webapp/utils/syntax_hightlighting.jsx b/webapp/utils/syntax_hightlighting.jsx new file mode 100644 index 000000000..981ce6b35 --- /dev/null +++ b/webapp/utils/syntax_hightlighting.jsx @@ -0,0 +1,197 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import * as Utils from './utils.jsx'; +import * as TextFormatting from './text_formatting.jsx'; +import Constants from './constants.jsx'; + +import hlJS from 'highlight.js/lib/highlight.js'; + +import hljsActionscript from 'highlight.js/lib/languages/actionscript.js'; +import hljsApplescript from 'highlight.js/lib/languages/applescript.js'; +import hljsBash from 'highlight.js/lib/languages/bash.js'; +import hljsClojure from 'highlight.js/lib/languages/clojure.js'; +import hljsCoffeescript from 'highlight.js/lib/languages/coffeescript.js'; +import hljsCpp from 'highlight.js/lib/languages/cpp.js'; +import hljsCs from 'highlight.js/lib/languages/cs.js'; +import hljsCss from 'highlight.js/lib/languages/css.js'; +import hljsD from 'highlight.js/lib/languages/d.js'; +import hljsDart from 'highlight.js/lib/languages/dart.js'; +import hljsDelphi from 'highlight.js/lib/languages/delphi.js'; +import hljsDiff from 'highlight.js/lib/languages/diff.js'; +import hljsDjango from 'highlight.js/lib/languages/django.js'; +import hljsDockerfile from 'highlight.js/lib/languages/dockerfile.js'; +import hljsErlang from 'highlight.js/lib/languages/erlang.js'; +import hljsFortran from 'highlight.js/lib/languages/fortran.js'; +import hljsFsharp from 'highlight.js/lib/languages/fsharp.js'; +import hljsGcode from 'highlight.js/lib/languages/gcode.js'; +import hljsGo from 'highlight.js/lib/languages/go.js'; +import hljsGroovy from 'highlight.js/lib/languages/groovy.js'; +import hljsHandlebars from 'highlight.js/lib/languages/handlebars.js'; +import hljsHaskell from 'highlight.js/lib/languages/haskell.js'; +import hljsHaxe from 'highlight.js/lib/languages/haxe.js'; +import hljsJava from 'highlight.js/lib/languages/java.js'; +import hljsJavascript from 'highlight.js/lib/languages/javascript.js'; +import hljsJson from 'highlight.js/lib/languages/json.js'; +import hljsJulia from 'highlight.js/lib/languages/julia.js'; +import hljsKotlin from 'highlight.js/lib/languages/kotlin.js'; +import hljsLess from 'highlight.js/lib/languages/less.js'; +import hljsLisp from 'highlight.js/lib/languages/lisp.js'; +import hljsLua from 'highlight.js/lib/languages/lua.js'; +import hljsMakefile from 'highlight.js/lib/languages/makefile.js'; +import hljsMarkdown from 'highlight.js/lib/languages/markdown.js'; +import hljsMatlab from 'highlight.js/lib/languages/matlab.js'; +import hljsObjectivec from 'highlight.js/lib/languages/objectivec.js'; +import hljsOcaml from 'highlight.js/lib/languages/ocaml.js'; +import hljsPerl from 'highlight.js/lib/languages/perl.js'; +import hljsPhp from 'highlight.js/lib/languages/php.js'; +import hljsPowershell from 'highlight.js/lib/languages/powershell.js'; +import hljsPuppet from 'highlight.js/lib/languages/puppet.js'; +import hljsPython from 'highlight.js/lib/languages/python.js'; +import hljsR from 'highlight.js/lib/languages/r.js'; +import hljsRuby from 'highlight.js/lib/languages/ruby.js'; +import hljsRust from 'highlight.js/lib/languages/rust.js'; +import hljsScala from 'highlight.js/lib/languages/scala.js'; +import hljsScheme from 'highlight.js/lib/languages/scheme.js'; +import hljsScss from 'highlight.js/lib/languages/scss.js'; +import hljsSmalltalk from 'highlight.js/lib/languages/smalltalk.js'; +import hljsSql from 'highlight.js/lib/languages/sql.js'; +import hljsSwift from 'highlight.js/lib/languages/swift.js'; +import hljsTex from 'highlight.js/lib/languages/tex.js'; +import hljsVbnet from 'highlight.js/lib/languages/vbnet.js'; +import hljsVbscript from 'highlight.js/lib/languages/vbscript.js'; +import hljsVerilog from 'highlight.js/lib/languages/verilog.js'; +import hljsXml from 'highlight.js/lib/languages/xml.js'; +import hljsYaml from 'highlight.js/lib/languages/yaml.js'; + +hlJS.registerLanguage('actionscript', hljsActionscript); +hlJS.registerLanguage('applescript', hljsApplescript); +hlJS.registerLanguage('bash', hljsBash); +hlJS.registerLanguage('clojure', hljsClojure); +hlJS.registerLanguage('coffeescript', hljsCoffeescript); +hlJS.registerLanguage('cpp', hljsCpp); +hlJS.registerLanguage('cs', hljsCs); +hlJS.registerLanguage('css', hljsCss); +hlJS.registerLanguage('d', hljsD); +hlJS.registerLanguage('dart', hljsDart); +hlJS.registerLanguage('delphi', hljsDelphi); +hlJS.registerLanguage('diff', hljsDiff); +hlJS.registerLanguage('django', hljsDjango); +hlJS.registerLanguage('dockerfile', hljsDockerfile); +hlJS.registerLanguage('erlang', hljsErlang); +hlJS.registerLanguage('fortran', hljsFortran); +hlJS.registerLanguage('fsharp', hljsFsharp); +hlJS.registerLanguage('gcode', hljsGcode); +hlJS.registerLanguage('go', hljsGo); +hlJS.registerLanguage('groovy', hljsGroovy); +hlJS.registerLanguage('handlebars', hljsHandlebars); +hlJS.registerLanguage('haskell', hljsHaskell); +hlJS.registerLanguage('haxe', hljsHaxe); +hlJS.registerLanguage('java', hljsJava); +hlJS.registerLanguage('javascript', hljsJavascript); +hlJS.registerLanguage('json', hljsJson); +hlJS.registerLanguage('julia', hljsJulia); +hlJS.registerLanguage('kotlin', hljsKotlin); +hlJS.registerLanguage('less', hljsLess); +hlJS.registerLanguage('lisp', hljsLisp); +hlJS.registerLanguage('lua', hljsLua); +hlJS.registerLanguage('makefile', hljsMakefile); +hlJS.registerLanguage('markdown', hljsMarkdown); +hlJS.registerLanguage('matlab', hljsMatlab); +hlJS.registerLanguage('objectivec', hljsObjectivec); +hlJS.registerLanguage('ocaml', hljsOcaml); +hlJS.registerLanguage('perl', hljsPerl); +hlJS.registerLanguage('php', hljsPhp); +hlJS.registerLanguage('powershell', hljsPowershell); +hlJS.registerLanguage('puppet', hljsPuppet); +hlJS.registerLanguage('python', hljsPython); +hlJS.registerLanguage('r', hljsR); +hlJS.registerLanguage('ruby', hljsRuby); +hlJS.registerLanguage('rust', hljsRust); +hlJS.registerLanguage('scala', hljsScala); +hlJS.registerLanguage('scheme', hljsScheme); +hlJS.registerLanguage('scss', hljsScss); +hlJS.registerLanguage('smalltalk', hljsSmalltalk); +hlJS.registerLanguage('sql', hljsSql); +hlJS.registerLanguage('swift', hljsSwift); +hlJS.registerLanguage('tex', hljsTex); +hlJS.registerLanguage('vbnet', hljsVbnet); +hlJS.registerLanguage('vbscript', hljsVbscript); +hlJS.registerLanguage('verilog', hljsVerilog); +hlJS.registerLanguage('xml', hljsXml); +hlJS.registerLanguage('yaml', hljsYaml); + +const HighlightedLanguages = Constants.HighlightedLanguages; + +export function formatCode(lang, data, filename) { + var language = lang || ''; + var parsed; + var header = ''; + + language = language.toLowerCase(); + + if (HighlightedLanguages[language]) { + var name = HighlightedLanguages[language].name; + + if (filename) { + const fname = decodeURIComponent(Utils.getFileName(filename)); + name = fname + ' - ' + name; + } + + header = '<span class="post-body--code__language">' + name + '</span>'; + + try { + parsed = hlJS.highlight(language, data).value; + } catch (e) { + parsed = TextFormatting.sanitizeHtml(data); + } + } else { + parsed = TextFormatting.sanitizeHtml(data); + } + + const lines = data.match(/\r\n|\r|\n|$/g).length; + var strlines = ''; + for (var i = 1; i <= lines; i++) { + if (strlines) { + strlines += '\n' + i; + } else { + strlines += i; + } + } + + return ( + '<div class="post-body--code">' + + header + + '<pre>' + + '<code class="hljs">' + + '<table>' + + '<tbody>' + + '<tr>' + + '<td class="post-body--code__lineno">' + strlines + '</td>' + + '<td>' + + parsed + + '</td>' + + '</tr>' + + '</tbody>' + + '</table>' + + '</code>' + + '</pre>' + + '</div>' + ); +} + +export function getLang(filename) { + const fileInfo = Utils.splitFileLocation(filename); + var ext = fileInfo.ext; + if (!ext) { + return null; + } + + ext = ext.toLowerCase(); + for (var key in HighlightedLanguages) { + if (HighlightedLanguages[key].extensions.find((x) => x === ext)) { + return key; + } + } + return null; +} diff --git a/webapp/utils/text_formatting.jsx b/webapp/utils/text_formatting.jsx index 9833b995c..4c8b5e24c 100644 --- a/webapp/utils/text_formatting.jsx +++ b/webapp/utils/text_formatting.jsx @@ -213,6 +213,11 @@ function highlightCurrentMentions(text, tokens) { } for (const mention of UserStore.getCurrentMentionKeys()) { + // occasionally we get an empty mention which matches a bunch of empty strings + if (!mention) { + continue; + } + output = output.replace(new RegExp(`(^|\\W)(${escapeRegex(mention)})\\b`, 'gi'), replaceCurrentMentionWithToken); } diff --git a/webapp/utils/utils.jsx b/webapp/utils/utils.jsx index 686630a9b..12a7ff50e 100644 --- a/webapp/utils/utils.jsx +++ b/webapp/utils/utils.jsx @@ -680,7 +680,7 @@ export function applyTheme(theme) { } if (theme.centerChannelBg) { - changeCss('.app__content, .markdown__table, .markdown__table tbody tr, .suggestion-list__content, .modal .modal-content', 'background:' + theme.centerChannelBg, 1); + changeCss('.app__content, .markdown__table, .markdown__table tbody tr, .suggestion-list__content, .modal .modal-content, .modal .modal-back', 'background:' + theme.centerChannelBg, 1); changeCss('#post-list .post-list-holder-by-time', 'background:' + theme.centerChannelBg, 1); changeCss('#post-create', 'background:' + theme.centerChannelBg, 1); changeCss('.date-separator .separator__text, .new-separator .separator__text', 'background:' + theme.centerChannelBg, 1); @@ -763,7 +763,6 @@ export function applyTheme(theme) { if (theme.buttonBg) { changeCss('.btn.btn-primary, .tutorial__circles .circle.active', 'background:' + theme.buttonBg, 1); changeCss('.btn.btn-primary:hover, .btn.btn-primary:active, .btn.btn-primary:focus', 'background:' + changeColor(theme.buttonBg, -0.25), 1); - changeCss('.file-playback__controls', 'color:' + changeColor(theme.buttonBg, -0.25), 1); } if (theme.buttonColor) { diff --git a/webapp/webpack.config.js b/webapp/webpack.config.js index 14abf6ffa..5e1df9bfe 100644 --- a/webapp/webpack.config.js +++ b/webapp/webpack.config.js @@ -17,20 +17,21 @@ module.exports = { loaders: [ { test: /\.jsx?$/, - loader: 'babel-loader', + loader: 'babel', exclude: /(node_modules|non_npm_dependencies)/, query: { - presets: ['react', 'es2015', 'stage-0'], - plugins: ['transform-runtime'] + presets: ['react', 'es2015-webpack', 'stage-0'], + plugins: ['transform-runtime'], + cacheDirectory: true } }, { test: /\.json$/, - loader: 'json-loader' + loader: 'json' }, { test: /(node_modules|non_npm_dependencies)\/.+\.(js|jsx)$/, - loader: 'imports-loader', + loader: 'imports', query: { $: 'jquery', jQuery: 'jquery' @@ -46,7 +47,7 @@ module.exports = { }, { test: /\.(png|eot|tiff|svg|woff2|woff|ttf|gif)$/, - loader: 'file-loader', + loader: 'file', query: { name: 'files/[hash].[ext]' } @@ -67,7 +68,22 @@ module.exports = { htmlExtract, new CopyWebpackPlugin([ {from: 'images/emoji', to: 'emoji'} - ]) + ]), + new webpack.optimize.UglifyJsPlugin({ + 'screw-ie8': true, + mangle: { + toplevel: false + }, + compress: { + warnings: false + }, + comments: false + }), + new webpack.optimize.AggressiveMergingPlugin(), + new webpack.LoaderOptionsPlugin({ + minimize: true, + debug: false + }) ], resolve: { alias: { |