diff --git a/src/components/pages/view-comments.js b/src/components/pages/view-comments.js
index 7a03ed6..ad84658 100644
--- a/src/components/pages/view-comments.js
+++ b/src/components/pages/view-comments.js
@@ -20,67 +20,15 @@ import { TouchableOpacity } from "react-native-gesture-handler";
import * as requests from "src/requests";
-const TEST_IMAGE = "https://cache.desktopnexus.com/thumbseg/2255/2255124-bigthumbnail.jpg";
+import {
+ Menu,
+ MenuOptions,
+ MenuOption,
+ MenuTrigger,
+ renderers
+} from "react-native-popup-menu";
-const TEST_CONTEXT = {
- ancestors: [],
- descendants: [
- {
- id: "1",
- in_reply_to_id: "0",
- username: "respondant1",
- avatar: TEST_IMAGE,
- content: "This is a comment",
- favourited: false,
- created_at: 1596745156000
- },
- {
- id: "2",
- in_reply_to_id: "0",
- username: "respondant2",
- avatar: TEST_IMAGE,
- content: "This is a comment",
- favourited: true,
- created_at: 1596745156000
- },
- {
- id: "3",
- in_reply_to_id: "2",
- username: "respondant3",
- avatar: TEST_IMAGE,
- content: "This is a comment",
- favourited: false,
- created_at: 1596745156000
- },
- {
- id: "4",
- in_reply_to_id: "2",
- username: "respondant2",
- avatar: TEST_IMAGE,
- content: "This is a comment",
- favourited: false,
- created_at: 1596745156000
- },
- {
- id: "5",
- in_reply_to_id: "1",
- username: "respondant4",
- avatar: TEST_IMAGE,
- content: "This is a comment",
- favourited: false,
- created_at: 1596745156000
- },
- {
- id: "6",
- in_reply_to_id: "4",
- username: "respondant5",
- avatar: TEST_IMAGE,
- content: "This is a comment",
- favourited: false,
- created_at: 1596745156000
- },
- ]
-}
+const { SlideInMenu } = renderers;
function chunkWhile(arr, fun) {
/*
@@ -172,6 +120,22 @@ function threadify(descendants) {
}
const CommentJsx = (props) => {
+ const menuOptionsStyles = {
+ optionWrapper: { // The wrapper around a single option
+ paddingLeft: SCREEN_WIDTH / 15,
+ paddingTop: SCREEN_WIDTH / 30,
+ paddingBottom: SCREEN_WIDTH / 30
+ },
+ optionsWrapper: { // The wrapper around all options
+ marginTop: SCREEN_WIDTH / 20,
+ marginBottom: SCREEN_WIDTH / 20,
+ },
+ optionsContainer: { // The Animated.View
+ borderTopLeftRadius: 10,
+ borderTopRightRadius: 10
+ }
+ };
+
const packs = {
favourited: {
active: require("assets/eva-icons/post-actions/heart-active.png"),
@@ -219,6 +183,27 @@ const CommentJsx = (props) => {
style = { [styles.heart, styles.action] }
source = { activeOrNot(props.data.favourited, packs.favourited) } />
+
+
+
@@ -262,6 +247,17 @@ const ViewCommentsJsx = (props) => {
});
}, []);
+ const _fetchNewThreads = async () => {
+ // Fetch an updated context to rerender the page
+ const { descendants } = await requests.fetchStatusContext(
+ state.instance,
+ state.postData.id,
+ state.accessToken,
+ );
+
+ return threadify(descendants);
+ }
+
const _onReplyFactory = (acct, id) => {
return () => {
setState({...state,
@@ -289,19 +285,34 @@ const ViewCommentsJsx = (props) => {
)
}
- // Fetch the updated context to rerender the page
- const newContext = await requests.fetchStatusContext(
- state.instance,
- state.postData.id,
- state.accessToken,
- );
-
setState({...state,
- descendants: threadify(newContext.descendants),
+ descendants: await _fetchNewThreads(),
});
}
}
+ const _onDeleteFactory = data => {
+ return async () => {
+ await requests.deleteStatus(
+ state.instance,
+ data.id,
+ state.accessToken,
+ );
+
+ // NOTE: It appears that it takes a moment for the Context of a
+ // post to register that a comment has been deleted, so instead
+ // of waiting for it, it's more efficient to just drop the comment
+ // on the client side.
+ const newThreads = state.descendants.map(thread =>
+ thread.filter(comment => comment.id != data.id)
+ ).filter(thread => thread.length > 0);
+
+ setState({...state,
+ descendants: newThreads,
+ });
+ };
+ };
+
const _handleCancelSubReply = () => {
setState({...state,
inReplyTo: {
@@ -322,26 +333,29 @@ const ViewCommentsJsx = (props) => {
}
);
- // Fetch the updated context to rerender the page
- const newContext = await requests.fetchStatusContext(
- state.instance,
- state.postData.id,
- state.accessToken,
- );
-
setState({...state,
- descendants: threadify(newContext.descendants),
-
- //Reset the comment form
+ // Reset the comment form
inReplyTo: {
acct: state.postData.account.acct,
id: state.postData.id,
},
reply: "",
+
+ // Retrieve updated context
+ descendants: await _fetchNewThreads(),
});
}
};
+ const PartialComment = (props) => (
+
+ );
+
return (
<>
{ state.loaded ?
@@ -352,9 +366,7 @@ const ViewCommentsJsx = (props) => {
{ state.loaded
?
-
@@ -364,9 +376,7 @@ const ViewCommentsJsx = (props) => {
const subs = thread.slice(1);
return (
-
{
subs.map((sub, j) => {
@@ -374,9 +384,7 @@ const ViewCommentsJsx = (props) => {
-
)
@@ -421,6 +429,7 @@ const ViewCommentsJsx = (props) => {
style = { styles.commentInput }
placeholder = "Say something..."
multiline = { true }
+ value = { state.reply }
onChangeText = { c => setState({...state, reply: c }) }/>
diff --git a/src/requests.js b/src/requests.js
index 75d06e1..fd66e5e 100644
--- a/src/requests.js
+++ b/src/requests.js
@@ -82,6 +82,17 @@ export async function get(url, token = false, data = false) {
return resp;
}
+export async function _delete(url, token = false) {
+ const resp = await fetch(url, {
+ method: "DELETE",
+ headers: token
+ ? { "Authorization": `Bearer ${token}`, }
+ : {},
+ });
+
+ return resp;
+}
+
export async function fetchProfile(domain, id) {
const resp = await get(`https://${domain}/api/v1/accounts/${id}`);
return resp.json();
@@ -97,6 +108,11 @@ export async function publishStatus(domain, token, params) {
return resp.json();
}
+export async function deleteStatus(domain, id, token) {
+ const resp = await _delete(`https://${domain}/api/v1/statuses/${id}`, token);
+ return resp.json();
+}
+
export async function fetchStatusContext(domain, id, token) {
const resp = await get(`https://${domain}/api/v1/statuses/${id}/context`, token);
return resp.json();