Add support for more than one media_attachment element

This commit is contained in:
Nat 2021-03-13 13:17:54 -04:00
parent 4d458734ca
commit 39d15067c2
2 changed files with 85 additions and 34 deletions

View File

@ -18,7 +18,7 @@ const TEST_POSTS = [
content: "Also learning Claire de Lune feels a lot like reading the communist manifesto", content: "Also learning Claire de Lune feels a lot like reading the communist manifesto",
timestamp: 1596745156000, timestamp: 1596745156000,
media_attachments: [ media_attachments: [
{preview_url: TEST_IMAGE} {url: TEST_IMAGE}
] ]
}, },
{ {
@ -31,7 +31,9 @@ const TEST_POSTS = [
content: "Also learning Claire de Lune feels a lot like reading the communist manifesto", content: "Also learning Claire de Lune feels a lot like reading the communist manifesto",
timestamp: 1596745156000, timestamp: 1596745156000,
media_attachments: [ media_attachments: [
{preview_url: TEST_IMAGE} { url: "https://college.mayo.edu/media/mccms/content-assets/campus-amp-community/arizona/mayo-clinic-phoenix-arizona-is453080663-hero-mobile.jpg" },
{ url: TEST_IMAGE },
{ url: TEST_IMAGE }
] ]
} }
]; ];

View File

@ -1,5 +1,12 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Image, View, Text, Dimensions, TouchableWithoutFeedback } from "react-native"; import {
Image,
View,
Text,
Dimensions,
TouchableWithoutFeedback,
ScrollView
} from "react-native";
import { import {
Menu, Menu,
@ -9,6 +16,7 @@ import {
renderers renderers
} from "react-native-popup-menu"; } from "react-native-popup-menu";
import { pluralize, timeToAge } from "src/interface/rendering" import { pluralize, timeToAge } from "src/interface/rendering"
import PostActionBarJsx from "src/components/posts/post-action-bar"; import PostActionBarJsx from "src/components/posts/post-action-bar";
@ -39,6 +47,29 @@ function getAutoHeight(w1, h1, w2) {
return w2 * (h1 / w1) return w2 * (h1 / w1)
} }
function getDimensionsPromises(uris) {
return uris.map(attachment => new Promise(resolve => {
Image.getSize(attachment.url, (width, height) => {
const autoHeight = getAutoHeight(width, height, SCREEN_WIDTH)
resolve([SCREEN_WIDTH, autoHeight]);
});
}));
}
const PostImageJsx = (props) => {
return <Image
source = { { uri: props.uri } }
style = {
{
flex: 1,
width: SCREEN_WIDTH,
height: getAutoHeight(props.width, props.height, SCREEN_WIDTH),
objectFit: "cover"
}
} />
};
export const RawPostJsx = (props) => { export const RawPostJsx = (props) => {
const repliesCount = props.data.replies_count; const repliesCount = props.data.replies_count;
@ -74,14 +105,30 @@ export const RawPostJsx = (props) => {
</Menu> </Menu>
</View> </View>
</View> </View>
{ /* TODO: support for more than one image per post */ } {
<Image props.data.media_attachments.length > 1 ?
source = { { uri: TEST_IMAGE/* props.data.media_attachments[0] */ } } <ScrollView
style = { { horizontal = { true }
flex: 1, snapToInterval = { SCREEN_WIDTH }
width: SCREEN_WIDTH, decelerationRate = { "fast" }
height: getAutoHeight(props.width, props.height, SCREEN_WIDTH) style = { styles.carousel }
} } /> contentContainerStyle = { styles.carouselContainer }>
{
props.data.media_attachments
.map((attachment, i) => {
return (<PostImageJsx
key = { i }
uri = { attachment.url }
width = { props.dimensions[i][0] }
height = { props.dimensions[i][1] } />);
})
}
</ScrollView>
: <PostImageJsx
uri = { props.data.media_attachments[0].url }
width = { props.dimensions[0][0] }
height = { props.dimensions[0][1] } />
}
<PostActionBarJsx <PostActionBarJsx
favourited = { props.data.favourited } favourited = { props.data.favourited }
reblogged = { props.data.reblogged } /> reblogged = { props.data.reblogged } />
@ -116,18 +163,15 @@ export const PostByDataJsx = (props) => {
*/ */
let [state, setState] = useState({ let [state, setState] = useState({
width: 0, loaded: false,
height: 0, dimensions: []
loaded: false
}); });
useEffect(() => { useEffect(() => {
Image.getSize(TEST_IMAGE, (width, height) => { Promise.all(getDimensionsPromises(props.data.media_attachments))
const newHeight = getAutoHeight(width, height, SCREEN_WIDTH) .then(dimensions => {
setState({ setState({
width: SCREEN_WIDTH, dimensions: dimensions,
height: newHeight,
loaded: true loaded: true
}); });
}); });
@ -138,8 +182,7 @@ export const PostByDataJsx = (props) => {
{ state.loaded ? { state.loaded ?
<RawPostJsx <RawPostJsx
data = { props.data } data = { props.data }
width = { state.width } dimensions = { state.dimensions }
height = { state.height }
navigation = { props.navigation }/> navigation = { props.navigation }/>
: <View></View> } : <View></View> }
</View> </View>
@ -159,37 +202,36 @@ export const PostByIdJsx = (props) => {
reblogged: false, reblogged: false,
content: "", content: "",
timestamp: 0, timestamp: 0,
loaded: false,
dimensions: []
}); });
useEffect(() => { useEffect(() => {
// TODO: Make API request using props.id, set it as the state // TODO: Make API request using props.id, set it as the state
((/* This would be the data retrieved */) => { (() => {
Image.getSize(TEST_IMAGE, (width, height) => { Promise.all(getDimensionsPromises([{ url: TEST_IMAGE }]))
const newHeight = getAutoHeight(width, height, SCREEN_WIDTH) .then(dimensions => {
setState({ setState({
avatar: TEST_IMAGE, avatar: TEST_IMAGE,
username: "njms", username: "njms",
media_attachments: [TEST_IMAGE], media_attachments: [{ url: TEST_IMAGE }],
favourited: false, favourited: false,
reblogged: false, reblogged: false,
content: "Also learning Claire de Lune feels a lot like reading the communist manifesto", content: "Also learning Claire de Lune feels a lot like reading the communist manifesto",
timestamp: 1596745156000, timestamp: 1596745156000,
width: SCREEN_WIDTH, loaded: true,
height: newHeight, dimensions: dimensions
loaded: true
}); });
}); });
})(); })();
}, []); });
return ( return (
<View> <View>
{ state.loaded ? { state.loaded ?
<RawPostJsx <RawPostJsx
data = { state } data = { state }
width = { state.width } dimensions = { state.dimensions }
height = { state.height }
navigation = { props.navigation }/> navigation = { props.navigation }/>
: <View></View> : <View></View>
} }
@ -229,7 +271,14 @@ const styles = {
photo: { photo: {
flex: 1, flex: 1,
}, },
carousel: {
width: SCREEN_WIDTH,
height: SCREEN_WIDTH,
},
carouselContainer: {
display: "flex",
alignItems: "center"
},
caption: { caption: {
padding: SCREEN_WIDTH / 24, padding: SCREEN_WIDTH / 24,
}, },