diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c052bc551..a160089bc 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -772,4 +772,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 9c48318ea254e2c78005a7a0c2d8bfc14ddd783d -COCOAPODS: 1.11.2 +COCOAPODS: 1.10.1 diff --git a/package.json b/package.json index 7b4c6377e..2595cf0f5 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dependencies": { "@babel/runtime": "^7.5.5", "@bugsnag/react-native": "^7.11.0", - "@ecency/render-helper": "^2.2.9", + "@ecency/render-helper": "^2.2.12", "@esteemapp/dhive": "0.15.0", "@esteemapp/react-native-autocomplete-input": "^4.2.1", "@esteemapp/react-native-multi-slider": "^1.1.0", diff --git a/src/components/autoHeightImage/autoHeightImage.tsx b/src/components/autoHeightImage/autoHeightImage.tsx index f92748e09..d222a43d2 100644 --- a/src/components/autoHeightImage/autoHeightImage.tsx +++ b/src/components/autoHeightImage/autoHeightImage.tsx @@ -47,7 +47,7 @@ import { TouchableWithoutFeedback } from "react-native-gesture-handler"; } return ( - + { //local state to manage fake upvote if available - const [activeVotesCount, setActiveVotesCount] = useState(0); + const activeVotesCount = activeVotes ? activeVotes.length : 0; + const [cacheVoteIcrement, setCacheVoteIcrement] = useState(0); const [calcImgHeight, setCalcImgHeight] = useState(imageHeight || 300); - useEffect(() => { - setActiveVotesCount(activeVotes ? activeVotes.length : 0); - }, [activeVotes]); - // Component Functions const _handleOnUserPress = (username) => { if (handleOnUserPress) { @@ -76,7 +73,7 @@ const PostCardView = ({ const _handleIncrementVoteCount = () => { //fake increment vote using based on local change - setActiveVotesCount(activeVotesCount + 1); + setCacheVoteIcrement(1); }; const rebloggedBy = get(content, 'reblogged_by[0]', null); @@ -183,7 +180,7 @@ const PostCardView = ({ iconStyle={styles.commentIcon} iconType="MaterialCommunityIcons" isClickable - text={activeVotesCount} + text={activeVotesCount + cacheVoteIcrement} onPress={_handleOnVotersPress} /> diff --git a/src/components/postElements/body/view/commentBodyView.tsx b/src/components/postElements/body/view/commentBodyView.tsx index 096cb4beb..bf7b79d29 100644 --- a/src/components/postElements/body/view/commentBodyView.tsx +++ b/src/components/postElements/body/view/commentBodyView.tsx @@ -21,7 +21,6 @@ import styles from './commentBodyStyles'; // Services and Actions import { writeToClipboard } from '../../../../utils/clipboard'; import { toastNotification } from '../../../../redux/actions/uiAction'; -import getYoutubeId from '../../../../utils/getYoutubeId'; import VideoPlayerSheet from './videoPlayerSheet'; import { LongPressGestureHandler, State } from 'react-native-gesture-handler'; import { useCallback } from 'react'; @@ -29,6 +28,7 @@ import { OptionsModal } from '../../../atoms'; import { useAppDispatch } from '../../../../hooks'; import { isCommunity } from '../../../../utils/communityValidation'; import { GLOBAL_POST_FILTERS_VALUE } from '../../../../constants/options/filters'; +import { startsWith } from 'core-js/core/string'; const WIDTH = Dimensions.get('window').width; @@ -54,6 +54,7 @@ const CommentBody = ({ const [revealComment, setRevealComment] = useState(reputation > 0 && !isMuted); const [videoUrl, setVideoUrl] = useState(null); const [youtubeVideoId, setYoutubeVideoId] = useState(null) + const [videoStartTime, setVideoStartTime] = useState(0); const intl = useIntl(); const actionImage = useRef(null); @@ -265,10 +266,10 @@ const CommentBody = ({ } }; - const _handleYoutubePress = (embedUrl) => { - const videoId = getYoutubeId(embedUrl); + const _handleYoutubePress = (videoId, startTime) => { if (videoId && youtubePlayerRef.current) { setYoutubeVideoId(videoId); + setVideoStartTime(startTime); youtubePlayerRef.current.setModalVisible(true); } }; @@ -276,6 +277,7 @@ const CommentBody = ({ const _handleVideoPress = (embedUrl) => { if (embedUrl && youtubePlayerRef.current) { setVideoUrl(embedUrl); + setVideoStartTime(0) youtubePlayerRef.current.setModalVisible(true); } }; @@ -366,7 +368,7 @@ const CommentBody = ({ setVideoUrl(null); }} > - + ); diff --git a/src/components/postElements/body/view/postBodyView.js b/src/components/postElements/body/view/postBodyView.js index 738039d65..052931d6b 100644 --- a/src/components/postElements/body/view/postBodyView.js +++ b/src/components/postElements/body/view/postBodyView.js @@ -15,7 +15,6 @@ import { toastNotification } from '../../../../redux/actions/uiAction'; // Constants import { default as ROUTES } from '../../../../constants/routeNames'; -import getYoutubeId from '../../../../utils/getYoutubeId'; import VideoPlayerSheet from './videoPlayerSheet'; import { OptionsModal } from '../../../atoms'; import { isCommunity } from '../../../../utils/communityValidation'; @@ -33,6 +32,7 @@ const PostBody = ({ navigation, body, dispatch, onLoadEnd }) => { const [html, setHtml] = useState(''); const [youtubeVideoId, setYoutubeVideoId] = useState(null); const [videoUrl, setVideoUrl] = useState(null); + const [videoStartTime, setVideoStartTime] = useState(0); const intl = useIntl(); const actionImage = useRef(null); @@ -45,10 +45,10 @@ const PostBody = ({ navigation, body, dispatch, onLoadEnd }) => { } }, [body]); - const _handleYoutubePress = (embedUrl) => { - const videoId = getYoutubeId(embedUrl); + const _handleYoutubePress = (videoId, startTime) => { if (videoId && youtubePlayerRef.current) { setYoutubeVideoId(videoId); + setVideoStartTime(startTime); youtubePlayerRef.current.setModalVisible(true); } }; @@ -56,6 +56,7 @@ const PostBody = ({ navigation, body, dispatch, onLoadEnd }) => { const _handleVideoPress = (embedUrl) => { if (embedUrl && youtubePlayerRef.current) { setVideoUrl(embedUrl); + setVideoStartTime(0); youtubePlayerRef.current.setModalVisible(true); } }; @@ -293,7 +294,11 @@ const PostBody = ({ navigation, body, dispatch, onLoadEnd }) => { setVideoUrl(null); }} > - + { +const VideoPlayerSheet = ({youtubeVideoId, videoUrl, startTime}: VideoPlayerSheetProps) => { const PLAYER_HEIGHT = Dimensions.get('screen').width * (9/16); @@ -30,6 +30,10 @@ const VideoPlayerSheet = ({youtubeVideoId, videoUrl}: VideoPlayerSheetProps) => setLoading(false) } + const initialParams:InitialPlayerParams = { + start:startTime + } + return ( @@ -37,6 +41,7 @@ const VideoPlayerSheet = ({youtubeVideoId, videoUrl}: VideoPlayerSheetProps) => { @@ -17,10 +20,27 @@ export const parseLinkData = (tnode:TNode):LinkData => { } if(tnode.classes.includes('markdown-external-link')){ + + //inline external links can contain video links, for such tags and video id or url is contained as + //attribute if that is the case, use in app video modal to play content + //for now, only youtube id is supported + const youtubeId = tnode.attributes['data-youtube'] + const startTime= tnode.attributes['data-start-time']; + if(youtubeId){ + return { - type:'markdown-external-link', - href: tnode.attributes['data-href'] + type:'markdown-video-link-youtube', + youtubeId:youtubeId, + startTime:parseInt(startTime) || 0, } + } + //TOOD: support other video link later + + //use default markdown-external-link with url; + return { + type:'markdown-external-link', + href: tnode.attributes['data-href'] + } } @@ -90,15 +110,23 @@ export const parseLinkData = (tnode:TNode):LinkData => { } + if(tnode.classes.includes('markdown-community-link')){ + return { + type: 'markdown-community-link', + community: tnode.attributes['data-community'], + filter: tnode.attributes['data-filter'], + } + } + if (tnode.classes.includes('markdown-video-link-youtube')) { - var embedUrl = tnode.attributes['data-embed-src']; + var youtubeId = tnode.attributes['data-youtube']; + const startTime= tnode.attributes['data-start-time']; - - - if (embedUrl) { + if (youtubeId) { return { type: 'markdown-video-link-youtube', - tag: embedUrl + youtubeId : youtubeId, + startTime : parseInt(startTime) || 0, }; } } diff --git a/src/components/postHtmlRenderer/postHtmlRenderer.tsx b/src/components/postHtmlRenderer/postHtmlRenderer.tsx index 336661c28..1f0bd0e41 100644 --- a/src/components/postHtmlRenderer/postHtmlRenderer.tsx +++ b/src/components/postHtmlRenderer/postHtmlRenderer.tsx @@ -9,7 +9,7 @@ import { AutoHeightImage } from "../autoHeightImage/autoHeightImage"; interface PostHtmlRendererProps { contentWidth:number; body:string; - onLoaded:()=>void; + onLoaded?:()=>void; setSelectedImage:(imgUrl:string)=>void; setSelectedLink:(url:string)=>void; onElementIsImage:(imgUrl:string)=>void; @@ -17,7 +17,7 @@ interface PostHtmlRendererProps { handleOnUserPress:(username:string)=>void; handleTagPress:(tag:string, filter?:string)=>void; handleVideoPress:(videoUrl:string)=>void; - handleYoutubePress:(videoId:string)=>void; + handleYoutubePress:(videoId:string, startTime:number)=>void; } export const PostHtmlRenderer = memo(({ @@ -37,6 +37,7 @@ export const PostHtmlRenderer = memo(({ //new renderer functions body = body.replace(/
/g, '
').replace(/<\/center>/g,'
'); + console.log("Comment body:", body); const _handleOnLinkPress = (data:LinkData) => { @@ -51,8 +52,11 @@ export const PostHtmlRenderer = memo(({ author, permlink, tag, + youtubeId, + startTime, filter, videoHref, + community } = data; try { @@ -85,7 +89,7 @@ export const PostHtmlRenderer = memo(({ break; case 'markdown-video-link-youtube': if(handleYoutubePress){ - handleYoutubePress(tag) + handleYoutubePress(youtubeId, startTime) } break; @@ -98,6 +102,13 @@ export const PostHtmlRenderer = memo(({ case 'markdown-proposal-link': setSelectedLink(href); break; + + case 'markdown-community-link': + //tag press also handles community by default + if(handleTagPress){ + handleTagPress(community, filter) + } + break; default: break; @@ -147,6 +158,26 @@ export const PostHtmlRenderer = memo(({ /> ); } + + //this method checks if image is a child of table column + //and calculates img width accordingly, + //returns full width if img is not part of table + const getMaxImageWidth = (tnode:TNode)=>{ + + //return full width if not parent exist + if(!tnode.parent || tnode.parent.tagName === 'body'){ + return contentWidth; + } + + //return divided width based on number td tags + if(tnode.parent.tagName === 'td'){ + const cols = tnode.parent.parent.children.length + return contentWidth/cols; + } + + //check next parent + return getMaxImageWidth(tnode.parent); + } const _imageRenderer = ({ @@ -160,16 +191,17 @@ export const PostHtmlRenderer = memo(({ }; const isVideoThumb = tnode.classes?.indexOf('video-thumbnail') >= 0; - const isAnchored = !(tnode.parent?.classes?.indexOf('markdown-external-link') >= 0) + const isAnchored = tnode.parent?.tagName === 'a'; + if(isVideoThumb){ return ; } - else { + const maxImgWidth = getMaxImageWidth(tnode); return ( ); diff --git a/src/components/postView/view/postDisplayView.js b/src/components/postView/view/postDisplayView.js index 962fae761..2c55cfd0a 100644 --- a/src/components/postView/view/postDisplayView.js +++ b/src/components/postView/view/postDisplayView.js @@ -41,15 +41,14 @@ const PostDisplayView = ({ activeVotes, reblogs, activeVotesCount, - setActiveVotesCount, }) => { const [postHeight, setPostHeight] = useState(0); const [scrollHeight, setScrollHeight] = useState(0); + const [cacheVoteIcrement, setCacheVoteIcrement] = useState(0); const [isLoadedComments, setIsLoadedComments] = useState(false); const actionSheet = useRef(null); const [refreshing, setRefreshing] = useState(false); const [postBodyLoading, setPostBodyLoading] = useState(false); - const [tags, setTags] = useState([]); // Component Life Cycles @@ -94,7 +93,7 @@ const PostDisplayView = ({ }; const _handleIncrementActiveVotesCount = () => { - setActiveVotesCount(activeVotesCount + 1); + setCacheVoteIcrement(1); }; const _getTabBar = (isFixedFooter = false) => { @@ -114,7 +113,7 @@ const PostDisplayView = ({ iconType="MaterialCommunityIcons" isClickable onPress={() => handleOnVotersPress && handleOnVotersPress()} - text={activeVotesCount} + text={activeVotesCount + cacheVoteIcrement} textMarginLeft={20} /> { - dispatch(resetLocalVoteMap()); - }; - const _setFeedPosts = (_posts, scrollPos = 0) => { if (isFeedScreen) { dispatch(setFeedPosts(_posts, scrollPos)); @@ -305,7 +300,6 @@ const PostsContainer = ({ if (isFeedScreen) { AppState.addEventListener('change', _handleAppStateChange); _setFeedPosts(initPosts || []); - _resetLocalVoteMap(); } else { _setFeedPosts([]); } diff --git a/src/components/upvote/container/upvoteContainer.js b/src/components/upvote/container/upvoteContainer.js index 553c44bc4..07cdf075d 100644 --- a/src/components/upvote/container/upvoteContainer.js +++ b/src/components/upvote/container/upvoteContainer.js @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { connect, useSelector } from 'react-redux'; +import { connect } from 'react-redux'; import get from 'lodash/get'; // Realm @@ -7,7 +7,6 @@ import { setUpvotePercent } from '../../../realm/realm'; // Services and Actions import { setUpvotePercent as upvoteAction } from '../../../redux/actions/applicationActions'; -import { updateLocalVoteMap } from '../../../redux/actions/postsAction'; // Utils import { getTimeFromNow } from '../../../utils/time'; @@ -16,6 +15,8 @@ import parseAsset from '../../../utils/parseAsset'; // Component import UpvoteView from '../view/upvoteView'; +import { updateVoteCache } from '../../../redux/actions/cacheActions'; +import { useAppSelector } from '../../../hooks'; /* * Props Name Description Value @@ -41,7 +42,8 @@ const UpvoteContainer = (props) => { const [isVoted, setIsVoted] = useState(null); const [isDownVoted, setIsDownVoted] = useState(null); const [totalPayout, setTotalPayout] = useState(get(content, 'total_payout')); - const localVoteMap = useSelector((state) => state.posts.localVoteMap); + const cachedVotes = useAppSelector((state) => state.cache.votes); + const lastCacheUpdate = useAppSelector((state) => state.cache.lastUpdate); useEffect(() => { let _isMounted = true; @@ -54,8 +56,8 @@ const UpvoteContainer = (props) => { setIsVoted(_isVoted && parseInt(_isVoted, 10) / 10000); setIsDownVoted(_isDownVoted && (parseInt(_isDownVoted, 10) / 10000) * -1); - if (localVoteMap) { - _handleLocalVote(); + if (cachedVotes && cachedVotes.size > 0) { + _handleCachedVote(); } } }; @@ -64,6 +66,19 @@ const UpvoteContainer = (props) => { return () => (_isMounted = false); }, [activeVotes]); + useEffect(() => { + const postPath = `${content.author || ''}/${content.permlink || ''}`; + //this conditional makes sure on targetted already fetched post is updated + //with new cache status, this is to avoid duplicate cache merging + if ( + lastCacheUpdate && + lastCacheUpdate.postPath === postPath && + content.post_fetched_at < lastCacheUpdate.updatedAt + ) { + _handleCachedVote(); + } + }, [lastCacheUpdate]); + const _setUpvotePercent = (value) => { if (value) { setUpvotePercent(String(value)); @@ -71,14 +86,15 @@ const UpvoteContainer = (props) => { } }; - const _handleLocalVote = () => { - const postId = `${content.author || ''}-${content.permlink || ''}`; + const _handleCachedVote = () => { + const postPath = `${content.author || ''}/${content.permlink || ''}`; const postFetchedAt = get(content, 'post_fetched_at', 0); - const localVote = localVoteMap[postId] || null; - if (localVote) { - const { votedAt, amount, isDownvote, incrementStep } = localVote; - if (postFetchedAt > votedAt) { + if (cachedVotes.has(postPath)) { + const cachedVote = cachedVotes.get(postPath); + const { expiresAt, amount, isDownvote, incrementStep } = cachedVote; + + if (postFetchedAt > expiresAt) { return; } @@ -97,24 +113,21 @@ const UpvoteContainer = (props) => { const amountNum = parseFloat(amount); let incrementStep = 0; - if (!isVoted && !isDownVoted && incrementVoteCount) { + if (!isVoted && !isDownVoted) { incrementStep = 1; - incrementVoteCount(); } - setIsDownVoted(isDownvote ? true : false); - setIsVoted(isDownvote ? false : true); - - setTotalPayout(totalPayout + amountNum); //update redux - const postId = `${content.author || ''}-${content.permlink || ''}`; + const postPath = `${content.author || ''}/${content.permlink || ''}`; + const curTime = new Date().getTime(); const vote = { - votedAt: new Date().getTime(), + votedAt: curTime, amount: amountNum, isDownvote, incrementStep, + expiresAt: curTime + 30000, }; - dispatch(updateLocalVoteMap(postId, vote)); + dispatch(updateVoteCache(postPath, vote)); }; const author = get(content, 'author'); diff --git a/src/redux/actions/cacheActions.ts b/src/redux/actions/cacheActions.ts new file mode 100644 index 000000000..2ab0da214 --- /dev/null +++ b/src/redux/actions/cacheActions.ts @@ -0,0 +1,20 @@ +import { + UPDATE_VOTE_CACHE, + PURGE_EXPIRED_CACHE + } from '../constants/constants'; +import { Vote } from '../reducers/cacheReducer'; + + + export const updateVoteCache = (postPath:string, vote:Vote) => ({ + payload:{ + postPath, + vote + }, + type: UPDATE_VOTE_CACHE + }) + + export const purgeExpiredCache = () => ({ + type: PURGE_EXPIRED_CACHE + }) + + \ No newline at end of file diff --git a/src/redux/actions/postsAction.ts b/src/redux/actions/postsAction.ts index 9e24610ad..aac38c358 100644 --- a/src/redux/actions/postsAction.ts +++ b/src/redux/actions/postsAction.ts @@ -6,8 +6,6 @@ import { RESET, FILTER_SELECTED, SET_INIT_POSTS, - UPDATE_LOCAL_VOTE_MAP, - RESET_LOCAL_VOTE_MAP, SET_FEED_SCREEN_FILTERS, } from '../constants/constants'; @@ -31,23 +29,7 @@ export const setOtherPosts = (posts, scrollPosition = 0) => ({ }); -export const updateLocalVoteMap = (postId:string, localVote:{ - votedAt: number, - amount: number, - isDownvote: boolean, - incrementStep: number -}) => ({ - payload: { - postId, - localVote, - }, - type: UPDATE_LOCAL_VOTE_MAP, -}); - -export const resetLocalVoteMap = () => ({ - type: RESET_LOCAL_VOTE_MAP, -}); export const fetchPosts = (payload) => ({ payload, type: FETCH_POSTS, diff --git a/src/redux/constants/constants.js b/src/redux/constants/constants.js index 7a5441045..1356ede25 100644 --- a/src/redux/constants/constants.js +++ b/src/redux/constants/constants.js @@ -81,8 +81,6 @@ export const SUBSCRIBE_COMMUNITY_FAIL = 'SUBSCRIBE_COMMUNITY_FAIL'; export const LEAVE_COMMUNITY = 'LEAVE_COMMUNITY'; export const LEAVE_COMMUNITY_SUCCESS = 'LEAVE_COMMUNITY_SUCCESS'; export const LEAVE_COMMUNITY_FAIL = 'LEAVE_COMMUNITY_FAIL'; -export const UPDATE_LOCAL_VOTE_MAP = 'UPDATE_LOCAL_VOTE_MAP'; -export const RESET_LOCAL_VOTE_MAP = 'RESET_LOCAL_VOTE_MAP'; // USER export const FOLLOW_USER = 'FOLLOW_USER'; @@ -105,3 +103,7 @@ export const SET_OWN_PROFILE_TABS = 'SET_OWN_PROFILE_TABS'; export const SET_BENEFICIARIES = 'SET_BENEFICIARIES'; export const REMOVE_BENEFICIARIES = 'REMOVE_BENEFICIARIES'; export const TEMP_BENEFICIARIES_ID = 'temp-beneficiaries'; + +//CACHE +export const PURGE_EXPIRED_CACHE = 'PURGE_EXPIRED_CACHE'; +export const UPDATE_VOTE_CACHE = 'UPDATE_VOTE_CACHE'; diff --git a/src/redux/reducers/cacheReducer.ts b/src/redux/reducers/cacheReducer.ts new file mode 100644 index 000000000..891001548 --- /dev/null +++ b/src/redux/reducers/cacheReducer.ts @@ -0,0 +1,57 @@ +import { PURGE_EXPIRED_CACHE, UPDATE_VOTE_CACHE } from "../constants/constants"; + +export interface Vote { + amount:number; + isDownvote:boolean; + incrementStep:number; + votedAt:number; + expiresAt:number; +} + +interface State { + votes:Map + lastUpdate:{ + postPath:string, + updatedAt:number, + } +} + +const initialState:State = { + votes:new Map(), + lastUpdate:null, + }; + + export default function (state = initialState, action) { + const {type, payload} = action; + switch (type) { + case UPDATE_VOTE_CACHE: + if(!state.votes){ + state.votes = new Map(); + } + state.votes.set(payload.postPath, payload.vote); + return { + ...state, //spread operator in requried here, otherwise persist do not register change + lastUpdate:{ + postPath:payload.postPath, + updatedAt: new Date().getTime() + } + }; + case PURGE_EXPIRED_CACHE: + const currentTime = new Date().getTime(); + + if(state.votes && state.votes.entries){ + Array.from(state.votes).forEach((entry)=>{ + if(entry[1].expiresAt < currentTime){ + state.votes.delete(entry[0]); + } + }) + } + + return { + ...state + } + default: + return state; + } + } + diff --git a/src/redux/reducers/index.js b/src/redux/reducers/index.js index 16dda1007..a822a0345 100644 --- a/src/redux/reducers/index.js +++ b/src/redux/reducers/index.js @@ -8,6 +8,7 @@ import communities from './communitiesReducer'; import user from './userReducer'; import customTabsReducer from './customTabsReducer'; import editorReducer from './editorReducer'; +import cacheReducer from './cacheReducer'; export default combineReducers({ account: accountReducer, @@ -19,4 +20,5 @@ export default combineReducers({ ui, communities, user, + cache: cacheReducer, }); diff --git a/src/redux/reducers/postsReducer.ts b/src/redux/reducers/postsReducer.ts index 9200551d1..33562e4c3 100644 --- a/src/redux/reducers/postsReducer.ts +++ b/src/redux/reducers/postsReducer.ts @@ -7,8 +7,6 @@ import { FETCH_POSTS, FETCH_POSTS_SUCCESS, RESET, - UPDATE_LOCAL_VOTE_MAP, - RESET_LOCAL_VOTE_MAP, SET_FEED_SCREEN_FILTERS, } from '../constants/constants'; @@ -19,7 +17,6 @@ const initialState = { posts: [], loading: false, selectedFilterValue: '', - localVoteMap: new Map(), feedScreenFilters:DEFAULT_FEED_FILTERS }; @@ -44,20 +41,6 @@ export default function (state = initialState, action) { otherScrollPosition: action.payload.scrollPosition, posts: action.payload, }; - case UPDATE_LOCAL_VOTE_MAP: - const { postId, localVote } = action.payload; - const voteMap = state.localVoteMap || new Map(); - voteMap[postId] = localVote; - return { - ...state, - localVoteMap: voteMap, - }; - - case RESET_LOCAL_VOTE_MAP: - return { - ...state, - localVoteMap: new Map(), - }; case FILTER_SELECTED: { return { diff --git a/src/redux/store/store.ts b/src/redux/store/store.ts index c9363db2f..4b670207a 100644 --- a/src/redux/store/store.ts +++ b/src/redux/store/store.ts @@ -1,11 +1,17 @@ import { createStore, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; -import { persistStore, persistReducer } from 'redux-persist'; +import { persistStore, persistReducer, createTransform } from 'redux-persist'; import AsyncStorage from '@react-native-community/async-storage'; import Reactotron from '../../../reactotron-config'; import reducer from '../reducers'; +const transformCacheVoteMap = createTransform( + (inboundState:any) => ({ ...inboundState, votes : Array.from(inboundState.votes)}), + (outboundState) => ({ ...outboundState, votes:new Map(outboundState.votes)}), + {whitelist:['cache']} +); + // Middleware: Redux Persist Config const persistConfig = { // Root @@ -15,6 +21,7 @@ const persistConfig = { // Blacklist (Don't Save Specific Reducers) blacklist: ['nav', 'application', 'communities', 'user'], timeout: 0, + transforms:[transformCacheVoteMap] }; // Middleware: Redux Persist Persisted Reducer diff --git a/src/screens/application/container/applicationContainer.js b/src/screens/application/container/applicationContainer.js index 0fe7d0e63..591a32f79 100644 --- a/src/screens/application/container/applicationContainer.js +++ b/src/screens/application/container/applicationContainer.js @@ -94,12 +94,7 @@ import { toastNotification, updateActiveBottomTab, } from '../../../redux/actions/uiAction'; -import { - resetLocalVoteMap, - setFeedPosts, - setFeedScreenFilters, - setInitPosts, -} from '../../../redux/actions/postsAction'; +import { setFeedPosts, setInitPosts } from '../../../redux/actions/postsAction'; import { encryptKey } from '../../../utils/crypto'; @@ -109,6 +104,7 @@ import persistAccountGenerator from '../../../utils/persistAccountGenerator'; import parseVersionNumber from '../../../utils/parseVersionNumber'; import { getTimeFromNow, setMomentLocale } from '../../../utils/time'; import parseAuthUrl from '../../../utils/parseAuthUrl'; +import { purgeExpiredCache } from '../../../redux/actions/cacheActions'; // Workaround let previousAppState = 'background'; @@ -777,7 +773,7 @@ class ApplicationContainer extends Component { dispatch(hideActionModal()); dispatch(hideProfileModal()); dispatch(toastNotification('')); - dispatch(resetLocalVoteMap()); + dispatch(purgeExpiredCache()); dispatch(setRcOffer(false)); const settings = await getSettings(); diff --git a/src/utils/getYoutubeId.ts b/src/utils/getYoutubeId.ts deleted file mode 100644 index 36eac03f8..000000000 --- a/src/utils/getYoutubeId.ts +++ /dev/null @@ -1,10 +0,0 @@ - - -export default (url) => { - var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; - var match = url.match(regExp); - var videoId = (match&&match[7].length==11)? match[7] : false; - - console.log("Extracting id ", videoId, url); - return videoId; -} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 6e6da19f7..82d76faf5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1031,10 +1031,10 @@ exec-sh "^0.3.2" minimist "^1.2.0" -"@ecency/render-helper@^2.2.9": - version "2.2.9" - resolved "https://registry.yarnpkg.com/@ecency/render-helper/-/render-helper-2.2.9.tgz#067a4f3d3c27bcb814648c692a4dfb868035436b" - integrity sha512-Oiz2N7qbwRAuS7dtbSRmCr7Yp2wUyEmBNtEun1byYoE+1g4k7dxJLsigs9ErrJzZ/yFQVcLEB1YrfjZczl/vfQ== +"@ecency/render-helper@^2.2.12": + version "2.2.12" + resolved "https://registry.yarnpkg.com/@ecency/render-helper/-/render-helper-2.2.12.tgz#2eed5cf2fb05e9a6581a06e37fe0fda60d664450" + integrity sha512-QGUS0rkXJiO5QUXggo5u1HZs89pNsIc0F7lD5lWhwHWG5l/CZV9WHrzsxHmtwE5AomlE6KqrZ/B6Ly8nWc5ytA== dependencies: he "^1.2.0" lolight "^1.4.0"