Ensure timeline interruption only gets rendered after the posts. Fixes #38
This commit is contained in:
parent
78eaf0efe6
commit
1aebc9f770
|
@ -13,6 +13,7 @@ import * as requests from "src/requests";
|
||||||
const FeedJsx = (props) => {
|
const FeedJsx = (props) => {
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
loaded: false,
|
loaded: false,
|
||||||
|
postsRendered: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -63,27 +64,20 @@ const FeedJsx = (props) => {
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
const _handleTimelineLoaded = () => setState({...state,
|
||||||
<>
|
postsRendered: true,
|
||||||
{ state.loaded
|
});
|
||||||
? <ScreenWithTrayJsx
|
|
||||||
active = "Feed"
|
|
||||||
contentContainerStyle = {
|
|
||||||
state.posts.length == 0
|
|
||||||
? styles.ifCaughtUp
|
|
||||||
: {}
|
|
||||||
}
|
|
||||||
navigation = { props.navigation }>
|
|
||||||
|
|
||||||
<TimelineViewJsx
|
let endOfTimelineMessage = <></>;
|
||||||
navigation = { props.navigation }
|
if (state.postsRendered) {
|
||||||
posts = { state.posts } />
|
// Only render the timeline interruption if all of the posts have been
|
||||||
|
// rendered in the feed.
|
||||||
|
endOfTimelineMessage = <>
|
||||||
<View style = {
|
<View style = {
|
||||||
state.posts.length == 0
|
state.posts.length == 0
|
||||||
? {}
|
? {}
|
||||||
: styles.interruption.topBorder
|
: styles.interruption.topBorder
|
||||||
}>
|
}>
|
||||||
|
|
||||||
<View style = { styles.interruption.inner }>
|
<View style = { styles.interruption.inner }>
|
||||||
<Ionicons
|
<Ionicons
|
||||||
name="ios-checkmark-circle-outline"
|
name="ios-checkmark-circle-outline"
|
||||||
|
@ -104,6 +98,26 @@ const FeedJsx = (props) => {
|
||||||
</TouchableWithoutFeedback>
|
</TouchableWithoutFeedback>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
</>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{ state.loaded
|
||||||
|
? <ScreenWithTrayJsx
|
||||||
|
active = "Feed"
|
||||||
|
contentContainerStyle = {
|
||||||
|
state.posts.length == 0
|
||||||
|
? styles.ifCaughtUp
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
navigation = { props.navigation }>
|
||||||
|
|
||||||
|
<TimelineViewJsx
|
||||||
|
navigation = { props.navigation }
|
||||||
|
posts = { state.posts }
|
||||||
|
onTimelineLoaded = { _handleTimelineLoaded }/>
|
||||||
|
{ endOfTimelineMessage }
|
||||||
</ScreenWithTrayJsx>
|
</ScreenWithTrayJsx>
|
||||||
: <></>
|
: <></>
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,8 +180,8 @@ export const RawPostJsx = (props) => {
|
||||||
|
|
||||||
export const PostByDataJsx = (props) => {
|
export const PostByDataJsx = (props) => {
|
||||||
/*
|
/*
|
||||||
Renders a post where the data is supplied directly to the element through
|
* Renders a post where the data is supplied directly to the element through
|
||||||
its properties, as it is in a timeline.
|
* its properties, as it is in a timeline.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let [state, setState] = useState({
|
let [state, setState] = useState({
|
||||||
|
@ -217,6 +217,10 @@ export const PostByDataJsx = (props) => {
|
||||||
own,
|
own,
|
||||||
loaded: true
|
loaded: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (props.onPostLoaded != null) {
|
||||||
|
props.onPostLoaded();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -417,13 +421,6 @@ const styles = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// customStyles for react-native-popup-menu should be defined in particular
|
|
||||||
// objects to be interpreted correctly.
|
|
||||||
|
|
||||||
//const menuStyles = {
|
|
||||||
// menuProviderWrapper
|
|
||||||
//}
|
|
||||||
|
|
||||||
const optionsStyles = {
|
const optionsStyles = {
|
||||||
optionWrapper: { // The wrapper around a single option
|
optionWrapper: { // The wrapper around a single option
|
||||||
paddingLeft: SCREEN_WIDTH / 15,
|
paddingLeft: SCREEN_WIDTH / 15,
|
||||||
|
|
|
@ -1,15 +1,30 @@
|
||||||
import React from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
|
|
||||||
import { PostByDataJsx } from "src/components/posts/post";
|
import { PostByDataJsx } from "src/components/posts/post";
|
||||||
|
|
||||||
const TimelineViewJsx = (props) => {
|
const TimelineViewJsx = (props) => {
|
||||||
|
// Count the number of posts that have already loaded
|
||||||
|
const [postsLoaded, setPostsLoaded] = useState(0);
|
||||||
|
|
||||||
// Ensure only posts with media get in the timeline
|
// Ensure only posts with media get in the timeline
|
||||||
const posts = props.posts.filter(
|
const posts = props.posts.filter(
|
||||||
p => p.media_attachments != null
|
p => p.media_attachments != null
|
||||||
&& p.media_attachments.length > 0
|
&& p.media_attachments.length > 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// When all the posts have been loaded, call onTimelineLoaded
|
||||||
|
// if it's been defined
|
||||||
|
if (postsLoaded == posts.length) {
|
||||||
|
if (props.onTimelineLoaded != null) {
|
||||||
|
props.onTimelineLoaded();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [postsLoaded]);
|
||||||
|
|
||||||
|
_handlePostLoaded = () => setPostsLoaded(postsLoaded + 1);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
{ props.posts.map((post, i) => {
|
{ props.posts.map((post, i) => {
|
||||||
|
@ -17,7 +32,8 @@ const TimelineViewJsx = (props) => {
|
||||||
<View key = { i } >
|
<View key = { i } >
|
||||||
<PostByDataJsx
|
<PostByDataJsx
|
||||||
navigation = { props.navigation }
|
navigation = { props.navigation }
|
||||||
data = { post } />
|
data = { post }
|
||||||
|
onPostLoaded = { _handlePostLoaded }/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}) }
|
}) }
|
||||||
|
|
Loading…
Reference in New Issue