-
Notifications
You must be signed in to change notification settings - Fork 783
feat: Issue Events #438
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: Issue Events #438
Conversation
TODO:
|
Of course they are a lot of them, but you need to add support for everyone. We can create a test issue, and there apply different actions to show all the events for you.
And yet, it's better to show it the way it's presented on GitHub. You can do this, as I understand it, by comparing the date of the event?
This is not difficult, as an example you can see how it was done on the event screen. An example for the repository cloning event is going to the repository screen. |
: 'added this to'; | ||
|
||
return ( | ||
<View style={[styles.container, styles.header]}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think we need to have all of these separate components for each specific use case? Will it be possible to have 2 or 3 and then with props, be able to extend their icon
, user
and descriptions
for example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, i see exactly what you're saying. i was handling actor
s poorly at first, so i wasn't quite sure what the more abstract component would look like yet. it makes sense now tho
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries, always easier to start laying down and then refactoring it slightly :)
Cheers, otherwise I can't see much I would change. This is really coming together nicely mate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and don't forget to add yourself as a contributor with yarn contributors:add
:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks so crisp @brandly, thank you. This is so useful and really something we've needed in the app.
Don't forget to add yourself as a contributor! And WELCOME 🎉
Agree with @lex111 on all the cases, happy to test out any case with you.
With regards to combining multiple label changes into one ListItem - I actually think the way it is currently (with label change on a separate line) looks quite fine from the screenshot. Would probably be okay with having this included first and then deciding to include multiple in the same listitem if we all think that would be preferred.
Yep including links are relatively straightforward. You'll just need to add an onPress
prop with a callback to navigate to a specific screen. You can see an example of how I use it for UserListItem
here where I make it a TouchableOpacity
if I need it to be a link and otherwise it's just View
(Views
don't have an onPress
prop)
thanks!! i've been using this app for a while on my phone, so i'm glad to help out. i'm really impressed at how everything's put together here.
most of the time, it looks fine, but when there are a lot of label changes, grouping the labels is a big improvement. i started implementing this already. the logic for grouping label events together is working, but i'm still figuring out some of the styling. i created a new component for rending labels inline, but when i render a export class InlineLabel extends Component {
props: {
label: Object,
}
render() {
const { color, name } = this.props.label;
return (
<Text
style={{
backgroundColor: '#' + color,
color: getFontColorByBackground(color),
// Doesn't affect anything??
padding: 10,
margin: 10,
}}
>
{name}
</Text>
);
}
} ^ that component nested in some other is this the wrong approach? we could also postpone this for a later PR.
that makes sense! is the thanks for the feedback 🙏 |
@brandly I love it! ❤️ Hopefully you unterstand what i mean. |
for the remaining unimplemented events, i'm having trouble getting my hands on the data i need to render what github shows in their UIs. for example, if you hit the events api, there's an i implemented @housseindjirdeh i created an with regards to (un)labeled events, in rare situations of changing several labels, it sure takes up a lot of vertical space: as mentioned in my previous comment, i'm not sure how to inline things and make them look nice. using so i'm okay with postponing grouping (un)labeled events into a single row, but the current implementation has some shortcomings. i'm excited to see these in the app! let me know what you think of all this! |
got the labels working 🎃 seems as tho if you have this: <Text>
<Text></Text>
<Text></Text>
<Text></Text>
</Text> the inner <View>
<Text></Text>
<Text></Text>
<Text></Text>
</View> now, it looks like words only break/wrap between each
|
@@ -38,6 +38,31 @@ const styles = StyleSheet.create({ | |||
}, | |||
}); | |||
|
|||
export class InlineLabel extends Component { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might deserve its own file. We usually only create 1 component per file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's fair. i mainly wanted to share the getFontColorByBackground
function. is there an ideal location i should move that to so i can share it between components?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh, getFontColorByBackground
might be a good thing to move to src/utils
so we can access it from everywhere consistently!
src/issue/screens/issue.screen.js
Outdated
@@ -10,13 +10,14 @@ import { | |||
Platform, | |||
} from 'react-native'; | |||
import { Icon } from 'react-native-elements'; | |||
|
|||
import moment from 'moment/min/moment-with-locales.min'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a blank line after the moment import so we can separate external imports from local components.
src/issue/screens/issue.screen.js
Outdated
} | ||
|
||
// Merge events are always followed by a closed event, but we don't | ||
// want to render them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good thinking 👍
src/issue/screens/issue.screen.js
Outdated
} | ||
|
||
return results; | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of this logic might be able to be moved out into a src/utils
file so we can test it easier, but it's not the end of the world if that doesn't happen right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, this would be good to test. i don't see much testing going on currently. am i overlooking it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#407 is where the tests are being added
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed there's quite a bit of logic here that I would like to see tested (once we have our initial tests added). Definitely something we can do a bit later however.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
|
||
return 0; | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about (a, b) => a.created_at - b.created_at
? So that we can omit this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think created_at
is a date string, so i don't think we can -
them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brandly Yes, my mistake. 🙈
owner: string, | ||
repoName: string, | ||
issueNum: number, | ||
accessToken: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Types make function declaration clearer. But in other functions we never write them.
Means a lot mate, thank you <3
Nice, looking at that screenshot it definitely looks like grouping them together looks a lot nicer! And yep you got it, wrapping in a
Hmm if we're talking low level components - it usually makes sense to have callbacks passed upwards so the parent can take care of navigating. Because you have specific actions
Yep I was just thinking I really don't know if it's possible to have a single component to take care of all cases. We probably can if we extend more props but not sure if that makes things cleaner or not. Will go through your PR first thing tomorrow morning and let you know what I think :)
Labels are looking beautiful mate. Appreciate you taking the time to try and make them inline work nicely 💃 Super excited to get this in the app soon 🙏 |
you can press usernames now! it looks like commit pages are currently getting built, so i'm under impression we can't make the besides that, i think the only real shortcoming here is that i can't figure out how to get the necessary data for certain events, as described in an earlier comment. thanks for all the quick feedback! makes it easy to get involved here for the first time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments about structure. Only thing I can see is maybe we can further simplify how you've set up your Events components and one referenced
issue bug displaying. Otherwise this really is solid stuff mate 🙌
@@ -384,6 +384,13 @@ | |||
] | |||
}, | |||
{ | |||
"login": "brandly", | |||
"name": "Matthew Brandly", | |||
"avatar_url": "https://avatars3.githubusercontent.com/u/820696?v=4", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
src/issue/screens/issue.screen.js
Outdated
} | ||
|
||
return results; | ||
}, []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed there's quite a bit of logic here that I would like to see tested (once we have our initial tests added). Definitely something we can do a bit later however.
src/issue/screens/issue.screen.js
Outdated
const fullComments = !isPendingComments ? [issue, ...comments] : []; | ||
const isShowLoadingContainer = | ||
isPendingComments || isPendingIssue || isPendingEvents; | ||
const fullEvents = !isPendingComments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since fullEvents
is essentially everything (issue description, comments and events), maybe we can find a better name for this. fullConversation
or something? (Not sure if that's any better however 😂 😭)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i took care of this naming, while extracting that chunk of logic into utils/
for future testing.
import { colors } from 'config'; | ||
|
||
export const getFontColorByBackground = bgColor => { | ||
const r = parseInt(bgColor.substr(0, 2), 16); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
} | ||
} | ||
|
||
class Locked extends Component { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like how we have a base Event
component that's being used for other scenarios, but still think we can probably simplify things here a bit. Instead of having each component here take in the event and decide which icon to use, etc.., we can probably extend this with props. For example:
class EventInstance extends Component {
props: {
icon: string,
iconColor: color,
createdAt: string,
textChildren: React.Element<*>,
};
render() {
const {
name,
iconColor = '#586069',
iconBackgroundColor = '#E6EBF1',
createdAt,
textChildren
} = this.props;
const action = this.props.unassigned ? 'unassigned' : 'assigned';
return (
<Event
icon={
<Icon
iconStyle={{
marginLeft: marginLeftForIconName(name),
marginTop: 1,
color: iconColor,
}}
containerStyle={[styles.iconContainer, { iconBackgroundColor }]}
name={icon}
type="octicon"
size={16}
/>
}
text={
<Text style={{ padding: 3 }}>
{textChildren}
</Text>
}
createdAt={createdAt}
/>
);
}
}
If you think it makes sense to have a Event
component specified on it's own, then we can probably use something like this EventInstance
everywhere instead of having Locked
, Headref
, etc.. which are essentially the same components with slight variations. Please let me know what you think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notice how I'm just referencing Icon
directly. Don't know if it's worth creating an EventIcon
if we use a component like the above everywhere in my opinion as it'll only be used in one place (this component)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think i see what you're saying. i'm happy to rearrange things, but i want to make my case first 😄. i'm not trying to argue or to even say that things are ideal how they're currently implemented, but i want to understand more of the why you'd prefer things to be structured differently.
the more react
i've written, the more i've tended to break things apart into a bunch of small components. these components can be composed together to build larger structures.
you seem to be somewhat against tiny components like Bold
. in several different places surrounding inline text, i could write <Text style={styles.boldText}>
or i could pull that out into <Bold>
, allowing me to write nice things like
changed the title from <Bold>{event.rename.from.trim()}</Bold>{' '}
to <Bold>{event.rename.to.trim()}</Bold>
isn't this encapsulation the point of react?
similarly, i could get rid of <EventIcon>
, but even if it's only in like 2 or 3 spots, i'd always be setting the same name
, size
, and containerStyle
on an Icon
. why not pull it out?
as a project grows, i tend to build up a library of these small components. even if the small components are relatively context specific, refactoring tends to feel easy, cause i can often just build a new component using a few existing building blocks and be done with it.
y'all have invested way more into this project than i have, so i'm happy to structure things as you'd like. it just feels as tho i'd end up with more duplication and larger, more complex render
functions, neither of which i'm a big fan of. however, i could just be misunderstanding you or missing something altogether.
thanks again!!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh no please don't ever hesitate to let us know what you're thinking mate :)
Yeah everyone designs their component renders in different ways. I just happen to lean towards creating sub-components if I feel like they could live as separate entity in the components directory and be used throughout the app. However you're right, there's definitely benefit to break things down within the same component file and not have large render methods spread out across the app.
Definitely see where you're coming from trying to arrange things the way I suggested in causing large, duplicated logic. Perfectly fine with the way you've set things up if you feel like this is a nicer way to structure things in the file 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i refactored some things in the direction you suggested, and i really like how things ended up!
<Event>
became a bit more powerful, and i was able to eliminate most of the smaller components. <LabelGroup>
has to make quite a few decisions, so it held on. <Bold>
and <ActorLink>
still feel useful, so i kept them around too.
things feel more simple! let me know what you think 💯
|
||
class Event extends Component { | ||
props: { | ||
icon: Object, // TODO: enforce react instance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
React.Element<*>
should do the trick 🎉
} | ||
} | ||
|
||
class Bold extends Component { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For Date
and Bold
, if you consider my suggestion to begin to use EventInstance
or a component name similarly everywhere and if these components aren't being used more than once, we can probably remove their isolations. Otherwise this is fine 👍
createdAt={event.created_at} | ||
/> | ||
); | ||
// case 'referenced': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the commented out cases conditions you just can't test? Noticing this when I view this issue #439
Not sure why this is happening however 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, the most recent commit should've removed that. i had that in for development purposes.
@brandly just wanted to check in - are you still adding commits to this or do you think it's in a state where we can merge in? If it's the latter, will pull it down again, give it one more run through and if all is good we can merge this baby in |
@housseindjirdeh hey, i think things are stable! this comment got buried. let me know what you think of the current state of things! i'm pretty happy with it. |
Oops that did get buried, I'm sorry for missing it. Going through the codebase and it looks beautiful mate, appreciate you taking some of my considerations into account 🎉 . Going to pull this down and test it one more time tomorrow and keep you posted 🙌 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for not getting to this sooner mate.
It looks SOLID
There are some tiny things I'm noticing (the link is a TouchableHighlight while comment user links use TouchableOpacity + the labels are slightly more bold than the labels up top in the issue description). All that can be taken care of in another PR however :)
Please feel free to open an issue for the unimplemented events so we can keep track of it. Again thank you, this looks noicee
* feat(issue_events): Show events on issues * style(issue_events): Added styles to "added label" event * style(issue_events): Add icon & improve styling of added labels * style(issue_events): Improve <ReviewRequested /> styles * feat(issue_events): Remove mentioned/subscribed events from UI * feat(issue_events): Define <Closed /> events * refactor(issue_events): Extract <EventIcon /> and <Date /> * feat(issue_events): Add `unlabled` prop to <Labeled /> * feat(issue_events): Define <Merged /> event * feat(issue_events): Filter out `closed` events preceded by `merged` * feat(issue_events): Define <HeadRef /> events * feat(issue_events): Define <Assigned /> events * feat(issue_events): Define <Reopened /> & <Renamed /> events * refactor(issue_events): Render <Text /> from <ActorLink /> * style(issue_events): Trim issue names to ensure spacing * feat(issue_events): Define <Locked /> event * feat(issue_events): Define <Milestoned /> event * refactor(issue_events): Clean up authUser from LabeledComponent * feat(issue_events): Define <MarkedAsDuplicate /> event * refactor(issue_events): Define generic <Event /> component * docs(readme): Add @brandly as a contributor * feat(issue_events): Define <LabelGroup /> for list of label changes * refactor(issue_events): Use spread operator for textChildren * style(issue_events): Add blank line after external imports * feat(issue_events): <InlineLabel /> has rounded corners * refactor(issue_events): Move <InlineLabel /> into own file * feat(issue_events): Press username in events to view profile * refactor(events): Inline most <Event />s into <IssueEventListItem /> * refactor(events): Eliminate <Date /> since its only used once * refactor(events): Extract formatEventsToRender into event-helpers
i was away from my computer for a few days, so i'm excited to come back to a merged PR! thanks again |
* refactor(fonts): Remove useless fonts in android (#485) * refactor(fonts): Remove MaterialIcons from used fonts in android (#485) BREAKING CHANGE: Update link script in Package.json * Revert "refactor(fonts): Remove MaterialIcons from used fonts in android (#485)" This reverts commit 282f475. * fix: Update stateRandom and reset cookies after a successful login (#494) * feat(markdown): Add support for quoted emails (#501) * feat(markdown): Add support for quoted emails * fix: use paddingHorizontal instead of Left and Right * refactor: Drop rn-app-intro in favor of react-native-swiper (#493) * refactor: Drop rn-app-intro in favor of react-native-swiper * fix: Don't embed swiper in a View, so that it works on Android * chore: Hide the commitlint folder (#488) * feature(translation): add Spanish translation (#442) * Spanish file (first translation) * Languague related files * Fix * Replaced double quotes * Improved spanish translation * Minor improvements (spanish translation) * Some improvements (spanish translation) The GIT reserved words are kept without translate. * Removed english phrase * Updated analytics title * Updated spanish translation * Added missing fields (spanish translation) * Replaced tabs (spanish translation) * Changed some words to downcase (spanish translation) * feat: Issue Events (#438) * feat(issue_events): Show events on issues * style(issue_events): Added styles to "added label" event * style(issue_events): Add icon & improve styling of added labels * style(issue_events): Improve <ReviewRequested /> styles * feat(issue_events): Remove mentioned/subscribed events from UI * feat(issue_events): Define <Closed /> events * refactor(issue_events): Extract <EventIcon /> and <Date /> * feat(issue_events): Add `unlabled` prop to <Labeled /> * feat(issue_events): Define <Merged /> event * feat(issue_events): Filter out `closed` events preceded by `merged` * feat(issue_events): Define <HeadRef /> events * feat(issue_events): Define <Assigned /> events * feat(issue_events): Define <Reopened /> & <Renamed /> events * refactor(issue_events): Render <Text /> from <ActorLink /> * style(issue_events): Trim issue names to ensure spacing * feat(issue_events): Define <Locked /> event * feat(issue_events): Define <Milestoned /> event * refactor(issue_events): Clean up authUser from LabeledComponent * feat(issue_events): Define <MarkedAsDuplicate /> event * refactor(issue_events): Define generic <Event /> component * docs(readme): Add @brandly as a contributor * feat(issue_events): Define <LabelGroup /> for list of label changes * refactor(issue_events): Use spread operator for textChildren * style(issue_events): Add blank line after external imports * feat(issue_events): <InlineLabel /> has rounded corners * refactor(issue_events): Move <InlineLabel /> into own file * feat(issue_events): Press username in events to view profile * refactor(events): Inline most <Event />s into <IssueEventListItem /> * refactor(events): Eliminate <Date /> since its only used once * refactor(events): Extract formatEventsToRender into event-helpers * fix(ux): Add back button for AuthProfileScreen (#507) Adds back button when AuthProfileScreen is not the root of a StackNavigator. Ps. AuthProfileScreen is StackNavigator root when the routeName is MyProfile. * style(issueeventlistitem, commentlistitem): Slightly shrink issue event badges + change user click o (#516) * fix: Remove undefined var & fix typo (#517) * chore: fix `yarn run link` (#513) * chore(fonts): Not link all fonts from react-native-vector-icons * fix(fonts): Add the missing Menlo * fix(cli): Fix for RN 0.48 * chore(cli): Run `yarn run link` again * chore(*): convert notification icon styles to styled-component (#510) Convert notification-icon.component.js to use styled-components as part of #503 * chore(*): convert label-list-item component styles to styled component (#509) Converted the label-list-item component styles to styled-components * chore(*): style view-container.component.js (#508) Converted view-container.component.js to use styled components BREAKING CHANGE: none none * refactor(auth): get user data after login (#502) * test: begin implementing basic component tests (#407) * test: begin implementing tests * test: add more tests * test: add Buton and Badge tests * test: add StateBadge test * test: only import used enzyme wrappers * chore(deps): update table component to 1.1.0 * test: Add tests for ToggleView * Update ToggleView.js * refactor(fonts): Remove useless fonts in android (#485) * refactor(fonts): Remove MaterialIcons from used fonts in android (#485) BREAKING CHANGE: Update link script in Package.json * Revert "refactor(fonts): Remove MaterialIcons from used fonts in android (#485)" This reverts commit 282f475. * test: Add tests for CommentInput (#518) * refactor: Beautify the code of CommentInput unit test. * refactor: use jest mocks instead of sinon spies. * refactor: Apply @chinesedfan recommendations * refactor: Improve test descriptions. * test: Add two cases of test and integrate styled-components in tests. Add two more cases for userHasPushPermission and issueLocked. Update test to use migrated components to styled-components. * refactor: Remove console.log statement. * test: Improve test descriptions and remove useless console.log * test: Fix conflicts between descriptions and implementations. * refactor: Runned prettier on CommentInput.js
fixes #212. i've already posted some updates, but i'm close to finishing things up now. here's a screenshot:
i made a fake PR to render a bunch of events: