diff --git a/app/reducers/views/channel.js b/app/reducers/views/channel.js
index 3ffce2343..f9c771fbb 100644
--- a/app/reducers/views/channel.js
+++ b/app/reducers/views/channel.js
@@ -348,6 +348,11 @@ function lastChannelViewTime(state = {}, action) {
return state;
}
+ case ChannelTypes.POST_UNREAD_SUCCESS: {
+ const data = action.data;
+ return {...state, [data.channelId]: data.lastViewedAt};
+ }
+
default:
return state;
}
diff --git a/app/screens/post_options/__snapshots__/post_options.test.js.snap b/app/screens/post_options/__snapshots__/post_options.test.js.snap
index 7139754cc..596d208c3 100644
--- a/app/screens/post_options/__snapshots__/post_options.test.js.snap
+++ b/app/screens/post_options/__snapshots__/post_options.test.js.snap
@@ -1,192 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`PostOptions should match snapshot, no option for system message to user who doesn't have the permission to delete 1`] = `
-
-
-
-
-
-
-
-
-`;
-
-exports[`PostOptions should match snapshot, showing Delete option only for system message to user who has permission to delete 1`] = `
+
+
+
+
+`;
+
+exports[`PostOptions should match snapshot, showing Delete option only for system message to user who has permission to delete 1`] = `
+
+
+
+
+
+
+
{
- const actions = [
- this.getEditOption(),
- this.getReplyOption(),
- this.getFlagOption(),
- this.getPinOption(),
- this.getAddReactionOption(),
- this.getCopyPermalink(),
- this.getCopyText(),
- this.getDeleteOption(),
- ];
+ getMarkAsUnreadOption = () => {
+ const {post, isLandscape, theme} = this.props;
+ const {formatMessage} = this.context.intl;
- return actions.filter((a) => a !== null);
- };
-
- getOthersPostOptions = () => {
- const actions = [
- this.getReplyOption(),
- this.getFlagOption(),
- this.getAddReactionOption(),
- this.getPinOption(),
- this.getCopyPermalink(),
- this.getCopyText(),
- this.getEditOption(),
- this.getDeleteOption(),
- ];
-
- return actions.filter((a) => a !== null);
+ if (!isSystemMessage(post)) {
+ return (
+
+ );
+ }
+ return null;
};
getPostOptions = () => {
- const {isMyPost} = this.props;
+ const actions = [
+ this.getReplyOption(),
+ this.getAddReactionOption(),
+ this.getMarkAsUnreadOption(),
+ this.getCopyPermalink(),
+ this.getFlagOption(),
+ this.getCopyText(),
+ this.getPinOption(),
+ this.getEditOption(),
+ this.getDeleteOption(),
+ ];
- return isMyPost ? this.getMyPostOptions() : this.getOthersPostOptions();
+ return actions.filter((a) => a !== null);
};
handleAddReaction = () => {
@@ -325,6 +327,15 @@ export default class PostOptions extends PureComponent {
});
};
+ handleMarkUnread = () => {
+ const {actions, post, currentUserId} = this.props;
+
+ this.closeWithAnimation();
+ requestAnimationFrame(() => {
+ actions.setUnreadPost(currentUserId, post.id);
+ });
+ }
+
handlePostDelete = () => {
const {formatMessage} = this.context.intl;
const {actions, post} = this.props;
diff --git a/app/screens/post_options/post_options.test.js b/app/screens/post_options/post_options.test.js
index 56c380d7c..2c7ee6179 100644
--- a/app/screens/post_options/post_options.test.js
+++ b/app/screens/post_options/post_options.test.js
@@ -28,6 +28,7 @@ describe('PostOptions', () => {
unpinPost: jest.fn(),
dismissModal: jest.fn(),
showModal: jest.fn(),
+ setUnreadPost: jest.fn(),
};
const post = {
@@ -48,6 +49,7 @@ describe('PostOptions', () => {
canEditUntil: -1,
channelIsReadOnly: false,
currentTeamUrl: 'http://localhost:8065/team-name',
+ currentUserId: 'user1',
deviceHeight: 600,
hasBeenDeleted: false,
isFlagged: false,
diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json
index 7ed809399..0a0bce869 100644
--- a/assets/base/i18n/en.json
+++ b/assets/base/i18n/en.json
@@ -350,6 +350,7 @@
"mobile.post_info.add_reaction": "Add Reaction",
"mobile.post_info.copy_text": "Copy Text",
"mobile.post_info.flag": "Flag",
+ "mobile.post_info.mark_unread": "Mark post as unread",
"mobile.post_info.pin": "Pin to Channel",
"mobile.post_info.reply": "Reply",
"mobile.post_info.unflag": "Unflag",
diff --git a/assets/base/images/post_menu/bookmark.png b/assets/base/images/post_menu/bookmark.png
new file mode 100755
index 000000000..df28ccf58
Binary files /dev/null and b/assets/base/images/post_menu/bookmark.png differ
diff --git a/assets/base/images/post_menu/bookmark@2x.png b/assets/base/images/post_menu/bookmark@2x.png
new file mode 100755
index 000000000..7f1db3004
Binary files /dev/null and b/assets/base/images/post_menu/bookmark@2x.png differ
diff --git a/assets/base/images/post_menu/bookmark@3x.png b/assets/base/images/post_menu/bookmark@3x.png
new file mode 100755
index 000000000..805a4c668
Binary files /dev/null and b/assets/base/images/post_menu/bookmark@3x.png differ
diff --git a/package-lock.json b/package-lock.json
index 26fd97ed5..b6f3a1027 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14039,8 +14039,8 @@
"integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A=="
},
"mattermost-redux": {
- "version": "github:mattermost/mattermost-redux#6ea71dc77808041d7e953ac15cbc12e1c483ac69",
- "from": "github:mattermost/mattermost-redux#6ea71dc77808041d7e953ac15cbc12e1c483ac69",
+ "version": "github:mattermost/mattermost-redux#6bdeb3fefe2c3e812247920d7a58262d927c4eea",
+ "from": "github:mattermost/mattermost-redux#6bdeb3fefe2c3e812247920d7a58262d927c4eea",
"requires": {
"deep-equal": "1.0.1",
"eslint-plugin-header": "3.0.0",
@@ -14053,7 +14053,7 @@
"redux": "4.0.4",
"redux-action-buffer": "1.2.0",
"redux-batched-actions": "0.4.1",
- "redux-offline": "git+https://github.com/enahum/redux-offline.git#4bd85e7e3b279a2b11fb4d587808d583d2b5e7b5",
+ "redux-offline": "git+https://github.com/enahum/redux-offline.git#885024de96b6ec73650c340c8928066585c413df",
"redux-persist": "4.9.1",
"redux-thunk": "2.3.0",
"reselect": "4.0.0",
@@ -17434,10 +17434,18 @@
}
},
"redux-offline": {
- "version": "git+https://github.com/enahum/redux-offline.git#4bd85e7e3b279a2b11fb4d587808d583d2b5e7b5",
- "from": "git+https://github.com/enahum/redux-offline.git#4bd85e7e3b279a2b11fb4d587808d583d2b5e7b5",
+ "version": "git+https://github.com/enahum/redux-offline.git#885024de96b6ec73650c340c8928066585c413df",
+ "from": "git+https://github.com/enahum/redux-offline.git#885024de96b6ec73650c340c8928066585c413df",
"requires": {
+ "@react-native-community/netinfo": "^4.1.3",
"redux-persist": "^4.5.0"
+ },
+ "dependencies": {
+ "@react-native-community/netinfo": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-4.2.1.tgz",
+ "integrity": "sha512-kAnmYp8vXpZToPw8rgE7uO+MqmqHSR9VEDPkuZT0DnFMBJmIXCSD2NLAD28HGKVY/kujVWCknC/FuVWr5/A3uA=="
+ }
}
},
"redux-persist": {
diff --git a/package.json b/package.json
index ece3d5d3a..40a8a7b65 100644
--- a/package.json
+++ b/package.json
@@ -21,7 +21,7 @@
"intl": "1.2.5",
"jail-monkey": "2.2.0",
"jsc-android": "241213.2.0",
- "mattermost-redux": "github:mattermost/mattermost-redux#6ea71dc77808041d7e953ac15cbc12e1c483ac69",
+ "mattermost-redux": "github:mattermost/mattermost-redux#6bdeb3fefe2c3e812247920d7a58262d927c4eea",
"mime-db": "1.40.0",
"moment-timezone": "0.5.25",
"prop-types": "15.7.2",
diff --git a/packager/moduleNames.js b/packager/moduleNames.js
index aa799b51d..7d6583ee9 100644
--- a/packager/moduleNames.js
+++ b/packager/moduleNames.js
@@ -303,6 +303,7 @@ module.exports = [
'dist/assets/images/icons/word.png',
'dist/assets/images/post_header/flag.png',
'dist/assets/images/post_header/pin.png',
+ 'dist/assets/images/post_header/bookmark.png',
'dist/assets/images/profile.jpg',
'dist/assets/images/status/away.png',
'dist/assets/images/status/dnd.png',