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 = () => {
@@ -324,6 +326,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 6be5ab8e1..d2e7e9a0a 100644
--- a/app/screens/post_options/post_options.test.js
+++ b/app/screens/post_options/post_options.test.js
@@ -26,6 +26,7 @@ describe('PostOptions', () => {
removePost: jest.fn(),
unflagPost: jest.fn(),
unpinPost: jest.fn(),
+ setUnreadPost: jest.fn(),
};
const post = {
@@ -46,6 +47,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 057487627..a99e0da2e 100644
--- a/assets/base/i18n/en.json
+++ b/assets/base/i18n/en.json
@@ -360,6 +360,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 830ce926c..2020b0fa4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14133,8 +14133,8 @@
"integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A=="
},
"mattermost-redux": {
- "version": "github:mattermost/mattermost-redux#3bb89a5450b94da564d3a286fefb5945a1c3fca8",
- "from": "github:mattermost/mattermost-redux#3bb89a5450b94da564d3a286fefb5945a1c3fca8",
+ "version": "github:mattermost/mattermost-redux#dc5f8c1f30cbc6a25d4304f2923f5b78e674099d",
+ "from": "github:mattermost/mattermost-redux#dc5f8c1f30cbc6a25d4304f2923f5b78e674099d",
"requires": {
"deep-equal": "1.0.1",
"eslint-plugin-header": "3.0.0",
@@ -14147,7 +14147,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",
@@ -17575,8 +17575,8 @@
}
},
"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"
diff --git a/package.json b/package.json
index be2be758d..7ef0ff97c 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#3bb89a5450b94da564d3a286fefb5945a1c3fca8",
+ "mattermost-redux": "github:mattermost/mattermost-redux#dc5f8c1f30cbc6a25d4304f2923f5b78e674099d",
"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 9a92fb941..a7c0e11a1 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',