-
-
Notifications
You must be signed in to change notification settings - Fork 673
Clean up navigation logic (2/x). #4440
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
6c37879
cb549f6
00b0642
ff45bad
d38a67e
32748fb
56daac5
38ef774
41e6d45
0312a20
b02e152
8473fde
b7a6267
80cbcc1
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,13 +1,13 @@ | ||
| /* @flow strict-local */ | ||
|
|
||
| import React, { PureComponent } from 'react'; | ||
| import React, { useState, useCallback } from 'react'; | ||
| import { View, Dimensions, Easing } from 'react-native'; | ||
| import PhotoView from 'react-native-photo-view'; | ||
| import { connectActionSheet } from '@expo/react-native-action-sheet'; | ||
| import { useActionSheet } from '@expo/react-native-action-sheet'; | ||
|
|
||
| import * as NavigationService from '../nav/NavigationService'; | ||
| import type { Auth, Dispatch, Message } from '../types'; | ||
| import { connect } from '../react-redux'; | ||
| import type { Message } from '../types'; | ||
| import { useSelector } from '../react-redux'; | ||
| import type { ShowActionSheetWithOptions } from '../message/messageActionSheet'; | ||
| import { getAuth } from '../selectors'; | ||
| import { getResource } from '../utils/url'; | ||
|
|
@@ -38,106 +38,89 @@ const styles = createStyleSheet({ | |
| }); | ||
|
|
||
| type Props = $ReadOnly<{| | ||
| auth: Auth, | ||
| dispatch: Dispatch, | ||
| src: string, | ||
| message: Message, | ||
| showActionSheetWithOptions: ShowActionSheetWithOptions, | ||
| |}>; | ||
|
|
||
| type State = {| | ||
| movement: 'in' | 'out', | ||
| |}; | ||
| export default function Lightbox(props: Props) { | ||
| const [movement, setMovement] = useState<'in' | 'out'>('out'); | ||
| const showActionSheetWithOptions: ShowActionSheetWithOptions = useActionSheet() | ||
| .showActionSheetWithOptions; | ||
| const auth = useSelector(getAuth); | ||
|
|
||
| class Lightbox extends PureComponent<Props, State> { | ||
| state = { | ||
| movement: 'out', | ||
| }; | ||
|
|
||
| handleImagePress = () => { | ||
| this.setState(({ movement }, props) => ({ | ||
| movement: movement === 'out' ? 'in' : 'out', | ||
| })); | ||
| }; | ||
|
|
||
| handleOptionsPress = () => { | ||
| const options = constructActionSheetButtons(); | ||
| const cancelButtonIndex = options.length - 1; | ||
| const { showActionSheetWithOptions, src, auth } = this.props; | ||
| showActionSheetWithOptions( | ||
| { | ||
| options, | ||
| cancelButtonIndex, | ||
| }, | ||
| buttonIndex => { | ||
| executeActionSheetAction({ | ||
| title: options[buttonIndex], | ||
| src, | ||
| auth, | ||
| }); | ||
| }, | ||
| ); | ||
| }; | ||
| // Pulled out here just because this function is used twice. | ||
| const handleImagePress = useCallback(() => { | ||
| setMovement(m => (m === 'out' ? 'in' : 'out')); | ||
| }, [setMovement]); | ||
|
|
||
| handlePressBack = () => { | ||
| NavigationService.dispatch(navigateBack()); | ||
| }; | ||
| const { src, message } = props; | ||
| const footerMessage = | ||
| message.type === 'stream' | ||
| ? `Shared in #${streamNameOfStreamMessage(message)}` | ||
| : 'Shared with you'; | ||
| const resource = getResource(src, auth); | ||
| const { width: windowWidth, height: windowHeight } = Dimensions.get('window'); | ||
|
|
||
| getAnimationProps = () => ({ | ||
| const animationProps = { | ||
| easing: Easing.bezier(0.075, 0.82, 0.165, 1), | ||
| duration: 300, | ||
| movement: this.state.movement, | ||
| }); | ||
|
|
||
| render() { | ||
| const { src, message, auth } = this.props; | ||
| const footerMessage = | ||
| message.type === 'stream' | ||
| ? `Shared in #${streamNameOfStreamMessage(message)}` | ||
| : 'Shared with you'; | ||
| const resource = getResource(src, auth); | ||
| const { width, height } = Dimensions.get('window'); | ||
| movement, | ||
| }; | ||
|
|
||
| return ( | ||
| <View style={styles.container}> | ||
| <PhotoView | ||
| source={resource} | ||
| style={[styles.img, { width }]} | ||
| resizeMode="contain" | ||
| onTap={this.handleImagePress} | ||
| onViewTap={this.handleImagePress} | ||
| return ( | ||
| <View style={styles.container}> | ||
| <PhotoView | ||
| source={resource} | ||
| style={[styles.img, { width: windowWidth }]} | ||
| resizeMode="contain" | ||
| onTap={handleImagePress} | ||
| onViewTap={handleImagePress} | ||
| /> | ||
| <SlideAnimationView | ||
| property="translateY" | ||
| style={[styles.overlay, styles.header, { width: windowWidth }]} | ||
| from={-NAVBAR_SIZE} | ||
| to={0} | ||
| {...animationProps} | ||
| > | ||
| <LightboxHeader | ||
| onPressBack={() => { | ||
| NavigationService.dispatch(navigateBack()); | ||
| }} | ||
| timestamp={message.timestamp} | ||
| avatarUrl={message.avatar_url} | ||
| senderName={message.sender_full_name} | ||
| senderEmail={message.sender_email} | ||
| /> | ||
| <SlideAnimationView | ||
| property="translateY" | ||
| style={[styles.overlay, styles.header, { width }]} | ||
| from={-NAVBAR_SIZE} | ||
| to={0} | ||
| {...this.getAnimationProps()} | ||
| > | ||
| <LightboxHeader | ||
| onPressBack={this.handlePressBack} | ||
| timestamp={message.timestamp} | ||
| avatarUrl={message.avatar_url} | ||
| senderName={message.sender_full_name} | ||
| senderEmail={message.sender_email} | ||
| /> | ||
| </SlideAnimationView> | ||
| <SlideAnimationView | ||
| property="translateY" | ||
| style={[styles.overlay, { width, bottom: height - 44 }]} | ||
| from={height} | ||
| to={height - 44} | ||
| {...this.getAnimationProps()} | ||
| > | ||
| <LightboxFooter displayMessage={footerMessage} onOptionsPress={this.handleOptionsPress} /> | ||
| </SlideAnimationView> | ||
| </View> | ||
| ); | ||
| } | ||
| </SlideAnimationView> | ||
| <SlideAnimationView | ||
| property="translateY" | ||
| style={[styles.overlay, { width: windowWidth, bottom: windowHeight - 44 }]} | ||
| from={windowHeight} | ||
| to={windowHeight - 44} | ||
|
Comment on lines
+98
to
+100
Member
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 also notice, thanks to this cleanup calling my attention to it, that this longstanding bit of code is all unnecessarily complicated -- if you subtract
But that might all be made moot by the changes you're already working on to replace this
Collaborator
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. I've got a commit that does exactly that simplification; about to send the PR. 😄 |
||
| {...animationProps} | ||
| > | ||
| <LightboxFooter | ||
| displayMessage={footerMessage} | ||
| onOptionsPress={() => { | ||
| const options = constructActionSheetButtons(); | ||
| const cancelButtonIndex = options.length - 1; | ||
| showActionSheetWithOptions( | ||
| { | ||
| options, | ||
| cancelButtonIndex, | ||
| }, | ||
| buttonIndex => { | ||
| executeActionSheetAction({ | ||
| title: options[buttonIndex], | ||
| src, | ||
| auth, | ||
| }); | ||
| }, | ||
| ); | ||
| }} | ||
| /> | ||
| </SlideAnimationView> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| export default connectActionSheet( | ||
| connect(state => ({ | ||
| auth: getAuth(state), | ||
| }))(Lightbox), | ||
| ); | ||
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.
Ah, this is much nicer!