diff options
Diffstat (limited to 'web/react')
-rw-r--r-- | web/react/components/channel_loader.jsx | 4 | ||||
-rw-r--r-- | web/react/components/posts_view.jsx | 14 | ||||
-rw-r--r-- | web/react/components/sidebar.jsx | 65 | ||||
-rw-r--r-- | web/react/components/user_settings/user_settings_display.jsx | 83 | ||||
-rw-r--r-- | web/react/dispatcher/event_helpers.jsx | 4 | ||||
-rw-r--r-- | web/react/stores/channel_store.jsx | 44 | ||||
-rw-r--r-- | web/react/utils/async_client.jsx | 20 | ||||
-rw-r--r-- | web/react/utils/constants.jsx | 15 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 27 |
9 files changed, 202 insertions, 74 deletions
diff --git a/web/react/components/channel_loader.jsx b/web/react/components/channel_loader.jsx index c8f1196a8..13045d732 100644 --- a/web/react/components/channel_loader.jsx +++ b/web/react/components/channel_loader.jsx @@ -10,6 +10,7 @@ import SocketStore from '../stores/socket_store.jsx'; import ChannelStore from '../stores/channel_store.jsx'; import PostStore from '../stores/post_store.jsx'; import UserStore from '../stores/user_store.jsx'; +import PreferenceStore from '../stores/preference_store.jsx'; import * as Utils from '../utils/utils.jsx'; import Constants from '../utils/constants.jsx'; @@ -69,6 +70,9 @@ export default class ChannelLoader extends React.Component { Utils.applyTheme(Constants.THEMES.default); } + const selectedFont = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', {value: Constants.DEFAULT_FONT}).value; + Utils.applyFont(selectedFont); + $('body').on('mouseenter mouseleave', '.post', function mouseOver(ev) { if (ev.type === 'mouseenter') { $(this).parent('div').prev('.date-separator, .new-separator').addClass('hovered--after'); diff --git a/web/react/components/posts_view.jsx b/web/react/components/posts_view.jsx index 242b26b91..d0eee5a23 100644 --- a/web/react/components/posts_view.jsx +++ b/web/react/components/posts_view.jsx @@ -280,18 +280,22 @@ export default class PostsView extends React.Component { this.updateScrolling(); } window.addEventListener('resize', this.handleResize); - $(this.refs.postlist).perfectScrollbar(); - PreferenceStore.addChangeListener(this.updateState); } componentWillUnmount() { window.removeEventListener('resize', this.handleResize); - PreferenceStore.removeChangeListener(this.updateState); } componentDidUpdate() { if (this.props.postList != null) { this.updateScrolling(); } - $(this.refs.postlist).perfectScrollbar('update'); + } + componentWillReceiveProps(nextProps) { + if (!this.props.isActive && nextProps.isActive) { + this.updateState(); + PreferenceStore.addChangeListener(this.updateState); + } else if (this.props.isActive && !nextProps.isActive) { + PreferenceStore.removeChangeListener(this.updateState); + } } shouldComponentUpdate(nextProps, nextState) { if (this.props.isActive !== nextProps.isActive) { @@ -373,7 +377,7 @@ export default class PostsView extends React.Component { return ( <div ref='postlist' - className={'ps-container post-list-holder-by-time ' + activeClass} + className={'post-list-holder-by-time ' + activeClass} onScroll={this.handleScroll} > <div className='post-list__table'> diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx index 5c8e73874..3d7f449d1 100644 --- a/web/react/components/sidebar.jsx +++ b/web/react/components/sidebar.jsx @@ -19,7 +19,6 @@ import * as Utils from '../utils/utils.jsx'; import Constants from '../utils/constants.jsx'; const Preferences = Constants.Preferences; const TutorialSteps = Constants.TutorialSteps; -const NotificationPrefs = Constants.NotificationPrefs; const Tooltip = ReactBootstrap.Tooltip; const OverlayTrigger = ReactBootstrap.OverlayTrigger; @@ -38,7 +37,6 @@ export default class Sidebar extends React.Component { this.onScroll = this.onScroll.bind(this); this.updateUnreadIndicators = this.updateUnreadIndicators.bind(this); this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this); - this.updateScrollbar = this.updateScrollbar.bind(this); this.handleResize = this.handleResize.bind(this); this.showNewChannelModal = this.showNewChannelModal.bind(this); @@ -48,8 +46,6 @@ export default class Sidebar extends React.Component { this.createChannelElement = this.createChannelElement.bind(this); this.updateTitle = this.updateTitle.bind(this); - this.setUnreadCountPerChannel = this.setUnreadCountPerChannel.bind(this); - this.getUnreadCount = this.getUnreadCount.bind(this); this.isLeaving = new Map(); @@ -59,43 +55,15 @@ export default class Sidebar extends React.Component { state.loadingDMChannel = -1; state.windowWidth = Utils.windowWidth(); this.state = state; - - this.unreadCountPerChannel = {}; - this.setUnreadCountPerChannel(); - } - setUnreadCountPerChannel() { - const channels = ChannelStore.getAll(); - const members = ChannelStore.getAllMembers(); - const channelUnreadCounts = {}; - - channels.forEach((ch) => { - const chMember = members[ch.id]; - let chMentionCount = chMember.mention_count; - let chUnreadCount = ch.total_msg_count - chMember.msg_count - chMentionCount; - - if (ch.type === 'D') { - chMentionCount = chUnreadCount; - chUnreadCount = 0; - } else if (chMember.notify_props && chMember.notify_props.mark_unread === NotificationPrefs.MENTION) { - chUnreadCount = 0; - } - - channelUnreadCounts[ch.id] = {msgs: chUnreadCount, mentions: chMentionCount}; - }); - - this.unreadCountPerChannel = channelUnreadCounts; } - getUnreadCount(channelId) { - let mentions = 0; + getTotalUnreadCount() { let msgs = 0; + let mentions = 0; + const unreadCounts = this.state.unreadCounts; - if (channelId) { - return this.unreadCountPerChannel[channelId] ? this.unreadCountPerChannel[channelId] : {msgs, mentions}; - } - - Object.keys(this.unreadCountPerChannel).forEach((chId) => { - msgs += this.unreadCountPerChannel[chId].msgs; - mentions += this.unreadCountPerChannel[chId].mentions; + Object.keys(unreadCounts).forEach((chId) => { + msgs += unreadCounts[chId].msgs; + mentions += unreadCounts[chId].mentions; }); return {msgs, mentions}; @@ -156,6 +124,7 @@ export default class Sidebar extends React.Component { privateChannels, visibleDirectChannels, hiddenDirectChannelCount, + unreadCounts: JSON.parse(JSON.stringify(ChannelStore.getUnreadCounts())), showTutorialTip: parseInt(tutorialPref.value, 10) === TutorialSteps.CHANNEL_POPOVER }; } @@ -169,7 +138,6 @@ export default class Sidebar extends React.Component { this.updateTitle(); this.updateUnreadIndicators(); - this.updateScrollbar(); window.addEventListener('resize', this.handleResize); @@ -186,7 +154,6 @@ export default class Sidebar extends React.Component { componentDidUpdate() { this.updateTitle(); this.updateUnreadIndicators(); - this.updateScrollbar(); } componentWillUnmount() { window.removeEventListener('resize', this.handleResize); @@ -203,8 +170,6 @@ export default class Sidebar extends React.Component { windowHeight: Utils.windowHeight() }); } - updateScrollbar() { - } onChange() { this.setState(this.getStateFromStores()); } @@ -221,7 +186,7 @@ export default class Sidebar extends React.Component { currentChannelName = Utils.getDirectTeammate(channel.id).username; } - const unread = this.getUnreadCount(); + const unread = this.getTotalUnreadCount(); const mentionTitle = unread.mentions > 0 ? '(' + unread.mentions + ') ' : ''; const unreadTitle = unread.msgs > 0 ? '* ' : ''; document.title = mentionTitle + unreadTitle + currentChannelName + ' - ' + TeamStore.getCurrent().display_name + ' ' + currentSiteName; @@ -347,13 +312,13 @@ export default class Sidebar extends React.Component { } createChannelElement(channel, index, arr, handleClose) { - var members = this.state.members; - var activeId = this.state.activeId; - var channelMember = members[channel.id]; - var unreadCount = this.getUnreadCount(channel.id); - var msgCount; + const members = this.state.members; + const activeId = this.state.activeId; + const channelMember = members[channel.id]; + const unreadCount = this.state.unreadCounts[channel.id] || {msgs: 0, mentions: 0}; + let msgCount; - var linkClass = ''; + let linkClass = ''; if (channel.id === activeId) { linkClass = 'active'; } @@ -510,8 +475,6 @@ export default class Sidebar extends React.Component { render() { this.badgesActive = false; - this.setUnreadCountPerChannel(); - // keep track of the first and last unread channels so we can use them to set the unread indicators this.firstUnreadChannel = null; this.lastUnreadChannel = null; diff --git a/web/react/components/user_settings/user_settings_display.jsx b/web/react/components/user_settings/user_settings_display.jsx index 43c8d33d1..dc3865c68 100644 --- a/web/react/components/user_settings/user_settings_display.jsx +++ b/web/react/components/user_settings/user_settings_display.jsx @@ -6,14 +6,17 @@ import SettingItemMin from '../setting_item_min.jsx'; import SettingItemMax from '../setting_item_max.jsx'; import Constants from '../../utils/constants.jsx'; import PreferenceStore from '../../stores/preference_store.jsx'; +import * as Utils from '../../utils/utils.jsx'; function getDisplayStateFromStores() { const militaryTime = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', {value: 'false'}); const nameFormat = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', {value: 'username'}); + const selectedFont = PreferenceStore.getPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', {value: Constants.DEFAULT_FONT}); return { militaryTime: militaryTime.value, - nameFormat: nameFormat.value + nameFormat: nameFormat.value, + selectedFont: selectedFont.value }; } @@ -24,15 +27,20 @@ export default class UserSettingsDisplay extends React.Component { this.handleSubmit = this.handleSubmit.bind(this); this.handleClockRadio = this.handleClockRadio.bind(this); this.handleNameRadio = this.handleNameRadio.bind(this); + this.handleFont = this.handleFont.bind(this); this.updateSection = this.updateSection.bind(this); this.state = getDisplayStateFromStores(); + this.selectedFont = this.state.selectedFont; } handleSubmit() { const timePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'use_military_time', this.state.militaryTime); const namePreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', this.state.nameFormat); + const fontPreference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', this.state.selectedFont); - savePreferences([timePreference, namePreference], + this.selectedFont = this.state.selectedFont; + + savePreferences([timePreference, namePreference, fontPreference], () => { PreferenceStore.emitChange(); this.updateSection(''); @@ -48,6 +56,10 @@ export default class UserSettingsDisplay extends React.Component { handleNameRadio(nameFormat) { this.setState({nameFormat}); } + handleFont(selectedFont) { + Utils.applyFont(selectedFont); + this.setState({selectedFont}); + } updateSection(section) { this.setState(getDisplayStateFromStores()); this.props.updateSection(section); @@ -56,6 +68,8 @@ export default class UserSettingsDisplay extends React.Component { const serverError = this.state.serverError || null; let clockSection; let nameFormatSection; + let fontSection; + if (this.props.activeSection === 'clock') { const clockFormat = [false, false]; if (this.state.militaryTime === 'true') { @@ -209,6 +223,69 @@ export default class UserSettingsDisplay extends React.Component { ); } + if (this.props.activeSection === 'font') { + const options = []; + Object.keys(Constants.FONTS).forEach((fontName, idx) => { + const className = Constants.FONTS[fontName]; + options.push( + <option + key={'font_' + idx} + value={fontName} + className={className} + > + {fontName} + </option> + ); + }); + + const inputs = [ + <div key='userDisplayNameOptions'> + <div + className='input-group theme-group dropdown' + > + <select + className='form-control' + type='text' + value={this.state.selectedFont} + onChange={(e) => this.handleFont(e.target.value)} + > + {options} + </select> + <span className={'input-group-addon ' + Constants.FONTS[this.state.selectedFont]}> + {this.state.selectedFont} + </span> + </div> + <div><br/>{'Select the font displayed in the Mattermost user interface.'}</div> + </div> + ]; + + fontSection = ( + <SettingItemMax + title='Display Font' + inputs={inputs} + submit={this.handleSubmit} + server_error={serverError} + updateSection={(e) => { + if (this.selectedFont !== this.state.selectedFont) { + this.handleFont(this.selectedFont); + } + this.updateSection(''); + e.preventDefault(); + }} + /> + ); + } else { + fontSection = ( + <SettingItemMin + title='Display Font' + describe={this.state.selectedFont} + updateSection={() => { + this.props.updateSection('font'); + }} + /> + ); + } + return ( <div> <div className='modal-header'> @@ -239,6 +316,8 @@ export default class UserSettingsDisplay extends React.Component { <div className='divider-dark'/> {nameFormatSection} <div className='divider-dark'/> + {fontSection} + <div className='divider-dark'/> </div> </div> ); diff --git a/web/react/dispatcher/event_helpers.jsx b/web/react/dispatcher/event_helpers.jsx index 856eec2f1..57b4eaa11 100644 --- a/web/react/dispatcher/event_helpers.jsx +++ b/web/react/dispatcher/event_helpers.jsx @@ -11,8 +11,8 @@ import * as Client from '../utils/client.jsx'; export function emitChannelClickEvent(channel) { AsyncClient.getChannels(); - AsyncClient.getChannelExtraInfo(); - AsyncClient.updateLastViewedAt(); + AsyncClient.getChannelExtraInfo(channel.id); + AsyncClient.updateLastViewedAt(channel.id); AsyncClient.getPosts(channel.id); AppDispatcher.handleViewAction({ diff --git a/web/react/stores/channel_store.jsx b/web/react/stores/channel_store.jsx index dec4926f5..5dec86951 100644 --- a/web/react/stores/channel_store.jsx +++ b/web/react/stores/channel_store.jsx @@ -7,6 +7,7 @@ import EventEmitter from 'events'; var Utils; import Constants from '../utils/constants.jsx'; const ActionTypes = Constants.ActionTypes; +const NotificationPrefs = Constants.NotificationPrefs; const CHANGE_EVENT = 'change'; const LEAVE_EVENT = 'leave'; @@ -37,6 +38,10 @@ class ChannelStoreClass extends EventEmitter { this.getByName = this.getByName.bind(this); this.pSetPostMode = this.pSetPostMode.bind(this); this.getPostMode = this.getPostMode.bind(this); + this.setUnreadCount = this.setUnreadCount.bind(this); + this.setUnreadCounts = this.setUnreadCounts.bind(this); + this.getUnreadCount = this.getUnreadCount.bind(this); + this.getUnreadCounts = this.getUnreadCounts.bind(this); this.currentId = null; this.postMode = this.POST_MODE_CHANNEL; @@ -45,6 +50,7 @@ class ChannelStoreClass extends EventEmitter { this.moreChannels = {}; this.moreChannels.loading = true; this.extraInfos = {}; + this.unreadCounts = {}; } get POST_MODE_CHANNEL() { return 1; @@ -120,18 +126,18 @@ class ChannelStoreClass extends EventEmitter { this.currentId = id; } resetCounts(id) { - var cm = this.pGetChannelMembers(); + const cm = this.channelMembers; for (var cmid in cm) { if (cm[cmid].channel_id === id) { var c = this.get(id); if (c) { cm[cmid].msg_count = this.get(id).total_msg_count; cm[cmid].mention_count = 0; + this.setUnreadCount(id); } break; } } - this.pStoreChannelMembers(cm); } getCurrentId() { return this.currentId; @@ -250,6 +256,38 @@ class ChannelStoreClass extends EventEmitter { getPostMode() { return this.postMode; } + + setUnreadCount(id) { + const ch = this.get(id); + const chMember = this.getMember(id); + + let chMentionCount = chMember.mention_count; + let chUnreadCount = ch.total_msg_count - chMember.msg_count - chMentionCount; + + if (ch.type === 'D') { + chMentionCount = chUnreadCount; + chUnreadCount = 0; + } else if (chMember.notify_props && chMember.notify_props.mark_unread === NotificationPrefs.MENTION) { + chUnreadCount = 0; + } + + this.unreadCounts[id] = {msgs: chUnreadCount, mentions: chMentionCount}; + } + + setUnreadCounts() { + const channels = this.getAll(); + channels.forEach((ch) => { + this.setUnreadCount(ch.id); + }); + } + + getUnreadCount(id) { + return this.unreadCounts[id] || {msgs: 0, mentions: 0}; + } + + getUnreadCounts() { + return this.unreadCounts; + } } var ChannelStore = new ChannelStoreClass(); @@ -281,6 +319,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => { if (currentId) { ChannelStore.resetCounts(currentId); } + ChannelStore.setUnreadCounts(); ChannelStore.emitChange(); break; @@ -291,6 +330,7 @@ ChannelStore.dispatchToken = AppDispatcher.register((payload) => { if (currentId) { ChannelStore.resetCounts(currentId); } + ChannelStore.setUnreadCount(action.channel.id); ChannelStore.emitChange(); break; diff --git a/web/react/utils/async_client.jsx b/web/react/utils/async_client.jsx index 8cf111d55..5df43b548 100644 --- a/web/react/utils/async_client.jsx +++ b/web/react/utils/async_client.jsx @@ -106,10 +106,15 @@ export function getChannel(id) { ); } -export function updateLastViewedAt() { - const channelId = ChannelStore.getCurrentId(); +export function updateLastViewedAt(id) { + let channelId; + if (id) { + channelId = id; + } else { + channelId = ChannelStore.getCurrentId(); + } - if (channelId === null) { + if (channelId == null) { return; } @@ -159,8 +164,13 @@ export function getMoreChannels(force) { } } -export function getChannelExtraInfo() { - const channelId = ChannelStore.getCurrentId(); +export function getChannelExtraInfo(id) { + let channelId; + if (id) { + channelId = id; + } else { + channelId = ChannelStore.getCurrentId(); + } if (channelId != null) { if (isCallInProgress('getChannelExtraInfo_' + channelId)) { diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx index 7d9532867..8164095b9 100644 --- a/web/react/utils/constants.jsx +++ b/web/react/utils/constants.jsx @@ -353,6 +353,21 @@ export default { } ], DEFAULT_CODE_THEME: 'github', + FONTS: { + 'Droid Serif': 'font--droid_serif', + 'Roboto Slab': 'font--roboto_slab', + Lora: 'font--lora', + Slabo: 'font--slabo', + Arvo: 'font--arvo', + 'Open Sans': 'font--open_sans', + Roboto: 'font--roboto', + 'PT Sans': 'font--pt_sans', + Lato: 'font--lato', + 'Source Sans Pro': 'font--source_sans_pro', + 'Exo 2': 'font--exo_2', + Ubuntu: 'font--ubuntu' + }, + DEFAULT_FONT: 'Open Sans', Preferences: { CATEGORY_DIRECT_CHANNEL_SHOW: 'direct_channel_show', CATEGORY_DISPLAY_SETTINGS: 'display_settings', diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index d6ed34e70..7cc8a5c97 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -539,11 +539,11 @@ export function applyTheme(theme) { if (theme.sidebarText) { changeCss('.sidebar--left .nav-pills__container li>a, .sidebar--right, .settings-modal .nav-pills>li a, .sidebar--menu', 'color:' + changeOpacity(theme.sidebarText, 0.6), 1); - changeCss('@media(max-width: 960px){.settings-modal .settings-table .nav>li>a', 'color:' + theme.sidebarText, 1); + changeCss('@media(max-width: 768px){.settings-modal .settings-table .nav>li>a', 'color:' + theme.sidebarText, 1); changeCss('.sidebar--left .nav-pills__container li>h4, .sidebar--left .add-channel-btn', 'color:' + changeOpacity(theme.sidebarText, 0.6), 1); changeCss('.sidebar--left .add-channel-btn:hover, .sidebar--left .add-channel-btn:focus', 'color:' + theme.sidebarText, 1); changeCss('.sidebar--left .status path', 'fill:' + changeOpacity(theme.sidebarText, 0.5), 1); - changeCss('@media(max-width: 960px){.settings-modal .settings-table .nav>li>a', 'border-color:' + changeOpacity(theme.sidebarText, 0.2), 2); + changeCss('@media(max-width: 768px){.settings-modal .settings-table .nav>li>a', 'border-color:' + changeOpacity(theme.sidebarText, 0.2), 2); } if (theme.sidebarUnreadText) { @@ -552,7 +552,7 @@ export function applyTheme(theme) { if (theme.sidebarTextHoverBg) { changeCss('.sidebar--left .nav-pills__container li>a:hover, .sidebar--left .nav-pills__container li>a:focus, .settings-modal .nav-pills>li:hover a, .settings-modal .nav-pills>li:focus a', 'background:' + theme.sidebarTextHoverBg, 1); - changeCss('@media(max-width: 960px){.settings-modal .settings-table .nav>li:hover a', 'background:' + theme.sidebarTextHoverBg, 1); + changeCss('@media(max-width: 768px){.settings-modal .settings-table .nav>li:hover a', 'background:' + theme.sidebarTextHoverBg, 1); } if (theme.sidebarTextActiveBorder) { @@ -568,7 +568,7 @@ export function applyTheme(theme) { changeCss('.sidebar--left .team__header, .sidebar--menu .team__header', 'background:' + theme.sidebarHeaderBg, 1); changeCss('.modal .modal-header', 'background:' + theme.sidebarHeaderBg, 1); changeCss('#navbar .navbar-default', 'background:' + theme.sidebarHeaderBg, 1); - changeCss('@media(max-width: 960px){.search-bar__container', 'background:' + theme.sidebarHeaderBg, 1); + changeCss('@media(max-width: 768px){.search-bar__container', 'background:' + theme.sidebarHeaderBg, 1); changeCss('.attachment .attachment__container', 'border-left-color:' + theme.sidebarHeaderBg, 1); } @@ -579,7 +579,7 @@ export function applyTheme(theme) { changeCss('.modal .modal-header .modal-title, .modal .modal-header .modal-title .name, .modal .modal-header button.close', 'color:' + theme.sidebarHeaderTextColor, 1); changeCss('#navbar .navbar-default .navbar-brand .heading', 'color:' + theme.sidebarHeaderTextColor, 1); changeCss('#navbar .navbar-default .navbar-toggle .icon-bar, ', 'background:' + theme.sidebarHeaderTextColor, 1); - changeCss('@media(max-width: 960px){.search-bar__container', 'color:' + theme.sidebarHeaderTextColor, 2); + changeCss('@media(max-width: 768px){.search-bar__container', 'color:' + theme.sidebarHeaderTextColor, 2); } if (theme.onlineIndicator) { @@ -607,7 +607,7 @@ export function applyTheme(theme) { changeCss('.popover.right>.arrow:after, .tip-overlay.tip-overlay--sidebar .arrow, .tip-overlay.tip-overlay--header .arrow', 'border-right-color:' + theme.centerChannelBg, 1); changeCss('.popover.left>.arrow:after', 'border-left-color:' + theme.centerChannelBg, 1); changeCss('.popover.top>.arrow:after, .tip-overlay.tip-overlay--chat .arrow', 'border-top-color:' + theme.centerChannelBg, 1); - changeCss('@media(min-width: 960px){.search-bar__container .search__form .search-bar, .form-control', 'background:' + theme.centerChannelBg, 1); + changeCss('@media(min-width: 768px){.search-bar__container .search__form .search-bar, .form-control', 'background:' + theme.centerChannelBg, 1); changeCss('.attachment__content', 'background:' + theme.centerChannelBg, 1); } @@ -638,7 +638,7 @@ export function applyTheme(theme) { changeCss('.post-image__column', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 2); changeCss('.post-image__column .post-image__details', 'color:' + theme.centerChannelColor, 2); changeCss('.post-image__column a, .post-image__column a:hover, .post-image__column a:focus', 'color:' + theme.centerChannelColor, 1); - changeCss('@media(min-width: 960px){.search-bar__container .search__form .search-bar, .form-control', 'color:' + theme.centerChannelColor, 2); + changeCss('@media(min-width: 768px){.search-bar__container .search__form .search-bar, .form-control', 'color:' + theme.centerChannelColor, 2); changeCss('.input-group-addon, .search-bar__container .search__form, .form-control', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); changeCss('.form-control:focus', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1); changeCss('.attachment .attachment__content', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1); @@ -693,6 +693,19 @@ export function applyTheme(theme) { } updateCodeTheme(theme.codeTheme); } + +export function applyFont(fontName) { + const body = document.querySelector('body'); + const keys = Object.getOwnPropertyNames(body.classList); + keys.forEach((k) => { + const className = body.classList[k]; + if (className && className.lastIndexOf('font') === 0) { + body.classList.remove(className); + } + }); + body.classList.add(Constants.FONTS[fontName]); +} + export function changeCss(className, classValue, classRepeat) { // we need invisible container to store additional css definitions var cssMainContainer = $('#css-modifier-container'); |