Skip to content

Commit

Permalink
Add more tips to onboarding flow in web UI (#24646)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gargron committed Apr 25, 2023
1 parent 8099ba0 commit c35e3cb
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 8 deletions.
16 changes: 12 additions & 4 deletions app/javascript/mastodon/features/onboarding/follows.jsx
Expand Up @@ -46,6 +46,16 @@ class Follows extends React.PureComponent {
render () {
const { onBack, isLoading, suggestions, account } = this.props;

let loadedContent;

if (isLoading) {
loadedContent = (new Array(8)).fill().map((_, i) => <EmptyAccount key={i} />);
} else if (suggestions.isEmpty()) {
loadedContent = <div className='follow-recommendations__empty'><FormattedMessage id='onboarding.follows.empty' defaultMessage='Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.' /></div>;
} else {
loadedContent = suggestions.map(suggestion => <Account id={suggestion.get('account')} key={suggestion.get('account')} />);
}

return (
<Column>
<ColumnBackButton onClick={onBack} />
Expand All @@ -59,12 +69,10 @@ class Follows extends React.PureComponent {
<ProgressIndicator steps={7} completed={account.get('following_count') * 1} />

<div className='follow-recommendations'>
{isLoading ? (new Array(8)).fill().map((_, i) => <EmptyAccount key={i} />) : suggestions.map(suggestion => (
<Account id={suggestion.get('account')} key={suggestion.get('account')} />
))}
{loadedContent}
</div>

<p className='onboarding__lead'><FormattedHTMLMessage id='onboarding.tips.accounts_from_other_servers' defaultMessage='<strong>Did you know?</strong> Since Mastodon is decentralized, some profiles you come across will be hosted on servers other than yours. And yet you can interact with them seamlessly! Their server is in the second half of their username!' values={{ strong: text => <strong>{text}</strong> }} /></p>
<p className='onboarding__lead'><FormattedHTMLMessage id='onboarding.tips.accounts_from_other_servers' defaultMessage='<strong>Did you know?</strong> Since Mastodon is decentralized, some profiles you come across will be hosted on servers other than yours. And yet you can interact with them seamlessly! Their server is in the second half of their username!' /></p>

<div className='onboarding__footer'>
<button className='link-button' onClick={onBack}><FormattedMessage id='onboarding.actions.back' defaultMessage='Take me back' /></button>
Expand Down
65 changes: 63 additions & 2 deletions app/javascript/mastodon/features/onboarding/share.jsx
Expand Up @@ -5,14 +5,15 @@ import PropTypes from 'prop-types';
import { me, domain } from 'mastodon/initial_state';
import { connect } from 'react-redux';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { defineMessages, injectIntl, FormattedMessage, FormattedHTMLMessage } from 'react-intl';
import classNames from 'classnames';
import Icon from 'mastodon/components/icon';
import ArrowSmallRight from './components/arrow_small_right';
import { Link } from 'react-router-dom';
import SwipeableViews from 'react-swipeable-views';

const messages = defineMessages({
shareableMessage: { id: 'onboarding.share.message', defaultMessage: 'I\'m {username} on Mastodon! Come follow me at {url}' },
shareableMessage: { id: 'onboarding.share.message', defaultMessage: 'I\'m {username} on #Mastodon! Come follow me at {url}' },
});

const mapStateToProps = state => ({
Expand Down Expand Up @@ -80,6 +81,60 @@ class CopyPasteText extends React.PureComponent {

}

class TipCarousel extends React.PureComponent {

static propTypes = {
children: PropTypes.node,
};

state = {
index: 0,
};

handleSwipe = index => {
this.setState({ index });
};

handleChangeIndex = e => {
this.setState({ index: Number(e.currentTarget.getAttribute('data-index')) });
};

handleKeyDown = e => {
switch(e.key) {
case 'ArrowLeft':
e.preventDefault();
this.setState(({ index }, { children }) => ({ index: Math.abs(index - 1) % children.length }));
break;
case 'ArrowRight':
e.preventDefault();
this.setState(({ index }, { children }) => ({ index: (index + 1) % children.length }));
break;
}
};

render () {
const { children } = this.props;
const { index } = this.state;

return (
<div className='tip-carousel' tabIndex='0' onKeyDown={this.handleKeyDown}>
<SwipeableViews onChangeIndex={this.handleSwipe} index={index} enableMouseEvents tabIndex='-1'>
{children}
</SwipeableViews>

<div className='media-modal__pagination'>
{children.map((_, i) => (
<button key={i} className={classNames('media-modal__page-dot', { active: i === index })} data-index={i} onClick={this.handleChangeIndex}>
{i + 1}
</button>
))}
</div>
</div>
);
}

}

class Share extends React.PureComponent {

static propTypes = {
Expand All @@ -105,6 +160,12 @@ class Share extends React.PureComponent {

<CopyPasteText value={intl.formatMessage(messages.shareableMessage, { username: `@${account.get('username')}@${domain}`, url })} />

<TipCarousel>
<div><p className='onboarding__lead'><FormattedHTMLMessage id='onboarding.tips.verification' defaultMessage='<strong>Did you know?</strong> You can verify your account by putting a link to your Mastodon profile on your own website and adding the website to your profile. No fees or documents necessary!' /></p></div>
<div><p className='onboarding__lead'><FormattedHTMLMessage id='onboarding.tips.migration' defaultMessage='<strong>Did you know?</strong> If you feel like {domain} is not a great server choice for you in the future, you can move to another Mastodon server without losing your followers. You can even host your own server!' values={{ domain }} /></p></div>
<div><p className='onboarding__lead'><FormattedHTMLMessage id='onboarding.tips.2fa' defaultMessage='<strong>Did you know?</strong> You can secure your account by setting up two-factor authentication in your account settings. It works with any TOTP app of your choice, no phone number necessary!' /></p></div>
</TipCarousel>

<p className='onboarding__lead'><FormattedMessage id='onboarding.share.next_steps' defaultMessage='Possible next steps:' /></p>

<div className='onboarding__links'>
Expand Down
18 changes: 17 additions & 1 deletion app/javascript/mastodon/locales/defaultMessages.json
Expand Up @@ -3186,6 +3186,10 @@
},
{
"descriptors": [
{
"defaultMessage": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.",
"id": "onboarding.follows.empty"
},
{
"defaultMessage": "Popular on Mastodon",
"id": "onboarding.follows.title"
Expand Down Expand Up @@ -3265,7 +3269,7 @@
{
"descriptors": [
{
"defaultMessage": "I'm {username} on Mastodon! Come follow me at {url}",
"defaultMessage": "I'm {username} on #Mastodon! Come follow me at {url}",
"id": "onboarding.share.message"
},
{
Expand All @@ -3284,6 +3288,18 @@
"defaultMessage": "Let people know how they can find you on Mastodon!",
"id": "onboarding.share.lead"
},
{
"defaultMessage": "<strong>Did you know?</strong> You can verify your account by putting a link to your Mastodon profile on your own website and adding the website to your profile. No fees or documents necessary!",
"id": "onboarding.tips.verification"
},
{
"defaultMessage": "<strong>Did you know?</strong> If you feel like {domain} is not a great server choice for you in the future, you can move to another Mastodon server without losing your followers. You can even host your own server!",
"id": "onboarding.tips.migration"
},
{
"defaultMessage": "<strong>Did you know?</strong> You can secure your account by setting up two-factor authentication in your account settings. It works with any TOTP app of your choice, no phone number necessary!",
"id": "onboarding.tips.2fa"
},
{
"defaultMessage": "Possible next steps:",
"id": "onboarding.share.next_steps"
Expand Down
6 changes: 5 additions & 1 deletion app/javascript/mastodon/locales/en.json
Expand Up @@ -445,10 +445,11 @@
"onboarding.actions.close": "Don't show this screen again",
"onboarding.actions.go_to_explore": "See what's trending",
"onboarding.actions.go_to_home": "Go to your home feed",
"onboarding.follows.empty": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.",
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
"onboarding.follows.title": "Popular on Mastodon",
"onboarding.share.lead": "Let people know how they can find you on Mastodon!",
"onboarding.share.message": "I'm {username} on Mastodon! Come follow me at {url}",
"onboarding.share.message": "I'm {username} on #Mastodon! Come follow me at {url}",
"onboarding.share.next_steps": "Possible next steps:",
"onboarding.share.title": "Share your profile",
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
Expand All @@ -462,7 +463,10 @@
"onboarding.steps.setup_profile.title": "Customize your profile",
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
"onboarding.steps.share_profile.title": "Share your profile",
"onboarding.tips.2fa": "<strong>Did you know?</strong> You can secure your account by setting up two-factor authentication in your account settings. It works with any TOTP app of your choice, no phone number necessary!",
"onboarding.tips.accounts_from_other_servers": "<strong>Did you know?</strong> Since Mastodon is decentralized, some profiles you come across will be hosted on servers other than yours. And yet you can interact with them seamlessly! Their server is in the second half of their username!",
"onboarding.tips.migration": "<strong>Did you know?</strong> If you feel like {domain} is not a great server choice for you in the future, you can move to another Mastodon server without losing your followers. You can even host your own server!",
"onboarding.tips.verification": "<strong>Did you know?</strong> You can verify your account by putting a link to your Mastodon profile on your own website and adding the website to your profile. No fees or documents necessary!",
"password_confirmation.exceeds_maxlength": "Password confirmation exceeds the maximum password length",
"password_confirmation.mismatching": "Password confirmation does not match",
"picture_in_picture.restore": "Put it back",
Expand Down
28 changes: 28 additions & 0 deletions app/javascript/styles/mastodon/components.scss
Expand Up @@ -3026,6 +3026,29 @@ $ui-header-height: 55px;
.account:last-child {
border-bottom: 0;
}

&__empty {
text-align: center;
color: $darker-text-color;
font-weight: 500;
padding: 40px;
}
}

.tip-carousel {
border: 1px solid transparent;
border-radius: 8px;
padding: 16px;
margin-bottom: 30px;

&:focus {
outline: 0;
border-color: $highlight-text-color;
}

.media-modal__pagination {
margin-bottom: 0;
}
}

.copy-paste-text {
Expand Down Expand Up @@ -5539,6 +5562,11 @@ a.status-card.compact:hover {
&.active {
opacity: 1;
}

&:focus {
outline: 0;
background-color: $highlight-text-color;
}
}

.media-modal__close {
Expand Down

0 comments on commit c35e3cb

Please sign in to comment.