diff --git a/package.json b/package.json index c4d2daa09..525169eef 100644 --- a/package.json +++ b/package.json @@ -101,8 +101,8 @@ "react-native-linear-gradient": "^2.4.2", "react-native-matomo-sdk": "feruzm/react-native-matomo-sdk", "react-native-modal": "^11.5.6", + "react-native-modal-popover": "^2.1.0", "react-native-modal-dropdown": "^1.0.2", - "react-native-modal-popover": "^2.0.1", "react-native-modal-translucent": "^5.0.0", "react-native-navigation-bar-color": "^1.0.0", "react-native-os": "^1.0.1", diff --git a/src/components/index.js b/src/components/index.js index 55747394c..816758a65 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -93,6 +93,7 @@ import { ForegroundNotification } from './foregroundNotification'; import { PostHtmlRenderer } from './postHtmlRenderer'; import { QuickProfileModal } from './organisms'; import QuickReplyModal from './quickReplyModal/quickReplyModalView'; +import Tooltip from './tooltip/tooltipView'; import VideoPlayer from './videoPlayer/videoPlayerView'; // Basic UI Elements @@ -235,5 +236,6 @@ export { PostHtmlRenderer, QuickProfileModal, QuickReplyModal, + Tooltip, VideoPlayer, }; diff --git a/src/components/markdownEditor/view/markdownEditorView.js b/src/components/markdownEditor/view/markdownEditorView.js index 3efa6e40f..a85a083c9 100644 --- a/src/components/markdownEditor/view/markdownEditorView.js +++ b/src/components/markdownEditor/view/markdownEditorView.js @@ -36,6 +36,7 @@ import { Modal, SnippetsModal, UploadsGalleryModal, + Tooltip, } from '../../index'; import { ThemeContainer } from '../../../containers'; @@ -48,6 +49,7 @@ import isAndroidOreo from '../../../utils/isAndroidOreo'; import { OptionsModal } from '../../atoms'; import { UsernameAutofillBar } from './usernameAutofillBar'; import applyUsername from './formats/applyUsername'; +import { walkthrough } from '../../../redux/constants/walkthroughConstants'; const MIN_BODY_INPUT_HEIGHT = 300; @@ -88,6 +90,7 @@ const MarkdownEditorView = ({ const galleryRef = useRef(null); const clearRef = useRef(null); const uploadsGalleryModalRef = useRef(null); + const tooltipRef = useRef(null); const dispatch = useDispatch(); const isVisibleAccountsBottomSheet = useSelector( @@ -302,17 +305,29 @@ const MarkdownEditorView = ({ onLoadDraftPress(); }; return ( - - - + <> + tooltipRef.current?.openTooltip()} + > + + + + + ); } }; diff --git a/src/components/tooltip/tooltipStyles.ts b/src/components/tooltip/tooltipStyles.ts new file mode 100644 index 000000000..66bbb1011 --- /dev/null +++ b/src/components/tooltip/tooltipStyles.ts @@ -0,0 +1,26 @@ +import EStyleSheet from 'react-native-extended-stylesheet'; + +export default EStyleSheet.create({ + popoverDetails: { + flexDirection: 'row', + width: '$deviceWidth / 2', + borderRadius: 20, + padding: 16, + + backgroundColor: '$primaryBackgroundColor', + }, + arrow: { + borderTopColor: '$primaryBackgroundColor', + }, + popoverWrapper: { + flex: 1, + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }, + overlay: {}, + popoverText: { + color: '$primaryDarkText', + textAlign: 'center', + }, +}); diff --git a/src/components/tooltip/tooltipView.tsx b/src/components/tooltip/tooltipView.tsx new file mode 100644 index 000000000..3b875a610 --- /dev/null +++ b/src/components/tooltip/tooltipView.tsx @@ -0,0 +1,68 @@ +import React, { forwardRef, useImperativeHandle } from 'react'; +import { View, Text } from 'react-native'; +import { Popover, usePopover } from 'react-native-modal-popover'; +import { useDispatch, useSelector } from 'react-redux'; +import { registerTooltip } from '../../redux/actions/walkthroughActions'; +import { Walkthrough } from '../../redux/reducers/walkthroughReducer'; + +import styles from './tooltipStyles'; +interface TooltipProps { + children?: any; + text?: string; + walkthroughIndex?: number; +} +const Tooltip = ({ children, text, walkthroughIndex }: TooltipProps, ref) => { + const { + openPopover, + closePopover, + popoverVisible, + touchableRef, + popoverAnchorRect, + } = usePopover(); + + const dispatch = useDispatch(); + const tooltipState = useSelector((state) => state.walkthrough.walkthroughMap); + const tooltipRegistered = tooltipState.get(walkthroughIndex); + + + useImperativeHandle(ref, () => ({ + openTooltip() { + if (!tooltipRegistered) { + openPopover(); + } + if (tooltipRegistered && !tooltipRegistered.isShown) { + openPopover(); + } + }, + closeTooltip() { + if (!tooltipRegistered || (tooltipRegistered && !tooltipRegistered.isShown)) { + const walkthrough: Walkthrough = { + walkthroughIndex: walkthroughIndex, + isShown: true, + }; + dispatch(registerTooltip(walkthrough)); + } + closePopover(); + }, + })); + + return ( + <> + {children} + + {text} + + + ); +}; + +export default forwardRef(Tooltip as any); diff --git a/src/config/locales/en-US.json b/src/config/locales/en-US.json index 7b3c0c2d7..416ce5be2 100644 --- a/src/config/locales/en-US.json +++ b/src/config/locales/en-US.json @@ -716,5 +716,8 @@ "comment": "Comment", "reply": "REPLY", "close":"CLOSE" + }, + "walkthrough":{ + "load_draft_tooltip": "Load your lastest draft here" } } diff --git a/src/redux/actions/walkthroughActions.ts b/src/redux/actions/walkthroughActions.ts new file mode 100644 index 000000000..8c0f842d7 --- /dev/null +++ b/src/redux/actions/walkthroughActions.ts @@ -0,0 +1,7 @@ +import { REGISTER_TOOLTIP } from '../constants/constants'; +import { Walkthrough } from '../reducers/walkthroughReducer'; + +export const registerTooltip = (walkthrough: Walkthrough) => ({ + payload: walkthrough, + type: REGISTER_TOOLTIP, +}); diff --git a/src/redux/constants/constants.js b/src/redux/constants/constants.js index 1356ede25..4d7321d87 100644 --- a/src/redux/constants/constants.js +++ b/src/redux/constants/constants.js @@ -107,3 +107,6 @@ export const TEMP_BENEFICIARIES_ID = 'temp-beneficiaries'; //CACHE export const PURGE_EXPIRED_CACHE = 'PURGE_EXPIRED_CACHE'; export const UPDATE_VOTE_CACHE = 'UPDATE_VOTE_CACHE'; + +// TOOLTIPS +export const REGISTER_TOOLTIP = 'REGISTER_TOOLTIP'; diff --git a/src/redux/constants/walkthroughConstants.ts b/src/redux/constants/walkthroughConstants.ts new file mode 100644 index 000000000..50d44f76a --- /dev/null +++ b/src/redux/constants/walkthroughConstants.ts @@ -0,0 +1,3 @@ +export const walkthrough = { + EDITOR_DRAFT_BTN: 1, +}; diff --git a/src/redux/reducers/index.js b/src/redux/reducers/index.js index a822a0345..972a9fbbb 100644 --- a/src/redux/reducers/index.js +++ b/src/redux/reducers/index.js @@ -9,6 +9,7 @@ import user from './userReducer'; import customTabsReducer from './customTabsReducer'; import editorReducer from './editorReducer'; import cacheReducer from './cacheReducer'; +import walkthroughReducer from './walkthroughReducer'; export default combineReducers({ account: accountReducer, @@ -21,4 +22,5 @@ export default combineReducers({ communities, user, cache: cacheReducer, + walkthrough: walkthroughReducer, }); diff --git a/src/redux/reducers/walkthroughReducer.ts b/src/redux/reducers/walkthroughReducer.ts new file mode 100644 index 000000000..6198c07f1 --- /dev/null +++ b/src/redux/reducers/walkthroughReducer.ts @@ -0,0 +1,31 @@ +import { REGISTER_TOOLTIP } from '../constants/constants'; + +export interface WalkthroughItem { + walkthroughIndex:number, + isShown?:boolean, +} +interface State { + walkthroughMap: Map +} + +const initialState:State = { + walkthroughMap:new Map(), +}; +export default function (state = initialState, action) { + console.log('action : ', action); + + const { type, payload } = action; + switch (type) { + case REGISTER_TOOLTIP: + if(!state.walkthroughMap){ + state.walkthroughMap = new Map(); + } + state.walkthroughMap.set(payload.walkthroughIndex, payload); + return { + ...state, + }; + + default: + return state; + } +} diff --git a/src/redux/store/store.ts b/src/redux/store/store.ts index 4b670207a..bd92b215f 100644 --- a/src/redux/store/store.ts +++ b/src/redux/store/store.ts @@ -12,6 +12,12 @@ const transformCacheVoteMap = createTransform( {whitelist:['cache']} ); +const transformWalkthroughMap = createTransform( + (inboundState:any) => ({ ...inboundState, walkthroughMap : Array.from(inboundState.walkthroughMap)}), + (outboundState) => ({ ...outboundState, walkthroughMap:new Map(outboundState.walkthroughMap)}), + {whitelist:['walkthrough']} +); + // Middleware: Redux Persist Config const persistConfig = { // Root @@ -21,7 +27,7 @@ const persistConfig = { // Blacklist (Don't Save Specific Reducers) blacklist: ['nav', 'application', 'communities', 'user'], timeout: 0, - transforms:[transformCacheVoteMap] + transforms:[transformCacheVoteMap,transformWalkthroughMap] }; // Middleware: Redux Persist Persisted Reducer diff --git a/yarn.lock b/yarn.lock index eddbd939e..94641bf0f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6837,7 +6837,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: +lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8631,12 +8631,12 @@ react-native-modal-dropdown@^1.0.2: dependencies: prop-types "^15.6.0" -react-native-modal-popover@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/react-native-modal-popover/-/react-native-modal-popover-2.0.1.tgz#119fb04606a205ffff41fc56666ea4c0cc833aa6" - integrity sha512-4aqjeNf3TNSUH4tK0t9ADNGqNQmY/xb0XKGtdNGhhdSZDp0oME36dj92AKxoFeU3AzfQdmd0ehOXvYUu7aaj8g== +react-native-modal-popover@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/react-native-modal-popover/-/react-native-modal-popover-2.1.0.tgz#45a2060012796f29184e6c41b787f14336d3b435" + integrity sha512-t7KMk1q5Hi3jkk3/0fpa3mA7E3TJLL/Uz48Fa07AlocjMbG3okim9fNPLf5dJGw4JlcYWxLMYeswEcTjKr0M1g== dependencies: - lodash "^4.17.20" + lodash "^4.17.21" prop-types "^15.7.2" react-native-modal-translucent@^5.0.0: