Rewrap pages in ScrollViews

This commit is contained in:
Nat 2022-05-16 17:10:06 -07:00
parent 52e8f8f59b
commit 985cbe6ca1
8 changed files with 138 additions and 85 deletions

View File

@ -1,5 +1,12 @@
import React, { useEffect, useState } from "react";
import { View, TextInput, Text, Dimensions } from "react-native";
import {
ScrollView,
TouchableOpacity,
View,
TextInput,
Text,
Dimensions
} from "react-native";
import { TabView, TabBar, SceneMap } from "react-native-tab-view";
@ -142,24 +149,26 @@ const Discover = (props) => {
return (
<>
{ state.loaded
? <>
<TouchableWithoutFeedback
onPress = { () => props.navigation.navigate("Search") }>
<View style = { styles.form }>
<View style = { styles.searchBarContainer }>
<Text style = { styles.searchBar }>
Search...
</Text>
</View>
</View>
</TouchableWithoutFeedback>
? <ScrollView>
<View style = { styles.form.container }>
<TextInput
style = { styles.form.input }
placeholder = "Search..."
onPressIn = {
() => props.navigation.navigate("Search")
}/>
<TouchableOpacity
style = { styles.form.submit }>
<Ionicons name="search" size={24} color="black" />
</TouchableOpacity>
</View>
<TabView
navigationState = { { index, routes } }
renderScene = { renderScene }
renderTabBar = { renderTabBar }
onIndexChange = { setIndex }
initialLayout = { { width: SCREEN_WIDTH } } />
</>
</ScrollView>
: <></>
}
</>
@ -169,10 +178,25 @@ const Discover = (props) => {
const SCREEN_WIDTH = Dimensions.get("window").width;
const styles = {
form: {
justifyContent: "center",
backgroundColor: "white",
padding: 20
container: {
flexDirection: "row",
justifyContent: "center",
backgroundColor: "white",
padding: 20,
},
input: {
flexGrow: 1,
padding: 10,
fontSize: 17,
color: "#888"
},
submit: {
padding: 20,
}
},
searchBar: {
padding: 10,
fontSize: 17,

View File

@ -1,5 +1,6 @@
import React, { useState, useEffect } from "react";
import {
ScrollView,
View,
TextInput,
Text,
@ -7,7 +8,7 @@ import {
Image,
} from "react-native";
import { TabView, TabBar, SceneMap } from "react-native-tab-view";
import { FontAwesome } from '@expo/vector-icons';
import { Ionicons, FontAwesome5 } from '@expo/vector-icons';
import AsyncStorage from "@react-native-async-storage/async-storage";
import * as requests from "src/requests";
@ -112,7 +113,7 @@ const Search = ({navigation}) => {
const [ routes ] = useState([
{
key: "accounts",
icon: "user",
icon: "user-alt",
},
{
key: "hashtags",
@ -152,7 +153,7 @@ const Search = ({navigation}) => {
);
const renderIcon = ({ route, color }) => (
<FontAwesome
<FontAwesome5
name = { route.icon }
size = { 24 }
color = { color } />
@ -161,7 +162,7 @@ const Search = ({navigation}) => {
return (
<>
{ state.loaded
? <>
? <ScrollView>
<View style = { styles.form.container }>
<TextInput
style = { styles.form.input }
@ -182,7 +183,7 @@ const Search = ({navigation}) => {
<TouchableOpacity
onPress = { _handleSearch }
style = { styles.form.submit }>
<FontAwesome name="search" size={24} color="black" />
<Ionicons name="search" size={24} color="black" />
</TouchableOpacity>
</View>
{ state.results
@ -194,7 +195,7 @@ const Search = ({navigation}) => {
initialLayout = { { width: SCREEN_WIDTH } } />
: <></>
}
</>
</ScrollView>
: <></>
}
</>

View File

@ -1,14 +1,14 @@
import React, { useState, useEffect } from "react";
import { View, Image, Dimensions, Text } from "react-native";
import { ScrollView, View, Image, Dimensions, Text } from "react-native";
import PagedGrid from "src/components/posts/paged-grid";
import * as requests from "src/requests";
import AsyncStorage from "@react-native-async-storage/async-storage";
const ViewHashtag = ({navigation}) => {
const ViewHashtag = ({ navigation, route }) => {
const FETCH_LIMIT = 18;
let [state, setState] = useState({
tag: navigation.getParam("tag", null),
tag: route.params.tag,
posts: [],
offset: 0,
followed: false,
@ -66,10 +66,16 @@ const ViewHashtag = ({navigation}) => {
});
};
const latest = state.tag.history[0];
// A hashtag's history describes how actively it's being used. There's
// one element in the history array for every set interval of time.
// state.tag.history may be undefined, and its length might be 0.
let latest = null;
if (state.tag.history && state.tag.history.length > 0) {
latest = state.tag.history[0];
}
return (
<>
<ScrollView>
<View>
<View style = { styles.headerContainer }>
<View>
@ -105,17 +111,19 @@ const ViewHashtag = ({navigation}) => {
</View>
<>
{ state.loaded && state.posts.length > 0
? <PagedGrid
navigation = { navigation }
posts = { state.posts }
onShowMore = { _handleShowMore } />
: <Text style = { styles.nothing }>
Nothing to show
</Text>
? state.posts.length > 0
? <PagedGrid
navigation = { navigation }
posts = { state.posts }
onShowMore = { _handleShowMore } />
: <Text style = { styles.nothing }>
Nothing to show
</Text>
: <></>
}
</>
</View>
</>
</ScrollView>
);
};

View File

@ -6,6 +6,7 @@ import {
Text,
TouchableOpacity,
FlatList,
ScrollView,
} from "react-native";
import * as Linking from "expo-linking";
@ -13,7 +14,12 @@ import AsyncStorage from "@react-native-async-storage/async-storage";
import { activeOrNot } from "src/interface/interactions";
import HTML from "react-native-render-html";
import { withLeadingAcct, withoutHTML, pluralize } from "src/interface/rendering";
import {
withLeadingAcct,
withoutHTML,
pluralize,
StatusBarSpace,
} from "src/interface/rendering";
import * as requests from "src/requests";
import GridView from "src/components/posts/grid-view";
@ -56,11 +62,11 @@ const HTMLLink = ({link}) => {
}
}
const ViewProfile = ({navigation}) => {
const ViewProfile = ({ navigation, route }) => {
// As rendered when opened from somewhere other than the tab bar
const [state, setState] = useState({
loaded: false,
profile: navigation.getParam("profile"),
profile: route.params.profile,
});
useEffect(() => {
@ -159,9 +165,7 @@ const ViewProfile = ({navigation}) => {
return (
<>
{ state.loaded
? <>
active = { navigation.getParam("originTab") }
navigation = { navigation }>
? <ScrollView>
<RawProfile
navigation = { navigation }
onFollow = { _handleFollow }
@ -172,7 +176,7 @@ const ViewProfile = ({navigation}) => {
listedUsers = { state.listedUsers }
followed = { state.followed }
posts = { state.posts }/>
</>
</ScrollView>
: <></>
}
</>
@ -184,57 +188,65 @@ const Profile = ({ navigation }) => {
loaded: false,
});
useEffect(() => {
let profile;
let notifs;
let domain;
let accessToken;
const init = async () => {
const [
profilePair,
notifPair,
instancePair,
tokenPair
] = await AsyncStorage.multiGet([
"@user_profile",
"@user_notifications",
"@user_instance",
"@user_token",
]);
AsyncStorage
.multiGet([
const profile = JSON.parse(profilePair[1]);
const notifs = JSON.parse(notifPair[1]);
const instance = instancePair[1];
const accessToken = JSON.parse(tokenPair[1]).access_token;
const latestProfile =
await requests.fetchProfile(instance, profile.id, accessToken);
const posts =
await requests.fetchAccountStatuses(instance, profile.id, accessToken);
const followers =
await requests.fetchFollowers(instance, profile.id, accessToken);
const latestProfileString = JSON.stringify(latestProfile);
// Update the profile in AsyncStorage if it's changed
if(latestProfileString != JSON.stringify(profile)) {
await AsyncStorage.setItem(
"@user_profile",
"@user_notifications",
"@user_instance",
"@user_token",
])
.then(([profilePair, notifPair, domainPair, tokenPair]) => {
profile = JSON.parse(profilePair[1]);
notifs = JSON.parse(notifPair[1]);
domain = domainPair[1];
accessToken = JSON.parse(tokenPair[1]).access_token;
latestProfileString
);
}
return Promise.all([
requests.fetchProfile(domain, profile.id),
requests.fetchAccountStatuses(domain, profile.id, accessToken),
requests.fetchFollowers(domain, profile.id, accessToken),
]);
})
.then(([latestProfile, posts, followers]) => {
if(JSON.stringify(latestProfile) != JSON.stringify(profile)) {
profile = latestProfile
}
setState({...state,
profile: profile,
notifs: notifs,
posts: posts,
setState({...state,
profile: latestProfile,
notifs: notifs,
posts: posts,
listedUsers: followers,
loaded: true,
});
});
}, []);
loaded: true,
});
};
useEffect(() => { init(); }, []);
return (
<>
<StatusBarSpace/>
{ state.loaded
? <>
? <ScrollView>
<RawProfile
navigation = { navigation }
own = { true }
profile = { state.profile }
posts = { state.posts }
listedUsers = { state.listedUsers }
listedUsers = { state.listedUsers }
notifs = { state.notifs }/>
</>
</ScrollView>
: <></>
}
</>

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect } from "react";
import {
ScrollView,
SafeAreaView,
View,
TextInput,
@ -134,7 +135,7 @@ const Settings = (props) => {
return (
<>
{ state.loaded
? <>
? <ScrollView>
<View style = { styles.avatar.container }>
<Image
source = { { uri: state.newAvatar.uri } }
@ -215,7 +216,7 @@ const Settings = (props) => {
</Text>
</TouchableOpacity>
</View>
</>
</ScrollView>
: <></>
}
</>

View File

@ -40,7 +40,7 @@ const GridView = (props) => {
&& p.media_attachments.length > 0
);
let rows = partition(props.posts, 3);
let rows = partition(postsWithMedia, 3);
return (
<View>
{

View File

@ -80,6 +80,12 @@ export const RawPost = (props) => {
});
};
useEffect(() => {
if (props.onRendered != null) {
props.onRendered();
}
}, []);
return (
<View>
<View style = { styles.postHeader }>
@ -349,6 +355,7 @@ export const PostByData = (props) => {
<RawPost
data = { state.data }
dimensions = { state.dimensions }
onRendered = { props.onRendered }
onFavourite = { _handleFavourite }
onReblog = { _handleReblog }
onBookmark = { _handleDelete }

View File

@ -104,8 +104,8 @@ export async function verifyCredentials(domain, token) {
return resp.json();
}
export async function fetchProfile(domain, id) {
const resp = await get(`https://${domain}/api/v1/accounts/${id}`);
export async function fetchProfile(domain, id, token) {
const resp = await get(`https://${domain}/api/v1/accounts/${id}`, token);
return resp.json();
}