Enable retrieving hashtag timelines.

See #25 for why this never returns hashtag timelines
This commit is contained in:
Nat 2021-05-22 22:53:03 -03:00
parent 19c9629197
commit 860c5313ba
3 changed files with 113 additions and 54 deletions

View File

@ -271,7 +271,7 @@ const HashtagListJsx = (props) => {
key = { i } key = { i }
thumbnail = { require("assets/hashtag.png") } thumbnail = { require("assets/hashtag.png") }
callback = { props.callback } callback = { props.callback }
navParams = { { hashtag: item } }> navParams = { { tag: item } }>
<Text style = { styles.username }> <Text style = { styles.username }>
#{ item.name } #{ item.name }
</Text> </Text>

View File

@ -1,68 +1,122 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { View, Image, Dimensions, Text } from "react-native"; import { View, Image, Dimensions, Text } from "react-native";
import { ScreenWithFullNavigationJsx } from "src/components/navigation/navigators"; import { ScreenWithBackBarJsx } from "src/components/navigation/navigators";
import PagedGridJsx from "src/components/posts/paged-grid"; import PagedGridJsx from "src/components/posts/paged-grid";
import { TouchableOpacity } from "react-native-gesture-handler";
const FollowHashtagButtonJsx = ({followed, onPress}) => { import * as requests from "src/requests";
return ( import AsyncStorage from "@react-native-async-storage/async-storage";
<TouchableOpacity
style = {
[
styles.button,
followed ? { backgroundColor: "#888" } : {}
]
}
onPress = { onPress }>
<Text
style = { followed ? { color: "white" } : {} }>
{ followed ? "Followed" : "Follow" }
</Text>
</TouchableOpacity>
);
};
const ViewHashtagJsx = ({navigation}) => { const ViewHashtagJsx = ({navigation}) => {
const FETCH_LIMIT = 18;
let [state, setState] = useState({ let [state, setState] = useState({
name: navigation.getParam("name", ""), tag: navigation.getParam("tag", null),
posts: [], posts: [],
nPosts: 0, offset: 0,
followed: false, followed: false,
loaded: false, loaded: false,
}); });
useEffect(() => {
let instance, accessToken;
AsyncStorage
.multiGet([
"@user_instance",
"@user_token",
])
.then(([instancePair, tokenPair]) => {
instance = instancePair[1];
accessToken = JSON.parse(tokenPair[1]).access_token;
return requests.fetchHashtagTimeline(
instance,
state.tag.name,
accessToken,
{
only_media: true,
limit: FETCH_LIMIT,
}
);
})
.then(posts => {
setState({...state,
posts,
offset: state.offset + FETCH_LIMIT,
instance,
accessToken,
loaded: true,
});
});
}, []);
const _handleShowMore = async () => {
const newPosts = await requests.fetchHashtagTimeline(
state.instance,
state.tag.name,
state.accessToken,
{
only_media: true,
limit: FETCH_LIMIT,
max_id: state.offset,
}
);
setState({...state,
posts: state.posts.concat(newPosts),
offset: state.offset + FETCH_LIMIT,
});
};
const latest = state.tag.history[0];
return ( return (
<ScreenWithFullNavigationJsx <ScreenWithBackBarJsx navigation = { navigation }>
active = "Discover"
navigation = { navigation }>
<View> <View>
<View style = { styles.headerContainer }> <View style = { styles.headerContainer }>
<View> <View>
<Image <Image
style = { styles.image } style = { styles.image }
source = { require("assets/hashtag.png") } /> source = {
</View> state.loaded && state.posts.length > 0
<View style = { styles.headerText }> ? {
<Text style = { styles.hashtag}> uri: state
#{ state.name } .posts[0]
</Text> .media_attachments[0]
<Text> .preview_url
<Text style = { styles.strong}>{ state.nPosts }</Text> posts }
</Text> : require("assets/hashtag.png")
<FollowHashtagButtonJsx
followed = { state.followed }
onPress = { () => {
// Send request to follow hashtag and such...
setState({ ...state, followed: !state.followed});
}
}/> }/>
</View> </View>
<View style = { styles.headerText }>
<Text style = { styles.hashtag }>
#{ state.tag.name }
</Text>
<>
{ latest
? <Text>
<Text style = { styles.strong }>{ latest.uses }</Text>&nbsp;
posts from&nbsp;
<Text style = { styles.strong }>{ latest.accounts }</Text>&nbsp;
people today
</Text>
:<></>
}
</>
</View>
</View> </View>
<PagedGridJsx <>
navigation = { navigation } { state.loaded && state.posts.length > 0
originTab = "Discover" /> ? <PagedGridJsx
navigation = { navigation }
posts = { state.posts }
onShowMore = { _handleShowMore } />
: <Text style = { styles.nothing }>
Nothing to show
</Text>
}
</>
</View> </View>
</ScreenWithFullNavigationJsx> </ScreenWithBackBarJsx>
); );
}; };
@ -85,14 +139,10 @@ const styles = {
fontWeight: "bold", fontWeight: "bold",
fontSize: 20 fontSize: 20
}, },
button: { nothing: {
borderWidth: 1, color: "#666",
borderColor: "#888", textAlign: "center",
borderRadius: 5, paddingTop: 20,
padding: 10,
paddingLeft: 30,
paddingRight: 30,
marginTop: 10,
}, },
strong: { strong: {
fontWeight: "bold", fontWeight: "bold",

View File

@ -206,6 +206,15 @@ export async function fetchPublicTimeline(domain, token, params = false) {
return resp.json(); return resp.json();
} }
export async function fetchHashtagTimeline(domain, hashtag, token, params = false) {
const resp = await get(
`https://${domain}/api/v1/timelines/tag/${hashtag}`,
token,
params
);
return resp.json();
}
export async function fetchConversations(domain, token, params = false) { export async function fetchConversations(domain, token, params = false) {
const resp = await get( const resp = await get(
`https://${domain}/api/v1/conversations`, `https://${domain}/api/v1/conversations`,