From 9c2c941449c387b2407d10c101f39a2266a2e65a Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Fri, 22 Jul 2016 10:53:57 -0400 Subject: [PATCH] PLT-1866/PLT-3509 Added links to download the native apps (#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 --- api/user.go | 5 + config/config.json | 5 + i18n/en.json | 4 + model/config.go | 22 ++++ templates/welcome_body.html | 11 ++ utils/config.go | 4 + .../admin_console/admin_sidebar.jsx | 10 ++ .../native_app_link_settings.jsx | 104 ++++++++++++++++++ webapp/components/navbar_dropdown.jsx | 22 ++++ webapp/components/sidebar_right_menu.jsx | 20 ++++ .../tutorial/tutorial_intro_screens.jsx | 46 +++++++- webapp/i18n/en.json | 11 ++ webapp/images/appIcons.png | Bin 0 -> 10107 bytes webapp/routes/route_admin_console.jsx | 5 + webapp/sass/components/_tutorial.scss | 6 +- webapp/webpack.config.js | 3 +- 16 files changed, 274 insertions(+), 4 deletions(-) create mode 100644 webapp/components/admin_console/native_app_link_settings.jsx create mode 100644 webapp/images/appIcons.png diff --git a/api/user.go b/api/user.go index 8cc4ed8dd7..fa643007f2 100644 --- a/api/user.go +++ b/api/user.go @@ -362,6 +362,11 @@ func sendWelcomeEmail(c *Context, userId string, email string, siteURL string, v bodyPage.Props["Info3"] = c.T("api.templates.welcome_body.info3") bodyPage.Props["SiteURL"] = siteURL + if *utils.Cfg.NativeAppSettings.AppDownloadLink != "" { + bodyPage.Props["AppDownloadInfo"] = c.T("api.templates.welcome_body.app_download_info") + bodyPage.Props["AppDownloadLink"] = *utils.Cfg.NativeAppSettings.AppDownloadLink + } + if !verified { link := fmt.Sprintf("%s/do_verify_email?uid=%s&hid=%s&email=%s", siteURL, userId, model.HashPassword(userId), url.QueryEscape(email)) bodyPage.Props["VerifyUrl"] = link diff --git a/config/config.json b/config/config.json index 745be73e3e..8f1bea3cac 100644 --- a/config/config.json +++ b/config/config.json @@ -195,5 +195,10 @@ "NicknameAttribute": "", "LocaleAttribute": "", "LoginButtonText": "With SAML" + }, + "NativeAppSettings": { + "AppDownloadLink": "https://about.mattermost.com/downloads/", + "AndroidAppDownloadLink": "https://about.mattermost.com/mattermost-android-app/", + "IosAppDownloadLink": "https://about.mattermost.com/mattermost-ios-app/" } } \ No newline at end of file diff --git a/i18n/en.json b/i18n/en.json index 426b1ec1bb..d91fea61c1 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1571,6 +1571,10 @@ "id": "api.templates.verify_subject", "translation": "[{{ .SiteName }}] Email Verification" }, + { + "id": "api.templates.welcome_body.app_download_info", + "translation": "For the best experience, download the apps for PC, Mac, iOS and Android from:" + }, { "id": "api.templates.welcome_body.button", "translation": "Verify Email" diff --git a/model/config.go b/model/config.go index 4767378fb8..b38179cf18 100644 --- a/model/config.go +++ b/model/config.go @@ -268,6 +268,12 @@ type SamlSettings struct { LoginButtonText *string } +type NativeAppSettings struct { + AppDownloadLink *string + AndroidAppDownloadLink *string + IosAppDownloadLink *string +} + type Config struct { ServiceSettings ServiceSettings TeamSettings TeamSettings @@ -285,6 +291,7 @@ type Config struct { ComplianceSettings ComplianceSettings LocalizationSettings LocalizationSettings SamlSettings SamlSettings + NativeAppSettings NativeAppSettings } func (o *Config) ToJson() string { @@ -792,6 +799,21 @@ func (o *Config) SetDefaults() { o.SamlSettings.LocaleAttribute = new(string) *o.SamlSettings.LocaleAttribute = "" } + + if o.NativeAppSettings.AppDownloadLink == nil { + o.NativeAppSettings.AppDownloadLink = new(string) + *o.NativeAppSettings.AppDownloadLink = "https://about.mattermost.com/downloads/" + } + + if o.NativeAppSettings.AndroidAppDownloadLink == nil { + o.NativeAppSettings.AndroidAppDownloadLink = new(string) + *o.NativeAppSettings.AndroidAppDownloadLink = "https://about.mattermost.com/mattermost-android-app/" + } + + if o.NativeAppSettings.IosAppDownloadLink == nil { + o.NativeAppSettings.IosAppDownloadLink = new(string) + *o.NativeAppSettings.IosAppDownloadLink = "https://about.mattermost.com/mattermost-ios-app/" + } } func (o *Config) IsValid() *AppError { diff --git a/templates/welcome_body.html b/templates/welcome_body.html index 8dee99cf5e..22867e64ba 100644 --- a/templates/welcome_body.html +++ b/templates/welcome_body.html @@ -33,6 +33,17 @@

{{.Props.Info3}}

+ {{if .Props.AppDownloadLink}} + + +

{{.Props.AppDownloadInfo}}

+ +

{{.Props.AppDownloadLink}}

+ +
+ + + {{end}} diff --git a/utils/config.go b/utils/config.go index cbae0e2cb4..39dbca4d82 100644 --- a/utils/config.go +++ b/utils/config.go @@ -264,6 +264,10 @@ func getClientConfig(c *model.Config) map[string]string { props["RestrictCustomEmojiCreation"] = *c.ServiceSettings.RestrictCustomEmojiCreation props["MaxFileSize"] = strconv.FormatInt(*c.FileSettings.MaxFileSize, 10) + props["AppDownloadLink"] = *c.NativeAppSettings.AppDownloadLink + props["AndroidAppDownloadLink"] = *c.NativeAppSettings.AndroidAppDownloadLink + props["IosAppDownloadLink"] = *c.NativeAppSettings.IosAppDownloadLink + if IsLicensed { if *License.Features.CustomBrand { props["EnableCustomBrand"] = strconv.FormatBool(*c.TeamSettings.EnableCustomBrand) diff --git a/webapp/components/admin_console/admin_sidebar.jsx b/webapp/components/admin_console/admin_sidebar.jsx index 49df8f8205..5c02f419ed 100644 --- a/webapp/components/admin_console/admin_sidebar.jsx +++ b/webapp/components/admin_console/admin_sidebar.jsx @@ -581,6 +581,16 @@ export default class AdminSidebar extends React.Component { /> } /> + + + } + /> + + + ); + } + + renderSettings() { + return ( + + + } + helpText={ + + } + value={this.state.appDownloadLink} + onChange={this.handleChange} + /> + + } + helpText={ + + } + value={this.state.androidAppDownloadLink} + onChange={this.handleChange} + /> + + } + helpText={ + + } + value={this.state.iosAppDownloadLink} + onChange={this.handleChange} + /> + + ); + } +} diff --git a/webapp/components/navbar_dropdown.jsx b/webapp/components/navbar_dropdown.jsx index 4912b8ebf6..81bd312697 100644 --- a/webapp/components/navbar_dropdown.jsx +++ b/webapp/components/navbar_dropdown.jsx @@ -332,6 +332,26 @@ export default class NavbarDropdown extends React.Component { ); } + let nativeAppDivider = null; + let nativeAppLink = null; + if (global.window.mm_config.AppDownloadLink) { + nativeAppDivider =
  • ; + nativeAppLink = ( +
  • + + + +
  • + ); + } + return (
    • + {nativeAppDivider} + {nativeAppLink} this.setState({showUserSettingsModal: false})} diff --git a/webapp/components/sidebar_right_menu.jsx b/webapp/components/sidebar_right_menu.jsx index 25136e8bc6..27e7c25d4a 100644 --- a/webapp/components/sidebar_right_menu.jsx +++ b/webapp/components/sidebar_right_menu.jsx @@ -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 = ( +
    • + + + + +
    • + ); + } + return (
      + {nativeAppLink}
    + + + ) + }} + /> + ); + + appDownloadImage = ( + + + + ); + } + return (
    Communication happens in public discussion channels, private groups and direct messages.

    Everything is archived and searchable from any web-enabled desktop, laptop or phone.

    ' /> + {appDownloadLink} + {appDownloadImage} {circles}
    ); diff --git a/webapp/i18n/en.json b/webapp/i18n/en.json index ab7406d458..ad1c1d3636 100644 --- a/webapp/i18n/en.json +++ b/webapp/i18n/en.json @@ -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.", @@ -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}", @@ -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", @@ -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": "

    Welcome to:

    Mattermost

    Your team communication all in one place, instantly searchable and available anywhere

    Keep your team connected to help them achieve what matters most.

    ", "tutorial_intro.screenTwo": "

    How Mattermost works:

    Communication happens in public discussion channels, private groups and direct messages.

    Everything is archived and searchable from any web-enabled desktop, laptop or phone.

    ", diff --git a/webapp/images/appIcons.png b/webapp/images/appIcons.png new file mode 100644 index 0000000000000000000000000000000000000000..ce38166fb540b3f06fc5a533721cb05b62b5469a GIT binary patch literal 10107 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 + diff --git a/webapp/sass/components/_tutorial.scss b/webapp/sass/components/_tutorial.scss index e4aff17851..a8d3ffdf67 100644 --- a/webapp/sass/components/_tutorial.scss +++ b/webapp/sass/components/_tutorial.scss @@ -183,7 +183,7 @@ display: inline-block; margin-bottom: 50px; max-width: 310px; - min-height: 370px; + min-height: 410px; position: relative; text-align: left; } @@ -234,3 +234,7 @@ } } } + +.tutorial__app-icons { + margin: 2em 0; +} \ No newline at end of file diff --git a/webapp/webpack.config.js b/webapp/webpack.config.js index 4f33eaf84c..8b1f4b21ab 100644 --- a/webapp/webpack.config.js +++ b/webapp/webpack.config.js @@ -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,