Skip to content

Commit 2e45013

Browse files
agrawal-dchrisbobbe
authored andcommitted
message: Add feature to view edit history.
Creates a component 'EditHistory' that renders a webview to show the edit history of a message. This webview is non-interactive - the user can select/copy message contents, but can not interact with them - like open links/navigate to narrows etc. Fixes: #4134
1 parent e53b460 commit 2e45013

File tree

5 files changed

+109
-1
lines changed

5 files changed

+109
-1
lines changed

src/message/EditHistory.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/* @flow strict-local */
2+
3+
import React from 'react';
4+
import { View } from 'react-native';
5+
import type { NavigationScreenProp } from 'react-navigation';
6+
import type { Dispatch, Auth, ThemeName, UserOrBot } from '../types';
7+
import SpinningProgress from '../common/SpinningProgress';
8+
import type { MessageSnapshot } from '../api/modelTypes';
9+
import { connect } from '../react-redux';
10+
import { getAuth, getSettings, getAllUsersById } from '../selectors';
11+
import { Screen, ZulipWebView } from '../common';
12+
import { showToast } from '../utils/info';
13+
import * as api from '../api';
14+
import editHistoryHtml from '../webview/html/editHistoryHtml';
15+
16+
type SelectorProps = {|
17+
auth: Auth,
18+
usersById: Map<number, UserOrBot>,
19+
themeName: ThemeName,
20+
|};
21+
22+
type Props = $ReadOnly<{|
23+
navigation: NavigationScreenProp<{ params: {| messageId: number |} }>,
24+
25+
dispatch: Dispatch,
26+
...SelectorProps,
27+
|}>;
28+
29+
type State = $ReadOnly<{|
30+
messageHistory: MessageSnapshot[] | null,
31+
|}>;
32+
33+
class EditHistory extends React.Component<Props, State> {
34+
state = {
35+
messageHistory: null,
36+
};
37+
38+
componentDidMount() {
39+
const { auth, navigation } = this.props;
40+
41+
api
42+
.getMessageHistory(auth, navigation.state.params.messageId)
43+
.then(response => {
44+
this.setState({
45+
messageHistory: response.message_history,
46+
});
47+
})
48+
.catch(err => {
49+
navigation.goBack();
50+
showToast('An error occurred while loading edit history');
51+
});
52+
}
53+
54+
render() {
55+
const { messageHistory } = this.state;
56+
57+
if (messageHistory === null) {
58+
return (
59+
<Screen title="Edit History">
60+
<View style={{ justifyContent: 'center', alignItems: 'center', flex: 1 }}>
61+
<SpinningProgress color="white" size={48} />
62+
</View>
63+
</Screen>
64+
);
65+
}
66+
const { usersById, auth, themeName } = this.props;
67+
68+
return (
69+
<Screen title="Edit History">
70+
<ZulipWebView
71+
html={editHistoryHtml(messageHistory, themeName, usersById, auth)}
72+
onError={(msg: mixed) => {
73+
// eslint-disable-next-line no-console
74+
console.error(msg);
75+
}}
76+
/>
77+
</Screen>
78+
);
79+
}
80+
}
81+
82+
export default connect<SelectorProps, _, _>((state, props) => ({
83+
auth: getAuth(state),
84+
usersById: getAllUsersById(state),
85+
themeName: getSettings(state).theme,
86+
}))(EditHistory);

