Skip to content

Commit

Permalink
Show action sheet on long press of header (#801)
Browse files Browse the repository at this point in the history
* Show action sheet on long press of header

* Rename mutetReducers to muteReducers
  • Loading branch information
kunall17 authored and borisyankov committed Jul 5, 2017
1 parent b53fea7 commit 4815abf
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 74 deletions.
4 changes: 3 additions & 1 deletion src/common/Touchable.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ const background = Platform.Version >= 21 ?

type Props = {
onPress?: () => void | Promise<any>,
onLongPress?: () => void,
style?: StyleObj,
children?: [],
};

export default ({ onPress, style, children }: Props) => (
export default ({ onPress, style, children, onLongPress }: Props) => (
<TouchableNativeFeedback
style={style}
background={background}
onPress={onPress}
onLongPress={onLongPress}
>
<View>
{children}
Expand Down
4 changes: 3 additions & 1 deletion src/common/Touchable.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ import { HIGHLIGHT_COLOR } from '../styles';

type Props = {
onPress?: () => void | Promise<any>,
onLongPress?: () => void,
style?: StyleObj,
children?: [],
};

export default ({ onPress, style, children }: Props) => (
export default ({ onPress, style, children, onLongPress }: Props) => (
<TouchableHighlight
underlayColor={HIGHLIGHT_COLOR}
style={style}
onPress={onPress}
onLongPress={onLongPress}
>
<View>
{children}
Expand Down
41 changes: 29 additions & 12 deletions src/message/MessageList.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { LoadingIndicator } from '../common';
import MessageTyping from '../message/MessageTyping';
import InfiniteScrollView from './InfiniteScrollView';
import renderMessages from './renderMessages';
import { constructActionButtons, executeActionSheetAction } from './messageActionSheet';
import { constructActionButtons, executeActionSheetAction, constructHeaderActionButtons } from './messageActionSheet';

class MessageList extends React.PureComponent {

Expand All @@ -25,22 +25,38 @@ class MessageList extends React.PureComponent {
this.autoScrollToBottom = this.props.caughtUp.newer && nextProps.caughtUp.newer;
}

handleLongPress = (message) => {
const { auth, narrow, subscriptions, mute, flags } = this.props;
const options = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });
const cancelButtonIndex = options.length - 1;
handleHeaderLongPress = (item) => {
const { subscriptions, mute } = this.props;
const options = constructHeaderActionButtons({ item, subscriptions, mute });
const callback = (buttonIndex) => {
executeActionSheetAction({
title: options[buttonIndex],
message: item,
header: true,
...this.props
});
};
this.showActionSheet({ options, cancelButtonIndex: options.length - 1, callback });
}

showActionSheet = ({ options, cancelButtonIndex, callback }) => {
this.props.showActionSheetWithOptions({
options,
cancelButtonIndex,
},
(buttonIndex) => {
executeActionSheetAction({
title: options[buttonIndex],
message,
...this.props
});
}, callback);
}

handleLongPress = (message) => {
const { auth, narrow, subscriptions, mute, flags } = this.props;
const options = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });
const callback = (buttonIndex) => {
executeActionSheetAction({
title: options[buttonIndex],
message,
...this.props
});
};
this.showActionSheet({ options, cancelButtonIndex: options.length - 1, callback });
}

render() {
Expand All @@ -58,6 +74,7 @@ class MessageList extends React.PureComponent {

const messageList = renderMessages({
onLongPress: this.handleLongPress,
onHeaderLongPress: this.handleHeaderLongPress,
...this.props,
});

Expand Down
72 changes: 41 additions & 31 deletions src/message/__tests__/messageActionSheet-test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { constructActionButtons } from '../messageActionSheet';
import { constructActionButtons, constructHeaderActionButtons } from '../messageActionSheet';
import {
streamNarrow,
homeNarrow,
Expand All @@ -15,8 +15,8 @@ describe('constructActionButtons', () => {
};

let message = {};
let subscriptions = [];
let mute = [];
const subscriptions = [];
const mute = [];
const narrow = [];
const flags = {
starred: {
Expand Down Expand Up @@ -90,8 +90,38 @@ describe('constructActionButtons', () => {
expect(streamButtons).toContain('Narrow to conversation');
});

test('show Unmute topic option if topic is muted', () => {
test('show star message option if message is not starred', () => {
message = {
id: 3,
};

const buttons = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });

expect(buttons).toContain('Star Message');
});

test('show unstar message option if message is starred', () => {
message = {
id: 1,
};

const buttons = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });

expect(buttons).toContain('Unstar Message');
});
});


describe('constructHeaderActionButtons', () => {
let subscriptions = [
{ name: 'denmark', in_home_view: true },
{ name: 'donald', in_home_view: false },
];
let mute = [];
let item = {};

test('show Unmute topic option if topic is muted', () => {
item = {
type: 'stream',
display_recipient: 'electron issues',
subject: 'issue #556'
Expand All @@ -100,25 +130,25 @@ describe('constructActionButtons', () => {
'electron issues', 'issue #556'
]];

const buttons = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });
const buttons = constructHeaderActionButtons({ item, subscriptions, mute });

expect(buttons).toContain('Unmute topic');
});

test('show mute topic option if topic is not muted', () => {
message = {
item = {
type: 'stream',
display_recipient: 'electron issues',
subject: 'PR #558'
};

const buttons = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });
const buttons = constructHeaderActionButtons({ item, subscriptions, mute });

expect(buttons).toContain('Mute topic');
});

test('show Unmute stream option if stream is not in home view', () => {
message = {
item = {
type: 'stream',
display_recipient: 'electron issues',
};
Expand All @@ -127,38 +157,18 @@ describe('constructActionButtons', () => {
in_home_view: false,
}];

const buttons = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });
const buttons = constructHeaderActionButtons({ item, subscriptions, mute });

expect(buttons).toContain('Unmute stream');
});

test('show mute stream option if stream is in home view', () => {
message = {
item = {
type: 'stream',
};

const buttons = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });
const buttons = constructHeaderActionButtons({ item, subscriptions, mute });

expect(buttons).toContain('Mute stream');
});

test('show star message option if message is not starred', () => {
message = {
id: 3,
};

const buttons = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });

expect(buttons).toContain('Star Message');
});

test('show unstar message option if message is starred', () => {
message = {
id: 1,
};

const buttons = constructActionButtons({ message, auth, narrow, subscriptions, mute, flags });

expect(buttons).toContain('Unstar Message');
});
});
10 changes: 10 additions & 0 deletions src/message/headers/MessageHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,15 @@ export default class MessageHeader extends React.PureComponent {
narrow: Narrow,
subscriptions: any[],
doNarrow: () => void,
narrow: () => {},
onHeaderLongPress: () => void,
}

