Skip to content

Commit

Permalink
PLT-1866/PLT-3509 Added links to download the native apps (mattermost…
Browse files Browse the repository at this point in the history
…#3651)

* PLT-1866 Added configurable links for native app downloads

* PLT-1866 Added native app download link to main menu

* PLT-3509 Added native app link to tutorial

* PLT-3509 Added native app link to welcome email

* PLT-3509 Made link to apps in welcome email conditional on being set
  • Loading branch information
hmhealey committed Jul 22, 2016
1 parent 482d49d commit 71d1cc3
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 4 deletions.
10 changes: 10 additions & 0 deletions components/admin_console/admin_sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,16 @@ export default class AdminSidebar extends React.Component {
/>
}
/>
<AdminSidebarSection
name='native_app_links'
title={
<FormattedMessage
id='admin.sidebar.nativeAppLinks'
defaultMessage='Native App Links'
/>

}
/>
</AdminSidebarSection>
<AdminSidebarSection
name='advanced'
Expand Down
104 changes: 104 additions & 0 deletions components/admin_console/native_app_link_settings.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.

import React from 'react';

import AdminSettings from './admin_settings.jsx';
import {FormattedMessage} from 'react-intl';
import SettingsGroup from './settings_group.jsx';
import TextSetting from './text_setting.jsx';

export default class NativeAppLinkSettings extends AdminSettings {
constructor(props) {
super(props);

this.getConfigFromState = this.getConfigFromState.bind(this);

this.renderSettings = this.renderSettings.bind(this);
}

getConfigFromState(config) {
config.NativeAppSettings.AppDownloadLink = this.state.appDownloadLink;
config.NativeAppSettings.AndroidAppDownloadLink = this.state.androidAppDownloadLink;
config.NativeAppSettings.IosAppDownloadLink = this.state.iosAppDownloadLink;

return config;
}

getStateFromConfig(config) {
return {
appDownloadLink: config.NativeAppSettings.AppDownloadLink,
androidAppDownloadLink: config.NativeAppSettings.AndroidAppDownloadLink,
iosAppDownloadLink: config.NativeAppSettings.IosAppDownloadLink
};
}

renderTitle() {
return (
<h3>
<FormattedMessage
id='admin.customization.nativeAppLinks'
defaultMessage='Native App Links'
/>
</h3>
);
}

renderSettings() {
return (
<SettingsGroup>
<TextSetting
id='appDownloadLink'
label={
<FormattedMessage
id='admin.customization.appDownloadLinkTitle'
defaultMessage='Mattermost Apps Download Page Link:'
/>
}
helpText={
<FormattedMessage
id='admin.customization.appDownloadLinkDesc'
defaultMessage='Add a link to a download page for the Mattermost apps. When a link is present, an option to "Download Mattermost Apps" will be added in the Main Menu so users can find the download page. Leave this field blank to hide the option from the Main Menu.'
/>
}
value={this.state.appDownloadLink}
onChange={this.handleChange}
/>
<TextSetting
id='androidAppDownloadLink'
label={
<FormattedMessage
id='admin.customization.androidAppDownloadLinkTitle'
defaultMessage='Android App Download Link:'
/>
}
helpText={
<FormattedMessage
id='admin.customization.androidAppDownloadLinkDesc'
defaultMessage='Add a link to download the Android app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.'
/>
}
value={this.state.androidAppDownloadLink}
onChange={this.handleChange}
/>
<TextSetting
id='iosAppDownloadLink'
label={
<FormattedMessage
id='admin.customization.iosAppDownloadLinkTitle'
defaultMessage='iOS App Download Link:'
/>
}
helpText={
<FormattedMessage
id='admin.customization.iosAppDownloadLinkDesc'
defaultMessage='Add a link to download the iOS app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.'
/>
}
value={this.state.iosAppDownloadLink}
onChange={this.handleChange}
/>
</SettingsGroup>
);
}
}
22 changes: 22 additions & 0 deletions components/navbar_dropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,26 @@ export default class NavbarDropdown extends React.Component {
);
}

let nativeAppDivider = null;
let nativeAppLink = null;
if (global.window.mm_config.AppDownloadLink) {
nativeAppDivider = <li className='divider'/>;
nativeAppLink = (
<li>
<Link
target='_blank'
rel='noopener noreferrer'
to={global.window.mm_config.AppDownloadLink}
>
<FormattedMessage
id='navbar_dropdown.nativeApps'
defaultMessage='Download Native Apps'
/>
</Link>
</li>
);
}

