Add entrypoint to ViewProfile from a post's header
This commit is contained in:
parent
5c42133e53
commit
f133458df6
|
@ -12,93 +12,30 @@ import * as Linking from "expo-linking";
|
||||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
|
|
||||||
import { activeOrNot } from "src/interface/interactions";
|
import { activeOrNot } from "src/interface/interactions";
|
||||||
import { withoutHTML } from "src/interface/rendering";
|
import { withoutHTML, pluralize } from "src/interface/rendering";
|
||||||
import * as requests from "src/requests";
|
import * as requests from "src/requests";
|
||||||
|
|
||||||
import GridViewJsx from "src/components/posts/grid-view";
|
import GridViewJsx from "src/components/posts/grid-view";
|
||||||
import {
|
import {
|
||||||
ScreenWithTrayJsx,
|
ScreenWithTrayJsx,
|
||||||
ScreenWithFullNavigationJsx
|
ScreenWithBackBarJsx,
|
||||||
} from "src/components/navigation/navigators";
|
} from "src/components/navigation/navigators";
|
||||||
|
|
||||||
import ModerateMenuJsx from "src/components/moderate-menu.js";
|
import ModerateMenuJsx from "src/components/moderate-menu.js";
|
||||||
|
|
||||||
const TEST_IMAGE = "https://cache.desktopnexus.com/thumbseg/2255/2255124-bigthumbnail.jpg";
|
|
||||||
const TEST_POSTS = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
media_attachments: [
|
|
||||||
{preview_url: TEST_IMAGE}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
media_attachments: [
|
|
||||||
{preview_url: TEST_IMAGE}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
media_attachments: [
|
|
||||||
{preview_url: TEST_IMAGE}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
media_attachments: [
|
|
||||||
{preview_url: TEST_IMAGE}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const TEST_PROFILE = {
|
|
||||||
username: "njms",
|
|
||||||
acct: "njms",
|
|
||||||
display_name: "Nat🔆",
|
|
||||||
locked: false,
|
|
||||||
bot: false,
|
|
||||||
note: "Yeah heart emoji.",
|
|
||||||
avatar: TEST_IMAGE,
|
|
||||||
followers_count: "1 jillion",
|
|
||||||
statuses_count: 334,
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: "Blog",
|
|
||||||
value: "<a href=\"https://njms.ca\">https://njms.ca</a>",
|
|
||||||
verified_at: "some time"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Github",
|
|
||||||
value: "<a href=\"https://github.com/natjms\">https://github.com/natjms</a>",
|
|
||||||
verified_at: null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const TEST_YOUR_FOLLOWERS = [
|
|
||||||
{ id: 1 },
|
|
||||||
{ id: 2 },
|
|
||||||
{ id: 3 },
|
|
||||||
{ id: 4 },
|
|
||||||
{ id: 5 },
|
|
||||||
];
|
|
||||||
|
|
||||||
const TEST_THEIR_FOLLOWERS = [
|
|
||||||
{ id: 2 },
|
|
||||||
{ id: 3 },
|
|
||||||
{ id: 4 },
|
|
||||||
{ id: 6 },
|
|
||||||
];
|
|
||||||
|
|
||||||
function getMutuals(yourFollowing, theirFollowers) {
|
function getMutuals(yourFollowing, theirFollowers) {
|
||||||
// Where yours and theirs are arrays of followers, as returned by the API
|
// Where yours and theirs are arrays of followers, as returned by the API
|
||||||
// Returns a list of people you are following that are following some other
|
// Returns a list of people you are following that are following some other
|
||||||
// account
|
// account
|
||||||
|
|
||||||
const acctsArray = ({acct}) => acct;
|
const getAcct = ({acct}) => acct;
|
||||||
const asIDs = new Set(theirFollowers.map(acctArray));
|
const theirsAsAccts = new Set(
|
||||||
|
theirFollowers.map(({acct}) => acct)
|
||||||
|
);
|
||||||
|
|
||||||
return yourFollowing.filter(x => asIDs.has(idify(x)));
|
return yourFollowing.filter(x =>
|
||||||
|
theirsAsAccts.has(x.acct)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const HTMLLink = ({link}) => {
|
const HTMLLink = ({link}) => {
|
||||||
|
@ -129,18 +66,16 @@ const ViewProfileJsx = ({navigation}) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let ownProfile, ownDomain, accessToken, domain;
|
||||||
AsyncStorage
|
AsyncStorage
|
||||||
.multiGet(["@user_profile", "@user_instance", "@user_token"])
|
.multiGet(["@user_profile", "@user_instance", "@user_token"])
|
||||||
.then(([ownProfilePair, ownDomainPair, tokenPair]) =>
|
.then(([ ownProfilePair, ownDomainPair, tokenPair ]) => {
|
||||||
[
|
ownProfile = JSON.parse(ownProfilePair[1]);
|
||||||
JSON.parse(ownProfilePair[1]),
|
ownDomain = ownDomainPair[1];
|
||||||
ownDomainPair[1],
|
accessToken = JSON.parse(tokenPair[1]).access_token;
|
||||||
JSON.parse(tokenPair[1]).access_token,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
.then(([ ownProfile, ownDomain, accessToken ]) => {
|
|
||||||
const parsedAcct = state.profile.acct.split("@");
|
const parsedAcct = state.profile.acct.split("@");
|
||||||
const domain = parsedAcct.length == 1
|
domain = parsedAcct.length == 1
|
||||||
? ownDomain // There's no @ in the acct, thus it's a local user
|
? ownDomain // There's no @ in the acct, thus it's a local user
|
||||||
: parsedAcct [1] // The part of profile.acct after the @
|
: parsedAcct [1] // The part of profile.acct after the @
|
||||||
|
|
||||||
|
@ -155,26 +90,35 @@ const ViewProfileJsx = ({navigation}) => {
|
||||||
state.profile.id,
|
state.profile.id,
|
||||||
accessToken
|
accessToken
|
||||||
),
|
),
|
||||||
|
requests.fetchAccountStatuses(
|
||||||
|
// NOTE: Should be fetched from remote instance if
|
||||||
|
// necessary Thus, we use domain and not ownDomain
|
||||||
|
domain,
|
||||||
|
state.profile.id,
|
||||||
|
accessToken
|
||||||
|
)
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
.then(([ ownFollowing, theirFollowers ]) =>
|
.then(([ ownFollowing, theirFollowers, posts ]) => {
|
||||||
setState({...state,
|
setState({...state,
|
||||||
mutuals: getMutuals(ownFollowing, theirFollowers),
|
mutuals: getMutuals(ownFollowing, theirFollowers),
|
||||||
|
posts: posts,
|
||||||
loaded: true,
|
loaded: true,
|
||||||
})
|
});
|
||||||
);
|
});
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ state.loaded
|
{ state.loaded
|
||||||
? <ScreenWithFullNavigationJsx
|
? <ScreenWithBackBarJsx
|
||||||
active = { navigation.getParam("originTab") }
|
active = { navigation.getParam("originTab") }
|
||||||
navigation = { navigation }>
|
navigation = { navigation }>
|
||||||
<RawProfileJsx
|
<RawProfileJsx
|
||||||
profile = { state.profile }
|
profile = { state.profile }
|
||||||
|
mutuals = { state.mutuals }
|
||||||
notifs = { state.notifs }
|
notifs = { state.notifs }
|
||||||
posts = { TEST_POSTS }/>
|
posts = { state.posts }/>
|
||||||
</ScreenWithFullNavigationJsx>
|
</ScreenWithBackBarJsx>
|
||||||
: <></>
|
: <></>
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
|
@ -330,7 +274,16 @@ const RawProfileJsx = (props) => {
|
||||||
{
|
{
|
||||||
props.own ?
|
props.own ?
|
||||||
<>View followers</>
|
<>View followers</>
|
||||||
: <>{ props.mutuals + " mutuals" }</>
|
: <>
|
||||||
|
{
|
||||||
|
props.mutuals.length
|
||||||
|
+ pluralize(
|
||||||
|
props.mutuals.length,
|
||||||
|
" mutual",
|
||||||
|
" mutuals"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -4,8 +4,8 @@ import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
Dimensions,
|
Dimensions,
|
||||||
TouchableWithoutFeedback,
|
TouchableOpacity,
|
||||||
ScrollView
|
ScrollView,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
|
|
||||||
import { pluralize, timeToAge} from "src/interface/rendering"
|
import { pluralize, timeToAge} from "src/interface/rendering"
|
||||||
|
@ -71,15 +71,25 @@ export const RawPostJsx = (props) => {
|
||||||
+ pluralize(repliesCount, " comment", " comments");
|
+ pluralize(repliesCount, " comment", " comments");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _handleProfileButton = () => {
|
||||||
|
props.navigation.navigate("ViewProfile", {
|
||||||
|
profile: props.data.account,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<View style = { styles.postHeader }>
|
<View style = { styles.postHeader }>
|
||||||
|
<TouchableOpacity onPress = { _handleProfileButton }>
|
||||||
<Image
|
<Image
|
||||||
style = { styles.pfp }
|
style = { styles.pfp }
|
||||||
source = { { uri: props.data.account.avatar } } />
|
source = { { uri: props.data.account.avatar } } />
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity onPress = { _handleProfileButton }>
|
||||||
<Text style = { styles.postHeaderName }>
|
<Text style = { styles.postHeaderName }>
|
||||||
{ props.data.account.acct }
|
{ props.data.account.acct }
|
||||||
</Text>
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
<ModerateMenuJsx
|
<ModerateMenuJsx
|
||||||
containerStyle = { styles.menu }
|
containerStyle = { styles.menu }
|
||||||
triggerStyle = { styles.ellipsis } />
|
triggerStyle = { styles.ellipsis } />
|
||||||
|
@ -118,7 +128,7 @@ export const RawPostJsx = (props) => {
|
||||||
</Text>
|
</Text>
|
||||||
{ props.data.content }
|
{ props.data.content }
|
||||||
</Text>
|
</Text>
|
||||||
<TouchableWithoutFeedback
|
<TouchableOpacity
|
||||||
onPress = {
|
onPress = {
|
||||||
() => props.navigation.navigate("ViewComments", {
|
() => props.navigation.navigate("ViewComments", {
|
||||||
originTab: props.navigation.getParam("originTab"),
|
originTab: props.navigation.getParam("originTab"),
|
||||||
|
@ -128,7 +138,7 @@ export const RawPostJsx = (props) => {
|
||||||
<View>
|
<View>
|
||||||
<Text style = { styles.comments }>{ commentsText }</Text>
|
<Text style = { styles.comments }>{ commentsText }</Text>
|
||||||
</View>
|
</View>
|
||||||
</TouchableWithoutFeedback>
|
</TouchableOpacity>
|
||||||
|
|
||||||
<Text style = { styles.captionDate }>
|
<Text style = { styles.captionDate }>
|
||||||
{ timeToAge(Date.now(), (new Date(props.data.created_at)).getTime()) }
|
{ timeToAge(Date.now(), (new Date(props.data.created_at)).getTime()) }
|
||||||
|
|
Loading…
Reference in New Issue