onLongPress = () => {
const { item, onHeaderLongPress } = this.props;
onHeaderLongPress(item);
};

render() {
const { item, subscriptions, auth, narrow, doNarrow } = this.props;

Expand All @@ -37,6 +44,7 @@ export default class MessageHeader extends React.PureComponent {
topic={item.subject}
doNarrow={doNarrow}
style={styles.margin}
onLongPress={this.onLongPress}
/>
);
}
Expand All @@ -56,6 +64,7 @@ export default class MessageHeader extends React.PureComponent {
itemId={item.id}
doNarrow={doNarrow}
style={styles.margin}
onLongPress={this.onLongPress}
/>
);
}
Expand All @@ -72,6 +81,7 @@ export default class MessageHeader extends React.PureComponent {
itemId={item.id}
doNarrow={doNarrow}
style={styles.margin}
onLongPress={this.onLongPress}
/>
);
}
Expand Down
5 changes: 3 additions & 2 deletions src/message/headers/PrivateMessageHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default class PrivateMessageHeader extends React.PureComponent {
itemId: number,
recipients: Object[],
doNarrow: () => void,
onLongPress: () => void,
}

performNarrow = () => {
Expand All @@ -45,12 +46,12 @@ export default class PrivateMessageHeader extends React.PureComponent {
}

render() {
const { recipients, style } = this.props;
const { recipients, style, onLongPress } = this.props;
const others = recipients.map(r => r.full_name).sort().join(', ');

return (
<View style={[styles.container, style]}>
<Touchable onPress={this.performNarrow}>
<Touchable onPress={this.performNarrow} onLongPress={onLongPress}>
<View style={styles.header}>
<IconPrivateChat color="white" size={16} style={styles.icon} />
<Text style={styles.private}>
Expand Down
7 changes: 5 additions & 2 deletions src/message/headers/StreamMessageHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export default class StreamMessageHeader extends React.PureComponent {
isMuted: boolean,
isPrivate: boolean,
doNarrow: () => void,
onLongPress: () => void,
}

static contextTypes = {
Expand All @@ -59,13 +60,14 @@ export default class StreamMessageHeader extends React.PureComponent {

render() {
const { styles } = this.context;
const { stream, isPrivate, isMuted, topic, color, itemId, doNarrow, style } = this.props;
const { stream, isPrivate, isMuted, topic, color, itemId,
doNarrow, style, onLongPress } = this.props;
const textColor = foregroundColorFromBackground(color);
const iconType = isPrivate ? 'lock' : 'hashtag';

return (
<View style={[componentStyles.header, style, styles.background]}>
<Touchable onPress={this.performStreamNarrow}>
<Touchable onPress={this.performStreamNarrow} onLongPress={onLongPress}>
<View style={[componentStyles.header, { backgroundColor: color }]}>
<StreamIcon
name={iconType}
Expand All @@ -86,6 +88,7 @@ export default class StreamMessageHeader extends React.PureComponent {
stream={stream}
topic={topic}
doNarrow={doNarrow}
onLongPress={onLongPress}
/>
</View>
);
Expand Down
9 changes: 7 additions & 2 deletions src/message/headers/TopicMessageHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default class TopicMessageHeader extends React.PureComponent {
stream: string,
topic: string,
doNarrow: () => void,
onLongPress: () => void,
}

performTopicNarrow = () => {
Expand All @@ -44,11 +45,15 @@ export default class TopicMessageHeader extends React.PureComponent {

render() {
const { styles } = this.context;
const { topic, style } = this.props;
const { topic, style, onLongPress } = this.props;

return (
<View style={[componentStyles.wrapper, styles.background, style]}>
<Touchable style={componentStyles.touch} onPress={this.performTopicNarrow}>
<Touchable
style={componentStyles.touch}
onPress={this.performTopicNarrow}
onLongPress={onLongPress}
>
<Text
style={[componentStyles.topic, styles.color]}
numberOfLines={1}
Expand Down
Loading

0 comments on commit 4815abf

Please sign in to comment.