return (
<ul className='nav navbar-nav navbar-right'>
<li
Expand Down Expand Up @@ -403,6 +423,8 @@ export default class NavbarDropdown extends React.Component {
/>
</a>
</li>
{nativeAppDivider}
{nativeAppLink}
<UserSettingsModal
show={this.state.showUserSettingsModal}
onModalDismissed={() => this.setState({showUserSettingsModal: false})}
Expand Down
20 changes: 20 additions & 0 deletions components/sidebar_right_menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,25 @@ export default class SidebarRightMenu extends React.Component {
this.openRightSidebar();
}

let nativeAppLink = null;
if (global.window.mm_config.AppDownloadLink && !Utils.isMobileApp()) {
nativeAppLink = (
<li>
<Link
target='_blank'
rel='noopener noreferrer'
to={global.window.mm_config.AppDownloadLink}
>
<i className='icon fa fa-mobile'></i>
<FormattedMessage
id='sidebar_right_menu.nativeApps'
defaultMessage='Download Native Apps'
/>
</Link>
</li>
);
}

return (
<div
className='sidebar--menu'
Expand Down Expand Up @@ -378,6 +397,7 @@ export default class SidebarRightMenu extends React.Component {
/>
</a>
</li>
{nativeAppLink}
</ul>
</div>
<UserSettingsModal
Expand Down
46 changes: 44 additions & 2 deletions components/tutorial/tutorial_intro_screens.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import PreferenceStore from 'stores/preference_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
import * as GlobalActions from 'actions/global_actions.jsx';

import Constants from 'utils/constants.jsx';
import {Constants, Preferences} from 'utils/constants.jsx';

import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
import {browserHistory} from 'react-router/es6';

const Preferences = Constants.Preferences;
import AppIcons from 'images/appIcons.png';

const NUM_SCREENS = 3;

Expand Down Expand Up @@ -91,6 +91,46 @@ export default class TutorialIntroScreens extends React.Component {
createScreenTwo() {
const circles = this.createCircles();

let appDownloadLink = null;
let appDownloadImage = null;
if (global.window.mm_config.AppDownloadLink) {
// not using a FormattedHTMLMessage here since mm_config.AppDownloadLink is configurable and could be used
// to inject HTML if we're not careful
appDownloadLink = (
<FormattedMessage
id='tutorial_intro.mobileApps'
defaultMessage='Install the apps for {link} for easy access and notifications on the go.'
values={{
link: (
<a
href={global.window.mm_config.AppDownloadLink}
target='_blank'
rel='noopener noreferrer'
>
<FormattedMessage
id='tutorial_intro.mobileAppsLinkText'
defaultMessage='PC, Mac, iOS and Android'
/>
</a>
)
}}
/>
);

appDownloadImage = (
<a
href={global.window.mm_config.AppDownloadLink}
target='_blank'
rel='noopener noreferrer'
>
<img
className='tutorial__app-icons'
src={AppIcons}
/>
</a>
);
}

return (
<div>
<FormattedHTMLMessage
Expand All @@ -99,6 +139,8 @@ export default class TutorialIntroScreens extends React.Component {
<p>Communication happens in public discussion channels, private groups and direct messages.</p>
<p>Everything is archived and searchable from any web-enabled desktop, laptop or phone.</p>'
/>
{appDownloadLink}
{appDownloadImage}
{circles}
</div>
);
Expand Down
11 changes: 11 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,17 @@
"admin.connectionSecurityTitle": "Connection Security:",
"admin.connectionSecurityTls": "TLS",
"admin.connectionSecurityTlsDescription": "Encrypts the communication between Mattermost and your server.",
"admin.customization.appDownloadLinkDesc": "Add a link to a download page for the Mattermost apps. When a link is present, an option to \"Download Mattermost Apps\" will be added in the Main Menu so users can find the download page. Leave this field blank to hide the option from the Main Menu.",
"admin.customization.appDownloadLinkTitle": "Mattermost Apps Download Page Link:",
"admin.customization.androidAppDownloadLinkDesc": "Add a link to download the Android app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.",
"admin.customization.androidAppDownloadLinkTitle": "Android App Download Link:",
"admin.customization.customBrand": "Custom Branding",
"admin.customization.customEmoji": "Custom Emoji",
"admin.customization.enableCustomEmojiDesc": "Enable users to create custom emoji for use in messages. When enabled, Custom Emoji settings can be accessed by switching to a team and clicking the three dots above the channel sidebar, and selecting \"Custom Emoji\".",
"admin.customization.enableCustomEmojiTitle": "Enable Custom Emoji:",
"admin.customization.iosAppDownloadLinkDesc": "Add a link to download the iOS app. Users who access the site on a mobile web browser will be prompted with a page giving them the option to download the app. Leave this field blank to prevent the page from appearing.",
"admin.customization.iosAppDownloadLinkTitle": "iOS App Download Link:",
"admin.customization.nativeAppLinks": "Native App Links",
"admin.customization.restrictCustomEmojiCreationAdmin": "Allow System and Team Admins to create custom emoji",
"admin.customization.restrictCustomEmojiCreationAll": "Allow everyone to create custom emoji",
"admin.customization.restrictCustomEmojiCreationDesc": "Restrict the creation of custom emoji to certain users.",
Expand Down Expand Up @@ -1229,6 +1236,7 @@
"navbar_dropdown.leave": "Leave Team",
"navbar_dropdown.logout": "Logout",
"navbar_dropdown.manageMembers": "Manage Members",
"navbar_dropdown.nativeApps": "Download Native Apps",
"navbar_dropdown.viewMembers": "View Members",
"navbar_dropdown.report": "Report a Problem",
"navbar_dropdown.switchTeam": "Switch to {team}",
Expand Down Expand Up @@ -1358,6 +1366,7 @@
"sidebar_right_menu.inviteNew": "Invite New Member",
"sidebar_right_menu.logout": "Logout",
"sidebar_right_menu.manageMembers": "Manage Members",
"sidebar_right_menu.nativeApps": "Download Native App",
"sidebar_right_menu.recentMentions": "Recent Mentions",
"sidebar_right_menu.report": "Report a Problem",
"sidebar_right_menu.switch_team": "Team Selection",
Expand Down Expand Up @@ -1457,6 +1466,8 @@
"tutorial_intro.allSet": "You’re all set",
"tutorial_intro.end": "Click “Next” to enter {channel}. This is the first channel teammates see when they sign up. Use it for posting updates everyone needs to know.",
"tutorial_intro.invite": "Invite teammates",
"tutorial_intro.mobileApps": "Install the apps for {link} for easy access and notifications on the go.",
"tutorial_intro.mobileAppsLinkText": "PC, Mac, iOS and Android",
"tutorial_intro.next": "Next",
"tutorial_intro.screenOne": "<h3>Welcome to:</h3><h1>Mattermost</h1><p>Your team communication all in one place, instantly searchable and available anywhere</p><p>Keep your team connected to help them achieve what matters most.</p>",
"tutorial_intro.screenTwo": "<h3>How Mattermost works:</h3><p>Communication happens in public discussion channels, private groups and direct messages.</p><p>Everything is archived and searchable from any web-enabled desktop, laptop or phone.</p>",
Expand Down
Binary file added images/appIcons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions routes/route_admin_console.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import ImageSettings from 'components/admin_console/image_settings.jsx';
import CustomBrandSettings from 'components/admin_console/custom_brand_settings.jsx';
import CustomEmojiSettings from 'components/admin_console/custom_emoji_settings.jsx';
import LegalAndSupportSettings from 'components/admin_console/legal_and_support_settings.jsx';
import NativeAppLinkSettings from 'components/admin_console/native_app_link_settings.jsx';
import ComplianceSettings from 'components/admin_console/compliance_settings.jsx';
import RateSettings from 'components/admin_console/rate_settings.jsx';
import DeveloperSettings from 'components/admin_console/developer_settings.jsx';
Expand Down Expand Up @@ -166,6 +167,10 @@ export default (
path='legal_and_support'
component={LegalAndSupportSettings}
/>
<Route
path='native_app_links'
component={NativeAppLinkSettings}
/>
</Route>
<Route path='advanced'>
<IndexRedirect to='rate'/>
Expand Down
6 changes: 5 additions & 1 deletion sass/components/_tutorial.scss
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
display: inline-block;
margin-bottom: 50px;
max-width: 310px;
min-height: 370px;
min-height: 410px;
position: relative;
text-align: left;
}
Expand Down Expand Up @@ -234,3 +234,7 @@
}
}
}

.tutorial__app-icons {
margin: 2em 0;
}
3 changes: 2 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ var config = {
{from: 'images/emoji', to: 'emoji'},
{from: 'images/logo-email.png', to: 'images'},
{from: 'images/circles.png', to: 'images'},
{from: 'images/favicon', to: 'images/favicon'}
{from: 'images/favicon', to: 'images/favicon'},
{from: 'images/appIcons.png', to: 'images'}
]),
new webpack.LoaderOptionsPlugin({
minimize: !DEV,
Expand Down

0 comments on commit 71d1cc3

Please sign in to comment.