src/message/messageActionSheet.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { isTopicMuted } from '../utils/message';
2525
import * as api from '../api';
2626
import { showToast } from '../utils/info';
2727
import { doNarrow, deleteOutboxMessage, navigateToEmojiPicker } from '../actions';
28-
import { navigateToMessageReactionScreen } from '../nav/navActions';
28+
import { navigateToMessageReactionScreen, navigateToEditHistory } from '../nav/navActions';
2929
import { pmUiRecipientsFromMessage, streamNameOfStreamMessage } from '../utils/recipient';
3030
import { deleteMessagesForTopic } from '../topics/topicActions';
3131
import * as logging from '../utils/logging';
@@ -44,6 +44,7 @@ type ButtonDescription = {
4444
ownUser: User,
4545
message: Message | Outbox,
4646
subscriptions: Subscription[],
47+
backgroundData: BackgroundData,
4748
dispatch: Dispatch,
4849
_: GetText,
4950
startEditMessage: (editMessage: EditMessage) => void,
@@ -204,6 +205,12 @@ const showReactions = ({ message, dispatch }) => {
204205
showReactions.title = 'See who reacted';
205206
showReactions.errorMessage = 'Failed to show reactions';
206207

208+
const editHistory = ({ message, dispatch }) => {
209+
NavigationService.dispatch(navigateToEditHistory(message.id));
210+
};
211+
editHistory.title = 'Show edit history';
212+
editHistory.errorMessage = 'Failed to show edit history';
213+
207214
const cancel = params => {};
208215
cancel.title = 'Cancel';
209216
cancel.errorMessage = 'Failed to hide menu';
@@ -219,6 +226,7 @@ const allButtonsRaw = {
219226
starMessage,
220227
unstarMessage,
221228
showReactions,
229+
editHistory,
222230

223231
// For headers
224232
unmuteTopic,
@@ -321,6 +329,11 @@ export const constructMessageActionButtons = ({
321329
} else {
322330
buttons.push('starMessage');
323331
}
332+
333+
if (message.last_edit_timestamp !== undefined) {
334+
buttons.push('editHistory');
335+
}
336+
324337
buttons.push('cancel');
325338
return buttons;
326339
};

src/nav/AppNavigator.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import EmojiPickerScreen from '../emoji/EmojiPickerScreen';
4444
import LegalScreen from '../settings/LegalScreen';
4545
import UserStatusScreen from '../user-status/UserStatusScreen';
4646
import SharingScreen from '../sharing/SharingScreen';
47+
import EditHistory from '../message/EditHistory';
4748

4849
export default createStackNavigator(
4950
// $FlowFixMe react-navigation types :-/ -- see a36814e80
@@ -65,6 +66,7 @@ export default createStackNavigator(
6566
},
6667
},
6768
'message-reactions': { screen: MessageReactionList },
69+
'edit-history': { screen: EditHistory },
6870
password: { screen: PasswordAuthScreen },
6971
realm: { screen: RealmScreen },
7072
search: { screen: SearchMessagesScreen },

src/nav/navActions.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ export const navigateToMessageReactionScreen = (
117117
): NavigationAction =>
118118
StackActions.push({ routeName: 'message-reactions', params: { messageId, reactionName } });
119119

120+
export const navigateToEditHistory = (messageId: number): NavigationAction =>
121+
StackActions.push({ routeName: 'edit-history', params: { messageId } });
122+
120123
export const navigateToLegal = (): NavigationAction => StackActions.push({ routeName: 'legal' });
121124

122125
export const navigateToUserStatus = (): NavigationAction =>

static/translations/messages_en.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@
139139
"Share": "Share",
140140
"Star message": "Star message",
141141
"Unstar message": "Unstar message",
142+
"Show edit history": "Show edit history",
143+
"Failed to show edit history": "Failed to show edit history",
144+
"An error occurred while loading edit history": "An error occurred while loading edit history",
142145
"Cancel": "Cancel",
143146
"Message copied": "Message copied",
144147
"Edit message": "Edit message",
@@ -188,6 +191,7 @@
188191
"Please download the image from your browser": "Please download the image from your browser",
189192
"Can not download": "Can not download",
190193
"Download file": "Download file",
194+
"Edit History": "Edit History",
191195
"Update": "Update",
192196
"Save": "Save",
193197
"Pinned": "Pinned",

0 commit comments

Comments
 (0)