Skip to content

Commit

Permalink
Merge pull request #5733 from parasharrajat/tooltip
Browse files Browse the repository at this point in the history
Added tooltip sense & add missing tooltips
  • Loading branch information
mountiny authored Oct 19, 2021
2 parents f32953b + 9113606 commit ce7a759
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 48 deletions.
1 change: 1 addition & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ const CONST = {
SIDEBAR_LOADED: 'sidebar_loaded',
COLD: 'cold',
REPORT_ACTION_ITEM_LAYOUT_DEBOUNCE_TIME: 1500,
TOOLTIP_SENSE: 1000,
},
PRIORITY_MODE: {
GSD: 'gsd',
Expand Down
8 changes: 4 additions & 4 deletions src/components/AttachmentView.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ const AttachmentView = (props) => {
</View>
<Text style={[styles.textStrong]}>{props.file && props.file.name}</Text>
{props.shouldShowDownloadIcon && (
<Tooltip text={props.translate('common.download')}>
<View style={styles.ml2}>
<View style={styles.ml2}>
<Tooltip text={props.translate('common.download')}>
<Icon src={Download} />
</View>
</Tooltip>
</Tooltip>
</View>
)}
</View>
);
Expand Down
19 changes: 11 additions & 8 deletions src/components/AvatarWithImagePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import withLocalize, {withLocalizePropTypes} from './withLocalize';
import variables from '../styles/variables';
import CONST from '../CONST';
import SpinningIndicatorAnimation from '../styles/animation/SpinningIndicatorAnimation';
import Tooltip from './Tooltip';
import stylePropTypes from '../styles/stylePropTypes';

const propTypes = {
Expand Down Expand Up @@ -175,14 +176,16 @@ class AvatarWithImagePicker extends React.Component {
)
: (
<>
<View style={[styles.smallEditIcon, styles.smallAvatarEditIcon]}>
<Icon
src={Camera}
width={variables.iconSizeSmall}
height={variables.iconSizeSmall}
fill={themeColors.iconReversed}
/>
</View>
<Tooltip absolute text={this.props.translate('avatarWithImagePicker.editImage')}>
<View style={[styles.smallEditIcon, styles.smallAvatarEditIcon]}>
<Icon
src={Camera}
width={variables.iconSizeSmall}
height={variables.iconSizeSmall}
fill={themeColors.iconReversed}
/>
</View>
</Tooltip>
<PopoverMenu
isVisible={this.state.isMenuVisible}
onClose={() => this.setState({isMenuVisible: false})}
Expand Down
28 changes: 16 additions & 12 deletions src/components/FAB/FAB.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {Plus} from '../Icon/Expensicons';
import styles, {getAnimatedFABStyle} from '../../styles/styles';
import themeColors from '../../styles/themes/default';
import fabPropTypes from './fabPropTypes';
import Tooltip from '../Tooltip';
import withLocalize from '../withLocalize';

const AnimatedIcon = Animated.createAnimatedComponent(Icon);
AnimatedIcon.displayName = 'AnimatedIcon';
Expand Down Expand Up @@ -58,20 +60,22 @@ class FAB extends PureComponent {
});

return (
<AnimatedPressable
accessibilityLabel={this.props.accessibilityLabel}
accessibilityRole={this.props.accessibilityRole}
onPress={this.props.onPress}
style={[
styles.floatingActionButton,
getAnimatedFABStyle(rotate, backgroundColor),
]}
>
<AnimatedIcon src={Plus} fill={fill} />
</AnimatedPressable>
<Tooltip absolute text={this.props.translate('common.new')}>
<AnimatedPressable
accessibilityLabel={this.props.accessibilityLabel}
accessibilityRole={this.props.accessibilityRole}
onPress={this.props.onPress}
style={[
styles.floatingActionButton,
getAnimatedFABStyle(rotate, backgroundColor),
]}
>
<AnimatedIcon src={Plus} fill={fill} />
</AnimatedPressable>
</Tooltip>
);
}
}

FAB.propTypes = fabPropTypes;
export default FAB;
export default withLocalize(FAB);
30 changes: 30 additions & 0 deletions src/components/Tooltip/TooltipSense.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import _ from 'underscore';
import CONST from '../../CONST';

let active = false;

/**
* Debounced function to deactive the TooltipSense after a specific time
*/
const debouncedDeactivate = _.debounce(() => {
active = false;
}, CONST.TIMING.TOOLTIP_SENSE);

function activate() {
active = true;
debouncedDeactivate.cancel();
}

