Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(*): status for following users/starring repos #260

Merged
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions .all-contributorsrc
Expand Up @@ -248,6 +248,15 @@
"bug",
"code"
]
},
{
"login": "reyhansofian",
"name": "Reyhan Sofian",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

"avatar_url": "https://avatars2.githubusercontent.com/u/5353857?v=4",
"profile": "https://www.reyhan.tech/",
"contributions": [
"code"
]
}
]
}
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -83,5 +83,5 @@ Please take a look at the [contributing guidelines](./CONTRIBUTING.md) for a det
| :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| [<img src="https://avatars3.githubusercontent.com/u/3055294?v=3" width="100px;"/><br /><sub>Patrick Wang</sub>](https://patw.me)<br />[💻](https://github.com/gitpoint/git-point/commits?author=patw0929 "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3Apatw0929 "Bug reports") | [<img src="https://avatars5.githubusercontent.com/u/627794?v=4" width="100px;"/><br /><sub>Mike Kavouras</sub>](https://github.com/mikekavouras)<br />[💻](https://github.com/gitpoint/git-point/commits?author=mikekavouras "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3Amikekavouras "Bug reports") | [<img src="https://avatars4.githubusercontent.com/u/4848554?v=4" width="100px;"/><br /><sub>Peter Lazar</sub>](https://github.com/peterlazar1993)<br />[💻](https://github.com/gitpoint/git-point/commits?author=peterlazar1993 "Code") | [<img src="https://avatars6.githubusercontent.com/u/5106887?v=4" width="100px;"/><br /><sub>June Domingo</sub>](https://github.com/junedomingo)<br />[💻](https://github.com/gitpoint/git-point/commits?author=junedomingo "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3Ajunedomingo "Bug reports") | [<img src="https://avatars7.githubusercontent.com/u/9287184?v=4" width="100px;"/><br /><sub>Antoine Boisadam</sub>](https://github.com/Antoine38660)<br />[💻](https://github.com/gitpoint/git-point/commits?author=Antoine38660 "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3AAntoine38660 "Bug reports") | [<img src="https://avatars6.githubusercontent.com/u/13142418?v=4" width="100px;"/><br /><sub>Wang Shidong</sub>](https://wsdjeg.github.io)<br />[💻](https://github.com/gitpoint/git-point/commits?author=wsdjeg "Code") | [<img src="https://avatars4.githubusercontent.com/u/2190589?v=4" width="100px;"/><br /><sub>Swapnil Joshi</sub>](http://swapnilmj.users.sourceforge.net/)<br />[💻](https://github.com/gitpoint/git-point/commits?author=swapnilmj "Code") |
| [<img src="https://avatars5.githubusercontent.com/u/408959?v=4" width="100px;"/><br /><sub>Rolf Koenders</sub>](https://github.com/RolfKoenders)<br />[💻](https://github.com/gitpoint/git-point/commits?author=RolfKoenders "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3ARolfKoenders "Bug reports") | [<img src="https://avatars1.githubusercontent.com/u/10191084?v=4" width="100px;"/><br /><sub>Andrew Dassonville</sub>](https://andrewda.me)<br />[💻](https://github.com/gitpoint/git-point/commits?author=andrewda "Code") [💬](#question-andrewda "Answering Questions") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3Aandrewda "Bug reports") [👀](#review-andrewda "Reviewed Pull Requests") | [<img src="https://avatars0.githubusercontent.com/u/2076088?v=4" width="100px;"/><br /><sub>Anton</sub>](https://medium.com/@antondomashnev)<br />[💻](https://github.com/gitpoint/git-point/commits?author=Antondomashnev "Code") | [<img src="https://avatars0.githubusercontent.com/u/14795799?v=4" width="100px;"/><br /><sub>Xuezheng Ma</sub>](https://github.com/xuezhma)<br />[💻](https://github.com/gitpoint/git-point/commits?author=xuezhma "Code") | [<img src="https://avatars0.githubusercontent.com/u/8962228?v=4" width="100px;"/><br /><sub>Sammy Israwi</sub>](https://github.com/SammyIsra)<br />[💻](https://github.com/gitpoint/git-point/commits?author=SammyIsra "Code") [🐛](https://github.com/gitpoint/git-point/issues?q=author%3ASammyIsra "Bug reports") | [<img src="https://avatars1.githubusercontent.com/u/8122587?v=4" width="100px;"/><br /><sub>Chao Ren</sub>](https://github.com/RogerAbyss)<br />[🐛](https://github.com/gitpoint/git-point/issues?q=author%3ARogerAbyss "Bug reports") [💻](https://github.com/gitpoint/git-point/commits?author=RogerAbyss "Code") | [<img src="https://avatars0.githubusercontent.com/u/11228182?v=4" width="100px;"/><br /><sub>Harish Toshniwal</sub>](https://introwit.in)<br />[📖](https://github.com/gitpoint/git-point/commits?author=introwit "Documentation") |
| [<img src="https://avatars2.githubusercontent.com/u/774577?v=4" width="100px;"/><br /><sub>Ferran Negre</sub>](http://github.com/ferrannp)<br />[💻](https://github.com/gitpoint/git-point/commits?author=ferrannp "Code") | [<img src="https://avatars0.githubusercontent.com/u/4316908?v=4" width="100px;"/><br /><sub>Wanda Ichsanul Isra</sub>](https://www.linkedin.com/in/wlisrausr)<br />[💻](https://github.com/gitpoint/git-point/commits?author=wlisrausr "Code") | [<img src="https://avatars0.githubusercontent.com/u/25394678?v=4" width="100px;"/><br /><sub>Cameron Samuels</sub>](http://cameronsamuels.com)<br />[📖](https://github.com/gitpoint/git-point/commits?author=CameronSamuels "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/304450?v=4" width="100px;"/><br /><sub>Mehdi Achour</sub>](https://machour.idk.tn/)<br />[🐛](https://github.com/gitpoint/git-point/issues?q=author%3Amachour "Bug reports") [💻](https://github.com/gitpoint/git-point/commits?author=machour "Code") |
| [<img src="https://avatars2.githubusercontent.com/u/774577?v=4" width="100px;"/><br /><sub>Ferran Negre</sub>](http://github.com/ferrannp)<br />[💻](https://github.com/gitpoint/git-point/commits?author=ferrannp "Code") | [<img src="https://avatars0.githubusercontent.com/u/4316908?v=4" width="100px;"/><br /><sub>Wanda Ichsanul Isra</sub>](https://www.linkedin.com/in/wlisrausr)<br />[💻](https://github.com/gitpoint/git-point/commits?author=wlisrausr "Code") | [<img src="https://avatars0.githubusercontent.com/u/25394678?v=4" width="100px;"/><br /><sub>Cameron Samuels</sub>](http://cameronsamuels.com)<br />[📖](https://github.com/gitpoint/git-point/commits?author=CameronSamuels "Documentation") | [<img src="https://avatars2.githubusercontent.com/u/304450?v=4" width="100px;"/><br /><sub>Mehdi Achour</sub>](https://machour.idk.tn/)<br />[🐛](https://github.com/gitpoint/git-point/issues?q=author%3Amachour "Bug reports") [💻](https://github.com/gitpoint/git-point/commits?author=machour "Code") | [<img src="https://avatars2.githubusercontent.com/u/5353857?v=4" width="100px;"/><br /><sub>Reyhan Sofian</sub>](https://www.reyhan.tech/)<br />[💻](https://github.com/gitpoint/git-point/commits?author=reyhansofian "Code") |
<!-- ALL-CONTRIBUTORS-LIST:END -->
31 changes: 29 additions & 2 deletions src/components/repository-profile.component.js
Expand Up @@ -75,6 +75,12 @@ const styles = StyleSheet.create({
fontSize: normalize(10),
...fonts.fontPrimary,
},
unitStatus: {
textAlign: 'center',
color: colors.lighterBoldGreen,
fontSize: normalize(8),
...fonts.fontPrimary,
},
green: {
color: colors.lightGreen,
},
Expand All @@ -92,6 +98,19 @@ const styles = StyleSheet.create({
fontSize: normalize(10),
...fonts.fontPrimary,
},
badge: {
paddingTop: 3,
paddingBottom: 3,
marginTop: 5,
marginLeft: 27,
marginRight: 27,
borderWidth: 0.5,
borderRadius: 5,
borderColor: colors.lighterBoldGreen,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
},
});

export const RepositoryProfile = ({
Expand Down Expand Up @@ -167,23 +186,31 @@ export const RepositoryProfile = ({

<View style={styles.details}>
<View style={styles.unit}>
<Text style={[styles.unitNumber, starred && styles.green]}>
<Text style={styles.unitNumber}>
{!isNaN(parseInt(repository.stargazers_count, 10))
? abbreviateNumber(repository.stargazers_count)
: ' '}
</Text>
<Text style={styles.unitText}>
{translate('repository.main.starsTitle', language)}
</Text>
{starred &&
<Text style={[styles.unitStatus, styles.badge]}>
{translate('repository.main.starred', language)}
</Text>}
</View>

<View style={styles.unit}>
<Text style={[styles.unitNumber, subscribed && styles.green]}>
<Text style={styles.unitNumber}>
{!isNaN(parseInt(repository.watchers_count, 10))
? abbreviateNumber(repository.watchers_count)
: ' '}
</Text>
<Text style={styles.unitText}>Watchers</Text>
{subscribed &&
<Text style={[styles.unitStatus, styles.badge]}>
{translate('repository.main.watching', language)}
</Text>}
</View>

<View style={styles.unit}>
Expand Down
29 changes: 28 additions & 1 deletion src/components/user-profile.component.js
Expand Up @@ -9,6 +9,7 @@ type Props = {
initialUser: Object,
user: Object,
isFollowing: boolean,
isFollower: boolean,
language: string,
navigation: Object,
};
Expand Down Expand Up @@ -68,6 +69,23 @@ const styles = StyleSheet.create({
fontSize: normalize(10),
...fonts.fontPrimary,
},
unitStatus: {
textAlign: 'center',
color: colors.lighterBoldGreen,
fontSize: normalize(8),
...fonts.fontPrimary,
},
badge: {
paddingTop: 3,
paddingBottom: 3,
marginTop: 5,
marginLeft: 35,
marginRight: 35,
borderWidth: 0.5,
borderRadius: 5,
borderColor: colors.lighterBoldGreen,
justifyContent: 'center',
},
green: {
color: colors.lightGreen,
},
Expand All @@ -78,6 +96,7 @@ export const UserProfile = ({
initialUser,
user,
isFollowing,
isFollower,
language,
navigation,
}: Props) =>
Expand Down Expand Up @@ -132,12 +151,16 @@ export const UserProfile = ({
followerCount: user.followers > 15 ? 15 : user.followers,
})}
>
<Text style={[styles.unitNumber, isFollowing && styles.green]}>
<Text style={styles.unitNumber}>
{!isNaN(parseInt(user.followers, 10)) ? user.followers : ' '}
</Text>
<Text style={styles.unitText}>
{translate('common.followers', language)}
</Text>
{isFollowing &&
<Text style={[styles.unitStatus, styles.badge]}>
{translate('common.following', language)}
</Text>}
</TouchableOpacity>}

{type !== 'org' &&
Expand All @@ -156,6 +179,10 @@ export const UserProfile = ({
<Text style={styles.unitText}>
{translate('common.following', language)}
</Text>
{isFollower &&
<Text style={[styles.unitStatus, styles.badge]}>
{translate('user.followYou.title')}
</Text>}
</TouchableOpacity>}
</View>
</View>;
1 change: 1 addition & 0 deletions src/config/colors.js
Expand Up @@ -12,6 +12,7 @@ export const colors = {
greyMidLight: '#f6f8fa',
greyVeryLight: '#fbfbfb',
lightGreen: '#00FF00',
lighterBoldGreen: '#359d68',
green: '#2cbe4e',
darkGreen: '#27ae60',
red: '#ee0701',
Expand Down
8 changes: 8 additions & 0 deletions src/locale/languages/en.js
@@ -1,3 +1,6 @@
// Hash: 01ae4880b9b4296907d680e9b909713c36c42491
// Link: https://github.com/gitpoint/git-point/pull/260

export const en = {
auth: {
login: {
Expand Down Expand Up @@ -156,6 +159,9 @@ export const en = {
followingList: {
title: 'Following',
},
followYou: {
title: 'Follows you',
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As part of trying to streamline translation updates, could you add a comment to the top of en.js with the commit hash and link to the PR? That way we can sort of be able to tell if translations are not the same between multiple different languages.

CC @machour

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will do

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And what if you add new phrases for translation into all language files? Then it will be clear what needs to be translated in other languages. In fact, we need to do this, because we get the situation that in the English version we have followYou, and in that case there will be an error (missing value) in other languages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realised that we have France translation. I will add the followYou key there

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make it fall back on the English translation if a phrase doesn't exist in a certain language? That would make everything a lot smoother IMO, and make it so we don't have to update every language in small PR's.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@housseindjirdeh no need to do that for the en.js file, this is only for translators to keep some kind of internal record.

+1 on @andrewda request, we need a fallback to english and developers shouldn't have to touch translations files. It used to be the case with the previous system.

@reyhansofian if you do touch the french file, here's the translation: "Vous suit".

},
repository: {
main: {
Expand Down Expand Up @@ -185,6 +191,8 @@ export const en = {
starsTitle: 'Stars',
forksTitle: 'Forks',
forkedFromMessage: 'forked from',
starred: 'Starred',
watching: 'Watching',
},
codeList: {
title: 'Code',
Expand Down
3 changes: 3 additions & 0 deletions src/locale/languages/fr.js
Expand Up @@ -161,6 +161,9 @@ export const fr = {
followingList: {
title: 'Following',
},
followYou: {
title: 'Vous suit',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

},
},
repository: {
main: {
Expand Down
16 changes: 1 addition & 15 deletions src/user/screens/follower-list.screen.js
Expand Up @@ -3,32 +3,20 @@ import { connect } from 'react-redux';
import { FlatList, View } from 'react-native';

import { ViewContainer, UserListItem, LoadingUserListItem } from 'components';
import { getFollowers } from 'user';

const mapStateToProps = state => ({
user: state.user.user,
followers: state.user.followers,
isPendingFollowers: state.user.isPendingFollowers,
});

const mapDispatchToProps = dispatch => ({
getFollowers: (user, type) => dispatch(getFollowers(user, type)),
});

class FollowerList extends Component {
props: {
getFollowers: Function,
followers: Array,
isPendingFollowers: boolean,
navigation: Object,
};

componentDidMount() {
const user = this.props.navigation.state.params.user;

this.props.getFollowers(user);
}

keyExtractor = item => {
return item.id;
};
Expand Down Expand Up @@ -63,6 +51,4 @@ class FollowerList extends Component {
}
}

export const FollowerListScreen = connect(mapStateToProps, mapDispatchToProps)(
FollowerList
);
export const FollowerListScreen = connect(mapStateToProps)(FollowerList);
11 changes: 11 additions & 0 deletions src/user/screens/profile.screen.js
Expand Up @@ -23,7 +23,9 @@ import { colors, fonts } from 'config';
import { getUserInfo, changeFollowStatus } from '../user.action';

const mapStateToProps = state => ({
auth: state.auth.user,
user: state.user.user,
followers: state.user.followers,
orgs: state.user.orgs,
language: state.auth.language,
isFollowing: state.user.isFollowing,
Expand Down Expand Up @@ -53,7 +55,9 @@ class Profile extends Component {
props: {
getUserInfoByDispatch: Function,
changeFollowStatusByDispatch: Function,
auth: Object,
user: Object,
followers: Array,
orgs: Array,
language: string,
isFollowing: boolean,
Expand Down Expand Up @@ -102,6 +106,12 @@ class Profile extends Component {
}
};

isFollower = () => {
const { auth, followers } = this.props;

return followers.filter(follower => follower.login === auth).legth > 0;
};

render() {
const {
user,
Expand Down Expand Up @@ -132,6 +142,7 @@ class Profile extends Component {
isFollowing={
isPendingUser || isPendingCheckFollowing ? false : isFollowing
}
isFollower={this.isFollower}
user={initialUser.login === user.login ? user : {}}
language={language}
navigation={navigation}
Expand Down
45 changes: 23 additions & 22 deletions src/user/user.action.js
Expand Up @@ -85,13 +85,36 @@ export const checkFollowStatus = url => {
};
};

export const getFollowers = user => {
return (dispatch, getState) => {
const accessToken = getState().auth.accessToken;

dispatch({ type: GET_FOLLOWERS.PENDING });

fetchUrl(`${USER_ENDPOINT(user.login)}/followers?per_page=100`, accessToken)
.then(data => {
dispatch({
type: GET_FOLLOWERS.SUCCESS,
payload: data,
});
})
.catch(error => {
dispatch({
type: GET_FOLLOWERS.ERROR,
payload: error,
});
});
};
};

export const getUserInfo = user => {
return dispatch => {
return dispatch(getUser(user)).then(() => {
dispatch(getOrgs(user));
dispatch(
checkFollowStatus(`https://api.github.com/user/following/${user}`)
);
dispatch(getFollowers(user));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming we fire this to get the list of followers as soon as a user navigates to the user profile screen so that we can determine whether we're following them correct? If that's the case, it's also currently being fired in the follower-list.screen so we'll need to remove it there to prevent it being called unnecessarily for the second time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exactly! I'll remove that action on follower-list.screen. Thanks for pointing out 👍

});
};
};
Expand Down Expand Up @@ -149,28 +172,6 @@ export const getRepositories = user => {
};
};

export const getFollowers = user => {
return (dispatch, getState) => {
const accessToken = getState().auth.accessToken;

dispatch({ type: GET_FOLLOWERS.PENDING });

fetchUrl(`${USER_ENDPOINT(user.login)}/followers?per_page=100`, accessToken)
.then(data => {
dispatch({
type: GET_FOLLOWERS.SUCCESS,
payload: data,
});
})
.catch(error => {
dispatch({
type: GET_FOLLOWERS.ERROR,
payload: error,
});
});
};
};

export const getFollowing = user => {
return (dispatch, getState) => {
const accessToken = getState().auth.accessToken;
Expand Down
2 changes: 2 additions & 0 deletions src/utils/method-helpers.js
Expand Up @@ -37,6 +37,8 @@ export const translate = (key, lang, interpolation = null) =>

export const configureLocale = language => {
I18n.locale = language;
I18n.fallbacks = true;

moment.updateLocale(language, {
relativeTime: translate('common.relativeTime', language),
});
Expand Down