diff --git a/babel.config.js b/babel.config.js index e1f5bc5..cda3fce 100644 --- a/babel.config.js +++ b/babel.config.js @@ -5,6 +5,7 @@ module.exports = function (api) { presets: ['babel-preset-expo'], plugins: [ 'nativewind/babel', + 'react-native-reanimated/plugin', [ 'module-resolver', { diff --git a/bun.lockb b/bun.lockb index 3a5a0b1..e64d3ca 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index a6ae96b..3a3b638 100644 --- a/package.json +++ b/package.json @@ -31,11 +31,12 @@ "nativewind": "^2.0.11", "react": "18.2.0", "react-native": "0.72.6", + "react-native-reanimated": "~3.3.0", "react-native-render-html": "^6.3.4", "react-native-safe-area-context": "4.6.3", "react-native-screens": "~3.22.0", - "react-native-svg": "^14.1.0", - "react-native-webview": "^13.6.4", + "react-native-svg": "13.9.0", + "react-native-webview": "13.2.2", "wretch": "^2.8.0" }, "devDependencies": { diff --git a/src/components/HtmlToNativeViewer.tsx b/src/components/HtmlToNativeViewer.tsx index d596995..7b014de 100644 --- a/src/components/HtmlToNativeViewer.tsx +++ b/src/components/HtmlToNativeViewer.tsx @@ -1,7 +1,7 @@ import IframeRenderer, { iframeModel } from '@native-html/iframe-plugin'; import colors from '@theme/colors'; import { width } from '@utils/helpers'; -import { observer } from 'mobx-react-lite'; +import { memo } from 'react'; import { StyleSheet } from 'react-native'; import RenderHtml from 'react-native-render-html'; import { WebView } from 'react-native-webview'; @@ -90,4 +90,4 @@ const styles = StyleSheet.create({ }, }); -export default observer(HtmlToNativeViewer); +export default memo(HtmlToNativeViewer); diff --git a/src/components/PostDetail/PostDetailHeader.tsx b/src/components/PostDetail/PostDetailHeader.tsx index d9adf7f..16ba9e5 100644 --- a/src/components/PostDetail/PostDetailHeader.tsx +++ b/src/components/PostDetail/PostDetailHeader.tsx @@ -36,7 +36,7 @@ const PostDetailHeader = ({ const styles = StyleSheet.create({ header: { - height: width * 0.6, + height: width * 0.9, }, }); diff --git a/src/screens/Blog/PostDetailScreen.tsx b/src/screens/Blog/PostDetailScreen.tsx index 3318e55..339de23 100644 --- a/src/screens/Blog/PostDetailScreen.tsx +++ b/src/screens/Blog/PostDetailScreen.tsx @@ -6,11 +6,18 @@ import savedStore from '@store/SavedStore'; import { text } from '@theme/text'; import { width } from '@utils/helpers'; import { observer } from 'mobx-react-lite'; -import { SafeAreaView, ScrollView, Text, View } from 'react-native'; +import { Text, View } from 'react-native'; +import Animated, { + Extrapolation, + interpolate, + useAnimatedScrollHandler, + useAnimatedStyle, + useSharedValue, +} from 'react-native-reanimated'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; const HEADER_HEIGHT = width * 0.6; -const CONTENT_MARGIN_TOP = HEADER_HEIGHT * 0.5; +const CONTENT_MARGIN_TOP = HEADER_HEIGHT * 0.9; const PostDetailScreen = () => { const { @@ -18,10 +25,26 @@ const PostDetailScreen = () => { } = useRoute>(); const { goBack } = useNavigation(); const { top } = useSafeAreaInsets(); + const scrollY = useSharedValue(0); + const scrollableContentMarginTop = CONTENT_MARGIN_TOP + top; + + const animatedStyle = useAnimatedStyle(() => ({ + marginTop: interpolate( + scrollY.value, + [0, 200], + [scrollableContentMarginTop, top + 48], + Extrapolation.CLAMP, + ), + })); + + const scrollHandler = useAnimatedScrollHandler(event => { + scrollY.value = event.contentOffset.y; + }); + const onPressSave = () => post && savedStore.addPost(post); return ( - + { headerImage={post?.headerImage} isSavedPost={savedStore.isSavedPost(post.id)} /> - - + + {post?.category} @@ -39,8 +66,8 @@ const PostDetailScreen = () => { - - + + ); }; diff --git a/src/store/PostStore.ts b/src/store/PostStore.ts index 3ff467a..0f8f37e 100644 --- a/src/store/PostStore.ts +++ b/src/store/PostStore.ts @@ -23,7 +23,7 @@ export const Post = t const media = yield api.getMediaByUrl(self.mediaUrl); self.image = media?.media_details?.sizes?.medium?.source_url || media?.guid?.rendered; - self.headerImage = media?.guid?.rendered; + self.headerImage = media?.media_details?.sizes?.large?.source_url || media?.guid?.rendered; self.imageLoaded = true; }),