Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F33019188
D6658.1768384305.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
22 KB
Referenced Files
None
Subscribers
None
D6658.1768384305.diff
View Options
diff --git a/native/chat/multimedia-message-tooltip-button.react.js b/native/chat/multimedia-message-tooltip-button.react.js
--- a/native/chat/multimedia-message-tooltip-button.react.js
+++ b/native/chat/multimedia-message-tooltip-button.react.js
@@ -1,15 +1,15 @@
// @flow
import * as React from 'react';
-import Animated, { type SharedValue } from 'react-native-reanimated';
+import Animated from 'react-native-reanimated';
import EmojiPicker from 'rn-emoji-keyboard';
import { localIDPrefix } from 'lib/shared/message-utils';
import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
-import type { SetState } from 'lib/types/hook-types';
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import { useSelector } from '../redux/redux-utils';
+import { useTooltipActions } from '../tooltip/tooltip-hooks';
import type { TooltipRoute } from '../tooltip/tooltip.react';
import { TooltipInlineEngagement } from './inline-engagement.react';
import { InnerMultimediaMessage } from './inner-multimedia-message.react';
@@ -33,17 +33,9 @@
+route: TooltipRoute<'MultimediaMessageTooltipModal'>,
+progress: Node,
+isOpeningSidebar: boolean,
- +setHideTooltip: SetState<boolean>,
- +showEmojiKeyboard: SharedValue<boolean>,
};
function MultimediaMessageTooltipButton(props: Props): React.Node {
- const {
- navigation,
- progress,
- isOpeningSidebar,
- setHideTooltip,
- showEmojiKeyboard,
- } = props;
+ const { navigation, route, progress, isOpeningSidebar } = props;
const windowWidth = useSelector(state => state.dimensions.width);
@@ -55,12 +47,7 @@
setSidebarInputBarHeight(height);
}, []);
- const {
- item,
- verticalBounds,
- initialCoordinates,
- margin,
- } = props.route.params;
+ const { item, verticalBounds, initialCoordinates, margin } = route.params;
const { style: messageContainerStyle } = useAnimatedMessageTooltipButton({
sourceMessage: item,
@@ -138,6 +125,11 @@
margin,
});
+ const [emojiPickerOpen, setEmojiPickerOpen] = React.useState<boolean>(false);
+ const openEmojiPicker = React.useCallback(() => {
+ setEmojiPickerOpen(true);
+ }, []);
+
const reactionSelectionPopover = React.useMemo(() => {
if (!canCreateReactionFromMessage) {
return null;
@@ -145,8 +137,9 @@
return (
<ReactionSelectionPopover
- setHideTooltip={setHideTooltip}
- showEmojiKeyboard={showEmojiKeyboard}
+ navigation={navigation}
+ route={route}
+ openEmojiPicker={openEmojiPicker}
reactionSelectionPopoverContainerStyle={
reactionSelectionPopoverPosition
}
@@ -154,26 +147,25 @@
/>
);
}, [
+ navigation,
+ route,
+ openEmojiPicker,
canCreateReactionFromMessage,
reactionSelectionPopoverPosition,
sendReaction,
- setHideTooltip,
- showEmojiKeyboard,
]);
+ const tooltipRouteKey = route.key;
+ const { dismissTooltip } = useTooltipActions(navigation, tooltipRouteKey);
+
const onEmojiSelected = React.useCallback(
emoji => {
sendReaction(emoji.emoji);
- setHideTooltip(true);
+ dismissTooltip();
},
- [sendReaction, setHideTooltip],
+ [sendReaction, dismissTooltip],
);
- const onCloseEmojiPicker = React.useCallback(() => {
- showEmojiKeyboard.value = false;
- navigation.goBackOnce();
- }, [navigation, showEmojiKeyboard]);
-
return (
<>
<Animated.View style={messageContainerStyle}>
@@ -190,8 +182,8 @@
</Animated.View>
<EmojiPicker
onEmojiSelected={onEmojiSelected}
- open={showEmojiKeyboard.value}
- onClose={onCloseEmojiPicker}
+ open={emojiPickerOpen}
+ onClose={dismissTooltip}
/>
</>
);
diff --git a/native/chat/reaction-selection-popover.react.js b/native/chat/reaction-selection-popover.react.js
--- a/native/chat/reaction-selection-popover.react.js
+++ b/native/chat/reaction-selection-popover.react.js
@@ -2,27 +2,30 @@
import * as React from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
-import type { SharedValue } from 'react-native-reanimated';
-
-import type { SetState } from 'lib/types/hook-types';
import SWMansionIcon from '../components/swmansion-icon.react';
+import type { AppNavigationProp } from '../navigation/app-navigator.react';
+import type { TooltipModalParamList } from '../navigation/route-names';
import { useStyles } from '../themes/colors';
+import { useTooltipActions } from '../tooltip/tooltip-hooks';
+import type { TooltipRoute } from '../tooltip/tooltip.react';
import type { ViewStyle } from '../types/styles';
-type ReactionSelectionPopoverProps = {
- +setHideTooltip: SetState<boolean>,
- +showEmojiKeyboard: SharedValue<boolean>,
+type Props<RouteName: $Keys<TooltipModalParamList>> = {
+ +navigation: AppNavigationProp<RouteName>,
+ +route: TooltipRoute<RouteName>,
+ +openEmojiPicker: () => mixed,
+reactionSelectionPopoverContainerStyle: ViewStyle,
+sendReaction: (reaction: string) => mixed,
};
-function ReactionSelectionPopover(
- props: ReactionSelectionPopoverProps,
+function ReactionSelectionPopover<RouteName: $Keys<TooltipModalParamList>>(
+ props: Props<RouteName>,
): React.Node {
const {
- setHideTooltip,
- showEmojiKeyboard,
+ navigation,
+ route,
+ openEmojiPicker,
reactionSelectionPopoverContainerStyle,
sendReaction,
} = props;
@@ -40,18 +43,24 @@
],
);
+ const tooltipRouteKey = route.key;
+ const { hideTooltip, dismissTooltip } = useTooltipActions(
+ navigation,
+ tooltipRouteKey,
+ );
+
const onPressDefaultEmoji = React.useCallback(
(emoji: string) => {
sendReaction(emoji);
- setHideTooltip(true);
+ dismissTooltip();
},
- [sendReaction, setHideTooltip],
+ [sendReaction, dismissTooltip],
);
const onPressEmojiKeyboardButton = React.useCallback(() => {
- showEmojiKeyboard.value = true;
- setHideTooltip(true);
- }, [setHideTooltip, showEmojiKeyboard]);
+ openEmojiPicker();
+ hideTooltip();
+ }, [openEmojiPicker, hideTooltip]);
const defaultEmojis = React.useMemo(() => {
const defaultEmojisData = ['❤️', '😆', '😮', '😠', '👍'];
diff --git a/native/chat/robotext-message-tooltip-button.react.js b/native/chat/robotext-message-tooltip-button.react.js
--- a/native/chat/robotext-message-tooltip-button.react.js
+++ b/native/chat/robotext-message-tooltip-button.react.js
@@ -1,15 +1,15 @@
// @flow
import * as React from 'react';
-import Animated, { type SharedValue } from 'react-native-reanimated';
+import Animated from 'react-native-reanimated';
import EmojiPicker from 'rn-emoji-keyboard';
import { localIDPrefix } from 'lib/shared/message-utils';
import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
-import type { SetState } from 'lib/types/hook-types';
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import { useSelector } from '../redux/redux-utils';
+import { useTooltipActions } from '../tooltip/tooltip-hooks';
import type { TooltipRoute } from '../tooltip/tooltip.react';
import { TooltipInlineEngagement } from './inline-engagement.react';
import { InnerRobotextMessage } from './inner-robotext-message.react';
@@ -31,17 +31,9 @@
+route: TooltipRoute<'RobotextMessageTooltipModal'>,
+progress: Node,
+isOpeningSidebar: boolean,
- +setHideTooltip: SetState<boolean>,
- +showEmojiKeyboard: SharedValue<boolean>,
};
function RobotextMessageTooltipButton(props: Props): React.Node {
- const {
- navigation,
- progress,
- isOpeningSidebar,
- setHideTooltip,
- showEmojiKeyboard,
- } = props;
+ const { navigation, route, progress, isOpeningSidebar } = props;
const windowWidth = useSelector(state => state.dimensions.width);
@@ -53,12 +45,7 @@
setSidebarInputBarHeight(height);
}, []);
- const {
- item,
- verticalBounds,
- initialCoordinates,
- margin,
- } = props.route.params;
+ const { item, verticalBounds, initialCoordinates, margin } = route.params;
const { style: messageContainerStyle } = useAnimatedMessageTooltipButton({
sourceMessage: item,
@@ -122,6 +109,11 @@
margin,
});
+ const [emojiPickerOpen, setEmojiPickerOpen] = React.useState<boolean>(false);
+ const openEmojiPicker = React.useCallback(() => {
+ setEmojiPickerOpen(true);
+ }, []);
+
const reactionSelectionPopover = React.useMemo(() => {
if (!canCreateReactionFromMessage) {
return null;
@@ -129,8 +121,9 @@
return (
<ReactionSelectionPopover
- setHideTooltip={setHideTooltip}
- showEmojiKeyboard={showEmojiKeyboard}
+ navigation={navigation}
+ route={route}
+ openEmojiPicker={openEmojiPicker}
reactionSelectionPopoverContainerStyle={
reactionSelectionPopoverPosition
}
@@ -138,26 +131,25 @@
/>
);
}, [
+ navigation,
+ route,
+ openEmojiPicker,
canCreateReactionFromMessage,
reactionSelectionPopoverPosition,
sendReaction,
- setHideTooltip,
- showEmojiKeyboard,
]);
+ const tooltipRouteKey = route.key;
+ const { dismissTooltip } = useTooltipActions(navigation, tooltipRouteKey);
+
const onEmojiSelected = React.useCallback(
emoji => {
sendReaction(emoji.emoji);
- setHideTooltip(true);
+ dismissTooltip();
},
- [sendReaction, setHideTooltip],
+ [sendReaction, dismissTooltip],
);
- const onCloseEmojiPicker = React.useCallback(() => {
- showEmojiKeyboard.value = false;
- navigation.goBackOnce();
- }, [navigation, showEmojiKeyboard]);
-
return (
<>
<Animated.View style={messageContainerStyle}>
@@ -174,8 +166,8 @@
</Animated.View>
<EmojiPicker
onEmojiSelected={onEmojiSelected}
- open={showEmojiKeyboard.value}
- onClose={onCloseEmojiPicker}
+ open={emojiPickerOpen}
+ onClose={dismissTooltip}
/>
</>
);
diff --git a/native/chat/text-message-tooltip-button.react.js b/native/chat/text-message-tooltip-button.react.js
--- a/native/chat/text-message-tooltip-button.react.js
+++ b/native/chat/text-message-tooltip-button.react.js
@@ -1,15 +1,15 @@
// @flow
import * as React from 'react';
-import Animated, { type SharedValue } from 'react-native-reanimated';
+import Animated from 'react-native-reanimated';
import EmojiPicker from 'rn-emoji-keyboard';
import { localIDPrefix } from 'lib/shared/message-utils';
import { useCanCreateReactionFromMessage } from 'lib/shared/reaction-utils';
-import type { SetState } from 'lib/types/hook-types';
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import { useSelector } from '../redux/redux-utils';
+import { useTooltipActions } from '../tooltip/tooltip-hooks';
import type { TooltipRoute } from '../tooltip/tooltip.react';
import { TooltipInlineEngagement } from './inline-engagement.react';
import { InnerTextMessage } from './inner-text-message.react';
@@ -33,17 +33,9 @@
+route: TooltipRoute<'TextMessageTooltipModal'>,
+progress: Node,
+isOpeningSidebar: boolean,
- +setHideTooltip: SetState<boolean>,
- +showEmojiKeyboard: SharedValue<boolean>,
};
function TextMessageTooltipButton(props: Props): React.Node {
- const {
- navigation,
- progress,
- isOpeningSidebar,
- setHideTooltip,
- showEmojiKeyboard,
- } = props;
+ const { navigation, route, progress, isOpeningSidebar } = props;
const windowWidth = useSelector(state => state.dimensions.width);
@@ -55,12 +47,7 @@
setSidebarInputBarHeight(height);
}, []);
- const {
- item,
- verticalBounds,
- initialCoordinates,
- margin,
- } = props.route.params;
+ const { item, verticalBounds, initialCoordinates, margin } = route.params;
const {
style: messageContainerStyle,
@@ -137,6 +124,11 @@
margin,
});
+ const [emojiPickerOpen, setEmojiPickerOpen] = React.useState<boolean>(false);
+ const openEmojiPicker = React.useCallback(() => {
+ setEmojiPickerOpen(true);
+ }, []);
+
const reactionSelectionPopover = React.useMemo(() => {
if (!canCreateReactionFromMessage) {
return null;
@@ -144,8 +136,9 @@
return (
<ReactionSelectionPopover
- setHideTooltip={setHideTooltip}
- showEmojiKeyboard={showEmojiKeyboard}
+ navigation={navigation}
+ route={route}
+ openEmojiPicker={openEmojiPicker}
reactionSelectionPopoverContainerStyle={
reactionSelectionPopoverPosition
}
@@ -153,26 +146,25 @@
/>
);
}, [
+ navigation,
+ route,
+ openEmojiPicker,
canCreateReactionFromMessage,
reactionSelectionPopoverPosition,
sendReaction,
- setHideTooltip,
- showEmojiKeyboard,
]);
+ const tooltipRouteKey = route.key;
+ const { dismissTooltip } = useTooltipActions(navigation, tooltipRouteKey);
+
const onEmojiSelected = React.useCallback(
emoji => {
sendReaction(emoji.emoji);
- setHideTooltip(true);
+ dismissTooltip();
},
- [sendReaction, setHideTooltip],
+ [sendReaction, dismissTooltip],
);
- const onCloseEmojiPicker = React.useCallback(() => {
- showEmojiKeyboard.value = false;
- navigation.goBackOnce();
- }, [navigation, showEmojiKeyboard]);
-
return (
<MessageListContextProvider threadID={threadID}>
<SidebarInputBarHeightMeasurer
@@ -198,8 +190,8 @@
</Animated.View>
<EmojiPicker
onEmojiSelected={onEmojiSelected}
- open={showEmojiKeyboard.value}
- onClose={onCloseEmojiPicker}
+ open={emojiPickerOpen}
+ onClose={dismissTooltip}
/>
</MessageListContextProvider>
);
diff --git a/native/tooltip/tooltip-context.react.js b/native/tooltip/tooltip-context.react.js
--- a/native/tooltip/tooltip-context.react.js
+++ b/native/tooltip/tooltip-context.react.js
@@ -24,6 +24,7 @@
+maxOptionsToDisplay: number,
+visibleEntryIDs: ?$ReadOnlyArray<string>,
+cancel: () => mixed,
+ +hideTooltip: () => mixed,
+children: React.Node,
};
function TooltipContextProvider(props: ProviderProps): React.Node {
@@ -72,9 +73,11 @@
optionsRef.current = optionsRef.current.filter(option => option.id !== id);
}, []);
- const { cancel } = props;
+ const { cancel, hideTooltip } = props;
const { showActionSheetWithOptions } = useActionSheet();
const showActionSheet = React.useCallback(() => {
+ hideTooltip();
+
const options = optionsRef.current;
const optionsToDisplay = options.filter(option =>
@@ -131,6 +134,7 @@
onPressAction,
);
}, [
+ hideTooltip,
maxOptionsToDisplay,
visibleEntryIDsSet,
cancel,
diff --git a/native/tooltip/tooltip-hooks.js b/native/tooltip/tooltip-hooks.js
new file mode 100644
--- /dev/null
+++ b/native/tooltip/tooltip-hooks.js
@@ -0,0 +1,39 @@
+// @flow
+
+import * as React from 'react';
+
+import type { AppNavigationProp } from '../navigation/app-navigator.react';
+import type { TooltipModalParamList } from '../navigation/route-names';
+
+type TooltipActions = {
+ // Hiding will keep the Tooltip ReactNav screen open, which means that the
+ // background will still be dimmed. But it will hide the actual tooltip menu.
+ +hideTooltip: () => void,
+ // Dismiss the tooltip will dismiss the ReactNav screen. This will start the
+ // OverlayNavigator animation to dismiss the screen.
+ +dismissTooltip: () => void,
+};
+function useTooltipActions<RouteName: $Keys<TooltipModalParamList>>(
+ navigation: AppNavigationProp<RouteName>,
+ tooltipRouteKey: string,
+): TooltipActions {
+ const { clearOverlayModals, setRouteParams } = navigation;
+
+ const hideTooltip = React.useCallback(() => {
+ setRouteParams(tooltipRouteKey, { hideTooltip: true });
+ }, [setRouteParams, tooltipRouteKey]);
+
+ const dismissTooltip = React.useCallback(() => {
+ clearOverlayModals([tooltipRouteKey]);
+ }, [clearOverlayModals, tooltipRouteKey]);
+
+ return React.useMemo(
+ () => ({
+ hideTooltip,
+ dismissTooltip,
+ }),
+ [hideTooltip, dismissTooltip],
+ );
+}
+
+export { useTooltipActions };
diff --git a/native/tooltip/tooltip-item.react.js b/native/tooltip/tooltip-item.react.js
--- a/native/tooltip/tooltip-item.react.js
+++ b/native/tooltip/tooltip-item.react.js
@@ -20,7 +20,7 @@
type Props = {
...TooltipItemBaseProps,
+containerStyle?: ViewStyle,
- +closeTooltip: () => mixed,
+ +closeTooltip?: () => mixed,
};
function TooltipItem(props: Props): React.Node {
const tooltipContext = React.useContext(TooltipContext);
@@ -45,7 +45,7 @@
const onPress = React.useCallback(() => {
onPressItem();
- closeTooltip();
+ closeTooltip?.();
}, [onPressItem, closeTooltip]);
if (!shouldRender) {
diff --git a/native/tooltip/tooltip.react.js b/native/tooltip/tooltip.react.js
--- a/native/tooltip/tooltip.react.js
+++ b/native/tooltip/tooltip.react.js
@@ -10,15 +10,7 @@
Platform,
Keyboard,
} from 'react-native';
-import Animated, {
- SlideInDown,
- SlideOutDown,
- runOnJS,
- useSharedValue,
- type SharedValue,
-} from 'react-native-reanimated';
-
-import type { SetState } from 'lib/types/hook-types';
+import Animated, { SlideInDown, SlideOutDown } from 'react-native-reanimated';
import { ChatContext, type ChatContextType } from '../chat/chat-context';
import SWMansionIcon from '../components/swmansion-icon.react';
@@ -59,6 +51,7 @@
+margin?: number,
+visibleEntryIDs?: $ReadOnlyArray<string>,
+chatInputBarHeight?: number,
+ +hideTooltip?: boolean,
};
export type TooltipRoute<RouteName: $Keys<TooltipModalParamList>> = RouteProp<
TooltipModalParamList,
@@ -73,8 +66,6 @@
...Base,
+progress: Node,
+isOpeningSidebar: boolean,
- +setHideTooltip: SetState<boolean>,
- +showEmojiKeyboard: SharedValue<boolean>,
};
type TooltipProps<Base> = {
...Base,
@@ -82,11 +73,6 @@
+dimensions: DimensionsInfo,
+overlayContext: ?OverlayContextType,
+chatContext: ?ChatContextType,
- +actionSheetShown: SharedValue<boolean>,
- +hideTooltip: boolean,
- +setHideTooltip: SetState<boolean>,
- +showEmojiKeyboard: SharedValue<boolean>,
- +exitAnimationWorklet: (finished: boolean) => void,
+styles: typeof unboundStyles,
+tooltipContext: TooltipContextType,
+closeTooltip: () => mixed,
@@ -301,11 +287,6 @@
dimensions,
overlayContext,
chatContext,
- actionSheetShown,
- hideTooltip,
- setHideTooltip,
- showEmojiKeyboard,
- exitAnimationWorklet,
styles,
tooltipContext,
closeTooltip,
@@ -335,7 +316,6 @@
onPress={this.onPressMore}
renderIcon={this.renderMoreIcon}
containerStyle={tooltipContainerStyle}
- closeTooltip={this.props.closeTooltip}
key="more"
/>,
);
@@ -376,16 +356,13 @@
...navAndRouteForFlow,
progress: position,
isOpeningSidebar,
- setHideTooltip,
- showEmojiKeyboard,
};
const itemsStyles = [styles.items, styles.itemsFixed];
const animationDelay = Platform.OS === 'ios' ? 200 : 500;
const enterAnimation = SlideInDown.delay(animationDelay);
-
- const exitAnimation = SlideOutDown.withCallback(exitAnimationWorklet);
+ const exitAnimation = SlideOutDown;
let tooltip = null;
@@ -402,8 +379,7 @@
);
} else if (
this.tooltipLocation === 'fixed' &&
- !hideTooltip &&
- !showEmojiKeyboard.value
+ !this.props.route.params.hideTooltip
) {
tooltip = (
<AnimatedView
@@ -438,8 +414,6 @@
onPressMore = () => {
Keyboard.dismiss();
- this.props.actionSheetShown.value = true;
- this.props.setHideTooltip(true);
this.props.tooltipContext.showActionSheet();
};
@@ -467,45 +441,24 @@
}
};
}
- function ConnectedTooltip(props: BaseTooltipPropsType) {
+ function ConnectedTooltip(props) {
const dimensions = useSelector(state => state.dimensions);
const overlayContext = React.useContext(OverlayContext);
const chatContext = React.useContext(ChatContext);
- const actionSheetShown = useSharedValue(false);
- const [hideTooltip, setHideTooltip] = React.useState<boolean>(false);
-
- const showEmojiKeyboard = useSharedValue(false);
-
- const { goBackOnce } = props.navigation;
- const goBackCallback = React.useCallback(() => {
- if (!actionSheetShown.value) {
- goBackOnce();
- }
- }, [actionSheetShown.value, goBackOnce]);
-
- const exitAnimationWorklet = React.useCallback(
- finished => {
- 'worklet';
- if (finished) {
- runOnJS(goBackCallback)();
- }
- },
- [goBackCallback],
- );
-
const { params } = props.route;
const { tooltipLocation } = params;
const isFixed = tooltipLocation === 'fixed';
+ const { hideTooltip, ...rest } = props;
+
+ const { goBackOnce } = props.navigation;
const closeTooltip = React.useCallback(() => {
- if (isFixed && !actionSheetShown.value) {
- setHideTooltip(true);
- } else {
- goBackOnce();
+ goBackOnce();
+ if (isFixed) {
+ hideTooltip();
}
- showEmojiKeyboard.value = false;
- }, [isFixed, actionSheetShown.value, goBackOnce, showEmojiKeyboard]);
+ }, [isFixed, hideTooltip, goBackOnce]);
const styles = useStyles(unboundStyles);
const boundTooltipItem = React.useCallback(
@@ -528,15 +481,10 @@
invariant(tooltipContext, 'TooltipContext should be set in Tooltip');
return (
<Tooltip
- {...props}
+ {...rest}
dimensions={dimensions}
overlayContext={overlayContext}
chatContext={chatContext}
- actionSheetShown={actionSheetShown}
- hideTooltip={hideTooltip}
- setHideTooltip={setHideTooltip}
- showEmojiKeyboard={showEmojiKeyboard}
- exitAnimationWorklet={exitAnimationWorklet}
styles={styles}
tooltipContext={tooltipContext}
closeTooltip={closeTooltip}
@@ -547,13 +495,21 @@
function MemoizedTooltip(props: BaseTooltipPropsType) {
const { visibleEntryIDs } = props.route.params;
const { goBackOnce } = props.navigation;
+
+ const { setParams } = props.navigation;
+ const hideTooltip = React.useCallback(() => {
+ const paramsUpdate: any = { hideTooltip: true };
+ setParams(paramsUpdate);
+ }, [setParams]);
+
return (
<TooltipContextProvider
maxOptionsToDisplay={4}
visibleEntryIDs={visibleEntryIDs}
cancel={goBackOnce}
+ hideTooltip={hideTooltip}
>
- <ConnectedTooltip {...props} />
+ <ConnectedTooltip {...props} hideTooltip={hideTooltip} />
</TooltipContextProvider>
);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jan 14, 9:51 AM (4 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5930760
Default Alt Text
D6658.1768384305.diff (22 KB)
Attached To
Mode
D6658: [native] Clean up Tooltip transition state
Attached
Detach File
Event Timeline
Log In to Comment