Add a context menu for posts
Curiously, the context menu doesn't seem to open when tested in FireFox while live reloading is active; it only works when the page loading has been interrupted. Presumably this won't be an issue when run on a device but something to look into nonetheless as it does kind of throw off debugging
This commit is contained in:
parent
0dd2094cbe
commit
37a6f1f84b
|
@ -6129,6 +6129,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz",
|
||||||
"integrity": "sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ=="
|
"integrity": "sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ=="
|
||||||
},
|
},
|
||||||
|
"react-native-popup-menu": {
|
||||||
|
"version": "0.15.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-native-popup-menu/-/react-native-popup-menu-0.15.10.tgz",
|
||||||
|
"integrity": "sha512-w7MaicsfpclK7g/omjMchNaXwhMi0apt/DC734AbHuJTWCfv5mF3JgL1UzRW19ncFMBRfQeYapPy/zUyJCGgEQ=="
|
||||||
|
},
|
||||||
"react-native-reanimated": {
|
"react-native-reanimated": {
|
||||||
"version": "1.9.0",
|
"version": "1.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-1.9.0.tgz",
|
||||||
|
|
|
@ -9,21 +9,22 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@react-native-community/masked-view": "0.1.10",
|
"@react-native-community/masked-view": "0.1.10",
|
||||||
|
"@react-navigation/core": "5.2.3",
|
||||||
"@react-navigation/native": "5.1.1",
|
"@react-navigation/native": "5.1.1",
|
||||||
|
"@react-navigation/stack": "5.2.3",
|
||||||
"expo": "^38.0.9",
|
"expo": "^38.0.9",
|
||||||
"expo-status-bar": "^1.0.2",
|
"expo-status-bar": "^1.0.2",
|
||||||
"react": "~16.11.0",
|
"react": "~16.11.0",
|
||||||
"react-dom": "~16.11.0",
|
"react-dom": "~16.11.0",
|
||||||
"react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
|
"react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz",
|
||||||
"react-native-gesture-handler": "~1.6.0",
|
"react-native-gesture-handler": "~1.6.0",
|
||||||
|
"react-native-popup-menu": "^0.15.10",
|
||||||
"react-native-reanimated": "~1.9.0",
|
"react-native-reanimated": "~1.9.0",
|
||||||
"react-native-safe-area-context": "~3.0.7",
|
"react-native-safe-area-context": "~3.0.7",
|
||||||
"react-native-screens": "~2.9.0",
|
"react-native-screens": "~2.9.0",
|
||||||
"react-native-web": "~0.11.7",
|
"react-native-web": "~0.11.7",
|
||||||
"react-navigation": "^4.4.0",
|
"react-navigation": "^4.4.0",
|
||||||
"react-navigation-stack": "^2.8.2",
|
"react-navigation-stack": "^2.8.2"
|
||||||
"@react-navigation/stack": "5.2.3",
|
|
||||||
"@react-navigation/core": "5.2.3"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.8.6",
|
"@babel/core": "^7.8.6",
|
||||||
|
|
|
@ -1,43 +1,69 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
import { ScrollView } from "react-native-gesture-handler";
|
import { ScrollView } from "react-native-gesture-handler";
|
||||||
|
|
||||||
|
import { MenuProvider } from "react-native-popup-menu";
|
||||||
|
|
||||||
import BackBarJsx from "./back-bar";
|
import BackBarJsx from "./back-bar";
|
||||||
import TrayJsx from "src/components/navigation/tray";
|
import TrayJsx from "src/components/navigation/tray";
|
||||||
|
|
||||||
|
// Provider for context menus
|
||||||
|
// Allows for establishing global styling of context menus
|
||||||
|
const ContextJsx = (props) => {
|
||||||
|
return (
|
||||||
|
<MenuProvider customStyles = { providerStyles }>
|
||||||
|
{ props.children }
|
||||||
|
</MenuProvider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const ScreenWithTrayJsx = (props) => {
|
export const ScreenWithTrayJsx = (props) => {
|
||||||
return (
|
return (
|
||||||
<View style = { { flex: 1 } }>
|
<ContextJsx>
|
||||||
<ScrollView>
|
<View style = { { flex: 1 } }>
|
||||||
{ props.children }
|
<ScrollView>
|
||||||
|
{ props.children }
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<TrayJsx
|
<TrayJsx
|
||||||
active = { props.active }
|
active = { props.active }
|
||||||
navigation = { props.navigation } />
|
navigation = { props.navigation } />
|
||||||
</View>
|
</View>
|
||||||
)
|
</ContextJsx>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ScreenWithBackBarJsx = (props) => {
|
export const ScreenWithBackBarJsx = (props) => {
|
||||||
return (
|
return (
|
||||||
<View style = { { flex: 1 } }>
|
<ContextJsx>
|
||||||
<BackBarJsx navigation = { props.navigation } />
|
<View style = { { flex: 1 } }>
|
||||||
<ScrollView>
|
<BackBarJsx navigation = { props.navigation } />
|
||||||
{ props.children }
|
<ScrollView>
|
||||||
</ScrollView>
|
{ props.children }
|
||||||
</View>
|
</ScrollView>
|
||||||
|
</View>
|
||||||
|
</ContextJsx>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ScreenWithFullNavigationJsx = (props) => {
|
export const ScreenWithFullNavigationJsx = (props) => {
|
||||||
return (
|
return (
|
||||||
<View style = { { flex: 1 } }>
|
<ContextJsx>
|
||||||
<BackBarJsx navigation = { props.navigation } />
|
<View style = { { flex: 1 } }>
|
||||||
<ScrollView>
|
<BackBarJsx navigation = { props.navigation } />
|
||||||
{ props.children }
|
<ScrollView>
|
||||||
</ScrollView>
|
{ props.children }
|
||||||
<TrayJsx
|
</ScrollView>
|
||||||
active = { props.active }
|
<TrayJsx
|
||||||
navigation = { props.navigation } />
|
active = { props.active }
|
||||||
</View>
|
navigation = { props.navigation } />
|
||||||
|
</View>
|
||||||
|
</ContextJsx>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const providerStyles = {
|
||||||
|
backdrop: {
|
||||||
|
backgroundColor: "black",
|
||||||
|
opacity: 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,23 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Image, View, Text, Dimensions } from "react-native";
|
import { Image, View, Text, Dimensions, TouchableWithoutFeedback } from "react-native";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Menu,
|
||||||
|
MenuOptions,
|
||||||
|
MenuOption,
|
||||||
|
MenuTrigger,
|
||||||
|
renderers
|
||||||
|
} from "react-native-popup-menu";
|
||||||
|
|
||||||
import PostActionBarJsx from "src/components/posts/post-action-bar";
|
import PostActionBarJsx from "src/components/posts/post-action-bar";
|
||||||
|
|
||||||
const SCREEN_WIDTH = Dimensions.get("window").width;
|
const SCREEN_WIDTH = Dimensions.get("window").width;
|
||||||
const TEST_IMAGE = "https://cache.desktopnexus.com/thumbseg/2255/2255124-bigthumbnail.jpg";
|
const TEST_IMAGE = "https://cache.desktopnexus.com/thumbseg/2255/2255124-bigthumbnail.jpg";
|
||||||
|
|
||||||
|
// Extract the SlideInMenu function from `renderers`
|
||||||
|
// This will be used in RawPostJsx
|
||||||
|
const { SlideInMenu } = renderers;
|
||||||
|
|
||||||
function getAutoHeight(w1, h1, w2) {
|
function getAutoHeight(w1, h1, w2) {
|
||||||
/*
|
/*
|
||||||
Given the original dimensions and the new width, calculate what would
|
Given the original dimensions and the new width, calculate what would
|
||||||
|
@ -60,21 +72,35 @@ export const RawPostJsx = (props) => {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<View style = { styles.postHeader }>
|
<View style = { styles.postHeader }>
|
||||||
<Image
|
<Image
|
||||||
style = { styles.pfp }
|
style = { styles.pfp }
|
||||||
source = { { uri: props.data.avatar } } />
|
source = { { uri: props.data.avatar } } />
|
||||||
<Text
|
<Text
|
||||||
style = { styles.postHeaderName }>{ props.data.username }</Text>
|
style = { styles.postHeaderName }>{ props.data.username }</Text>
|
||||||
|
<View style = { styles.menu }>
|
||||||
|
<Menu renderer = { SlideInMenu }>
|
||||||
|
<MenuTrigger>
|
||||||
|
<Image
|
||||||
|
source = { require("assets/eva-icons/ellipsis.png") }
|
||||||
|
style = { styles.ellipsis }/>
|
||||||
|
</MenuTrigger>
|
||||||
|
<MenuOptions customStyles = { optionsStyles }>
|
||||||
|
<MenuOption text="Hide" />
|
||||||
|
<MenuOption text="Unfollow" />
|
||||||
|
<MenuOption text="Block" />
|
||||||
|
</MenuOptions>
|
||||||
|
</Menu>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
{ /* TODO: support for more than one image per post */ }
|
{ /* TODO: support for more than one image per post */ }
|
||||||
<Image
|
<Image
|
||||||
source = { { uri: TEST_IMAGE/* props.data.media_attachments[0] */ } }
|
source = { { uri: TEST_IMAGE/* props.data.media_attachments[0] */ } }
|
||||||
style = { {
|
style = { {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
width: SCREEN_WIDTH,
|
width: SCREEN_WIDTH,
|
||||||
height: getAutoHeight(props.width, props.height, SCREEN_WIDTH)
|
height: getAutoHeight(props.width, props.height, SCREEN_WIDTH)
|
||||||
} } />
|
} } />
|
||||||
<PostActionBarJsx
|
<PostActionBarJsx
|
||||||
favourited = { props.data.favourited }
|
favourited = { props.data.favourited }
|
||||||
reblogged = {props.data.reblogged } />
|
reblogged = {props.data.reblogged } />
|
||||||
<View style = { styles.caption }>
|
<View style = { styles.caption }>
|
||||||
|
@ -108,7 +134,7 @@ export const PostByDataJsx = (props) => {
|
||||||
setState({
|
setState({
|
||||||
width: SCREEN_WIDTH,
|
width: SCREEN_WIDTH,
|
||||||
height: newHeight,
|
height: newHeight,
|
||||||
loaded: true
|
loaded: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -145,7 +171,7 @@ export const PostByIdJsx = (props) => {
|
||||||
((/* This would be the data retrieved */) => {
|
((/* This would be the data retrieved */) => {
|
||||||
Image.getSize(TEST_IMAGE, (width, height) => {
|
Image.getSize(TEST_IMAGE, (width, height) => {
|
||||||
const newHeight = getAutoHeight(width, height, SCREEN_WIDTH)
|
const newHeight = getAutoHeight(width, height, SCREEN_WIDTH)
|
||||||
|
|
||||||
setState({
|
setState({
|
||||||
avatar: TEST_IMAGE,
|
avatar: TEST_IMAGE,
|
||||||
username: "njms",
|
username: "njms",
|
||||||
|
@ -156,7 +182,7 @@ export const PostByIdJsx = (props) => {
|
||||||
timestamp: 1596745156000,
|
timestamp: 1596745156000,
|
||||||
width: SCREEN_WIDTH,
|
width: SCREEN_WIDTH,
|
||||||
height: newHeight,
|
height: newHeight,
|
||||||
loaded: true
|
loaded: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
@ -164,8 +190,8 @@ export const PostByIdJsx = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
{ state.loaded ?
|
{ state.loaded ?
|
||||||
<RawPostJsx
|
<RawPostJsx
|
||||||
data = { state }
|
data = { state }
|
||||||
width = { state.width }
|
width = { state.width }
|
||||||
height = { state.height } />
|
height = { state.height } />
|
||||||
|
@ -190,12 +216,20 @@ const styles = {
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
marginTop: -2
|
marginTop: -2
|
||||||
},
|
},
|
||||||
|
menu: {
|
||||||
|
marginLeft: "auto",
|
||||||
|
marginRight: SCREEN_WIDTH / 30
|
||||||
|
},
|
||||||
pfp: {
|
pfp: {
|
||||||
width: SCREEN_WIDTH / 10,
|
width: SCREEN_WIDTH / 10,
|
||||||
height: SCREEN_WIDTH / 10,
|
height: SCREEN_WIDTH / 10,
|
||||||
marginRight: SCREEN_WIDTH / 28,
|
marginRight: SCREEN_WIDTH / 28,
|
||||||
borderRadius: "100%"
|
borderRadius: "100%"
|
||||||
},
|
},
|
||||||
|
ellipsis: {
|
||||||
|
width: SCREEN_WIDTH / 15,
|
||||||
|
height: SCREEN_WIDTH / 15
|
||||||
|
},
|
||||||
photo: {
|
photo: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
},
|
},
|
||||||
|
@ -208,4 +242,27 @@ const styles = {
|
||||||
color: "#666",
|
color: "#666",
|
||||||
paddingTop: 10
|
paddingTop: 10
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// customStyles for react-native-popup-menu should be defined in particular
|
||||||
|
// objects to be interpreted correctly.
|
||||||
|
|
||||||
|
//const menuStyles = {
|
||||||
|
// menuProviderWrapper
|
||||||
|
//}
|
||||||
|
|
||||||
|
const optionsStyles = {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue