[NEW] Read receipt (#975)
* switching to ubountu * added read Recipt functionality to the app fix: #542 * placed the check icon on the end of timestamp * removed linting errors * updating snapshots * done requested changes * removed width scrollView * done required changes * fixed linting errors * added migrations * resolved conflicts and done requested changes * undone uneesasary changes * adding migrations * done requested changes * Add stories and fix some issues
This commit is contained in:
parent
467a2d4002
commit
d68eb01b82
|
@ -9216,6 +9216,612 @@ exports[`Storyshots Message list 1`] = `
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"fontSize": 20,
|
||||||
|
"fontWeight": "300",
|
||||||
|
"marginLeft": 10,
|
||||||
|
"marginTop": 30,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"marginBottom": 0,
|
||||||
|
"marginTop": 30,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Message with read receipt
|
||||||
|
</Text>
|
||||||
|
<View
|
||||||
|
accessible={true}
|
||||||
|
isTVSelectable={true}
|
||||||
|
onResponderGrant={[Function]}
|
||||||
|
onResponderMove={[Function]}
|
||||||
|
onResponderRelease={[Function]}
|
||||||
|
onResponderTerminate={[Function]}
|
||||||
|
onResponderTerminationRequest={[Function]}
|
||||||
|
onStartShouldSetResponder={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"flexDirection": "column",
|
||||||
|
"paddingHorizontal": 14,
|
||||||
|
"paddingVertical": 4,
|
||||||
|
"width": "100%",
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"borderRadius": 4,
|
||||||
|
"height": 36,
|
||||||
|
"width": 36,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"marginTop": 4,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"overflow": "hidden",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"borderRadius": 4,
|
||||||
|
"height": 36,
|
||||||
|
"width": 36,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FastImageView
|
||||||
|
resizeMode="cover"
|
||||||
|
source={
|
||||||
|
Object {
|
||||||
|
"priority": "high",
|
||||||
|
"uri": "https://open.rocket.chat/avatar/diego.mello?format=png&width=50&height=50&rc_token=79q6lH40W4ZRGLOshDiDiVlQaCc4f_lU9HNdHLAzuHz&rc_uid=y8bd77ptZswPj3EW8",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"bottom": 0,
|
||||||
|
"left": 0,
|
||||||
|
"position": "absolute",
|
||||||
|
"right": 0,
|
||||||
|
"top": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"flex": 1,
|
||||||
|
"marginLeft": 46,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"marginLeft": 10,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"flex": 1,
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"flex": 1,
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
numberOfLines={1}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"color": "#2F343D",
|
||||||
|
"fontFamily": "System",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontWeight": "500",
|
||||||
|
"lineHeight": 22,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
diego.mello
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"color": "#9ca2a8",
|
||||||
|
"fontFamily": "System",
|
||||||
|
"fontSize": 12,
|
||||||
|
"fontWeight": "300",
|
||||||
|
"lineHeight": 22,
|
||||||
|
"paddingLeft": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
10:00 AM
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={Object {}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
numberOfLines={0}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "flex-start",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"flexWrap": "wrap",
|
||||||
|
"justifyContent": "flex-start",
|
||||||
|
"marginBottom": 0,
|
||||||
|
"marginTop": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"color": "#2F343D",
|
||||||
|
"fontFamily": "System",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontWeight": "400",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text>
|
||||||
|
I’m fine!
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
accessible={true}
|
||||||
|
isTVSelectable={true}
|
||||||
|
onResponderGrant={[Function]}
|
||||||
|
onResponderMove={[Function]}
|
||||||
|
onResponderRelease={[Function]}
|
||||||
|
onResponderTerminate={[Function]}
|
||||||
|
onResponderTerminationRequest={[Function]}
|
||||||
|
onStartShouldSetResponder={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"flexDirection": "column",
|
||||||
|
"paddingHorizontal": 14,
|
||||||
|
"paddingVertical": 4,
|
||||||
|
"width": "100%",
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"flex": 1,
|
||||||
|
"marginLeft": 46,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={Object {}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
numberOfLines={0}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "flex-start",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"flexWrap": "wrap",
|
||||||
|
"justifyContent": "flex-start",
|
||||||
|
"marginBottom": 0,
|
||||||
|
"marginTop": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"color": "#2F343D",
|
||||||
|
"fontFamily": "System",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontWeight": "400",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text>
|
||||||
|
I’m fine!
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
accessible={true}
|
||||||
|
isTVSelectable={true}
|
||||||
|
onResponderGrant={[Function]}
|
||||||
|
onResponderMove={[Function]}
|
||||||
|
onResponderRelease={[Function]}
|
||||||
|
onResponderTerminate={[Function]}
|
||||||
|
onResponderTerminationRequest={[Function]}
|
||||||
|
onStartShouldSetResponder={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"flexDirection": "column",
|
||||||
|
"paddingHorizontal": 14,
|
||||||
|
"paddingVertical": 4,
|
||||||
|
"width": "100%",
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"borderRadius": 4,
|
||||||
|
"height": 36,
|
||||||
|
"width": 36,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"marginTop": 4,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"overflow": "hidden",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"borderRadius": 4,
|
||||||
|
"height": 36,
|
||||||
|
"width": 36,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FastImageView
|
||||||
|
resizeMode="cover"
|
||||||
|
source={
|
||||||
|
Object {
|
||||||
|
"priority": "high",
|
||||||
|
"uri": "https://open.rocket.chat/avatar/diego.mello?format=png&width=50&height=50&rc_token=79q6lH40W4ZRGLOshDiDiVlQaCc4f_lU9HNdHLAzuHz&rc_uid=y8bd77ptZswPj3EW8",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"bottom": 0,
|
||||||
|
"left": 0,
|
||||||
|
"position": "absolute",
|
||||||
|
"right": 0,
|
||||||
|
"top": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"flex": 1,
|
||||||
|
"marginLeft": 46,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"marginLeft": 10,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"flex": 1,
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "center",
|
||||||
|
"flex": 1,
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
numberOfLines={1}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"color": "#2F343D",
|
||||||
|
"fontFamily": "System",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontWeight": "500",
|
||||||
|
"lineHeight": 22,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
diego.mello
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"color": "#9ca2a8",
|
||||||
|
"fontFamily": "System",
|
||||||
|
"fontSize": 12,
|
||||||
|
"fontWeight": "300",
|
||||||
|
"lineHeight": 22,
|
||||||
|
"paddingLeft": 10,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
10:00 AM
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
style={Object {}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
numberOfLines={0}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "flex-start",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"flexWrap": "wrap",
|
||||||
|
"justifyContent": "flex-start",
|
||||||
|
"marginBottom": 0,
|
||||||
|
"marginTop": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"color": "#2F343D",
|
||||||
|
"fontFamily": "System",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontWeight": "400",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text>
|
||||||
|
I’m fine!
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text
|
||||||
|
allowFontScaling={false}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#1d74f5",
|
||||||
|
"fontSize": 15,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"lineHeight": 20,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"fontFamily": "custom",
|
||||||
|
"fontStyle": "normal",
|
||||||
|
"fontWeight": "normal",
|
||||||
|
},
|
||||||
|
Object {},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
accessible={true}
|
||||||
|
isTVSelectable={true}
|
||||||
|
onResponderGrant={[Function]}
|
||||||
|
onResponderMove={[Function]}
|
||||||
|
onResponderRelease={[Function]}
|
||||||
|
onResponderTerminate={[Function]}
|
||||||
|
onResponderTerminationRequest={[Function]}
|
||||||
|
onStartShouldSetResponder={[Function]}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"opacity": 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"flexDirection": "column",
|
||||||
|
"paddingHorizontal": 14,
|
||||||
|
"paddingVertical": 4,
|
||||||
|
"width": "100%",
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"flexDirection": "row",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"flex": 1,
|
||||||
|
"marginLeft": 46,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
style={Object {}}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
numberOfLines={0}
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"alignItems": "flex-start",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"flexWrap": "wrap",
|
||||||
|
"justifyContent": "flex-start",
|
||||||
|
"marginBottom": 0,
|
||||||
|
"marginTop": 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"backgroundColor": "transparent",
|
||||||
|
"color": "#2F343D",
|
||||||
|
"fontFamily": "System",
|
||||||
|
"fontSize": 16,
|
||||||
|
"fontWeight": "400",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text>
|
||||||
|
I’m fine!
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<Text
|
||||||
|
allowFontScaling={false}
|
||||||
|
style={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"color": "#1d74f5",
|
||||||
|
"fontSize": 15,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"lineHeight": 20,
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"fontFamily": "custom",
|
||||||
|
"fontStyle": "normal",
|
||||||
|
"fontWeight": "normal",
|
||||||
|
},
|
||||||
|
Object {},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
<Text
|
<Text
|
||||||
style={
|
style={
|
||||||
Array [
|
Array [
|
||||||
|
|
|
@ -59,6 +59,12 @@ export default {
|
||||||
Assets_favicon_512: {
|
Assets_favicon_512: {
|
||||||
type: null
|
type: null
|
||||||
},
|
},
|
||||||
|
Message_Read_Receipt_Enabled: {
|
||||||
|
type: 'valueAsBoolean'
|
||||||
|
},
|
||||||
|
Message_Read_Receipt_Store_Users: {
|
||||||
|
type: 'valueAsBoolean'
|
||||||
|
},
|
||||||
Threads_enabled: {
|
Threads_enabled: {
|
||||||
type: null
|
type: null
|
||||||
},
|
},
|
||||||
|
|
|
@ -17,6 +17,7 @@ import { vibrate } from '../utils/vibration';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import I18n from '../i18n';
|
import I18n from '../i18n';
|
||||||
import log from '../utils/log';
|
import log from '../utils/log';
|
||||||
|
import Navigation from '../lib/Navigation';
|
||||||
|
|
||||||
@connect(
|
@connect(
|
||||||
state => ({
|
state => ({
|
||||||
|
@ -26,7 +27,8 @@ import log from '../utils/log';
|
||||||
Message_AllowEditing: state.settings.Message_AllowEditing,
|
Message_AllowEditing: state.settings.Message_AllowEditing,
|
||||||
Message_AllowEditing_BlockEditInMinutes: state.settings.Message_AllowEditing_BlockEditInMinutes,
|
Message_AllowEditing_BlockEditInMinutes: state.settings.Message_AllowEditing_BlockEditInMinutes,
|
||||||
Message_AllowPinning: state.settings.Message_AllowPinning,
|
Message_AllowPinning: state.settings.Message_AllowPinning,
|
||||||
Message_AllowStarring: state.settings.Message_AllowStarring
|
Message_AllowStarring: state.settings.Message_AllowStarring,
|
||||||
|
Message_Read_Receipt_Store_Users: state.settings.Message_Read_Receipt_Store_Users
|
||||||
}),
|
}),
|
||||||
dispatch => ({
|
dispatch => ({
|
||||||
actionsHide: () => dispatch(actionsHideAction()),
|
actionsHide: () => dispatch(actionsHideAction()),
|
||||||
|
@ -56,7 +58,8 @@ export default class MessageActions extends React.Component {
|
||||||
Message_AllowEditing: PropTypes.bool,
|
Message_AllowEditing: PropTypes.bool,
|
||||||
Message_AllowEditing_BlockEditInMinutes: PropTypes.number,
|
Message_AllowEditing_BlockEditInMinutes: PropTypes.number,
|
||||||
Message_AllowPinning: PropTypes.bool,
|
Message_AllowPinning: PropTypes.bool,
|
||||||
Message_AllowStarring: PropTypes.bool
|
Message_AllowStarring: PropTypes.bool,
|
||||||
|
Message_Read_Receipt_Store_Users: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -64,7 +67,7 @@ export default class MessageActions extends React.Component {
|
||||||
this.handleActionPress = this.handleActionPress.bind(this);
|
this.handleActionPress = this.handleActionPress.bind(this);
|
||||||
this.setPermissions();
|
this.setPermissions();
|
||||||
|
|
||||||
const { Message_AllowStarring, Message_AllowPinning } = this.props;
|
const { Message_AllowStarring, Message_AllowPinning, Message_Read_Receipt_Store_Users } = this.props;
|
||||||
|
|
||||||
// Cancel
|
// Cancel
|
||||||
this.options = [I18n.t('Cancel')];
|
this.options = [I18n.t('Cancel')];
|
||||||
|
@ -118,6 +121,12 @@ export default class MessageActions extends React.Component {
|
||||||
this.REACTION_INDEX = this.options.length - 1;
|
this.REACTION_INDEX = this.options.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read Receipts
|
||||||
|
if (Message_Read_Receipt_Store_Users) {
|
||||||
|
this.options.push(I18n.t('Read_Receipt'));
|
||||||
|
this.READ_RECEIPT_INDEX = this.options.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Report
|
// Report
|
||||||
this.options.push(I18n.t('Report'));
|
this.options.push(I18n.t('Report'));
|
||||||
this.REPORT_INDEX = this.options.length - 1;
|
this.REPORT_INDEX = this.options.length - 1;
|
||||||
|
@ -302,6 +311,11 @@ export default class MessageActions extends React.Component {
|
||||||
toggleReactionPicker(actionMessage);
|
toggleReactionPicker(actionMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleReadReceipt = () => {
|
||||||
|
const { actionMessage } = this.props;
|
||||||
|
Navigation.navigate('ReadReceiptsView', { messageId: actionMessage._id });
|
||||||
|
}
|
||||||
|
|
||||||
handleReport = async() => {
|
handleReport = async() => {
|
||||||
const { actionMessage } = this.props;
|
const { actionMessage } = this.props;
|
||||||
try {
|
try {
|
||||||
|
@ -348,6 +362,9 @@ export default class MessageActions extends React.Component {
|
||||||
case this.DELETE_INDEX:
|
case this.DELETE_INDEX:
|
||||||
this.handleDelete();
|
this.handleDelete();
|
||||||
break;
|
break;
|
||||||
|
case this.READ_RECEIPT_INDEX:
|
||||||
|
this.handleReadReceipt();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import Reactions from './Reactions';
|
||||||
import Broadcast from './Broadcast';
|
import Broadcast from './Broadcast';
|
||||||
import Discussion from './Discussion';
|
import Discussion from './Discussion';
|
||||||
import Content from './Content';
|
import Content from './Content';
|
||||||
|
import ReadReceipt from './ReadReceipt';
|
||||||
|
|
||||||
const MessageInner = React.memo((props) => {
|
const MessageInner = React.memo((props) => {
|
||||||
if (props.type === 'discussion-created') {
|
if (props.type === 'discussion-created') {
|
||||||
|
@ -72,6 +73,10 @@ const Message = React.memo((props) => {
|
||||||
>
|
>
|
||||||
<MessageInner {...props} />
|
<MessageInner {...props} />
|
||||||
</View>
|
</View>
|
||||||
|
<ReadReceipt
|
||||||
|
isReadReceiptEnabled={props.isReadReceiptEnabled}
|
||||||
|
unread={props.unread}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
@ -119,7 +124,9 @@ Message.propTypes = {
|
||||||
hasError: PropTypes.bool,
|
hasError: PropTypes.bool,
|
||||||
style: PropTypes.any,
|
style: PropTypes.any,
|
||||||
onLongPress: PropTypes.func,
|
onLongPress: PropTypes.func,
|
||||||
onPress: PropTypes.func
|
onPress: PropTypes.func,
|
||||||
|
isReadReceiptEnabled: PropTypes.bool,
|
||||||
|
unread: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
MessageInner.propTypes = {
|
MessageInner.propTypes = {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import { COLOR_PRIMARY } from '../../constants/colors';
|
||||||
|
import { CustomIcon } from '../../lib/Icons';
|
||||||
|
import styles from './styles';
|
||||||
|
|
||||||
|
const ReadReceipt = React.memo(({ isReadReceiptEnabled, unread }) => {
|
||||||
|
if (isReadReceiptEnabled && !unread && unread !== null) {
|
||||||
|
return <CustomIcon name='check' color={COLOR_PRIMARY} size={15} style={styles.readReceipt} />;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
ReadReceipt.displayName = 'MessageReadReceipt';
|
||||||
|
|
||||||
|
ReadReceipt.propTypes = {
|
||||||
|
isReadReceiptEnabled: PropTypes.bool,
|
||||||
|
unread: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReadReceipt;
|
|
@ -24,6 +24,7 @@ export default class MessageContainer extends React.Component {
|
||||||
_updatedAt: PropTypes.instanceOf(Date),
|
_updatedAt: PropTypes.instanceOf(Date),
|
||||||
baseUrl: PropTypes.string,
|
baseUrl: PropTypes.string,
|
||||||
Message_GroupingPeriod: PropTypes.number,
|
Message_GroupingPeriod: PropTypes.number,
|
||||||
|
isReadReceiptEnabled: PropTypes.bool,
|
||||||
useRealName: PropTypes.bool,
|
useRealName: PropTypes.bool,
|
||||||
useMarkdown: PropTypes.bool,
|
useMarkdown: PropTypes.bool,
|
||||||
status: PropTypes.number,
|
status: PropTypes.number,
|
||||||
|
@ -57,6 +58,9 @@ export default class MessageContainer extends React.Component {
|
||||||
if (item.tmsg !== nextProps.item.tmsg) {
|
if (item.tmsg !== nextProps.item.tmsg) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (item.unread !== nextProps.item.unread) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return _updatedAt.toISOString() !== nextProps._updatedAt.toISOString();
|
return _updatedAt.toISOString() !== nextProps._updatedAt.toISOString();
|
||||||
}
|
}
|
||||||
|
@ -187,10 +191,10 @@ export default class MessageContainer extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
item, user, style, archived, baseUrl, useRealName, broadcast, fetchThreadName, customThreadTimeFormat, onOpenFileModal, timeFormat, useMarkdown
|
item, user, style, archived, baseUrl, useRealName, broadcast, fetchThreadName, customThreadTimeFormat, onOpenFileModal, timeFormat, useMarkdown, isReadReceiptEnabled
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const {
|
const {
|
||||||
_id, msg, ts, attachments, urls, reactions, t, avatar, u, alias, editedBy, role, drid, dcount, dlm, tmid, tcount, tlm, tmsg, mentions, channels
|
_id, msg, ts, attachments, urls, reactions, t, avatar, u, alias, editedBy, role, drid, dcount, dlm, tmid, tcount, tlm, tmsg, mentions, channels, unread
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -213,6 +217,8 @@ export default class MessageContainer extends React.Component {
|
||||||
broadcast={broadcast}
|
broadcast={broadcast}
|
||||||
baseUrl={baseUrl}
|
baseUrl={baseUrl}
|
||||||
useRealName={useRealName}
|
useRealName={useRealName}
|
||||||
|
isReadReceiptEnabled={isReadReceiptEnabled}
|
||||||
|
unread={unread}
|
||||||
role={role}
|
role={role}
|
||||||
drid={drid}
|
drid={drid}
|
||||||
dcount={dcount}
|
dcount={dcount}
|
||||||
|
|
|
@ -234,5 +234,8 @@ export default StyleSheet.create({
|
||||||
flex: 1,
|
flex: 1,
|
||||||
color: COLOR_PRIMARY,
|
color: COLOR_PRIMARY,
|
||||||
...sharedStyles.textRegular
|
...sharedStyles.textRegular
|
||||||
|
},
|
||||||
|
readReceipt: {
|
||||||
|
lineHeight: 20
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -233,6 +233,7 @@ export default {
|
||||||
No_Message: 'No Message',
|
No_Message: 'No Message',
|
||||||
No_messages_yet: 'No messages yet',
|
No_messages_yet: 'No messages yet',
|
||||||
No_Reactions: 'No Reactions',
|
No_Reactions: 'No Reactions',
|
||||||
|
No_Read_Receipts: 'No Read Receipts',
|
||||||
Not_logged: 'Not logged',
|
Not_logged: 'Not logged',
|
||||||
Nothing_to_save: 'Nothing to save!',
|
Nothing_to_save: 'Nothing to save!',
|
||||||
Notify_active_in_this_room: 'Notify active users in this room',
|
Notify_active_in_this_room: 'Notify active users in this room',
|
||||||
|
@ -265,6 +266,7 @@ export default {
|
||||||
Reactions: 'Reactions',
|
Reactions: 'Reactions',
|
||||||
Read_Only_Channel: 'Read Only Channel',
|
Read_Only_Channel: 'Read Only Channel',
|
||||||
Read_Only: 'Read Only',
|
Read_Only: 'Read Only',
|
||||||
|
Read_Receipt: 'Read Receipt',
|
||||||
Register: 'Register',
|
Register: 'Register',
|
||||||
Repeat_Password: 'Repeat Password',
|
Repeat_Password: 'Repeat Password',
|
||||||
Replied_on: 'Replied on:',
|
Replied_on: 'Replied on:',
|
||||||
|
|
|
@ -266,6 +266,7 @@ export default {
|
||||||
Read_Only_Channel: 'Canal Somente Leitura',
|
Read_Only_Channel: 'Canal Somente Leitura',
|
||||||
Read_Only: 'Somente Leitura',
|
Read_Only: 'Somente Leitura',
|
||||||
Register: 'Registrar',
|
Register: 'Registrar',
|
||||||
|
Read_Receipt: 'Lida por',
|
||||||
Repeat_Password: 'Repetir Senha',
|
Repeat_Password: 'Repetir Senha',
|
||||||
Replied_on: 'Respondido em:',
|
Replied_on: 'Respondido em:',
|
||||||
replies: 'respostas',
|
replies: 'respostas',
|
||||||
|
|
|
@ -29,6 +29,7 @@ import RoomInfoView from './views/RoomInfoView';
|
||||||
import RoomInfoEditView from './views/RoomInfoEditView';
|
import RoomInfoEditView from './views/RoomInfoEditView';
|
||||||
import RoomMembersView from './views/RoomMembersView';
|
import RoomMembersView from './views/RoomMembersView';
|
||||||
import SearchMessagesView from './views/SearchMessagesView';
|
import SearchMessagesView from './views/SearchMessagesView';
|
||||||
|
import ReadReceiptsView from './views/ReadReceiptView';
|
||||||
import ThreadMessagesView from './views/ThreadMessagesView';
|
import ThreadMessagesView from './views/ThreadMessagesView';
|
||||||
import MessagesView from './views/MessagesView';
|
import MessagesView from './views/MessagesView';
|
||||||
import SelectedUsersView from './views/SelectedUsersView';
|
import SelectedUsersView from './views/SelectedUsersView';
|
||||||
|
@ -114,6 +115,7 @@ const ChatsStack = createStackNavigator({
|
||||||
SelectedUsersView,
|
SelectedUsersView,
|
||||||
ThreadMessagesView,
|
ThreadMessagesView,
|
||||||
MessagesView,
|
MessagesView,
|
||||||
|
ReadReceiptsView,
|
||||||
DirectoryView
|
DirectoryView
|
||||||
}, {
|
}, {
|
||||||
defaultNavigationOptions: defaultHeader
|
defaultNavigationOptions: defaultHeader
|
||||||
|
|
|
@ -26,6 +26,7 @@ export default (msg) => {
|
||||||
|
|
||||||
msg = normalizeAttachments(msg);
|
msg = normalizeAttachments(msg);
|
||||||
msg.reactions = msg.reactions || [];
|
msg.reactions = msg.reactions || [];
|
||||||
|
msg.unread = msg.unread || false;
|
||||||
// TODO: api problems
|
// TODO: api problems
|
||||||
// if (Array.isArray(msg.reactions)) {
|
// if (Array.isArray(msg.reactions)) {
|
||||||
// msg.reactions = msg.reactions.map((value, key) => ({ emoji: key, usernames: value.usernames.map(username => ({ value: username })) }));
|
// msg.reactions = msg.reactions.map((value, key) => ({ emoji: key, usernames: value.usernames.map(username => ({ value: username })) }));
|
||||||
|
|
|
@ -197,7 +197,8 @@ const messagesSchema = {
|
||||||
tlm: { type: 'date', optional: true },
|
tlm: { type: 'date', optional: true },
|
||||||
replies: 'string[]',
|
replies: 'string[]',
|
||||||
mentions: { type: 'list', objectType: 'users' },
|
mentions: { type: 'list', objectType: 'users' },
|
||||||
channels: { type: 'list', objectType: 'rooms' }
|
channels: { type: 'list', objectType: 'rooms' },
|
||||||
|
unread: { type: 'bool', optional: true }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -415,7 +416,7 @@ class DB {
|
||||||
return this.databases.activeDB = new Realm({
|
return this.databases.activeDB = new Realm({
|
||||||
path: `${ path }.realm`,
|
path: `${ path }.realm`,
|
||||||
schema,
|
schema,
|
||||||
schemaVersion: 11,
|
schemaVersion: 12,
|
||||||
migration: (oldRealm, newRealm) => {
|
migration: (oldRealm, newRealm) => {
|
||||||
if (oldRealm.schemaVersion >= 3 && newRealm.schemaVersion <= 11) {
|
if (oldRealm.schemaVersion >= 3 && newRealm.schemaVersion <= 11) {
|
||||||
const newSubs = newRealm.objects('subscriptions');
|
const newSubs = newRealm.objects('subscriptions');
|
||||||
|
|
|
@ -771,6 +771,12 @@ const RocketChat = {
|
||||||
sort: { ts: -1 }
|
sort: { ts: -1 }
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getReadReceipts(messageId) {
|
||||||
|
return this.sdk.get('chat.getMessageReadReceipts', {
|
||||||
|
messageId
|
||||||
|
});
|
||||||
|
},
|
||||||
searchMessages(roomId, searchText) {
|
searchMessages(roomId, searchText) {
|
||||||
// RC 0.60.0
|
// RC 0.60.0
|
||||||
return this.sdk.get('chat.search', {
|
return this.sdk.get('chat.search', {
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { FlatList, View, Text } from 'react-native';
|
||||||
|
import { SafeAreaView } from 'react-navigation';
|
||||||
|
import equal from 'deep-equal';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import Avatar from '../../containers/Avatar';
|
||||||
|
import styles from './styles';
|
||||||
|
import RCActivityIndicator from '../../containers/ActivityIndicator';
|
||||||
|
import I18n from '../../i18n';
|
||||||
|
import RocketChat from '../../lib/rocketchat';
|
||||||
|
import StatusBar from '../../containers/StatusBar';
|
||||||
|
|
||||||
|
@connect(state => ({
|
||||||
|
Message_TimeFormat: state.settings.Message_TimeFormat,
|
||||||
|
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
|
||||||
|
userId: state.login.user && state.login.user.id,
|
||||||
|
token: state.login.user && state.login.user.token
|
||||||
|
}))
|
||||||
|
export default class ReadReceiptsView extends React.Component {
|
||||||
|
static navigationOptions = {
|
||||||
|
title: I18n.t('Read_Receipt')
|
||||||
|
}
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
navigation: PropTypes.object,
|
||||||
|
Message_TimeFormat: PropTypes.string,
|
||||||
|
baseUrl: PropTypes.string,
|
||||||
|
userId: PropTypes.string,
|
||||||
|
token: PropTypes.string
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.messageId = props.navigation.getParam('messageId');
|
||||||
|
this.state = {
|
||||||
|
loading: false,
|
||||||
|
receipts: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
const { loading, receipts } = this.state;
|
||||||
|
if (nextState.loading !== loading) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!equal(nextState.receipts, receipts)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
load = async() => {
|
||||||
|
const { loading } = this.state;
|
||||||
|
if (loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ loading: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await RocketChat.getReadReceipts(this.messageId);
|
||||||
|
if (result.success) {
|
||||||
|
this.setState({
|
||||||
|
receipts: result.receipts,
|
||||||
|
loading: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({ loading: false });
|
||||||
|
console.log('err_fetch_read_receipts', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderEmpty = () => (
|
||||||
|
<View style={styles.listEmptyContainer} testID='read-receipt-view'>
|
||||||
|
<Text>{I18n.t('No_Read_Receipts')}</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
|
||||||
|
renderItem = ({ item }) => {
|
||||||
|
const {
|
||||||
|
Message_TimeFormat, userId, baseUrl, token
|
||||||
|
} = this.props;
|
||||||
|
const time = moment(item.ts).format(Message_TimeFormat);
|
||||||
|
return (
|
||||||
|
<View style={styles.itemContainer}>
|
||||||
|
<Avatar
|
||||||
|
text={item.user.username}
|
||||||
|
size={40}
|
||||||
|
baseUrl={baseUrl}
|
||||||
|
userId={userId}
|
||||||
|
token={token}
|
||||||
|
/>
|
||||||
|
<View style={styles.infoContainer}>
|
||||||
|
<View style={styles.item}>
|
||||||
|
<Text style={styles.name}>
|
||||||
|
{item.user.name}
|
||||||
|
</Text>
|
||||||
|
<Text>
|
||||||
|
{time}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<Text>
|
||||||
|
{`@${ item.user.username }`}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSeparator = () => <View style={styles.separator} />;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { receipts, loading } = this.state;
|
||||||
|
|
||||||
|
if (!loading && receipts.length === 0) {
|
||||||
|
return this.renderEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={styles.container} testID='read-receipt-view' forceInset={{ bottom: 'always' }}>
|
||||||
|
<StatusBar />
|
||||||
|
<View>
|
||||||
|
{loading
|
||||||
|
? <RCActivityIndicator />
|
||||||
|
: (
|
||||||
|
<FlatList
|
||||||
|
data={receipts}
|
||||||
|
renderItem={this.renderItem}
|
||||||
|
ItemSeparatorComponent={this.renderSeparator}
|
||||||
|
style={styles.list}
|
||||||
|
keyExtractor={item => item._id}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
import { COLOR_SEPARATOR, COLOR_WHITE, COLOR_BACKGROUND_CONTAINER } from '../../constants/colors';
|
||||||
|
import sharedStyles from '../Styles';
|
||||||
|
|
||||||
|
export default StyleSheet.create({
|
||||||
|
listEmptyContainer: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: COLOR_BACKGROUND_CONTAINER
|
||||||
|
},
|
||||||
|
item: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between'
|
||||||
|
},
|
||||||
|
separator: {
|
||||||
|
height: StyleSheet.hairlineWidth,
|
||||||
|
backgroundColor: COLOR_SEPARATOR
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
...sharedStyles.textColorTitle,
|
||||||
|
fontSize: 17
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
flex: 1,
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
...sharedStyles.textColorDescription,
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
infoContainer: {
|
||||||
|
flex: 1,
|
||||||
|
marginLeft: 10
|
||||||
|
},
|
||||||
|
itemContainer: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
|
padding: 10,
|
||||||
|
backgroundColor: COLOR_WHITE
|
||||||
|
},
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
backgroundColor: COLOR_BACKGROUND_CONTAINER
|
||||||
|
},
|
||||||
|
list: {
|
||||||
|
...sharedStyles.separatorVertical,
|
||||||
|
marginVertical: 10
|
||||||
|
}
|
||||||
|
});
|
|
@ -60,7 +60,8 @@ import { Toast } from '../../utils/info';
|
||||||
Message_GroupingPeriod: state.settings.Message_GroupingPeriod,
|
Message_GroupingPeriod: state.settings.Message_GroupingPeriod,
|
||||||
Message_TimeFormat: state.settings.Message_TimeFormat,
|
Message_TimeFormat: state.settings.Message_TimeFormat,
|
||||||
useMarkdown: state.markdown.useMarkdown,
|
useMarkdown: state.markdown.useMarkdown,
|
||||||
baseUrl: state.settings.baseUrl || state.server ? state.server.server : ''
|
baseUrl: state.settings.baseUrl || state.server ? state.server.server : '',
|
||||||
|
Message_Read_Receipt_Enabled: state.settings.Message_Read_Receipt_Enabled
|
||||||
}), dispatch => ({
|
}), dispatch => ({
|
||||||
editCancel: () => dispatch(editCancelAction()),
|
editCancel: () => dispatch(editCancelAction()),
|
||||||
replyCancel: () => dispatch(replyCancelAction()),
|
replyCancel: () => dispatch(replyCancelAction()),
|
||||||
|
@ -116,6 +117,7 @@ export default class RoomView extends React.Component {
|
||||||
isAuthenticated: PropTypes.bool,
|
isAuthenticated: PropTypes.bool,
|
||||||
Message_GroupingPeriod: PropTypes.number,
|
Message_GroupingPeriod: PropTypes.number,
|
||||||
Message_TimeFormat: PropTypes.string,
|
Message_TimeFormat: PropTypes.string,
|
||||||
|
Message_Read_Receipt_Enabled: PropTypes.bool,
|
||||||
editing: PropTypes.bool,
|
editing: PropTypes.bool,
|
||||||
replying: PropTypes.bool,
|
replying: PropTypes.bool,
|
||||||
baseUrl: PropTypes.string,
|
baseUrl: PropTypes.string,
|
||||||
|
@ -499,7 +501,7 @@ export default class RoomView extends React.Component {
|
||||||
renderItem = (item, previousItem) => {
|
renderItem = (item, previousItem) => {
|
||||||
const { room, lastOpen } = this.state;
|
const { room, lastOpen } = this.state;
|
||||||
const {
|
const {
|
||||||
user, Message_GroupingPeriod, Message_TimeFormat, useRealName, baseUrl, useMarkdown
|
user, Message_GroupingPeriod, Message_TimeFormat, useRealName, baseUrl, useMarkdown, Message_Read_Receipt_Enabled
|
||||||
} = this.props;
|
} = this.props;
|
||||||
let dateSeparator = null;
|
let dateSeparator = null;
|
||||||
let showUnreadSeparator = false;
|
let showUnreadSeparator = false;
|
||||||
|
@ -541,6 +543,7 @@ export default class RoomView extends React.Component {
|
||||||
timeFormat={Message_TimeFormat}
|
timeFormat={Message_TimeFormat}
|
||||||
useRealName={useRealName}
|
useRealName={useRealName}
|
||||||
useMarkdown={useMarkdown}
|
useMarkdown={useMarkdown}
|
||||||
|
isReadReceiptEnabled={Message_Read_Receipt_Enabled}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -311,6 +311,30 @@ export default (
|
||||||
}]}
|
}]}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Separator title='Message with read receipt' />
|
||||||
|
<Message
|
||||||
|
msg="I'm fine!"
|
||||||
|
isReadReceiptEnabled
|
||||||
|
unread
|
||||||
|
/>
|
||||||
|
<Message
|
||||||
|
msg="I'm fine!"
|
||||||
|
isReadReceiptEnabled
|
||||||
|
unread
|
||||||
|
isHeader={false}
|
||||||
|
/>
|
||||||
|
<Message
|
||||||
|
msg="I'm fine!"
|
||||||
|
isReadReceiptEnabled
|
||||||
|
read
|
||||||
|
/>
|
||||||
|
<Message
|
||||||
|
msg="I'm fine!"
|
||||||
|
isReadReceiptEnabled
|
||||||
|
read
|
||||||
|
isHeader={false}
|
||||||
|
/>
|
||||||
|
|
||||||
<Separator title='Message with thread' />
|
<Separator title='Message with thread' />
|
||||||
<Message
|
<Message
|
||||||
msg='How are you?'
|
msg='How are you?'
|
||||||
|
|
Loading…
Reference in New Issue