From 860c5313bafe204404a6726c75e6046ecef966c9 Mon Sep 17 00:00:00 2001 From: natjms Date: Sat, 22 May 2021 22:53:03 -0300 Subject: [PATCH] Enable retrieving hashtag timelines. See #25 for why this never returns hashtag timelines --- src/components/pages/discover/search.js | 2 +- src/components/pages/discover/view-hashtag.js | 156 ++++++++++++------ src/requests.js | 9 + 3 files changed, 113 insertions(+), 54 deletions(-) diff --git a/src/components/pages/discover/search.js b/src/components/pages/discover/search.js index f4c8766..5c380cb 100644 --- a/src/components/pages/discover/search.js +++ b/src/components/pages/discover/search.js @@ -271,7 +271,7 @@ const HashtagListJsx = (props) => { key = { i } thumbnail = { require("assets/hashtag.png") } callback = { props.callback } - navParams = { { hashtag: item } }> + navParams = { { tag: item } }> #{ item.name } diff --git a/src/components/pages/discover/view-hashtag.js b/src/components/pages/discover/view-hashtag.js index de478f7..c13a153 100644 --- a/src/components/pages/discover/view-hashtag.js +++ b/src/components/pages/discover/view-hashtag.js @@ -1,68 +1,122 @@ -import React, { useState } from "react"; +import React, { useState, useEffect } from "react"; 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 { TouchableOpacity } from "react-native-gesture-handler"; -const FollowHashtagButtonJsx = ({followed, onPress}) => { - return ( - - - { followed ? "Followed" : "Follow" } - - - ); -}; +import * as requests from "src/requests"; +import AsyncStorage from "@react-native-async-storage/async-storage"; const ViewHashtagJsx = ({navigation}) => { + const FETCH_LIMIT = 18; let [state, setState] = useState({ - name: navigation.getParam("name", ""), + tag: navigation.getParam("tag", null), posts: [], - nPosts: 0, + offset: 0, followed: 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 ( - + - - - - #{ state.name } - - - { state.nPosts } posts - - - { - // Send request to follow hashtag and such... - setState({ ...state, followed: !state.followed}); - } + source = { + state.loaded && state.posts.length > 0 + ? { + uri: state + .posts[0] + .media_attachments[0] + .preview_url + } + : require("assets/hashtag.png") }/> + + + #{ state.tag.name } + + <> + { latest + ? + { latest.uses }  + posts from  + { latest.accounts }  + people today + + :<> + } + + - + <> + { state.loaded && state.posts.length > 0 + ? + : + Nothing to show + + } + - + ); }; @@ -85,14 +139,10 @@ const styles = { fontWeight: "bold", fontSize: 20 }, - button: { - borderWidth: 1, - borderColor: "#888", - borderRadius: 5, - padding: 10, - paddingLeft: 30, - paddingRight: 30, - marginTop: 10, + nothing: { + color: "#666", + textAlign: "center", + paddingTop: 20, }, strong: { fontWeight: "bold", diff --git a/src/requests.js b/src/requests.js index 1582d49..3d61635 100644 --- a/src/requests.js +++ b/src/requests.js @@ -206,6 +206,15 @@ export async function fetchPublicTimeline(domain, token, params = false) { 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) { const resp = await get( `https://${domain}/api/v1/conversations`,