Commit 9f7b8e00 authored by Martin Kraft's avatar Martin Kraft
Browse files

Merge remote-tracking branch 'origin/master' into advanced-permissions-phase-2

parents ce8b39b6 6b306179
......@@ -113,11 +113,6 @@ export function sendDesktopNotification(post, msgProps) {
body = username + Utils.localizeMessage('channel_loader.wrote', ' wrote: ') + notifyText;
}
let duration = Constants.DEFAULT_NOTIFICATION_DURATION;
if (user.notify_props && user.notify_props.desktop_duration) {
duration = parseInt(user.notify_props.desktop_duration, 10) * 1000;
}
//Play a sound if explicitly set in settings
const sound = !user.notify_props || user.notify_props.desktop_sound === 'true';
......@@ -128,7 +123,7 @@ export function sendDesktopNotification(post, msgProps) {
const notify = (activeChannel && activeChannel.id !== channelId) || !NotificationStore.getFocus();
if (notify) {
Utils.notifyMe(title, body, channel, teamId, duration, !sound);
Utils.notifyMe(title, body, channel, teamId, !sound);
//Don't add extra sounds on native desktop clients
if (sound && !isWindowsApp() && !isMacApp() && !isMobileApp()) {
......
......@@ -7,7 +7,11 @@ import {bindActionCreators} from 'redux';
import {savePreferences} from 'mattermost-redux/actions/preferences';
import {leaveChannel} from 'mattermost-redux/actions/channels';
import {getChannelsNameMapInCurrentTeam, makeGetChannel, isChannelReadOnly} from 'mattermost-redux/selectors/entities/channels';
import {
getChannelsNameMapInCurrentTeam,
makeGetChannel,
shouldHideDefaultChannel,
} from 'mattermost-redux/selectors/entities/channels';
import {getMyChannelMemberships} from 'mattermost-redux/selectors/entities/common';
import {getUserIdsInChannels, getUser} from 'mattermost-redux/selectors/entities/users';
import {getInt, getTeammateNameDisplaySetting} from 'mattermost-redux/selectors/entities/preferences';
......@@ -78,8 +82,15 @@ function makeMapStateToProps() {
channelDisplayName = displayUsername(teammate, teammateNameDisplay);
}
const shouldHideChannel = isChannelReadOnly(state, channel) && !ownProps.active &&
!isFavoriteChannel(state.entities.preferences.myPreferences, channel.id);
let shouldHideChannel = false;
if (
channel.name === Constants.DEFAULT_CHANNEL &&
!ownProps.active &&
shouldHideDefaultChannel(state, channel) &&
!isFavoriteChannel(state.entities.preferences.myPreferences, channel.id)
) {
shouldHideChannel = true;
}
return {
config,
......
......@@ -87,7 +87,6 @@ export default class Textbox extends React.Component {
}
handleChange = (e) => {
this.checkMessageLength(e.target.value);
this.props.onChange(e);
}
......@@ -174,6 +173,9 @@ export default class Textbox extends React.Component {
}
}
}
if (this.props.value !== nextProps.value) {
this.checkMessageLength(nextProps.value);
}
}
render() {
......
......@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import {FormattedMessage} from 'react-intl';
import {NotificationLevels} from 'utils/constants.jsx';
import Constants, {NotificationLevels} from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';
import SettingItemMax from 'components/setting_item_max.jsx';
import SettingItemMin from 'components/setting_item_min.jsx';
......@@ -29,7 +29,6 @@ export default class DesktopNotificationSettings extends React.Component {
buildMaximizedSetting = () => {
const inputs = [];
let extraInfo = null;
const activityRadio = [false, false, false];
if (this.props.activity === NotificationLevels.MENTION) {
......@@ -41,7 +40,6 @@ export default class DesktopNotificationSettings extends React.Component {
}
let soundSection;
let durationSection;
if (this.props.activity !== NotificationLevels.NONE) {
const soundRadio = [false, false];
if (this.props.sound === 'false') {
......@@ -124,118 +122,6 @@ export default class DesktopNotificationSettings extends React.Component {
</div>
);
}
const durationRadio = [false, false, false, false];
if (this.props.duration === '3') {
durationRadio[0] = true;
} else if (this.props.duration === '10') {
durationRadio[2] = true;
} else if (this.props.duration === '0') {
durationRadio[3] = true;
} else {
durationRadio[1] = true;
}
durationSection = (
<div>
<hr/>
<label>
<FormattedMessage
id='user.settings.notifications.desktop.duration'
defaultMessage='Notification duration'
/>
</label>
<br/>
<div className='radio'>
<label>
<input
id='soundDuration3'
type='radio'
name='desktopDuration'
checked={durationRadio[0]}
data-key={'desktopDuration'}
data-value={'3'}
onChange={this.handleOnChange}
/>
<FormattedMessage
id='user.settings.notifications.desktop.seconds'
defaultMessage='{seconds} seconds'
values={{
seconds: '3',
}}
/>
</label>
<br/>
</div>
<div className='radio'>
<label>
<input
id='soundDuration5'
type='radio'
name='desktopDuration'
checked={durationRadio[1]}
data-key={'desktopDuration'}
data-value={'5'}
onChange={this.handleOnChange}
/>
<FormattedMessage
id='user.settings.notifications.desktop.seconds'
defaultMessage='{seconds} seconds'
values={{
seconds: '5',
}}
/>
</label>
<br/>
</div>
<div className='radio'>
<label>
<input
id='soundDuration10'
type='radio'
name='desktopDuration'
checked={durationRadio[2]}
data-key={'desktopDuration'}
data-value={'10'}
onChange={this.handleOnChange}
/>
<FormattedMessage
id='user.settings.notifications.desktop.seconds'
defaultMessage='{seconds} seconds'
values={{
seconds: '10',
}}
/>
</label>
</div>
<div className='radio'>
<label>
<input
id='soundDurationUnlimited'
type='radio'
name='desktopDuration'
checked={durationRadio[3]}
data-key={'desktopDuration'}
data-value={'0'}
onChange={this.handleOnChange}
/>
<FormattedMessage
id='user.settings.notifications.desktop.unlimited'
defaultMessage='Unlimited'
/>
</label>
</div>
</div>
);
extraInfo = (
<span>
<FormattedMessage
id='user.settings.notifications.desktop.durationInfo'
defaultMessage='Sets how long desktop notifications will remain on screen when using Firefox or Chrome. Desktop notifications in Edge, Safari and Mattermost Desktop Apps can only stay on screen for a maximum of 5 seconds.'
/>
</span>
);
}
inputs.push(
......@@ -308,14 +194,12 @@ export default class DesktopNotificationSettings extends React.Component {
/>
</span>
{soundSection}
{durationSection}
</div>
);
return (
<SettingItemMax
title={Utils.localizeMessage('user.settings.notifications.desktop.title', 'Desktop notifications')}
extraInfo={extraInfo}
inputs={inputs}
submit={this.props.submit}
saving={this.props.saving}
......@@ -329,62 +213,35 @@ export default class DesktopNotificationSettings extends React.Component {
let describe = '';
if (this.props.activity === NotificationLevels.MENTION) {
if (Utils.hasSoundOptions() && this.props.sound !== 'false') {
if (this.props.duration === '0') { //eslint-disable-line no-lonely-if
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsSoundForever'
defaultMessage='For mentions and direct messages, with sound, shown indefinitely'
/>
);
} else {
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsSoundTimed'
defaultMessage='For mentions and direct messages, with sound, shown for {seconds} seconds'
values={{
seconds: this.props.duration,
}}
/>
);
}
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsSoundTimed'
defaultMessage='For mentions and direct messages, with sound, shown for {seconds} seconds'
values={{
seconds: Constants.DEFAULT_NOTIFICATION_DURATION / 1000,
}}
/>
);
} else if (Utils.hasSoundOptions() && this.props.sound === 'false') {
if (this.props.duration === '0') {
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsNoSoundForever'
defaultMessage='For mentions and direct messages, without sound, shown indefinitely'
/>
);
} else {
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsNoSoundTimed'
defaultMessage='For mentions and direct messages, without sound, shown for {seconds} seconds'
values={{
seconds: this.props.duration,
}}
/>
);
}
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsNoSoundTimed'
defaultMessage='For mentions and direct messages, without sound, shown for {seconds} seconds'
values={{
seconds: Constants.DEFAULT_NOTIFICATION_DURATION / 1000,
}}
/>
);
} else {
if (this.props.duration === '0') { //eslint-disable-line no-lonely-if
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsSoundHiddenForever'
defaultMessage='For mentions and direct messages, shown indefinitely'
/>
);
} else {
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsSoundHiddenTimed'
defaultMessage='For mentions and direct messages, shown for {seconds} seconds'
values={{
seconds: this.props.duration,
}}
/>
);
}
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.mentionsSoundHiddenTimed'
defaultMessage='For mentions and direct messages, shown for {seconds} seconds'
values={{
seconds: Constants.DEFAULT_NOTIFICATION_DURATION / 1000,
}}
/>
);
}
} else if (this.props.activity === NotificationLevels.NONE) {
describe = (
......@@ -395,62 +252,35 @@ export default class DesktopNotificationSettings extends React.Component {
);
} else {
if (Utils.hasSoundOptions() && this.props.sound !== 'false') { //eslint-disable-line no-lonely-if
if (this.props.duration === '0') { //eslint-disable-line no-lonely-if
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allSoundForever'
defaultMessage='For all activity, with sound, shown indefinitely'
/>
);
} else {
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allSoundTimed'
defaultMessage='For all activity, with sound, shown for {seconds} seconds'
values={{
seconds: this.props.duration,
}}
/>
);
}
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allSoundTimed'
defaultMessage='For all activity, with sound, shown for {seconds} seconds'
values={{
seconds: Constants.DEFAULT_NOTIFICATION_DURATION / 1000,
}}
/>
);
} else if (Utils.hasSoundOptions() && this.props.sound === 'false') {
if (this.props.duration === '0') {
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allNoSoundForever'
defaultMessage='For all activity, without sound, shown indefinitely'
/>
);
} else {
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allNoSoundTimed'
defaultMessage='For all activity, without sound, shown for {seconds} seconds'
values={{
seconds: this.props.duration,
}}
/>
);
}
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allNoSoundTimed'
defaultMessage='For all activity, without sound, shown for {seconds} seconds'
values={{
seconds: Constants.DEFAULT_NOTIFICATION_DURATION / 1000,
}}
/>
);
} else {
if (this.props.duration === '0') { //eslint-disable-line no-lonely-if
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allSoundHiddenForever'
defaultMessage='For all activity, shown indefinitely'
/>
);
} else {
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allSoundHiddenTimed'
defaultMessage='For all activity, shown for {seconds} seconds'
values={{
seconds: this.props.duration,
}}
/>
);
}
describe = (
<FormattedMessage
id='user.settings.notifications.desktop.allSoundHiddenTimed'
defaultMessage='For all activity, shown for {seconds} seconds'
values={{
seconds: Constants.DEFAULT_NOTIFICATION_DURATION / 1000,
}}
/>
);
}
}
......@@ -477,7 +307,6 @@ export default class DesktopNotificationSettings extends React.Component {
DesktopNotificationSettings.propTypes = {
activity: PropTypes.string.isRequired,
sound: PropTypes.string.isRequired,
duration: PropTypes.string.isRequired,
updateSection: PropTypes.func,
setParentState: PropTypes.func,
submit: PropTypes.func,
......
......@@ -21,7 +21,6 @@ function getNotificationsStateFromStores() {
let desktop = NotificationLevels.MENTION;
let sound = 'true';
let desktopDuration = '5';
let comments = 'never';
let enableEmail = 'true';
let pushActivity = NotificationLevels.MENTION;
......@@ -39,9 +38,6 @@ function getNotificationsStateFromStores() {
if (user.notify_props.desktop_sound) {
sound = user.notify_props.desktop_sound;
}
if (user.notify_props.desktop_duration) {
desktopDuration = user.notify_props.desktop_duration;
}
if (user.notify_props.comments) {
comments = user.notify_props.comments;
}
......@@ -97,7 +93,6 @@ function getNotificationsStateFromStores() {
return {
desktopActivity: desktop,
desktopDuration,
enableEmail,
pushActivity,
pushStatus,
......@@ -135,7 +130,6 @@ export default class NotificationsTab extends React.Component {
data.email = enableEmail;
data.desktop_sound = this.state.desktopSound;
data.desktop = this.state.desktopActivity;
data.desktop_duration = this.state.desktopDuration;
data.push = this.state.pushActivity;
data.push_status = this.state.pushStatus;
data.comments = this.state.notifyCommentsLevel;
......@@ -937,7 +931,6 @@ export default class NotificationsTab extends React.Component {
<DesktopNotificationSettings
activity={this.state.desktopActivity}
sound={this.state.desktopSound}
duration={this.state.desktopDuration}
updateSection={this.updateSection}
setParentState={this.setStateValue}
submit={this.handleSubmit}
......
......@@ -69,16 +69,16 @@ export default class YoutubeVideo extends React.PureComponent {
}
handleYoutubeTime(link) {
const timeRegex = /[\\?&]t=([0-9]+h)?([0-9]+m)?([0-9]+s?)/;
const timeRegex = /[\\?&](t|start|time_continue)=([0-9]+h)?([0-9]+m)?([0-9]+s?)/;
const time = link.match(timeRegex);
if (!time || !time[0]) {
return '';
}
const hours = time[1] ? time[1].match(/([0-9]+)h/) : null;
const minutes = time[2] ? time[2].match(/([0-9]+)m/) : null;
const seconds = time[3] ? time[3].match(/([0-9]+)s?/) : null;
const hours = time[2] ? time[2].match(/([0-9]+)h/) : null;
const minutes = time[3] ? time[3].match(/([0-9]+)m/) : null;
const seconds = time[4] ? time[4].match(/([0-9]+)s?/) : null;
let ticks = 0;
......
......@@ -3129,24 +3129,14 @@
"user.settings.notifications.commentsNever": "Do not trigger notifications on messages in reply threads unless I'm mentioned",
"user.settings.notifications.commentsRoot": "Trigger notifications on messages in threads that I start",
"user.settings.notifications.desktop": "Send desktop notifications",
"user.settings.notifications.desktop.allNoSoundForever": "For all activity, without sound, shown indefinitely",
"user.settings.notifications.desktop.allNoSoundTimed": "For all activity, without sound, shown for {seconds} seconds",
"user.settings.notifications.desktop.allSoundForever": "For all activity, with sound, shown indefinitely",
"user.settings.notifications.desktop.allSoundHiddenForever": "For all activity, shown indefinitely",
"user.settings.notifications.desktop.allSoundHiddenTimed": "For all activity, shown for {seconds} seconds",
"user.settings.notifications.desktop.allSoundTimed": "For all activity, with sound, shown for {seconds} seconds",
"user.settings.notifications.desktop.duration": "Notification duration",
"user.settings.notifications.desktop.durationInfo": "Sets how long desktop notifications will remain on screen when using Firefox or Chrome. Desktop notifications in Edge, Safari and Mattermost Desktop Apps can only stay on screen for a maximum of 5 seconds.",
"user.settings.notifications.desktop.mentionsNoSoundForever": "For mentions and direct messages, without sound, shown indefinitely",
"user.settings.notifications.desktop.mentionsNoSoundTimed": "For mentions and direct messages, without sound, shown for {seconds} seconds",
"user.settings.notifications.desktop.mentionsSoundForever": "For mentions and direct messages, with sound, shown indefinitely",
"user.settings.notifications.desktop.mentionsSoundHiddenForever": "For mentions and direct messages, shown indefinitely",
"user.settings.notifications.desktop.mentionsSoundHiddenTimed": "For mentions and direct messages, shown for {seconds} seconds",
"user.settings.notifications.desktop.mentionsSoundTimed": "For mentions and direct messages, with sound, shown for {seconds} seconds",
"user.settings.notifications.desktop.seconds": "{seconds} seconds",
"user.settings.notifications.desktop.sound": "Notification sound",
"user.settings.notifications.desktop.title": "Desktop notifications",
"user.settings.notifications.desktop.unlimited": "Unlimited",
"user.settings.notifications.desktopSounds": "Desktop notification sounds",
"user.settings.notifications.email.disabled": "Email notifications are not enabled",
"user.settings.notifications.email.disabled_long": "Email notifications have not been enabled by your System Administrator.",
......
This diff is collapsed.
......@@ -126,6 +126,132 @@ exports[`components/TextBox should match snapshot with required props 1`] = `
</div>
`;
exports[`components/TextBox should throw error when new property is too long 1`] = `
<div
className="textarea-wrapper"
>
<SuggestionBox
className="form-control custom-textarea"
completeOnTab={true}
id="someid"
inputComponent={[Function]}
isRHS={false}
listComponent={[Function]}
listStyle="top"
onBlur={[Function]}
onChange={[Function]}
onHeightChange={[Function]}
onKeyDown={[Function]}
onKeyPress={[Function]}
openOnFocus={false}
openWhenEmpty={false}
placeholder="placeholder text"
popoverMentionKeyClick={false}
providers={
Array [
AtMentionProvider {
"channelId": undefined,
"disableDispatches": false,
"latestComplete": true,
"latestPrefix": "",
},
ChannelMentionProvider {
"disableDispatches": false,
"lastCompletedWord": "",
"lastPrefixWithNoResults": "",
"latestComplete": true,
"latestPrefix": "",
},
EmoticonProvider {},
]
}
renderDividers={true}
requiredCharacters={1}
spellCheck="true"
style={
Object {
"visibility": "visible",
}
}
value="some test text that exceeds char limit"
/>
<div
className="help__text hidden"
>
<div
className="help__format-text"
id="helpText"
style={
Object {
"opacity": "0.45",
"visibility": "visible",
}
}
>
<b>
<FormattedMessage
defaultMessage="**bold**"
id="textbox.bold"
values={Object {}}
/>
</b>
<i>
<FormattedMessage
defaultMessage="_italic_"
id="textbox.italic"
values={Object {}}