Skip to content

Commit

Permalink
feat: add header and bottom bar animations on webview scroll [LIVE-13…
Browse files Browse the repository at this point in the history
…188]

Also sync scroll on other pages with paddingTop under the absolute position for the header
  • Loading branch information
Justkant committed Aug 9, 2024
1 parent bd1b099 commit 6ebea98
Show file tree
Hide file tree
Showing 16 changed files with 419 additions and 161 deletions.
5 changes: 5 additions & 0 deletions .changeset/plenty-chairs-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"live-mobile": minor
---

feat: add header and bottom bar animations on webview scroll
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function renderLoading() {
);
}
export const PlatformAPIWebview = forwardRef<WebviewAPI, WebviewProps>(
({ manifest, inputs = {}, onStateChange }, ref) => {
({ manifest, inputs = {}, onStateChange, onScroll }, ref) => {
const tracking = useMemo(
() =>
trackingWrapper((eventName: string, properties?: Record<string, unknown> | null) =>
Expand Down Expand Up @@ -527,6 +527,8 @@ export const PlatformAPIWebview = forwardRef<WebviewAPI, WebviewProps>(
return (
<RNWebView
ref={webviewRef}
onScroll={onScroll}
decelerationRate="normal"
allowsBackForwardNavigationGestures
startInLoadingState={true}
showsHorizontalScrollIndicator={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const WalletAPIWebview = forwardRef<WebviewAPI, WebviewProps>(
customHandlers,
onStateChange,
allowsBackForwardNavigationGestures = true,
onScroll,
},
ref,
) => {
Expand Down Expand Up @@ -49,6 +50,8 @@ export const WalletAPIWebview = forwardRef<WebviewAPI, WebviewProps>(
return (
<RNWebView
ref={webviewRef}
onScroll={onScroll}
decelerationRate="normal"
startInLoadingState={true}
showsHorizontalScrollIndicator={false}
allowsBackForwardNavigationGestures={allowsBackForwardNavigationGestures}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ export const Web3AppWebview = forwardRef<WebviewAPI, WebviewProps>(
customHandlers,
onStateChange,
allowsBackForwardNavigationGestures,
onScroll,
},
ref,
) => {
if (semver.satisfies(WALLET_API_VERSION, manifest.apiVersion)) {
return (
<WalletAPIWebview
ref={ref}
onScroll={onScroll}
manifest={manifest}
currentAccountHistDb={currentAccountHistDb}
inputs={inputs}
Expand All @@ -33,6 +35,7 @@ export const Web3AppWebview = forwardRef<WebviewAPI, WebviewProps>(
return (
<PlatformAPIWebview
ref={ref}
onScroll={onScroll}
currentAccountHistDb={currentAccountHistDb}
manifest={manifest}
inputs={inputs}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ComponentProps } from "react";
import { LiveAppManifest } from "@ledgerhq/live-common/platform/types";
import { CurrentAccountHistDB } from "@ledgerhq/live-common/wallet-api/react";
import { WalletAPICustomHandlers } from "@ledgerhq/live-common/wallet-api/types";
Expand All @@ -10,6 +11,7 @@ export type WebviewProps = {
onStateChange?: (webviewState: WebviewState) => void;
allowsBackForwardNavigationGestures?: boolean;
customHandlers?: WalletAPICustomHandlers;
onScroll?: ComponentProps<typeof WebView>["onScroll"];
};

export type WebviewState = {
Expand Down
3 changes: 3 additions & 0 deletions apps/ledger-live-mobile/src/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -6844,6 +6844,9 @@
"description": "Discover the best of web3 curated by Ledger"
},
"main": {
"manifestsList": {
"title": "Discover"
},
"header": {
"title": "Explore web3",
"placeholder": "Search or type a URL"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useState } from "react";
import React, { ComponentProps, useCallback, useState } from "react";
import { View } from "react-native";
import Animated from "react-native-reanimated";
import { useTranslation } from "react-i18next";
Expand All @@ -18,7 +18,9 @@ type NavigationProp = MainProps["navigation"] | SearchProps["navigation"];

type Props = {
navigation: NavigationProp;
onScroll?: FlashListProps<AppManifest>["onScroll"];
onScroll?: ComponentProps<typeof AnimatedFlashList>["onScroll"];
title?: string;
pt?: number;
pb?: number;
};

Expand All @@ -38,7 +40,7 @@ const renderItem = ({
return <ManifestItem manifest={item} onPress={extraData} />;
};

export default function ManifestsList({ navigation, onScroll, pb = 0 }: Props) {
export default function ManifestsList({ navigation, onScroll, title, pt = 0, pb = 0 }: Props) {
const { t } = useTranslation();
const insets = useSafeAreaInsets();
const [selectedCategory, selectCategory] = useState("all");
Expand All @@ -63,12 +65,13 @@ export default function ManifestsList({ navigation, onScroll, pb = 0 }: Props) {
<Disclaimer disclaimer={disclaimer} />
<AnimatedFlashList
contentContainerStyle={{
paddingTop: pt ? pt + insets.top : pt,
paddingBottom: pb + insets.bottom,
}}
ListHeaderComponent={
<>
<Text mt={5} numberOfLines={1} variant="h5" mx={5} accessibilityRole="header">
{t("web3hub.manifestsList.title")}
{title ?? t("web3hub.manifestsList.title")}
</Text>
<Text mt={2} mb={5} numberOfLines={1} variant="body" mx={5} accessibilityRole="header">
{t("web3hub.manifestsList.description")}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import React from "react";
import React, { useContext } from "react";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useTheme } from "@react-navigation/native";
import { Box, Flex } from "@ledgerhq/native-ui";
import Animated, { useAnimatedStyle, interpolate, Extrapolation } from "react-native-reanimated";
import { Flex } from "@ledgerhq/native-ui";
import { HeaderContext } from "LLM/features/Web3Hub/HeaderContext";
import BackButton from "LLM/features/Web3Hub/components/BackButton";
import TabButton from "LLM/features/Web3Hub/components/TabButton";
import { AppProps } from "LLM/features/Web3Hub/types";
import TextInput from "~/components/TextInput";

const SEARCH_HEIGHT = 60;
export const TOTAL_HEADER_HEIGHT = SEARCH_HEIGHT;

const ANIMATION_HEIGHT = TOTAL_HEADER_HEIGHT;
const LAYOUT_RANGE = [0, ANIMATION_HEIGHT];

type Props = {
navigation: AppProps["navigation"];
Expand All @@ -16,26 +22,72 @@ type Props = {
export default function Web3HubAppHeader({ navigation }: Props) {
const insets = useSafeAreaInsets();
const { colors } = useTheme();
const { layoutY } = useContext(HeaderContext);

const heightStyle = useAnimatedStyle(() => {
if (!layoutY) return {};

const headerHeight = interpolate(
layoutY.value,
LAYOUT_RANGE,
[TOTAL_HEADER_HEIGHT, TOTAL_HEADER_HEIGHT - ANIMATION_HEIGHT],
Extrapolation.CLAMP,
);

return {
backgroundColor: colors.background,
paddingTop: insets.top,
height: headerHeight + insets.top,
};
});

const transformStyle = useAnimatedStyle(() => {
if (!layoutY) return {};

return {
// Height necessary for proper transform
height: TOTAL_HEADER_HEIGHT,
transform: [
{
translateY: interpolate(
layoutY.value,
LAYOUT_RANGE,
[0, -ANIMATION_HEIGHT],
Extrapolation.CLAMP,
),
},
],
};
});

const opacityStyle = useAnimatedStyle(() => {
if (!layoutY) return {};

return {
height: TOTAL_HEADER_HEIGHT,
opacity: interpolate(layoutY.value, [0, ANIMATION_HEIGHT], [1, 0], Extrapolation.CLAMP),
};
});

return (
<Box
backgroundColor={colors.background}
paddingTop={insets.top}
height={SEARCH_HEIGHT + insets.top}
>
<Flex flex={1} height={SEARCH_HEIGHT} flexDirection="row" alignItems="center">
<BackButton onPress={navigation.goBack} />
<Flex flex={1}>
<TextInput
placeholder="Current URL"
keyboardType="default"
returnKeyType="done"
value=""
disabled
/>
</Flex>
<TabButton count={2} navigation={navigation} />
</Flex>
</Box>
<Animated.View style={heightStyle}>
<Animated.View style={transformStyle}>
<Animated.View style={opacityStyle}>
<Flex flex={1} height={SEARCH_HEIGHT} flexDirection="row" alignItems="center">
<BackButton onPress={navigation.goBack} />
<Flex flex={1}>
<TextInput
placeholder="Current URL"
keyboardType="default"
returnKeyType="done"
value=""
disabled
/>
</Flex>
<TabButton count={2} navigation={navigation} />
</Flex>
</Animated.View>
</Animated.View>
</Animated.View>
);
}
Loading

0 comments on commit 6ebea98

Please sign in to comment.