compose components for messaging, show mock contacts

Signed-off-by: Baptiste Lemoine <contact@cipherbliss.com>
This commit is contained in:
Baptiste Lemoine 2020-01-07 11:11:48 +01:00
parent e8d5b39d02
commit ef47cee872
6 changed files with 167 additions and 35 deletions

View File

@ -20,13 +20,15 @@ const emptyList = ImmutableList();
const mapStateToProps = (state, { params: { accountId }, withReplies = false }) => { const mapStateToProps = (state, { params: { accountId }, withReplies = false }) => {
const path = withReplies ? `${accountId}:with_replies` : accountId; const path = withReplies ? `${accountId}:with_replies` : accountId;
console.log('state.getIn([\'accounts\', accountId])', state.getIn(['accounts', accountId]));
return { return {
isAccount: !!state.getIn(['accounts', accountId]), isAccount : !!state.getIn(['accounts', accountId]),
statusIds: state.getIn(['timelines', `account:${path}`, 'items'], emptyList), account : state.getIn(['accounts', accountId]),
statusIds : state.getIn(['timelines', `account:${path}`, 'items'], emptyList),
featuredStatusIds: withReplies ? ImmutableList() : state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], emptyList), featuredStatusIds: withReplies ? ImmutableList() : state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], emptyList),
isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading']), isLoading : state.getIn(['timelines', `account:${path}`, 'isLoading']),
hasMore: state.getIn(['timelines', `account:${path}`, 'hasMore']), hasMore : state.getIn(['timelines', `account:${path}`, 'hasMore']),
blockedBy: state.getIn(['relationships', accountId, 'blocked_by'], false), blockedBy : state.getIn(['relationships', accountId, 'blocked_by'], false),
}; };
}; };
@ -34,20 +36,20 @@ export default @connect(mapStateToProps)
class AccountTimeline extends ImmutablePureComponent { class AccountTimeline extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params : PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired, dispatch : PropTypes.func.isRequired,
shouldUpdateScroll: PropTypes.func, shouldUpdateScroll: PropTypes.func,
statusIds: ImmutablePropTypes.list, statusIds : ImmutablePropTypes.list,
featuredStatusIds: ImmutablePropTypes.list, featuredStatusIds : ImmutablePropTypes.list,
isLoading: PropTypes.bool, isLoading : PropTypes.bool,
hasMore: PropTypes.bool, hasMore : PropTypes.bool,
withReplies: PropTypes.bool, withReplies : PropTypes.bool,
blockedBy: PropTypes.bool, blockedBy : PropTypes.bool,
isAccount: PropTypes.bool, isAccount : PropTypes.bool,
multiColumn: PropTypes.bool, multiColumn : PropTypes.bool,
}; };
componentWillMount () { componentWillMount() {
const { params: { accountId }, withReplies } = this.props; const { params: { accountId }, withReplies } = this.props;
this.props.dispatch(fetchAccount(accountId)); this.props.dispatch(fetchAccount(accountId));
@ -60,7 +62,7 @@ class AccountTimeline extends ImmutablePureComponent {
this.props.dispatch(expandAccountTimeline(accountId, { withReplies })); this.props.dispatch(expandAccountTimeline(accountId, { withReplies }));
} }
componentWillReceiveProps (nextProps) { componentWillReceiveProps(nextProps) {
if ((nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) || nextProps.withReplies !== this.props.withReplies) { if ((nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) || nextProps.withReplies !== this.props.withReplies) {
this.props.dispatch(fetchAccount(nextProps.params.accountId)); this.props.dispatch(fetchAccount(nextProps.params.accountId));
this.props.dispatch(fetchAccountIdentityProofs(nextProps.params.accountId)); this.props.dispatch(fetchAccountIdentityProofs(nextProps.params.accountId));
@ -74,33 +76,42 @@ class AccountTimeline extends ImmutablePureComponent {
} }
handleLoadMore = maxId => { handleLoadMore = maxId => {
this.props.dispatch(expandAccountTimeline(this.props.params.accountId, { maxId, withReplies: this.props.withReplies })); this.props.dispatch(expandAccountTimeline(this.props.params.accountId, {
} maxId,
withReplies: this.props.withReplies,
}));
};
render () { render() {
const { shouldUpdateScroll, statusIds, featuredStatusIds, isLoading, hasMore, blockedBy, isAccount, multiColumn } = this.props; const { shouldUpdateScroll, statusIds, featuredStatusIds, isLoading, hasMore, blockedBy, isAccount, multiColumn } = this.props;
if (!isAccount) { if (!isAccount) {
return ( return (
<Column> <Column >
<ColumnBackButton multiColumn={multiColumn} /> <ColumnBackButton multiColumn={multiColumn} />
<MissingIndicator /> <MissingIndicator />
</Column> </Column >
); );
} }
if (!statusIds && isLoading) { if (!statusIds && isLoading) {
return ( return (
<Column> <Column >
<LoadingIndicator /> <LoadingIndicator />
</Column> </Column >
); );
} }
const emptyMessage = blockedBy ? <FormattedMessage id='empty_column.account_unavailable' defaultMessage='Profile unavailable' /> : <FormattedMessage id='empty_column.account_timeline' defaultMessage='No toots here!' />; const emptyMessage = blockedBy ? <FormattedMessage
id='empty_column.account_unavailable'
defaultMessage='Profile unavailable'
/> : <FormattedMessage
id='empty_column.account_timeline'
defaultMessage='No toots here!'
/>;
return ( return (
<Column> <Column >
<ColumnBackButton multiColumn={multiColumn} /> <ColumnBackButton multiColumn={multiColumn} />
<StatusList <StatusList
@ -116,7 +127,7 @@ class AccountTimeline extends ImmutablePureComponent {
emptyMessage={emptyMessage} emptyMessage={emptyMessage}
bindToDocument={!multiColumn} bindToDocument={!multiColumn}
/> />
</Column> </Column >
); );
} }

View File

@ -32,6 +32,7 @@ import NavigationPanel from './navigation_panel';
import detectPassiveEvents from 'detect-passive-events'; import detectPassiveEvents from 'detect-passive-events';
import { scrollRight } from '../../../scroll'; import { scrollRight } from '../../../scroll';
import LinkFooter from './link_footer'; import LinkFooter from './link_footer';
import InstantMessaging from './messaging/instantMessaging';
const componentMap = { const componentMap = {
'COMPOSE' : Compose, 'COMPOSE' : Compose,
@ -239,6 +240,7 @@ class ColumnsArea extends ImmutablePureComponent {
</div > </div >
<LinkFooter withHotkeys /> <LinkFooter withHotkeys />
{floatingActionButton} {floatingActionButton}
<InstantMessaging />
</div > </div >
); );
} }

View File

@ -2,19 +2,12 @@ import React from 'react';
import SearchContainer from 'mastodon/features/compose/containers/search_container'; import SearchContainer from 'mastodon/features/compose/containers/search_container';
import ComposeFormContainer from 'mastodon/features/compose/containers/compose_form_container'; import ComposeFormContainer from 'mastodon/features/compose/containers/compose_form_container';
import NavigationContainer from 'mastodon/features/compose/containers/navigation_container'; import NavigationContainer from 'mastodon/features/compose/containers/navigation_container';
import InstantMessaging from './messaging/instantMessaging';
const showIM = true;
const ComposePanel = () => ( const ComposePanel = () => (
<div className='compose-panel'> <div className='compose-panel'>
<SearchContainer openInRoute /> <SearchContainer openInRoute />
<NavigationContainer /> <NavigationContainer />
<ComposeFormContainer singleColumn /> <ComposeFormContainer singleColumn />
{showIM && (
<InstantMessaging />
)}
</div > </div >
); );

View File

@ -124,7 +124,9 @@ class LinkFooter extends React.PureComponent {
</span > </span >
) : ( ) : (
<span <span
onClick={this.changeTheme('dark')} onClick={
this.changeTheme
}
title='set dark' title='set dark'
> >
<i className='fa fa-pencil' /> to dark <i className='fa fa-pencil' /> to dark

View File

@ -0,0 +1,55 @@
import ImmutablePureComponent from 'react-immutable-pure-component';
import PropTypes from 'prop-types';
import React from 'react';
export default class Contact extends ImmutablePureComponent {
static propTypes = {
account: PropTypes.object,
};
static defaultProps = {};
constructor(props) {
super(props);
this.state = {
account: this.props.account,
};
}
openConversationWithAccount = (accountId) => {
dispatchEvent({ type: 'openConversation', target: accountId });
};
render() {
return (
<div
className='contact media'
onClick={this.openConversationWithAccount}
>
<div className='name media-left'>
<div className='avatar image is-32x32'>
<img
className='is-rounded'
src={this.props.account.avatar}
alt='avatar'
/>
</div >
</div >
<div className='media-content'>
<div className='username'>
{this.props.account.username}
</div >
</div >
<div className='media-right'>
<div className='last-seen'>
<i className='fa fa-clock-o' />
</div >
</div >
</div >
);
}
}

View File

@ -0,0 +1,69 @@
export const mockContactList = [{
'key' : '2',
'id' : '2',
'username' : 'demoguy',
'acct' : 'demoguy',
'display_name' : '',
'locked' : false,
'bot' : false,
'discoverable' : null,
'group' : false,
'created_at' : '2019-12-18T11:02:26.494Z',
'note' : '<p></p>',
'url' : 'http://localhost:3000/@demoguy',
'avatar' : 'http://localhost:3000/avatars/original/missing.png',
'avatar_static' : 'http://localhost:3000/avatars/original/missing.png',
'header' : 'http://localhost:3000/headers/original/missing.png',
'header_static' : 'http://localhost:3000/headers/original/missing.png',
'followers_count' : 1,
'following_count' : 1,
'statuses_count' : 8,
'last_status_at' : '2019-12-23T15:20:31.575Z',
'emojis' : [],
'fields' : [],
'display_name_html': 'demoguy',
'note_emojified' : '<p></p>',
}, {
'key' : '1',
'id' : '1',
'username' : 'admin',
'acct' : 'admin',
'display_name' : '',
'locked' : true,
'bot' : false,
'discoverable' : true,
'group' : false,
'created_at' : '2019-12-10T13:19:44.106Z',
'note' : '<p></p>',
'url' : 'http://localhost:3000/@admin',
'avatar' : 'http://localhost:3000/system/accounts/avatars/000/000/001/original/a1497a4af5fd8616.png?1576254102',
'avatar_static' : 'http://localhost:3000/system/accounts/avatars/000/000/001/original/a1497a4af5fd8616.png?1576254102',
'header' : 'http://localhost:3000/system/accounts/headers/000/000/001/original/f13ebf964b09ed26.png?1576254102',
'header_static' : 'http://localhost:3000/system/accounts/headers/000/000/001/original/f13ebf964b09ed26.png?1576254102',
'followers_count' : 4,
'following_count' : 3,
'statuses_count' : 31,
'last_status_at' : '2020-01-04T15:13:32.824Z',
'emojis' : [],
'fields' : [
{
'name' : 'sssss',
'value' : 'muuuuu',
'verified_at' : null,
'name_emojified' : 'sssss',
'value_emojified': 'muuuuu',
'value_plain' : 'muuuuu',
},
],
'display_name_html': 'admin',
'note_emojified' : '<p></p>',
}];
export const mockContactListShort = [{
'key' : '2',
'id' : '2',
'username': 'demoguy',
}, {
'key' : '1',
'id' : '1',
'username': 'admin',
}];