Last active
January 10, 2020 14:55
-
-
Save cms/ad37110123b133426aeacd6f8ce6707c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import _ from "lodash" | |
import React from "react" | |
import moment from "moment" | |
import { connect } from "react-redux" | |
import API from "@Services/Api/profile" | |
import { ApiManager } from "../../api/apiManager" | |
import ParsedText from "react-native-parsed-text" | |
import { NavigationEvents } from "react-navigation" | |
import { DateToWordsFromNow } from "../../helpers/helper" | |
import { ACTIVITY_NOTIFICATION } from "../../api/constants" | |
import EmptyState from "../../components/empty_state/emptyState" | |
import { | |
Feather, | |
MaterialCommunityIcons, | |
AntDesign, | |
Entypo | |
} from "@expo/vector-icons" | |
import { | |
scale, | |
blumerMainColor, | |
blumerSixthColor, | |
MAIN_FONT_FAMILY, | |
blumerSecondaryColor | |
} from "@Styles/style" | |
import { | |
Text, | |
View, | |
Alert, | |
Image, | |
FlatList, | |
Dimensions, | |
TouchableOpacity, | |
ActivityIndicator, | |
DeviceEventEmitter | |
} from "react-native" | |
import { notification } from "expo-haptics" | |
const { height, width } = Dimensions.get("window") | |
function firstCap(string) { | |
return string.charAt(0).toUpperCase() + string.slice(1) | |
} | |
const Thumbnail = ({ onLoad, notification, icon }) => ( | |
<View | |
style={{ | |
borderWidth: 0.5, | |
width: scale(60), | |
height: scale(60), | |
alignItems: "center", | |
borderColor: "#CDCDCD", | |
borderRadius: scale(30), | |
justifyContent: "center", | |
marginRight: 10 | |
}} | |
> | |
<View | |
style={{ | |
width: scale(55), | |
height: scale(55), | |
borderRadius: scale(55 / 2) | |
}} | |
> | |
<Image | |
onLoad={onLoad} | |
source={{ uri: notification.photo }} | |
style={{ | |
width: "100%", | |
height: "100%", | |
borderRadius: scale(55 / 2) | |
}} | |
/> | |
</View> | |
<View | |
style={{ | |
right: 2.5, | |
bottom: -5, | |
width: scale(25), | |
height: scale(25), | |
position: "absolute", | |
alignItems: "center", | |
justifyContent: "center", | |
borderRadius: scale(25 / 2), | |
backgroundColor: blumerSecondaryColor | |
}} | |
> | |
{icon} | |
</View> | |
</View> | |
) | |
const NoNotifications = () => { | |
return ( | |
<View | |
style={{ | |
flex: 1, | |
height: height - scale(150) | |
}} | |
> | |
<View | |
style={{ | |
marginTop: 8, | |
flexDirection: "row", | |
marginHorizontal: 70 | |
}} | |
> | |
<View | |
style={{ | |
flex: 1, | |
width: scale(240), | |
alignItems: "center", | |
justifyContent: "center" | |
}} | |
> | |
<Text | |
style={{ | |
color: "#a9c4fc", | |
textAlign: "center", | |
fontSize: scale(15) | |
}} | |
> | |
Agrega amigos para que comiences a interactuar | |
</Text> | |
</View> | |
<Image | |
style={{ width: scale(43), height: scale(43) }} | |
source={require("@Assets/images/arrow-up.png")} | |
/> | |
</View> | |
<View | |
style={{ | |
flex: 1, | |
alignItems: "center", | |
justifyContent: "center" | |
}} | |
> | |
<Image | |
style={{ width: width * 0.9, height: width * 0.9 }} | |
source={require("@Assets/images/notifications.png")} | |
/> | |
<Text | |
style={{ | |
marginTop: 15, | |
color: "#a9c4fc", | |
fontSize: scale(22) | |
}} | |
> | |
… Aún no tienes notificaciones … | |
</Text> | |
</View> | |
</View> | |
) | |
} | |
const FRIEND_RELATIONSHIP_STATUS = { | |
IS_FRIEND: 1, | |
IN_PROCESS: 2, | |
BLOCKED_USER: 4, | |
IS_NOT_FRIEND: 0, | |
FRIENDSHIP_REQUESTED: 3 | |
} | |
const FRIENDSHIP_STATUS = { | |
DENY: 3, // Reject/Cancel friendship request | |
DELETE: 4, // Delete friend | |
UNBLOCK: 6, // Unblock friend | |
BLOCKED: 5, // Block friend | |
ACCEPTED: 2, // <= Acept friend request | |
REQUESTED: 1 // <= Friendship request | |
} | |
class ProfileNotifications extends React.Component { | |
constructor(props) { | |
super(props) | |
this.state = { | |
loading: false, | |
refreshing: false, | |
notifications: [], | |
loadingFriendshipProcess: false, | |
friendshipStatus: FRIEND_RELATIONSHIP_STATUS.IS_NOT_FRIEND | |
} | |
this.page = 0 | |
this.lastPage = -1 | |
} | |
async componentDidMount() { | |
await this.getNotifications() | |
} | |
async getNotifications() { | |
this.setState({ loading: true }) | |
const res = await ApiManager.getNotifications(this.props.token, this.page) | |
this.setState({ loading: false }) | |
console.log("NOTIFICACIONES:", res) | |
this.lastPage = this.page | |
if (!res.error) { | |
const _notifications = | |
this.page == 0 | |
? res.message.data | |
: [...this.state.notifications, ...res.message.data] | |
let notifications = [] | |
for (let i = 0; i < _notifications.length; i++) { | |
const notification = _notifications[i] | |
if ( | |
_.findIndex(notifications, { | |
id: notification.id, | |
type_notification: notification.type_notification | |
}) == -1 | |
) { | |
notifications.push(notification) | |
} | |
} | |
this.setState({ notifications }) | |
if (res.message.data.length > 0) { | |
this.page++ | |
} | |
} else { | |
Alert.alert( | |
"Atención", | |
"No se pudo obtener el listado de notificaciones." | |
) | |
} | |
} | |
async setNotificationAsRead( | |
postId, | |
typeOfNotification, | |
typeOfNotificationId, | |
ownerProfileId = "", | |
...props | |
) { | |
DeviceEventEmitter.emit("onLoadingEvent", { loading: true }) | |
let notificationAsReadBody = { | |
friendShipId: typeOfNotificationId, | |
notificationId: typeOfNotificationId, | |
typeOfNotification: typeOfNotification | |
} | |
if (typeOfNotification == ACTIVITY_NOTIFICATION.FRIENDSHIP) { | |
delete notificationAsReadBody.notificationId | |
} else { | |
delete notificationAsReadBody.friendShipId | |
} | |
let res = await ApiManager.sendReadStatus( | |
this.props.token, | |
notificationAsReadBody | |
) | |
DeviceEventEmitter.emit("onLoadingEvent", { loading: false }) | |
if (!res.error) { | |
if (typeOfNotification == ACTIVITY_NOTIFICATION.FRIENDSHIP) { | |
this.props.navigation.navigate("PersonProfile", { | |
token: this.props.token, | |
userId: ownerProfileId | |
}) | |
} else { | |
this.props.navigation.navigate("PostDetails", { | |
token: this.props.token, | |
postId: postId | |
}) | |
} | |
} else { | |
Alert.alert( | |
"Atención", | |
"Se ha producido un error, por favor vuelve a intentarlo." | |
) | |
} | |
} | |
onFriendRequestAction = (allow = true, notification_id) => { | |
this.setState({ loadingFriendshipProcess: true }) | |
const { userId } = this.props | |
return API.cancelFriendRequest({ | |
notification: 1, | |
follow_id: userId, | |
status_id: allow ? FRIENDSHIP_STATUS.ACCEPTED : FRIENDSHIP_STATUS.DENY | |
}).then(({ response, rawResponse, error }) => { | |
if ( | |
!error && | |
!response.error && | |
[200, 201].indexOf(rawResponse.status) !== -1 | |
) { | |
return API.notificationFriendRequest({ | |
notification_id | |
}).then(({ error: error2, rawResponse: rawResponse2 }) => { | |
if (!error2 && [200, 201].indexOf(rawResponse2.status) !== -1) { | |
if (allow) { | |
const notifications = _.cloneDeep(this.state.notifications) | |
const _notification = _.find(notifications, { | |
id: notification_id | |
}) | |
if (!!_notification) { | |
_notification.by_read = true | |
} | |
this.setState({ notifications }) | |
} else { | |
this.setState({ | |
notifications: _.filter(({ id }) => id !== notification_id) | |
}) | |
} | |
} else { | |
console.log("Error Al leer la notificacion") | |
} | |
}) | |
} else { | |
this.setState({ loadingFriendshipProcess: false }) | |
Alert.alert( | |
"Lo sentimos", | |
"Ha ocurrido un error intentando procesar su solicitud" | |
) | |
} | |
}) | |
} | |
renderFriendRequestNotification(notificationElement) { | |
return ( | |
<TouchableOpacity | |
style={{ | |
flex: 1, | |
// width: width - 20, | |
padding: 10, | |
marginVertical: 1, | |
alignItems: "center", | |
flexDirection: "row", | |
backgroundColor: "#FFF", | |
justifyContent: "space-between", | |
paddingHorizontal: 20 | |
}} | |
onPress={() => { | |
this.setNotificationAsRead( | |
notificationElement.post_id, | |
notificationElement.type_notification, | |
notificationElement.id, | |
notificationElement.id_profile_owner, | |
notificationElement.by_read | |
) | |
}} | |
activeOpacity={0.9} | |
> | |
<View | |
style={{ | |
flexDirection: "row", | |
backgroundColor: "#FFF" | |
}} | |
> | |
<Thumbnail | |
onLoad={() => {}} | |
notification={notificationElement} | |
icon={<Feather name='user-plus' size={14} color='#FFF' />} | |
/> | |
<View style={{ flex: 1 }}> | |
{this.state.friendshipStatus === | |
FRIEND_RELATIONSHIP_STATUS.IS_FRIEND ? ( | |
<View style={{}}> | |
<Text | |
style={{ | |
color: "#000000", | |
fontSize: scale(13), | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
> | |
{`${_.startCase( | |
_.lowerCase(notificationElement.first_name) | |
)} ${_.startCase( | |
_.lowerCase(notificationElement.last_name) | |
)} y tu`} | |
</Text> | |
<Text | |
style={{ | |
marginTop: 2.5, | |
color: "#808080", | |
fontSize: scale(12), | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
> | |
Ahora son amigos en Blumer! | |
</Text> | |
</View> | |
) : ( | |
<View> | |
<Text | |
style={{ | |
color: "#000000", | |
fontSize: scale(13), | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
> | |
{_.startCase( | |
_.lowerCase( | |
`${notificationElement.first_name} ${notificationElement.last_name}` | |
) | |
)} | |
</Text> | |
<Text | |
style={{ | |
marginTop: 2.5, | |
color: "#808080", | |
fontSize: scale(12), | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
> | |
Te ha enviado una solicitud de amistad. | |
</Text> | |
<View | |
style={{ | |
marginTop: 10, | |
flexDirection: "row" | |
}} | |
> | |
<TouchableOpacity | |
activeOpacity={0.9} | |
onPress={() => | |
this.onFriendRequestAction( | |
true, | |
(notification_id = notificationElement.by_read) | |
) | |
} | |
disabled={this.state.loadingFriendshipProcess} | |
style={{ | |
flex: 1, | |
marginRight: 5, | |
borderRadius: 8, | |
height: scale(25), | |
flexDirection: "row", | |
alignItems: "center", | |
borderColor: "#D1D1D1", | |
justifyContent: "center", | |
backgroundColor: blumerSecondaryColor | |
}} | |
> | |
<Text | |
style={{ | |
color: "#FFF", | |
fontSize: scale(12), | |
textAlign: "center", | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
> | |
Confirmar | |
</Text> | |
{this.state.loadingFriendshipProcess && ( | |
<View | |
style={{ | |
marginLeft: 10 | |
}} | |
> | |
<ActivityIndicator color='#FFF' /> | |
</View> | |
)} | |
</TouchableOpacity> | |
<TouchableOpacity | |
activeOpacity={0.9} | |
onPress={() => | |
this.onFriendRequestAction( | |
false, | |
(notification_id = notificationElement.by_read) | |
) | |
} | |
disabled={this.state.loadingFriendshipProcess} | |
style={{ | |
flex: 1, | |
marginRight: 5, | |
borderRadius: 8, | |
height: scale(25), | |
flexDirection: "row", | |
alignItems: "center", | |
justifyContent: "center", | |
backgroundColor: "#E3E3E3" | |
}} | |
> | |
<Text | |
style={{ | |
color: "#979797", | |
fontSize: scale(12), | |
textAlign: "center", | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
> | |
Eliminar | |
</Text> | |
{this.state.loadingFriendshipProcess && ( | |
<View | |
style={{ | |
marginLeft: 10 | |
}} | |
> | |
<ActivityIndicator color='red' /> | |
</View> | |
)} | |
</TouchableOpacity> | |
</View> | |
</View> | |
)} | |
<Text | |
style={{ | |
marginTop: 10, | |
color: "#808080", | |
fontSize: scale(12), | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
> | |
{firstCap( | |
moment(notificationElement.date) | |
.startOf("hour") | |
.fromNow() | |
)} | |
</Text> | |
</View> | |
{this.state.friendshipStatus === | |
FRIEND_RELATIONSHIP_STATUS.IS_FRIEND ? ( | |
<View | |
style={{ | |
borderRadius: 8, | |
width: scale(65), | |
height: scale(65) | |
}} | |
> | |
<Image | |
resizeMode='cover' | |
source={require("@Assets/images/friend-blumer.png")} | |
style={{ | |
width: "100%", | |
height: "100%", | |
alignSelf: "center", | |
borderRadius: 8 | |
}} | |
/> | |
</View> | |
) : null} | |
</View> | |
</TouchableOpacity> | |
) | |
} | |
renderActivityNotification(notificationElement) { | |
// let message = `${notificationElement.first_name}`; | |
let message = `__name__` | |
if ("listado_actores" in notificationElement) { | |
if (notificationElement.listado_actores.length > 0) { | |
for ( | |
let index = 0; | |
index < notificationElement.listado_actores.length; | |
index++ | |
) { | |
const actor = notificationElement.listado_actores[index] | |
if (index == notificationElement.listado_actores.length - 1) { | |
if (notificationElement.count > 0) { | |
message += `, ${actor} y ${ | |
notificationElement.count > 1 | |
? `otras ${notificationElement.count} personas` | |
: `una persona más` | |
}` | |
} else { | |
message += ` y ${actor}` | |
} | |
} else { | |
message += `, ${actor}` | |
} | |
} | |
} | |
} | |
switch (notificationElement.type_notification) { | |
case ACTIVITY_NOTIFICATION.LIKE: | |
notificationIcon = <AntDesign name='like2' size={15} color='#FFF' /> | |
message += `${notificationElement.listado_actores} Le gusta tu publicación` | |
break | |
case ACTIVITY_NOTIFICATION.COMMENT: | |
notificationIcon = ( | |
<MaterialCommunityIcons | |
name='comment-multiple-outline' | |
size={15} | |
color='#FFF' | |
/> | |
) | |
message += `${notificationElement.listado_actores} Comentó en tu publicación` | |
break | |
case ACTIVITY_NOTIFICATION.SHARED: | |
notificationIcon = <Entypo name='share' size={15} color='#FFF' /> | |
message += `${notificationElement.listado_actores} Compartió tu publicación` | |
break | |
case ACTIVITY_NOTIFICATION.MENTION: | |
notificationIcon = null | |
message += " te ha mencionado en una publicación." | |
break | |
} | |
return ( | |
<TouchableOpacity | |
style={{ | |
padding: 10, | |
marginVertical: 1, | |
flexDirection: "row", | |
backgroundColor: "#FFF", | |
paddingHorizontal: 20 | |
}} | |
onPress={() => { | |
this.setNotificationAsRead( | |
notificationElement.post_id, | |
notificationElement.type_notification, | |
notificationElement.id | |
) | |
}} | |
activeOpacity={0.9} | |
> | |
<Thumbnail | |
onLoad={() => {}} | |
icon={notificationIcon} | |
notification={notificationElement} | |
/> | |
<View style={{ flex: 1 }}> | |
<ParsedText | |
style={{ | |
color: "#808080", | |
fontSize: scale(12), | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
parse={[ | |
{ | |
pattern: /__name__/, | |
onPress: name => {}, | |
renderText: string => | |
`${notificationElement.first_name} ${notificationElement.last_name}`, | |
style: { | |
color: "#000", | |
fontSize: scale(13), | |
fontFamily: MAIN_FONT_FAMILY | |
} | |
} | |
]} | |
> | |
{message} | |
</ParsedText> | |
<Text | |
style={{ | |
marginTop: 10, | |
color: "#808080", | |
fontSize: scale(12), | |
fontFamily: MAIN_FONT_FAMILY | |
}} | |
> | |
{firstCap( | |
moment(notificationElement.date) | |
.startOf("hour") | |
.fromNow() | |
)} | |
</Text> | |
</View> | |
<View | |
style={{ | |
width: scale(65), | |
height: scale(65), | |
backgroundColor: "#F4F4F4F4", | |
borderRadius: 8 | |
}} | |
> | |
<Image | |
resizeMode='cover' | |
source={{ uri: notificationElement.cover }} | |
style={{ | |
width: "100%", | |
height: "100%", | |
alignSelf: "center", | |
borderRadius: 8 | |
}} | |
onLoad={() => | |
this.setState({ ["loadingImage" + notificationElement.id]: true }) | |
} | |
/> | |
</View> | |
</TouchableOpacity> | |
) | |
} | |
_onRefresh = async () => { | |
this.setState({ refreshing: true }) | |
this.page = 0 | |
await this.getNotifications() | |
this.setState({ refreshing: false }) | |
} | |
_handleLoadMore = async () => { | |
if (!this.state.loading && this.lastPage !== this.page) | |
await this.getNotifications() | |
} | |
_renderFooter = () => { | |
if (!this.state.loading || this.lastPage === this.page) return null | |
return ( | |
<View style={{ width: "100%", alignItems: "center", padding: 15 }}> | |
<ActivityIndicator size='large' color={blumerMainColor} /> | |
</View> | |
) | |
} | |
render() { | |
return ( | |
<View style={{ flex: 1, backgroundColor: blumerSixthColor }}> | |
{/* <NavigationEvents onDidFocus={payload => this._onNavigationDidFocus(payload)}/> */} | |
<View style={{ flex: 1 }}> | |
<FlatList | |
keyExtractor={(item, index) => index.toString()} | |
ListEmptyComponent={ | |
this.state.notifications.length == 0 && | |
!this.state.loading && <NoNotifications /> | |
} | |
data={this.state.notifications} | |
onRefresh={this._onRefresh} | |
refreshing={this.state.refreshing} | |
onEndReached={this._handleLoadMore} | |
onEndReachedThreshold={0.8} | |
extraData={this.state} | |
ListFooterComponent={this._renderFooter} | |
renderItem={({ item, index }) => ( | |
<View key={index}> | |
{item.type_notification == ACTIVITY_NOTIFICATION.FRIENDSHIP && | |
this.renderFriendRequestNotification(item)} | |
{item.type_notification != ACTIVITY_NOTIFICATION.FRIENDSHIP && | |
this.renderActivityNotification(item)} | |
</View> | |
)} | |
/> | |
</View> | |
</View> | |
) | |
} | |
} | |
/** | |
* Function to map the global state into component props | |
* | |
* @param {Object} param0 The object global state | |
*/ | |
const mapStateToProps = ({ session }) => ({ | |
token: session.token, | |
userId: session.userId | |
}) | |
export default connect(mapStateToProps)(ProfileNotifications) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment