-
-
Notifications
You must be signed in to change notification settings - Fork 672
narrow: Convert more email usage to user IDs #4361
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
Changes from all commits
6253954
0a5fa1d
d4e7b97
0b58b91
8cef87f
a190063
fbb7153
fe45ce2
7cae3ab
2b35d3b
4116f83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,13 @@ | ||
| /* @flow strict-local */ | ||
|
|
||
| import React, { PureComponent } from 'react'; | ||
| import React, { type ComponentType, PureComponent } from 'react'; | ||
|
|
||
| import { createStyleSheet } from '../styles'; | ||
| import type { Dispatch } from '../types'; | ||
| import UserAvatar from './UserAvatar'; | ||
| import PresenceStatusIndicator from './PresenceStatusIndicator'; | ||
| import { AvatarURL } from '../utils/avatar'; | ||
| import { getUserForId } from '../users/userSelectors'; | ||
| import { connect } from '../react-redux'; | ||
|
|
||
| const styles = createStyleSheet({ | ||
| status: { | ||
|
|
@@ -17,33 +19,65 @@ const styles = createStyleSheet({ | |
|
|
||
| type Props = $ReadOnly<{| | ||
| avatarUrl: AvatarURL, | ||
| email: string, | ||
| size: number, | ||
| shape: 'rounded' | 'square', | ||
| onPress?: () => void, | ||
| email: string, | ||
| |}>; | ||
|
|
||
| /** | ||
| * Renders a user avatar with a PresenceStatusIndicator in the corner | ||
| * A user avatar with a PresenceStatusIndicator in the corner. | ||
| * | ||
| * Prefer `UserAvatarWithPresenceById` over this component: it does the same | ||
| * thing but avoids an email in the component's interface. Once all callers | ||
| * have migrated to that version, it'll replace this one. | ||
| * | ||
| * @prop [avatarUrl] | ||
| * @prop [email] - Sender's / user's email address, for the presence dot. | ||
| * @prop [size] - Sets width and height in logical pixels. | ||
| * @prop [shape] - 'rounded' (default) means a square with rounded corners. | ||
| * @prop [onPress] - Event fired on pressing the component. | ||
| */ | ||
| export default class UserAvatarWithPresence extends PureComponent<Props> { | ||
| static defaultProps = { | ||
| shape: 'rounded', | ||
| }; | ||
|
|
||
| // The underlying class gets an inexact Props type to express that it's fine | ||
| // for it to be passed extra props by the implementation of …ById. | ||
| // We don't export it with that type, because we want exact Props types to | ||
| // get the most effective type-checking. | ||
| class UserAvatarWithPresence extends PureComponent<$ReadOnly<{ ...Props, ... }>> { | ||
| render() { | ||
| const { avatarUrl, email, size, onPress, shape } = this.props; | ||
| const { avatarUrl, email, size, onPress } = this.props; | ||
|
|
||
| return ( | ||
| <UserAvatar avatarUrl={avatarUrl} size={size} onPress={onPress} shape={shape}> | ||
| <UserAvatar avatarUrl={avatarUrl} size={size} onPress={onPress}> | ||
| <PresenceStatusIndicator style={styles.status} email={email} hideIfOffline /> | ||
| </UserAvatar> | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| // Export the class with a tighter constraint on acceptable props, namely | ||
| // that the type is an exact object type as usual. | ||
| export default (UserAvatarWithPresence: ComponentType<Props>); | ||
|
|
||
| /** | ||
| * A user avatar with a PresenceStatusIndicator in the corner. | ||
| * | ||
| * Use this in preference to the default export `UserAvatarWithPresence`. | ||
| * We're migrating from that one to this in order to avoid using emails. | ||
| * | ||
| * @prop [userId] | ||
| * @prop [size] | ||
| * @prop [onPress] | ||
| */ | ||
| export const UserAvatarWithPresenceById = connect<{| avatarUrl: AvatarURL, email: string |}, _, _>( | ||
| (state, props) => { | ||
| const user = getUserForId(state, props.userId); | ||
| return { avatarUrl: user.avatar_url, email: user.email }; | ||
| }, | ||
| )( | ||
| // The type inference embedded in our `connect` type relies on seeing the | ||
| // exact Props type for the underlying component, complete with all the | ||
| // expected props. Normally that's just how our Props types are in the | ||
| // first place, but here we have to provide it explicitly. | ||
| /* eslint-disable flowtype/generic-spacing */ | ||
| (UserAvatarWithPresence: ComponentType< | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think using react-redux's But when we settle on using this one and removing the old one, I wonder about trying out React Hooks, in particular, react-redux's
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, that'd be interesting! (
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah of course 🤪. |
||
| $ReadOnly<{| ...Props, dispatch: Dispatch, userId: number |}>, | ||
| >), | ||
| ); | ||
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.
Nit in commit message: "we we"