import React, { useContext, useEffect, useState } from "react";
import { Text, View } from '../components/Themed';
import {Pressable, StyleSheet, Touchable} from "react-native";
import global, { width } from "../constants/global";
import Colors from "../constants/Colors";
import { getIncidentEmoji } from "../constants/emojis";
import { TouchableOpacity } from "react-native";
import { Badge, BadgeText, Button, ButtonIcon, ButtonText, get, HStack, Icon, Menu, MenuIcon, MenuItem, MenuItemLabel, Popover, set } from "@gluestack-ui/themed";
import { Ionicons, MaterialCommunityIcons, Octicons } from "@expo/vector-icons";
import { router, useNavigation } from "expo-router";
import { deleteEntity, dislikeEntity, getEntityCounts, hasLiked, likeEntity, unlikeEntity } from "./backend";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import { FeedContext } from "./feedContext";
import { SettingsContext, useSettings } from "./appSettingsContext";
import { UserFeedContext } from "./userFeedContext";
//Loads relative time plugin
dayjs.extend(relativeTime);
type PostListViewProps = {
post:any;
}
export function formatnum(num:number){
if(num>=1000000000){
return (num/1000000000).toFixed(1) + "B";
}else if(num>=1000000){
return (num/1000000).toFixed(1) + "M";
}else if(num>=1000){
return (num/1000).toFixed(1) + "K";
}else{
return num;
}
}
const PostListView = React.memo((props: PostListViewProps) => {
const route = useNavigation().getState().routes[0].name
const [feed, setFeed] = route=="home"?React.useContext(FeedContext) as any:React.useContext(UserFeedContext) as any;
const index = feed.findIndex((item:any) => item.eid == props.post.item.eid);
const [menuSelected, setMenuSelected] = useState(new Set([]) as any);
const appSettings = useSettings();
let post = props.post.item;
let emoji = getIncidentEmoji(post.alias, '6', true);
useEffect(() => {
hasLiked(post.eid).then((res) => {
let t =[...feed]
t[index].liked = res.sentiment == 'like';
t[index].disliked = res.sentiment == 'dislike';
// console.log("Liked: ", t[index].liked, " Disliked: ", t[index].disliked);
setFeed(t);
}).catch((err) => {
console.log("Error checking if liked: ", err);
})
getEntityCounts(post.eid).then((res) => {
let t = [...feed];
t[index].likeCount = res.likes;
t[index].commentCount = res.comments;
setFeed(t);
}).catch((err) => {
console.log("Error getting entity counts: ", err);
})
},[])
return(
<Pressable
style={styles.container}
onPress={()=>{
global.passedPost = post;
if(route=="home"){
router.navigate({
pathname: '/(home)/post',
});
}else{
router.navigate({
pathname:'/(profile)/post'
})
}
}}
>
{/* Header */}
<View style={styles.header}>
{/* Emoji view */}
<View style={[styles.emojiContainer, {backgroundColor:Colors.map["class"+emoji[1] as keyof typeof Colors.map]}]}>
<Text adjustsFontSizeToFit numberOfLines={1} style={styles.emoji}>{emoji[0]}</Text>
</View>
{/* User alias with divider */}
<View style={styles.headertitlecontainer}>
{feed[index].isOwner&& appSettings.settings.showOP &&<Badge
size="sm"
variant="outline"
backgroundColor={Colors.dark.alertBackground}
borderColor={Colors.dark.redPastelClicked}
borderRadius={5}
width={55}
>
<BadgeText textAlign="center" width='100%' color={Colors.dark.text}>Yours</BadgeText>
</Badge>}
<Text adjustsFontSizeToFit numberOfLines={1} style={styles.title}>{post.alias}</Text>
{/* <View style={[styles.separator, {marginTop:0, }]}/> */}
</View>
<Menu
placement="bottom right"
selectionMode="single"
shadowColor="transparent"
maxWidth={width*0.3}
backgroundColor={Colors.dark.background}
selectedKeys={menuSelected}
onSelectionChange={(keys) => {
setMenuSelected(keys)
//@ts-ignore
switch (keys.currentKey){
case "Report":
console.log("Report clicked");
break;
case "Delete":
deleteEntity(post.eid).then((res) => {
console.log("Post deleted: ", res);
let t = [...feed];
t = t.filter((item: any) => item.eid != post.eid);
console.log(t.length)
setFeed(t);
}).catch((err) => {
console.log("Error deleting post: ", err);
})
break;
default:
console.log("Default clicked");
}
}}
closeOnSelect={true}
trigger={({ ...triggerProps }) => {
return (
<Pressable
{...triggerProps}
style={styles.menu}
>
<MaterialCommunityIcons style={styles.menuIcon} name="dots-vertical" size={24} color={Colors.dark.text} />
</Pressable>
)
}}
>
{!feed[index].isOwner&&<MenuItem key="Report" textValue="Report" $active-bgColor={Colors.dark.backgroundModal} >
<MaterialCommunityIcons name="flag" size={24} color={Colors.dark.redBright} />
<MenuItemLabel size="sm" color={Colors.dark.text}>Report</MenuItemLabel>
</MenuItem>}
{feed[index].isOwner&&<MenuItem key="Delete" textValue="Delete" $active-bgColor={Colors.dark.backgroundModal} >
<MaterialCommunityIcons name="delete" size={24} color={Colors.dark.redBright} />
<MenuItemLabel size="sm" color={Colors.dark.text}>Delete</MenuItemLabel>
</MenuItem>}
</Menu>
</View>
{/* Main text body */}
<View style={styles.content}>
<Text adjustsFontSizeToFit minimumFontScale={0.6} style={styles.body}>{post.body}</Text>
</View>
{/* Footer */}
<View style={styles.footer}>
<View style={styles.time}>
<Text adjustsFontSizeToFit numberOfLines={1} style={[styles.footerText, styles.timetext]}>{dayjs(post.created_at).fromNow()}</Text>
</View>
{/* Comments */}
<TouchableOpacity
style={styles.iconcontainer}
activeOpacity={0.7}
onPress={()=>{
global.passedPost = post;
router.push({
pathname: '/(home)/post',
});
}}
>
<MaterialCommunityIcons name="comment" size={33} color={Colors.dark.text} style={styles.commenticon} />
<Text adjustsFontSizeToFit numberOfLines={1} style={[styles.footerText, styles.icontext]}>{formatnum(feed[index].commentCount)}</Text>
</TouchableOpacity>
{/* Likes */}
<View style={[styles.iconcontainer,{flex:1, maxWidth:'35%', marginRight:'5%', columnGap:5}]}>
{!feed[index].isOwner && <TouchableOpacity
style={[styles.iconcontainer]}
activeOpacity={0.7}
disabled={feed[index].isOwner}
onPress={()=>{
let tf = [...feed];
tf[index].disliked = !tf[index].disliked;
setFeed(tf);
if(tf[index].disliked){
let t = [...feed];
if(tf[index].liked){
t[index].likeCount = t[index].likeCount-2;
}else{
t[index].likeCount = t[index].likeCount-1;
}
t[index].liked = false;
setFeed(t);
dislikeEntity(post.eid).catch((err) => {
let t = [...feed];
if(tf[index].liked){
t[index].likeCount = t[index].likeCount+2;
} else{
t[index].likeCount = t[index].likeCount+1;
}
t[index].disliked = true;
setFeed(t);
console.log("Error disliking post: ", err);
})
}else{
let t = [...feed];
t[index].likeCount = t[index].likeCount+1;
setFeed(t);
unlikeEntity(post.eid).catch((err) => {
let t = [...feed];
t[index].likeCount = t[index].likeCount-1;
t[index].disliked = true;
setFeed(t);
console.log("Error unliking post: ", err);
})
}
}}
>
{!feed[index].disliked &&!feed[index].isOwner && <MaterialCommunityIcons name="chevron-down-box-outline" size={33} color={Colors.dark.redBright} style={styles.likeicon} />}
{feed[index].disliked &&!feed[index].isOwner && <MaterialCommunityIcons name="chevron-down-box" size={33} color={Colors.dark.redBright} style={styles.likeicon} />}
</TouchableOpacity>}
{feed[index].isOwner && <Ionicons name="chevron-expand-sharp" size={33} color={Colors.dark.redBright} style={styles.likeicon} />}
<Text adjustsFontSizeToFit numberOfLines={1} minimumFontScale={0.7} style={[styles.footerText, styles.icontext, {flex:1}]}>{formatnum(feed[index].likeCount)}</Text>
{!feed[index].isOwner && <TouchableOpacity
style={[styles.iconcontainer]}
activeOpacity={0.7}
onPress={()=>{
let tf = [...feed];
tf[index].liked = !tf[index].liked;
setFeed(tf);
if(tf[index].liked){
let t = [...feed];
if(tf[index].disliked){
t[index].likeCount = t[index].likeCount+2;
}else{
t[index].likeCount = t[index].likeCount+1;
}
t[index].disliked = false;
setFeed(t);
likeEntity(post.eid).catch((err) => {
let t = [...feed];
if(tf[index].disliked){
t[index].likeCount = t[index].likeCount-2;
}else{
t[index].likeCount = t[index].likeCount-1;
}
t[index].liked = false;
setFeed(t);
console.log("Error liking post: ", err);
})
}else{
let t = [...feed];
t[index].likeCount = t[index].likeCount-1;
setFeed(t);
unlikeEntity(post.eid).catch((err) => {
let t = [...feed];
t[index].likeCount = t[index].likeCount+1;
t[index].liked = true;
setFeed(t);
console.log("Error unliking post: ", err);
})
}
}}
>
{!feed[index].liked &&!feed[index].isOwner && <MaterialCommunityIcons name="chevron-up-box-outline" size={33} color={Colors.dark.redBright} style={styles.likeicon} />}
{feed[index].liked &&!feed[index].isOwner && <MaterialCommunityIcons name="chevron-up-box" size={33} color={Colors.dark.redBright} style={styles.likeicon} />}
</TouchableOpacity>}
</View>
</View>
{/* Divider between posts */}
<View style={[styles.separator, {alignSelf:'center', width:global.width, height:1}]} />
</Pressable>
)
})
const styles =StyleSheet.create({
container:{
flex:1,
width: global.width,
minHeight: global.height*0.32,
borderColor: Colors.dark.tabBg,
borderWidth: 2,
flexDirection: 'column',
alignItems: 'center',
padding:0,
},
content:{
backgroundColor: Colors.dark.tabBg,
flexDirection: 'column',
width:'100%',
flex:1,
borderRadius: 10,
overflow: 'hidden',
padding:1
},
header:{
backgroundColor: Colors.dark.tabBg,
flexDirection: 'row',
width: '100%',
alignItems: 'center',
columnGap: 10,
padding: 10,
flex:1,
borderRadius: 10,
height: global.height*.1,
maxHeight: global.height*.1,
},
menu:{
backgroundColor: Colors.dark.tabBg,
},
menuIcon:{
width:'100%',
},
title:{
fontSize: 25,
fontWeight: 'bold',
color: Colors.dark.cyan,
backgroundColor: Colors.dark.tabBg,
textAlignVertical:'bottom',
},
emojiContainer:{
justifyContent: 'center',
alignItems: 'center',
height: global.height*.08,
width: global.height*.08,
borderWidth:5,
borderColor:Colors.dark.backgroundProfile,
borderRadius: 10,
alignSelf:"flex-start",
},
emoji:{
fontSize: 40,
},
separator: {
height: 2,
// width: '80%',
alignSelf: "flex-start",
justifyContent: 'flex-start',
marginBottom:5,
backgroundColor: Colors.dark.darkText,
borderRadius: 10,
marginTop: 5,
},
footerdivide:{
alignSelf: 'center',
height:1,
backgroundColor: Colors.dark.darkText,
},
headertitlecontainer:{
flexDirection: 'column',
rowGap: 5,
width: global.width*0.9-global.height*.1-global.width*0.08,
backgroundColor: Colors.dark.tabBg,
height: global.height*.08,
justifyContent: 'center',
},
body:{
fontSize: 20,
fontWeight: 'bold',
color: Colors.dark.text,
textAlign: 'center',
backgroundColor: Colors.dark.tabBg,
width:global.width*0.9,
alignSelf:'center',
marginVertical:10,
},
footer:{
backgroundColor: Colors.dark.tabBg,
width: width,
height: global.height*0.08,
bottom:0,
flexDirection: 'row',
paddingHorizontal:10,
paddingBottom:0,
flex:1,
alignSelf:'center',
justifyContent:'space-between',
},
footerText:{
fontSize: 12,
fontWeight: 'bold',
color: Colors.dark.text,
alignSelf:'flex-start',
backgroundColor: Colors.dark.tabBg,
textAlignVertical:'bottom',
},
time:{
flexDirection: 'column',
rowGap: 2,
width: '26%',
height: '100%',
justifyContent: 'center',
backgroundColor: Colors.dark.tabBg,
borderRadius: 10,
marginBottom: 10,
},
timetext:{
textAlign:'center',
paddingLeft: 5,
justifyContent:'center',
alignSelf:'center',
},
likeicon:{
alignSelf:'center',
},
commenticon:{
alignSelf:'center',
transform: 'scaleX(-1)',
},
iconcontainer:{
flexDirection: 'row',
width: '26%',
height: '100%',
justifyContent: 'center',
backgroundColor: Colors.dark.tabBg,
// marginLeft: 10,
},
icontext:{
fontSize: 20,
textAlign:'center',
alignSelf:'center',
justifyContent:'center',
flex:1,
}
})
export default PostListView;