function deactivate() {
return debouncedDeactivate();
}

function isActive() {
return active === true;
}

export default {
activate,
deactivate,
isActive,
};
40 changes: 29 additions & 11 deletions src/components/Tooltip/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import TooltipRenderedOnPageBody from './TooltipRenderedOnPageBody';
import Hoverable from '../Hoverable';
import withWindowDimensions from '../withWindowDimensions';
import {propTypes, defaultProps} from './TooltipPropTypes';
import TooltipSense from './TooltipSense';

class Tooltip extends PureComponent {
constructor(props) {
Expand Down Expand Up @@ -36,6 +37,9 @@ class Tooltip extends PureComponent {
this.tooltip = null;

this.isComponentMounted = false;

// Whether the tooltip is first tooltip to activate the TooltipSense
this.isTooltipSenseInitiator = false;
this.shouldStartShowAnimation = false;
this.animation = new Animated.Value(0);

Expand Down Expand Up @@ -131,12 +135,19 @@ class Tooltip extends PureComponent {
// We may need this check due to the reason that the animation start will fire async
// and hideTooltip could fire before it thus keeping the Tooltip visible
if (this.shouldStartShowAnimation) {
Animated.timing(this.animation, {
toValue: 1,
duration: 140,
delay: 500,
useNativeDriver: false,
}).start();
// When TooltipSense is active, immediately show the tooltip
if (TooltipSense.isActive()) {
this.animation.setValue(1);
} else {
this.isTooltipSenseInitiator = true;
Animated.timing(this.animation, {
toValue: 1,
duration: 140,
delay: 500,
useNativeDriver: false,
}).start();
}
TooltipSense.activate();
}
});
}
Expand All @@ -147,11 +158,18 @@ class Tooltip extends PureComponent {
hideTooltip() {
this.animation.stopAnimation();
this.shouldStartShowAnimation = false;
Animated.timing(this.animation, {
toValue: 0,
duration: 140,
useNativeDriver: false,
}).start();
if (TooltipSense.isActive() && !this.isTooltipSenseInitiator) {
this.animation.setValue(0);
} else {
// Hide the first tooltip which initiated the TooltipSense with animation
this.isTooltipSenseInitiator = false;
Animated.timing(this.animation, {
toValue: 0,
duration: 140,
useNativeDriver: false,
}).start();
}
TooltipSense.deactivate();
}

render() {
Expand Down
2 changes: 1 addition & 1 deletion src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default {
attachment: 'Attachment',
to: 'To',
optional: 'Optional',
new: 'NEW',
new: 'New',
search: 'Search',
next: 'Next',
goBack: 'Go back',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default {
attachment: 'Archivo adjunto',
to: 'A',
optional: 'Opcional',
new: 'NUEVO',
new: 'Nuevo',
search: 'Buscar',
next: 'Siguiente',
goBack: 'Regresar',
Expand Down
24 changes: 13 additions & 11 deletions src/pages/home/sidebar/SidebarLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,19 @@ class SidebarLinks extends React.Component {
<Icon src={MagnifyingGlass} />
</TouchableOpacity>
</Tooltip>
<TouchableOpacity
accessibilityLabel={this.props.translate('sidebarScreen.buttonMySettings')}
accessibilityRole="button"
onPress={this.props.onAvatarClick}
>
<AvatarWithIndicator
source={this.props.myPersonalDetails.avatar}
isActive={this.props.network && !this.props.network.isOffline}
isSyncing={this.props.network && !this.props.network.isOffline && this.props.isSyncingData}
/>
</TouchableOpacity>
<Tooltip text={this.props.translate('common.settings')}>
<TouchableOpacity
accessibilityLabel={this.props.translate('sidebarScreen.buttonMySettings')}
accessibilityRole="button"
onPress={this.props.onAvatarClick}
>
<AvatarWithIndicator
source={this.props.myPersonalDetails.avatar}
isActive={this.props.network && !this.props.network.isOffline}
isSyncing={this.props.network && !this.props.network.isOffline && this.props.isSyncingData}
/>
</TouchableOpacity>
</Tooltip>
</View>
<OptionsList
contentContainerStyles={[
Expand Down
1 change: 1 addition & 0 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,7 @@ const styles = {
fontFamily: fontFamily.GTA_BOLD,
fontSize: variables.fontSizeSmall,
fontWeight: fontWeightBold,
textTransform: 'capitalize',
},

flipUpsideDown: {
Expand Down

0 comments on commit ce7a759

Please sign in to comment.