Improve comment composer and add Bible reference pills
This commit is contained in:
@@ -1,49 +1,108 @@
|
||||
import React, { useState } from 'react';
|
||||
import { View, StyleSheet, Icon } from 'react-native';
|
||||
import { TextInput, Button } from 'react-native-paper';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, StyleSheet, Pressable } from 'react-native';
|
||||
import { TextInput, Chip } from 'react-native-paper';
|
||||
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
||||
import API from './../API.js';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import AwesomeIcon from 'react-native-vector-icons/FontAwesome';
|
||||
import i18n from "../i18nMessages.js";
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { useSnapshot } from 'valtio';
|
||||
import GlobalState from '../contexts/GlobalState.js';
|
||||
import { createBibleToken } from '../utils/bibleReferences.js';
|
||||
|
||||
const CircleIconAction = ({ icon, onPress, color = "#6b7280", disabled = false }) => (
|
||||
<Pressable
|
||||
onPress={onPress}
|
||||
disabled={disabled}
|
||||
style={({ pressed }) => ({
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 18,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
backgroundColor: disabled ? "#f3f4f6" : (pressed ? "#e5e7eb" : "#f9fafb"),
|
||||
marginHorizontal: 2,
|
||||
transform: [{ scale: pressed ? 0.96 : 1 }],
|
||||
})}
|
||||
>
|
||||
<MaterialIcons name={icon} size={20} color={disabled ? "#9ca3af" : color} />
|
||||
</Pressable>
|
||||
);
|
||||
|
||||
let NewComment = ({ postid, newComentAdded }) => {
|
||||
let [commentContent, setCommentContent] = useState('');
|
||||
const gState = useSnapshot(GlobalState);
|
||||
const [commentContent, setCommentContent] = useState('');
|
||||
const [bibleReferences, setBibleReferences] = useState([]);
|
||||
const navigation = useNavigation();
|
||||
const biblePickerSelectionTs = gState?.biblePickerSelection?.ts;
|
||||
const hasContent = commentContent.trim().length > 0;
|
||||
|
||||
useEffect(() => {
|
||||
const selection = gState?.biblePickerSelection;
|
||||
if (!selection || selection.target !== "comment" || !selection.reference) return;
|
||||
setBibleReferences((prev) => {
|
||||
if (prev.includes(selection.reference)) return prev;
|
||||
return prev.concat(selection.reference);
|
||||
});
|
||||
GlobalState.biblePickerSelection = null;
|
||||
}, [biblePickerSelectionTs, gState?.biblePickerSelection]);
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!hasContent && bibleReferences.length === 0) return;
|
||||
const trimmedComment = commentContent.trim();
|
||||
const bibleTokens = bibleReferences.map((reference) => createBibleToken(reference)).filter(Boolean);
|
||||
setCommentContent('');
|
||||
setBibleReferences([]);
|
||||
API.newPostComment(postid, [trimmedComment, bibleTokens.join(" ")].join(" ").trim()).then((newPost) => {
|
||||
if (newComentAdded) newComentAdded(newPost);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.NewComment}>
|
||||
<TextInput
|
||||
label={i18n.t("message.newComment")}
|
||||
value={commentContent}
|
||||
onChangeText={setCommentContent}
|
||||
mode="outlined"
|
||||
multiline={true}
|
||||
dense={true}
|
||||
style={{
|
||||
flex: 8,
|
||||
fontSize: 12,
|
||||
backgroundColor: "white",
|
||||
}}
|
||||
/>
|
||||
<View style={{
|
||||
flex: 2,
|
||||
fontSize: 12,
|
||||
flexDirection: "column",
|
||||
alignItems: "center", // ignore this - we'll come back to it
|
||||
justifyContent: "center",
|
||||
}}>
|
||||
<Button mode="outlined" onPress={() => {
|
||||
if (commentContent.trim() === "") return 0;
|
||||
setCommentContent('');
|
||||
API.newPostComment(postid, commentContent).then((newPost) => {
|
||||
setCommentContent('');
|
||||
if(newComentAdded) newComentAdded(newPost);
|
||||
});
|
||||
}}>
|
||||
<AwesomeIcon name="send" />
|
||||
</Button>
|
||||
<View style={styles.newComment}>
|
||||
<View style={styles.composerShell}>
|
||||
<CircleIconAction
|
||||
icon="menu-book"
|
||||
onPress={() => navigation.navigate("BiblePicker", { target: "comment" })}
|
||||
color="#6b7280"
|
||||
/>
|
||||
<View style={styles.inputWrap}>
|
||||
<TextInput
|
||||
mode="flat"
|
||||
placeholder={i18n.t("message.newComment")}
|
||||
value={commentContent}
|
||||
onChangeText={setCommentContent}
|
||||
multiline
|
||||
maxLength={500}
|
||||
dense
|
||||
underlineColor="transparent"
|
||||
activeUnderlineColor="transparent"
|
||||
style={styles.input}
|
||||
contentStyle={styles.inputContent}
|
||||
/>
|
||||
</View>
|
||||
<CircleIconAction
|
||||
icon="send"
|
||||
onPress={handleSubmit}
|
||||
disabled={!hasContent && bibleReferences.length === 0}
|
||||
color="#0d6efd"
|
||||
/>
|
||||
</View>
|
||||
{bibleReferences.length ? (
|
||||
<View style={styles.referencesWrap}>
|
||||
{bibleReferences.map((reference) => (
|
||||
<Chip
|
||||
key={reference}
|
||||
style={styles.referenceChip}
|
||||
onPress={() => navigation.navigate("BibleChapter", { reference })}
|
||||
onClose={() => {
|
||||
setBibleReferences((prev) => prev.filter((item) => item !== reference));
|
||||
}}
|
||||
>
|
||||
{reference}
|
||||
</Chip>
|
||||
))}
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -51,9 +110,44 @@ let NewComment = ({ postid, newComentAdded }) => {
|
||||
export default NewComment;
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
NewComment: {
|
||||
margin: 10,
|
||||
newComment: {
|
||||
marginHorizontal: 10,
|
||||
marginTop: 10,
|
||||
marginBottom: 6,
|
||||
},
|
||||
composerShell: {
|
||||
borderWidth: 1,
|
||||
borderColor: "#e5e7eb",
|
||||
borderRadius: 28,
|
||||
backgroundColor: "#ffffff",
|
||||
paddingHorizontal: 4,
|
||||
paddingVertical: 2,
|
||||
flexDirection: "row",
|
||||
flex: 6
|
||||
}
|
||||
alignItems: "flex-end",
|
||||
shadowColor: "#111827",
|
||||
shadowOpacity: 0.08,
|
||||
shadowRadius: 10,
|
||||
shadowOffset: { width: 0, height: 3 },
|
||||
elevation: 2,
|
||||
},
|
||||
inputWrap: {
|
||||
flex: 1,
|
||||
paddingRight: 2,
|
||||
},
|
||||
input: {
|
||||
backgroundColor: "transparent",
|
||||
maxHeight: 120,
|
||||
},
|
||||
inputContent: {
|
||||
paddingVertical: 10,
|
||||
},
|
||||
referencesWrap: {
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
marginTop: 8,
|
||||
},
|
||||
referenceChip: {
|
||||
marginRight: 6,
|
||||
marginBottom: 6,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user