Skip to content

Commit

Permalink
promo loading rework
Browse files Browse the repository at this point in the history
  • Loading branch information
lendihop committed Oct 31, 2023
1 parent 38108f4 commit d6ead81
Show file tree
Hide file tree
Showing 14 changed files with 76 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export const useActivityGroupsListStyles = createUseStyles(({ colors, typography
promotionItemWrapper: {
paddingVertical: formatSize(12),
borderBottomWidth: formatSize(0.5),
borderBottomColor: colors.lines
borderBottomColor: colors.lines,
alignSelf: 'center'
},
centeredItem: {
alignSelf: 'center'
Expand Down
2 changes: 2 additions & 0 deletions src/components/activity-groups-list/activity-groups-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { emptyFn } from 'src/config/general';
import { useFakeRefreshControlProps } from 'src/hooks/use-fake-refresh-control-props.hook';
import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface';
import { isTheSameDay, isToday, isYesterday } from 'src/utils/date.utils';
import { OptimalPromotionAdType } from 'src/utils/optimal.utils';

import { ActivityGroupItem } from './activity-group-item/activity-group-item';
import { ActivityGroupsListSelectors } from './activity-groups-list.selectors';
Expand Down Expand Up @@ -69,6 +70,7 @@ export const ActivityGroupsList: FC<Props> = ({
() => (
<View style={styles.promotionItemWrapper}>
<OptimalPromotionItem
adType={OptimalPromotionAdType.TwMobile}
style={styles.promotionItem}
testID={ActivityGroupsListSelectors.promotion}
onImageError={onOptimalPromotionError}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import {
usePartnersPromoLoadingSelector,
usePartnersPromoSelector
} from 'src/store/partners-promotion/partners-promotion-selectors';
import { useIsEmptyPromotion } from 'src/utils/optimal.utils';
import { OptimalPromotionAdType, useIsEmptyPromotion } from 'src/utils/optimal.utils';

import { PromotionItem } from '../promotion-item/promotion-item';
import { TextPromotionItem } from '../text-promotion-item/text-promotion-item';
import { OptimalPromotionVariantEnum } from './optimal-promotion-variant.enum';

interface Props extends TestIdProps {
adType: OptimalPromotionAdType;
style?: StyleProp<ViewStyle>;
shouldShowCloseButton?: boolean;
variant?: OptimalPromotionVariantEnum;
Expand All @@ -23,14 +24,15 @@ interface Props extends TestIdProps {
}

export const OptimalPromotionItem: FC<Props> = ({
adType,
testID,
style,
shouldShowCloseButton = true,
variant = OptimalPromotionVariantEnum.Image,
onImageError,
onEmptyPromotionReceived
}) => {
const partnersPromotion = usePartnersPromoSelector();
const partnersPromotion = usePartnersPromoSelector(adType);
const partnersPromotionLoading = usePartnersPromoLoadingSelector();
const partnersPromotionEnabled = useIsPartnersPromoEnabledSelector();
const { disablePromotion } = usePromotionAfterConfirmation();
Expand Down
14 changes: 1 addition & 13 deletions src/hooks/use-partners-promo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';

import { PROMO_SYNC_INTERVAL } from 'src/config/fixed-times';
Expand All @@ -16,18 +15,6 @@ export const useIsPartnersPromoShown = () => {
return isEnabled && !areAdsNotEnabled;
};

export const usePartnersPromoLoad = () => {
const promoIsShown = useIsPartnersPromoShown();

const dispatch = useDispatch();

useEffect(() => {
if (promoIsShown) {
dispatch(loadPartnersPromoActions.submit(OptimalPromotionAdType.TwMobile));
}
}, [promoIsShown]);
};

export const usePartnersPromoSync = () => {
const promoIsShown = useIsPartnersPromoShown();

Expand All @@ -36,6 +23,7 @@ export const usePartnersPromoSync = () => {
useAuthorisedInterval(
() => {
if (promoIsShown) {
dispatch(loadPartnersPromoActions.submit(OptimalPromotionAdType.TwToken));
dispatch(loadPartnersPromoActions.submit(OptimalPromotionAdType.TwMobile));
}
},
Expand Down
6 changes: 3 additions & 3 deletions src/screens/d-apps/promotion-carousel/promotion-carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import type { CarouselRenderItemInfo } from 'react-native-reanimated-carousel/li

import { OptimalPromotionItem } from 'src/components/optimal-promotion-item/optimal-promotion-item';
import { useLayoutSizes } from 'src/hooks/use-layout-sizes.hook';
import { useIsPartnersPromoShown, usePartnersPromoLoad } from 'src/hooks/use-partners-promo';
import { useIsPartnersPromoShown } from 'src/hooks/use-partners-promo';
import { useActivePromotionSelector } from 'src/store/advertising/advertising-selectors';
import { formatSize } from 'src/styles/format-size';
import { isDefined } from 'src/utils/is-defined';
import { OptimalPromotionAdType } from 'src/utils/optimal.utils';

import { PromotionCarouselItem } from './promotion-carousel-item/promotion-carousel-item';
import { COMMON_PROMOTION_CAROUSEL_DATA } from './promotion-carousel.data';
Expand All @@ -22,8 +23,6 @@ export const PromotionCarousel = () => {
const [promotionErrorOccurred, setPromotionErrorOccurred] = useState(false);
const partnersPromoShown = useIsPartnersPromoShown();

usePartnersPromoLoad();

const data = useMemo<Array<JSX.Element>>(() => {
const result = [...COMMON_PROMOTION_CAROUSEL_DATA];

Expand All @@ -41,6 +40,7 @@ export const PromotionCarousel = () => {
if (partnersPromoShown && !promotionErrorOccurred) {
result.unshift(
<OptimalPromotionItem
adType={OptimalPromotionAdType.TwMobile}
testID={PromotionCarouselSelectors.optimalPromotionBanner}
shouldShowCloseButton={false}
style={styles.promotionItem}
Expand Down
2 changes: 2 additions & 0 deletions src/screens/market/top-coins-table/top-tokens-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useFilteredMarketTokens } from 'src/hooks/use-filtered-market-tokens.ho
import { MarketToken } from 'src/store/market/market.interfaces';
import { formatSize } from 'src/styles/format-size';

import { OptimalPromotionAdType } from '../../../utils/optimal.utils';
import { MarketSelectors } from '../market.selectors';
import { Filters } from './filters/filters';
import { RightSwipeView } from './right-swipe-view/right-swipe-view';
Expand Down Expand Up @@ -54,6 +55,7 @@ export const TopTokensTable = memo(() => {
<View style={styles.rootContainer}>
{!promotionErrorOccurred && (
<OptimalPromotionItem
adType={OptimalPromotionAdType.TwMobile}
style={styles.promotion}
testID={MarketSelectors.promotion}
onImageError={() => setPromotionErrorOccurred(true)}
Expand Down
3 changes: 0 additions & 3 deletions src/screens/token-screen/token-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { PublicKeyHashText } from 'src/components/public-key-hash-text/public-ke
import { TokenEquityValue } from 'src/components/token-equity-value/token-equity-value';
import { TokenScreenContentContainer } from 'src/components/token-screen-content-container/token-screen-content-container';
import { useContractActivity } from 'src/hooks/use-contract-activity';
import { usePartnersPromoLoad } from 'src/hooks/use-partners-promo';
import { ScreensEnum, ScreensParamList } from 'src/navigator/enums/screens.enum';
import { useIsPartnersPromoEnabledSelector } from 'src/store/partners-promotion/partners-promotion-selectors';
import { highPriorityLoadTokenBalanceAction } from 'src/store/wallet/wallet-actions';
Expand Down Expand Up @@ -56,8 +55,6 @@ export const TokenScreen = () => {
);
}, []);

usePartnersPromoLoad();

const { activities, handleUpdate } = useContractActivity(getTokenSlug(initialToken));

useNavigationSetOptions({ headerTitle: () => <HeaderTokenInfo token={token} /> }, [token]);
Expand Down
19 changes: 2 additions & 17 deletions src/screens/wallet/token-list/token-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { ScreensEnum } from 'src/navigator/enums/screens.enum';
import { useNavigation } from 'src/navigator/hooks/use-navigation.hook';
import { loadAdvertisingPromotionActions } from 'src/store/advertising/advertising-actions';
import { useTokensApyRatesSelector } from 'src/store/d-apps/d-apps-selectors';
import { loadPartnersPromoActions } from 'src/store/partners-promotion/partners-promotion-actions';
import { setZeroBalancesShown } from 'src/store/settings/settings-actions';
import { useHideZeroBalancesSelector, useIsEnabledAdsBannerSelector } from 'src/store/settings/settings-selectors';
import {
Expand Down Expand Up @@ -59,7 +58,7 @@ const getItemType = (item: ListItem) => (typeof item === 'string' ? 'promotion'
export const TokensList = memo(() => {
const dispatch = useDispatch();
const { trackEvent } = useAnalytics();
const { navigate, addListener: addNavigationListener, removeListener: removeNavigationListener } = useNavigation();
const { navigate } = useNavigation();
const styles = useTokenListStyles();

const apyRates = useTokensApyRatesSelector();
Expand All @@ -85,21 +84,6 @@ export const TokensList = memo(() => {
trackEvent(WalletSelectors.hideZeroBalancesCheckbox, AnalyticsEventCategory.ButtonPress);
}, []);

useEffect(() => {
const listener = () => {
dispatch(loadPartnersPromoActions.submit(OptimalPromotionAdType.TwToken));
setPromotionErrorOccurred(false);
};

if (partnersPromoShown) {
addNavigationListener('focus', listener);
}

return () => {
removeNavigationListener('focus', listener);
};
}, [dispatch, addNavigationListener, removeNavigationListener, partnersPromoShown]);

useEffect(() => {
if (partnersPromoShown) {
dispatch(loadAdvertisingPromotionActions.submit());
Expand Down Expand Up @@ -146,6 +130,7 @@ export const TokensList = memo(() => {
<View>
<View style={styles.promotionItemWrapper}>
<OptimalPromotionItem
adType={OptimalPromotionAdType.TwToken}
variant={OptimalPromotionVariantEnum.Text}
style={styles.promotionItem}
testID={WalletSelectors.promotion}
Expand Down
8 changes: 5 additions & 3 deletions src/store/partners-promotion/partners-promotion-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { OptimalPromotionAdType, OptimalPromotionType } from 'src/utils/optimal.

import { createActions } from '../create-actions';

export const loadPartnersPromoActions = createActions<OptimalPromotionAdType, OptimalPromotionType, string>(
'partnersPromo/LOAD_PARTNERS_PROMOTION'
);
export const loadPartnersPromoActions = createActions<
OptimalPromotionAdType,
{ adType: OptimalPromotionAdType; ad: OptimalPromotionType },
{ adType: OptimalPromotionAdType; error: string }
>('partnersPromo/LOAD_PARTNERS_PROMOTION');

export const togglePartnersPromotionAction = createAction<boolean>('partnersPromo/SET_IS_PROMOTION_ENABLED');
8 changes: 4 additions & 4 deletions src/store/partners-promotion/partners-promotion-epics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ const loadPartnersPromotionEpic: Epic<Action, Action, RootState> = (action$, sta
ofType(loadPartnersPromoActions.submit),
toPayload(),
withSelectedAccount(state$),
switchMap(([payload, account]) =>
from(getOptimalPromotion(payload, account.publicKeyHash)).pipe(
map(optimalPromotion => loadPartnersPromoActions.success(optimalPromotion)),
catchError(error => of(loadPartnersPromoActions.fail(error.message)))
switchMap(([adType, account]) =>
from(getOptimalPromotion(adType, account.publicKeyHash)).pipe(
map(optimalPromotion => loadPartnersPromoActions.success({ adType, ad: optimalPromotion })),
catchError(error => of(loadPartnersPromoActions.fail({ adType, error: error.message })))
)
)
);
Expand Down
53 changes: 41 additions & 12 deletions src/store/partners-promotion/partners-promotion-reducers.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,51 @@
import { createReducer } from '@reduxjs/toolkit';

import { OptimalPromotionAdType } from 'src/utils/optimal.utils';

import { createEntity } from '../create-entity';
import { loadPartnersPromoActions, togglePartnersPromotionAction } from './partners-promotion-actions';
import { partnersPromotionInitialState } from './partners-promotion-state';

export const partnersPromotionReducers = createReducer(partnersPromotionInitialState, builder => {
builder.addCase(loadPartnersPromoActions.submit, state => ({
...state,
promotion: createEntity(state.promotion.data, true)
}));
builder.addCase(loadPartnersPromoActions.success, (state, { payload }) => ({
...state,
promotion: createEntity(payload, false)
}));
builder.addCase(loadPartnersPromoActions.fail, (state, { payload }) => ({
...state,
promotion: createEntity(state.promotion.data, false, payload)
}));
builder.addCase(loadPartnersPromoActions.submit, (state, { payload: adType }) => {
if (adType === OptimalPromotionAdType.TwToken) {
return {
...state,
tokenPromotion: createEntity(state.tokenPromotion.data, true)
};
}

return {
...state,
promotion: createEntity(state.promotion.data, true)
};
});
builder.addCase(loadPartnersPromoActions.success, (state, { payload }) => {
if (payload.adType === OptimalPromotionAdType.TwToken) {
return {
...state,
tokenPromotion: createEntity(payload.ad, false)
};
}

return {
...state,
promotion: createEntity(payload.ad, false)
};
});
builder.addCase(loadPartnersPromoActions.fail, (state, { payload }) => {
if (payload.adType === OptimalPromotionAdType.TwToken) {
return {
...state,
tokenPromotion: createEntity(state.tokenPromotion.data, false, payload.error)
};
}

return {
...state,
promotion: createEntity(state.promotion.data, false, payload.error)
};
});
builder.addCase(togglePartnersPromotionAction, (state, { payload }) => ({
...state,
isEnabled: payload
Expand Down
8 changes: 7 additions & 1 deletion src/store/partners-promotion/partners-promotion-selectors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { OptimalPromotionAdType } from '../../utils/optimal.utils';
import { useSelector } from '../selector';

export const usePartnersPromoSelector = () => useSelector(state => state.partnersPromotion.promotion.data);
export const usePartnersPromoSelector = (adType: OptimalPromotionAdType) =>
useSelector(state =>
adType === OptimalPromotionAdType.TwToken
? state.partnersPromotion.tokenPromotion.data
: state.partnersPromotion.promotion.data
);
export const usePartnersPromoLoadingSelector = () => useSelector(state => state.partnersPromotion.promotion.isLoading);
export const useIsPartnersPromoEnabledSelector = () => useSelector(state => state.partnersPromotion.isEnabled);
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const mockPartnersPromotion = {
};

export const mockPartnersPromotionState: PartnersPromotionState = {
tokenPromotion: createEntity(mockPartnersPromotion),
promotion: createEntity(mockPartnersPromotion),
isEnabled: false
};
2 changes: 2 additions & 0 deletions src/store/partners-promotion/partners-promotion-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { LoadableEntityState } from '../types';
import { mockPartnersPromotion } from './partners-promotion-state.mock';

export interface PartnersPromotionState {
tokenPromotion: LoadableEntityState<OptimalPromotionType>;
promotion: LoadableEntityState<OptimalPromotionType>;
isEnabled: boolean;
}

export const partnersPromotionInitialState: PartnersPromotionState = {
tokenPromotion: createEntity(mockPartnersPromotion),
promotion: createEntity(mockPartnersPromotion),
isEnabled: false
};

0 comments on commit d6ead81

Please sign in to comment.