notificationDetailPage.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. import {
  2. View,
  3. Text,
  4. Pressable,
  5. Image,
  6. ScrollView,
  7. Alert,
  8. ImageBackground,
  9. ActivityIndicator,
  10. Dimensions
  11. } from 'react-native';
  12. import { SafeAreaView } from 'react-native-safe-area-context';
  13. import { router, useLocalSearchParams } from 'expo-router';
  14. import { CrossLogoSvg, PreviousPageBlackSvg } from '../../../../component/global/SVG';
  15. import { useEffect, useState } from 'react';
  16. import { FlashList } from '@shopify/flash-list';
  17. import DisplayedOnlyCouponTabView from '../../../../component/global/displayedOnlyCouponTabView';
  18. import NotificationTabView from '../../../../component/global/notificationTabViewComponent';
  19. import { chargeStationService } from '../../../../service/chargeStationService';
  20. import { formatToChineseDateTime } from '../../../../util/lib';
  21. const NotificationDetailPage = () => {
  22. const screenHeight = Dimensions.get('window').height;
  23. const { promotion } = useLocalSearchParams();
  24. const promotionObj = JSON.parse(promotion as string);
  25. const [loading, setLoading] = useState(false);
  26. const [promotionImage, setPromotionImage] = useState('');
  27. const AdaptiveImage = ({ source }: { source: string }) => {
  28. const [aspectRatio, setAspectRatio] = useState(1);
  29. const [error, setError] = useState(false);
  30. const windowWidth = Dimensions.get('window').width;
  31. useEffect(() => {
  32. if (source) {
  33. // Remote image
  34. Image.getSize(
  35. source,
  36. (width, height) => {
  37. if (width && height) {
  38. setAspectRatio(width / height);
  39. setError(false);
  40. } else {
  41. setError(true);
  42. console.error('Invalid image dimensions received');
  43. }
  44. },
  45. (error) => {
  46. setError(true);
  47. console.error('Error getting image size:', error);
  48. }
  49. );
  50. } else {
  51. try {
  52. // Local image
  53. const dimensions = Image.resolveAssetSource({ uri: source });
  54. if (dimensions && dimensions.width && dimensions.height) {
  55. setAspectRatio(dimensions.width / dimensions.height);
  56. setError(false);
  57. } else {
  58. setError(true);
  59. console.error('Invalid dimensions from resolveAssetSource');
  60. }
  61. } catch (e) {
  62. setError(true);
  63. console.error('Error resolving asset source:', e);
  64. }
  65. }
  66. }, [source]);
  67. if (error) {
  68. return;
  69. }
  70. return (
  71. <Image
  72. source={{ uri: source }}
  73. style={{
  74. width: windowWidth/1.1,
  75. aspectRatio,
  76. resizeMode: 'contain'
  77. }}
  78. />
  79. );
  80. };
  81. useEffect(() => {
  82. setLoading(true);
  83. const fetchPromotionImage = async () => {
  84. try {
  85. const promotionImage = await chargeStationService.getProcessedImageUrl(promotionObj.image_url);
  86. setPromotionImage(promotionImage);
  87. console.log('promotionImage', promotionImage);
  88. } catch (e) {
  89. console.log(e);
  90. } finally {
  91. setLoading(false);
  92. }
  93. };
  94. fetchPromotionImage();
  95. }, []);
  96. return (
  97. <SafeAreaView className="flex-1 bg-white" edges={['top', 'right', 'left']}>
  98. <ScrollView>
  99. {loading ? (
  100. <View className="items-center justify-center">
  101. <ActivityIndicator />
  102. </View>
  103. ) : (
  104. <View style={{ minHeight: screenHeight, flex: 1 }} className="mx-[5%]">
  105. <View style={{ marginTop: 25 }}>
  106. <Pressable
  107. onPress={() => {
  108. if (router.canGoBack()) {
  109. router.back();
  110. } else {
  111. router.replace('/notificationPage');
  112. }
  113. }}
  114. hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
  115. >
  116. <CrossLogoSvg />
  117. </Pressable>
  118. <Text style={{ fontSize: 45, marginVertical: 25 }}>詳情</Text>
  119. </View>
  120. <View className="space-y-2 ">
  121. <Text className="text-base lg:text-lg">{promotionObj.title}</Text>
  122. {promotionImage && (
  123. <View className="w-full flex items-center justify-center">
  124. <AdaptiveImage source={promotionImage} />
  125. </View>
  126. )}
  127. <Text className="text-sm">{promotionObj.text}</Text>
  128. <Text className="text-xs text-gray-500 pt-8 pb-4">
  129. 最新更新日期:{formatToChineseDateTime(promotionObj.updatedAt)}
  130. </Text>
  131. </View>
  132. </View>
  133. )}
  134. </ScrollView>
  135. </SafeAreaView>
  136. );
  137. };
  138. export default NotificationDetailPage;