Skip to content

Commit

Permalink
changed banner placement
Browse files Browse the repository at this point in the history
  • Loading branch information
lendihop committed Mar 13, 2024
1 parent ba11631 commit 94a1162
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@ import { formatSize } from 'src/styles/format-size';
export const useActivityGroupsListStyles = createUseStyles(({ colors, typography }) => ({
contentContainer: {
flex: 1,
paddingTop: formatSize(8),
paddingBottom: formatSize(16)
},
adContainer: {
paddingBottom: formatSize(12),
paddingRight: formatSize(16)
},
sectionHeaderText: {
...typography.numbersMedium13,
color: colors.gray2,
Expand All @@ -19,10 +14,7 @@ export const useActivityGroupsListStyles = createUseStyles(({ colors, typography
marginLeft: formatSize(16)
},
promotionItemWrapper: {
paddingVertical: formatSize(12),
marginLeft: formatSize(16),
borderBottomWidth: formatSize(0.5),
borderBottomColor: colors.lines
margin: formatSize(16)
},
centeredItem: {
alignSelf: 'center'
Expand All @@ -35,8 +27,5 @@ export const useActivityGroupsListStyles = createUseStyles(({ colors, typography
},
additionalLoader: {
paddingTop: formatSize(16)
},
listPromotionItem: {
marginRight: formatSize(16)
}
}));
153 changes: 47 additions & 106 deletions src/components/activity-groups-list/activity-groups-list.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FlashList, ListRenderItem } from '@shopify/flash-list';
import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { ActivityIndicator, LayoutChangeEvent, Text, View } from 'react-native';
import { ActivityIndicator, Text, View } from 'react-native';

import { DataPlaceholder } from 'src/components/data-placeholder/data-placeholder';
import { PromotionItem } from 'src/components/promotion-item';
Expand All @@ -9,7 +9,6 @@ import { emptyFn } from 'src/config/general';
import { useAdTemporaryHiding } from 'src/hooks/use-ad-temporary-hiding.hook';
import { useFakeRefreshControlProps } from 'src/hooks/use-fake-refresh-control-props.hook';
import { useInternalAdsAnalytics } from 'src/hooks/use-internal-ads-analytics.hook';
import { useListElementIntersection } from 'src/hooks/use-list-element-intersection.hook';
import { useOutsideOfListIntersection } from 'src/hooks/use-outside-of-list-intersection.hook';
import { ActivityGroup, emptyActivity } from 'src/interfaces/activity.interface';
import { useIsPartnersPromoEnabledSelector } from 'src/store/partners-promotion/partners-promotion-selectors';
Expand All @@ -23,8 +22,7 @@ import { useActivityGroupsListStyles } from './activity-groups-list.styles';
type ListItem = string | ActivityGroup;

const getItemType = (item: ListItem) => (typeof item === 'string' ? 'sectionHeader' : 'row');

const ListEmptyComponent = <DataPlaceholder text="No Activity records were found" />;
const keyExtractor = (item: ListItem) => (typeof item === 'string' ? item : item[0].hash);

const AVERAGE_ITEM_HEIGHT = 150;
const PROMOTION_ID = 'activities-promotion';
Expand All @@ -50,29 +48,9 @@ export const ActivityGroupsList: FC<Props> = ({
const { isHiddenTemporarily } = useAdTemporaryHiding(PROMOTION_ID);
const fakeRefreshControlProps = useFakeRefreshControlProps();
const [endIsReached, setEndIsReached] = useState(false);
const [loadingEnded, setLoadingEnded] = useState(!isLoading);
const [promotionErrorOccurred, setPromotionErrorOccurred] = useState(false);
const shouldShowPromotion = partnersPromotionEnabled && !promotionErrorOccurred && !isHiddenTemporarily;

const keyExtractor = useCallback(
(item: ListItem, index: number) => {
const keyRoot = typeof item === 'string' ? item : item[0].hash;

if (index === 1 && shouldShowPromotion) {
return `${keyRoot}-with-promotion`;
}

return keyRoot;
},
[shouldShowPromotion]
);

useEffect(() => {
if (!isLoading) {
setLoadingEnded(true);
}
}, [isLoading]);

const handleEndReached = useCallback(() => {
setEndIsReached(true);
handleUpdate();
Expand Down Expand Up @@ -105,119 +83,82 @@ export const ActivityGroupsList: FC<Props> = ({

return result;
}, [activityGroups]);
const shouldRenderList = sections.length > 0;

const adRef = useRef<View>(null);
const separateAdParentRef = useRef<View>(null);

const { onAdLoad, resetAdState, onIsVisible } = useInternalAdsAnalytics(pageName);
const {
onListScroll,
onElementLayoutChange: onListAdLayoutChange,
onListLayoutChange,
onUnmount: onListAdUnmount
} = useListElementIntersection(onIsVisible);
const { onElementOrParentLayout: onSeparateAdOrParentLayout, onUnmount: onSeparateAdUnmount } =
useOutsideOfListIntersection(separateAdParentRef, adRef, onIsVisible);

useEffect(() => {
if (shouldRenderList) {
onSeparateAdUnmount();
} else {
onListAdUnmount();
}
resetAdState();
}, [onListAdUnmount, onSeparateAdUnmount, resetAdState, shouldRenderList]);

const handlePromotionLayout = useCallback(
(e: LayoutChangeEvent) => {
if (shouldRenderList) {
onListAdLayoutChange(e);
} else {
onSeparateAdOrParentLayout();
}
},
[onListAdLayoutChange, onSeparateAdOrParentLayout, shouldRenderList]
);
const { onAdLoad, onIsVisible } = useInternalAdsAnalytics(pageName);

const Promotion = useMemo(
() => (
<View style={styles.promotionItemWrapper} onLayout={handlePromotionLayout}>
const { onElementOrParentLayout } = useOutsideOfListIntersection(undefined, adRef, onIsVisible);

const ListHeaderComponent = useMemo(
() =>
shouldShowPromotion ? (
<PromotionItem
ref={adRef}
id={PROMOTION_ID}
style={shouldRenderList && styles.listPromotionItem}
testID={ActivityGroupsListSelectors.promotion}
pageName={pageName}
ref={adRef}
testID={ActivityGroupsListSelectors.promotion}
style={styles.promotionItemWrapper}
onLayout={onElementOrParentLayout}
onError={handlePromotionError}
onLoad={onAdLoad}
/>
) : undefined,
[shouldShowPromotion, styles, onElementOrParentLayout, pageName, handlePromotionError, onAdLoad]
);

const ListEmptyComponent = useMemo(
() => (
<View style={styles.emptyListWrapper}>
{isLoading ? (
<View style={styles.loaderWrapper}>
<ActivityIndicator size="large" />
</View>
) : (
<DataPlaceholder text="No Activity records were found" />
)}
</View>
),
[styles, shouldRenderList, handlePromotionLayout, handlePromotionError, onAdLoad]
[isLoading, styles]
);

const renderItem: ListRenderItem<string | ActivityGroup> = useCallback(
({ item, index }) =>
({ item }) =>
typeof item === 'string' ? (
<Text style={styles.sectionHeaderText}>{item}</Text>
) : (
<>
<ActivityGroupItem group={item} />
{index === 1 && shouldShowPromotion && Promotion}
</>
<ActivityGroupItem group={item} />
),
[shouldShowPromotion, styles, Promotion]
[styles]
);

const stickyHeaderIndices = useMemo(
() => sections.map((item, index) => (typeof item === 'string' ? index : null)).filter(isDefined),
[sections]
);

const shouldRenderAdditionalLoader = !isAllLoaded && endIsReached;
const shouldRenderAdditionalLoader = !isAllLoaded && endIsReached && sections.length > 0;
const renderAdditionalLoader = useCallback(
() => (shouldRenderAdditionalLoader ? <ActivityIndicator style={styles.additionalLoader} size="large" /> : null),
[shouldRenderAdditionalLoader, styles.additionalLoader]
);

if (shouldRenderList) {
return (
<View style={styles.contentContainer}>
<FlashList
data={sections}
stickyHeaderIndices={stickyHeaderIndices}
onEndReachedThreshold={0.01}
onEndReached={handleEndReached}
onLayout={onListLayoutChange}
onScroll={onListScroll}
keyExtractor={keyExtractor}
renderItem={renderItem}
estimatedItemSize={AVERAGE_ITEM_HEIGHT}
getItemType={getItemType}
ListFooterComponent={renderAdditionalLoader}
refreshControl={<RefreshControl {...fakeRefreshControlProps} />}
/>
</View>
);
}

return (
<>
{shouldShowPromotion && (
<View style={styles.adContainer} ref={separateAdParentRef} onLayout={onSeparateAdOrParentLayout}>
{Promotion}
</View>
)}
<View style={styles.emptyListWrapper}>
{loadingEnded ? (
ListEmptyComponent
) : (
<View style={styles.loaderWrapper}>
<ActivityIndicator size="large" />
</View>
)}
</View>
</>
<View style={styles.contentContainer}>
<FlashList
data={sections}
stickyHeaderIndices={stickyHeaderIndices}
onEndReachedThreshold={0.01}
onEndReached={handleEndReached}
keyExtractor={keyExtractor}
renderItem={renderItem}
estimatedItemSize={AVERAGE_ITEM_HEIGHT}
getItemType={getItemType}
ListHeaderComponent={ListHeaderComponent}
ListEmptyComponent={ListEmptyComponent}
ListFooterComponent={renderAdditionalLoader}
refreshControl={<RefreshControl {...fakeRefreshControlProps} />}
/>
</View>
);
};
32 changes: 18 additions & 14 deletions src/screens/notifications/notifications.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { FlashList, ListRenderItem } from '@shopify/flash-list';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { View } from 'react-native';
import { useDispatch } from 'react-redux';

Expand Down Expand Up @@ -51,9 +51,9 @@ export const Notifications = () => {

usePageAnalytic(ScreensEnum.Notifications);

return (
<>
{partnersPromoShown && !promotionErrorOccurred && (
const ListHeaderComponent = useMemo(
() =>
partnersPromoShown && !promotionErrorOccurred ? (
<>
<PromotionItem
id={PROMOTION_ID}
Expand All @@ -67,15 +67,19 @@ export const Notifications = () => {
/>
<HorizontalBorder />
</>
)}
<FlashList
data={notifications}
renderItem={renderItem}
keyExtractor={keyExtractor}
estimatedItemSize={AVERAGE_NOTIFICATION_ITEM_HEIGHT}
contentContainerStyle={NotificationsStyles.contentContainer}
ListEmptyComponent={ListEmptyComponent}
/>
</>
) : undefined,
[handlePromotionItemError, onAdLoad, onElementOrParentLayout, partnersPromoShown, promotionErrorOccurred]
);

return (
<FlashList
data={notifications}
renderItem={renderItem}
keyExtractor={keyExtractor}
estimatedItemSize={AVERAGE_NOTIFICATION_ITEM_HEIGHT}
contentContainerStyle={NotificationsStyles.contentContainer}
ListHeaderComponent={ListHeaderComponent}
ListEmptyComponent={ListEmptyComponent}
/>
);
};

0 comments on commit 94a1162

Please sign in to comment.