|
@@ -5,18 +5,22 @@
|
|
* <dev@clicknpush.ca>, January 2022
|
|
* <dev@clicknpush.ca>, January 2022
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+import React from "react"
|
|
import { FontAwesome } from "@expo/vector-icons"
|
|
import { FontAwesome } from "@expo/vector-icons"
|
|
import { format, parseISO } from "date-fns"
|
|
import { format, parseISO } from "date-fns"
|
|
-import React from "react"
|
|
|
|
-import { TouchableOpacity, View, Text } from "react-native"
|
|
|
|
-import { LMComment } from "../../../../data/comments"
|
|
|
|
|
|
+import { TouchableOpacity, View, Text, StyleSheet, ImageSourcePropType } from "react-native"
|
|
import { useAuth } from "../../../../data/Auth/AuthContext"
|
|
import { useAuth } from "../../../../data/Auth/AuthContext"
|
|
import { Report } from "./Report"
|
|
import { Report } from "./Report"
|
|
|
|
+import { useReportComment, LMComment, useGetLandmark } from "../../../../data/comments"
|
|
|
|
+import ViewShot, { captureRef } from "react-native-view-shot"
|
|
|
|
+import { Svg, Image as ImageSVG } from "react-native-svg"
|
|
|
|
+import IndoorFloor from "../../IndoorFloor"
|
|
|
|
+import { lmTypes } from "../../../../utils/GlobalUtils"
|
|
|
|
|
|
/**
|
|
/**
|
|
* Props for the {@link Comment} component.
|
|
* Props for the {@link Comment} component.
|
|
*/
|
|
*/
|
|
- export interface CommentProps {
|
|
|
|
|
|
+export interface CommentProps {
|
|
/**
|
|
/**
|
|
* The [comment]{@link LMComment} object being displayed by the {@link Comment} component.
|
|
* The [comment]{@link LMComment} object being displayed by the {@link Comment} component.
|
|
*/
|
|
*/
|
|
@@ -28,36 +32,94 @@ import { Report } from "./Report"
|
|
focusComment: (id: string) => void
|
|
focusComment: (id: string) => void
|
|
startEditingComment: (comment: LMComment) => void
|
|
startEditingComment: (comment: LMComment) => void
|
|
deleteComment: (id: string) => void
|
|
deleteComment: (id: string) => void
|
|
|
|
+ uri: String
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
* Component that displays a {@link LMComment} object in a clean format.
|
|
* Component that displays a {@link LMComment} object in a clean format.
|
|
* @component
|
|
* @component
|
|
*/
|
|
*/
|
|
- export const CommentView: React.FC<CommentProps> = ({comment, selected, focusComment: selectComment, startEditingComment: startEditingComment, deleteComment}) => {
|
|
|
|
- const {userId} = useAuth()
|
|
|
|
|
|
+export const CommentView: React.FC<CommentProps> = ({ comment, selected, focusComment: selectComment, startEditingComment: startEditingComment, deleteComment, uri }) => {
|
|
|
|
+ const { userId } = useAuth()
|
|
|
|
+ const getLandmarkMutation = useGetLandmark(comment.landmark)
|
|
|
|
+ const landmark = getLandmarkMutation.data.landmark
|
|
|
|
+ const reportCommentMutation = useReportComment()
|
|
|
|
+
|
|
|
|
+ const capture: any = React.createRef();
|
|
|
|
+ const imgWidth = 346
|
|
|
|
+ const imgHeight = 448
|
|
|
|
+ const imageDim = 25
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Calls the {@linkcode reportComment} mutation from the {@link useReportComment} hook.
|
|
|
|
+ */
|
|
|
|
+ const reportComment = async (comment, reasons, extraComments) => {
|
|
|
|
+ if (landmark.floor !== null) { // Indoor landmark screenshot
|
|
|
|
+ const uri = await captureRef(capture, {
|
|
|
|
+ format: "jpg",
|
|
|
|
+ quality: 1,
|
|
|
|
+ result: 'base64'
|
|
|
|
+ })
|
|
|
|
+ comment['indoorLmLocImg'] = uri
|
|
|
|
+ }
|
|
|
|
+ else { // Outdoor landmark screenshot
|
|
|
|
+ console.log('outdoor comment reported')
|
|
|
|
+ comment['indoorLmLocImg'] = uri
|
|
|
|
+ }
|
|
|
|
+ comment['reasons'] = reasons
|
|
|
|
+ comment['isLandmark'] = false
|
|
|
|
+ comment['extraComments'] = extraComments
|
|
|
|
+ comment['landmarkInfo'] = landmark
|
|
|
|
+
|
|
|
|
+ await reportCommentMutation.mutateAsync(comment);
|
|
|
|
+ }
|
|
|
|
|
|
return (
|
|
return (
|
|
- <TouchableOpacity style={[{paddingHorizontal: 10}, selected ? {backgroundColor: '#E8E8E8'}: null]} onPress={() => selectComment(comment.id)}>
|
|
|
|
- <View style={{paddingTop: 10, flexDirection: 'row', justifyContent: 'space-between'}}>
|
|
|
|
- <Text style={{fontWeight: 'bold'}}>{comment.poster_name}:</Text>
|
|
|
|
- <Text style={{fontSize: 12, color: 'gray'}}>{format(parseISO(comment.timestamp.toString()), "MMMM do, yyyy h:mma")}</Text>
|
|
|
|
|
|
+ <TouchableOpacity style={[{ paddingHorizontal: 10 }, selected ? { backgroundColor: '#E8E8E8' } : null]} onPress={() => selectComment(comment.id)}>
|
|
|
|
+ <View style={{ paddingTop: 10, flexDirection: 'row', justifyContent: 'space-between' }}>
|
|
|
|
+ <Text style={{ fontWeight: 'bold' }}>{comment.poster_name}:</Text>
|
|
|
|
+ <Text style={{ fontSize: 12, color: 'gray' }}>{format(parseISO(comment.timestamp.toString()), "MMMM do, yyyy h:mma")}</Text>
|
|
</View>
|
|
</View>
|
|
- <View style={{marginVertical: 10}}>
|
|
|
|
- <Text style={{paddingBottom: 10}} >{comment.content}</Text>
|
|
|
|
- <View style={{flexDirection: 'row', alignSelf: 'flex-end'}}>
|
|
|
|
- {comment.edited ? <Text style={{color: 'grey', alignSelf: 'flex-end'}}>Edited</Text> : null}
|
|
|
|
|
|
+ <View style={{ marginVertical: 10 }}>
|
|
|
|
+ <Text style={{ paddingBottom: 10 }} >{comment.content}</Text>
|
|
|
|
+ <View style={{ flexDirection: 'row', alignSelf: 'flex-end' }}>
|
|
|
|
+ {comment.edited ? <Text style={{ color: 'grey', alignSelf: 'flex-end' }}>Edited</Text> : null}
|
|
{selected ?
|
|
{selected ?
|
|
comment.poster == userId ?
|
|
comment.poster == userId ?
|
|
- <View style={{marginTop: 10, flexDirection: 'row', alignSelf: 'flex-end'}}>
|
|
|
|
- <FontAwesome size={25} name="edit" style={{paddingTop: 1, marginLeft: 20}} onPress={() => startEditingComment(comment)}/>
|
|
|
|
- <FontAwesome color="red" size={25} style={{marginLeft: 15}} name="trash" onPress={() => deleteComment(comment.id)}/>
|
|
|
|
|
|
+ <View style={{ marginTop: 10, flexDirection: 'row', alignSelf: 'flex-end' }}>
|
|
|
|
+ <FontAwesome size={25} name="edit" style={{ paddingTop: 1, marginLeft: 20 }} onPress={() => startEditingComment(comment)} />
|
|
|
|
+ <FontAwesome color="red" size={25} style={{ marginLeft: 15 }} name="trash" onPress={() => deleteComment(comment.id)} />
|
|
</View> :
|
|
</View> :
|
|
- <View style={{marginTop: 10, flexDirection: 'row', alignSelf: 'flex-end'}}>
|
|
|
|
- <Report isLandmark={false} comment = {comment}/>
|
|
|
|
|
|
+ <View style={{ marginTop: 10, flexDirection: 'row', alignSelf: 'flex-end' }}>
|
|
|
|
+ {userId ? // Only show the report button if the user is logged in
|
|
|
|
+ <Report isLandmark={false} comment={comment} reportComment={reportComment} />
|
|
|
|
+ : null}
|
|
</View>
|
|
</View>
|
|
: null}
|
|
: null}
|
|
</View>
|
|
</View>
|
|
|
|
+ <ViewShot style={{ width: imgWidth + 20, height: imgHeight + 20, position: 'absolute', right: -2000 }} ref={capture} >
|
|
|
|
+ {landmark == null || landmark.floor == null || landmark.landmark_type == null ? <></> :
|
|
|
|
+ <View style={styles.container}>
|
|
|
|
+ <Svg>
|
|
|
|
+ <IndoorFloor floorNum={landmark.floor} />
|
|
|
|
+ <ImageSVG x={landmark.longitude * imgWidth - 3} y={landmark.latitude * imgHeight - 3} width={imageDim} height={imageDim} href={lmTypes[landmark.landmark_type]['image'] as ImageSourcePropType} />
|
|
|
|
+ </Svg>
|
|
|
|
+ </View>
|
|
|
|
+ }
|
|
|
|
+ </ViewShot>
|
|
</View>
|
|
</View>
|
|
</TouchableOpacity>
|
|
</TouchableOpacity>
|
|
- )}
|
|
|
|
|
|
+ )
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const styles = StyleSheet.create({
|
|
|
|
+ container: {
|
|
|
|
+ aspectRatio: 8 / 10, // (caters to portrait mode) (width is 80% the value of height dimension)
|
|
|
|
+ width: '100%',
|
|
|
|
+ height: '100%',
|
|
|
|
+ maxWidth: "100%",
|
|
|
|
+ maxHeight: "100%",
|
|
|
|
+ backgroundColor: "white",
|
|
|
|
+ padding: 10
|
|
|
|
+ }
|
|
|
|
+})
|