| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import {
- View,
- Text,
- Pressable,
- Image,
- ScrollView,
- Alert,
- ImageBackground,
- ActivityIndicator,
- Dimensions
- } from 'react-native';
- import { SafeAreaView } from 'react-native-safe-area-context';
- import { router, useLocalSearchParams } from 'expo-router';
- import { CrossLogoSvg, PreviousPageBlackSvg } from '../../../../component/global/SVG';
- import { useEffect, useState } from 'react';
- import { chargeStationService } from '../../../../service/chargeStationService';
- import { formatToChineseDateTime } from '../../../../util/lib';
- const NotificationDetailPage = () => {
- const screenHeight = Dimensions.get('window').height;
- const { promotion } = useLocalSearchParams();
- const promotionObj = JSON.parse(promotion as string);
- const [loading, setLoading] = useState(false);
- const [promotionImage, setPromotionImage] = useState('');
- const AdaptiveImage = ({ source }: { source: string }) => {
- const [aspectRatio, setAspectRatio] = useState(1);
- const [error, setError] = useState(false);
- const windowWidth = Dimensions.get('window').width;
- useEffect(() => {
- if (source) {
- // Remote image
- Image.getSize(
- source,
- (width, height) => {
- if (width && height) {
- setAspectRatio(width / height);
- setError(false);
- } else {
- setError(true);
- console.error('Invalid image dimensions received');
- }
- },
- (error) => {
- setError(true);
- console.error('Error getting image size:', error);
- }
- );
- } else {
- try {
- // Local image
- const dimensions = Image.resolveAssetSource({ uri: source });
- if (dimensions && dimensions.width && dimensions.height) {
- setAspectRatio(dimensions.width / dimensions.height);
- setError(false);
- } else {
- setError(true);
- console.error('Invalid dimensions from resolveAssetSource');
- }
- } catch (e) {
- setError(true);
- console.error('Error resolving asset source:', e);
- }
- }
- }, [source]);
- if (error) {
- return;
- }
- return (
- <Image
- source={{ uri: source }}
- style={{
- width: windowWidth / 1.1,
- aspectRatio,
- resizeMode: 'contain'
- }}
- />
- );
- };
- useEffect(() => {
- setLoading(true);
- const fetchPromotionImage = async () => {
- try {
- const promotionImage = await chargeStationService.getProcessedImageUrl(promotionObj.image_url);
- setPromotionImage(promotionImage);
- } catch (e) {
- } finally {
- setLoading(false);
- }
- };
- fetchPromotionImage();
- }, []);
- return (
- <SafeAreaView className="flex-1 bg-white" edges={['top', 'right', 'left']}>
- <ScrollView>
- {loading ? (
- <View className="items-center justify-center">
- <ActivityIndicator />
- </View>
- ) : (
- <View style={{ minHeight: screenHeight, flex: 1 }} className="mx-[5%]">
- <View style={{ marginTop: 25 }}>
- <Pressable
- onPress={() => {
- if (router.canGoBack()) {
- router.back();
- } else {
- router.replace('/notificationPage');
- }
- }}
- hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
- >
- <CrossLogoSvg />
- </Pressable>
- <Text style={{ fontSize: 45, marginVertical: 25 }}>詳情</Text>
- </View>
- <View className="space-y-2 ">
- <Text className="text-base lg:text-lg">{promotionObj.title}</Text>
- {promotionImage && (
- <View className="w-full flex items-center justify-center">
- <AdaptiveImage source={promotionImage} />
- </View>
- )}
- <Text className="text-sm">{promotionObj.text}</Text>
- <Text className="text-xs text-gray-500 pt-8 pb-4">
- 最新更新日期:{formatToChineseDateTime(promotionObj.updatedAt)}
- </Text>
- </View>
- </View>
- )}
- </ScrollView>
- </SafeAreaView>
- );
- };
- export default NotificationDetailPage;
|