1- import React , { ReactElement , useContext , useEffect , useState } from 'react' ;
1+ import React , { ReactElement , useContext , useEffect , useLayoutEffect , useState } from 'react' ;
22import { StyleSheet , Text , View , ViewStyle } from 'react-native' ;
33import Clipboard from '@react-native-clipboard/clipboard' ;
44import { Image } from 'expo-image' ;
@@ -15,19 +15,18 @@ import EventEmitter from '../../lib/methods/helpers/events';
1515import I18n from '../../i18n' ;
1616import MessageContext from './Context' ;
1717import { IUrl } from '../../definitions' ;
18- import { WidthAwareContext , WidthAwareView } from './Components/WidthAwareView' ;
18+ import { WidthAwareContext } from './Components/WidthAwareView' ;
1919
2020const styles = StyleSheet . create ( {
2121 container : {
2222 flex : 1 ,
2323 flexDirection : 'column' ,
24- marginTop : 4 ,
2524 gap : 4
2625 } ,
2726 textContainer : {
2827 flex : 1 ,
2928 flexDirection : 'column' ,
30- padding : 15 ,
29+ padding : 12 ,
3130 justifyContent : 'flex-start' ,
3231 alignItems : 'flex-start'
3332 } ,
@@ -40,10 +39,8 @@ const styles = StyleSheet.create({
4039 ...sharedStyles . textRegular
4140 } ,
4241 loading : {
43- height : 1 ,
44- width : 1 ,
45- borderWidth : 0 ,
46- marginTop : 0
42+ flex : 1 ,
43+ height : 150
4744 }
4845} ) ;
4946
@@ -66,69 +63,63 @@ const UrlContent = ({ title, description }: { title: string; description: string
6663} ;
6764const UrlImage = ( { image, hasContent } : { image : string ; hasContent : boolean } ) => {
6865 const { colors } = useTheme ( ) ;
69- const [ imageLoadedState , setImageLoadedState ] = useState < TImageLoadedState > ( 'loading' ) ;
7066 const [ imageDimensions , setImageDimensions ] = useState ( { width : 0 , height : 0 } ) ;
7167 const maxSize = useContext ( WidthAwareContext ) ;
7268
73- useEffect ( ( ) => {
74- if ( image ) {
69+ useLayoutEffect ( ( ) => {
70+ if ( image && maxSize ) {
7571 Image . loadAsync ( image , {
7672 onError : ( ) => {
77- setImageLoadedState ( 'error' ) ;
78- }
73+ setImageDimensions ( { width : - 1 , height : - 1 } ) ;
74+ } ,
75+ maxWidth : maxSize
7976 } ) . then ( image => {
8077 setImageDimensions ( { width : image . width , height : image . height } ) ;
8178 } ) ;
8279 }
83- } , [ image ] ) ;
80+ } , [ image , maxSize ] ) ;
8481
85- let imageStyle = { } ;
86- let containerStyle : ViewStyle = { } ;
82+ if ( ! imageDimensions . width || ! imageDimensions . height ) {
83+ return < View style = { styles . loading } /> ;
84+ }
85+ if ( imageDimensions . width === - 1 ) {
86+ return null ;
87+ }
8788
88- if ( imageLoadedState === 'done' ) {
89- const width = Math . min ( imageDimensions . width , maxSize ) || 0 ;
90- const height = Math . min ( ( imageDimensions . height * ( ( width * 100 ) / imageDimensions . width ) ) / 100 , maxSize ) || 0 ;
91- imageStyle = {
92- width,
93- height
94- } ;
89+ const width = Math . min ( imageDimensions . width , maxSize ) || 0 ;
90+ const height = Math . min ( ( imageDimensions . height * ( ( width * 100 ) / imageDimensions . width ) ) / 100 , maxSize ) || 0 ;
91+ const imageStyle = {
92+ width,
93+ height
94+ } ;
95+ let containerStyle : ViewStyle = {
96+ overflow : 'hidden' ,
97+ alignItems : 'center' ,
98+ justifyContent : 'center' ,
99+ ...( imageDimensions . width <= 64 && { width : 64 } ) ,
100+ ...( imageDimensions . height <= 64 && { height : 64 } )
101+ } ;
102+ if ( ! hasContent ) {
95103 containerStyle = {
96- overflow : 'hidden' ,
97- alignItems : 'center' ,
98- justifyContent : 'center' ,
99- ...( imageDimensions . width <= 64 && { width : 64 } ) ,
100- ...( imageDimensions . height <= 64 && { height : 64 } )
104+ ...containerStyle ,
105+ borderColor : colors . strokeLight ,
106+ borderWidth : 1 ,
107+ borderRadius : 4
101108 } ;
102- if ( ! hasContent ) {
103- containerStyle = {
104- ...containerStyle ,
105- borderColor : colors . strokeLight ,
106- borderWidth : 1 ,
107- borderRadius : 4
108- } ;
109- }
110109 }
111110
112111 return (
113112 < View style = { containerStyle } >
114- < Image
115- source = { { uri : image } }
116- style = { [ imageStyle , imageLoadedState === 'loading' && styles . loading ] }
117- contentFit = 'contain'
118- onError = { ( ) => setImageLoadedState ( 'error' ) }
119- onLoad = { ( ) => setImageLoadedState ( 'done' ) }
120- />
113+ < Image source = { { uri : image } } style = { imageStyle } contentFit = 'contain' />
121114 </ View >
122115 ) ;
123116} ;
124117
125- type TImageLoadedState = 'loading' | 'done' | 'error' ;
126-
127118const Url = ( { url } : { url : IUrl } ) => {
128119 const { colors, theme } = useTheme ( ) ;
129120 const { baseUrl, user } = useContext ( MessageContext ) ;
130121 const API_Embed = useAppSelector ( state => state . settings . API_Embed ) ;
131- const [ imageUrl , setImageUrl ] = useState ( '' ) ;
122+ const [ imageUrl , setImageUrl ] = useState ( url . image ) ;
132123
133124 useEffect ( ( ) => {
134125 const verifyUrlIsImage = async ( ) => {
@@ -165,7 +156,7 @@ const Url = ({ url }: { url: IUrl }) => {
165156
166157 const hasContent = ! ! ( url . title || url . description ) ;
167158
168- if ( ! url || url ?. ignoreParse || ! API_Embed || ! hasContent ) {
159+ if ( ! url || url ?. ignoreParse || ! API_Embed ) {
169160 return null ;
170161 }
171162
@@ -185,11 +176,7 @@ const Url = ({ url }: { url: IUrl }) => {
185176 ] }
186177 background = { Touchable . Ripple ( colors . surfaceNeutral ) } >
187178 < >
188- { imageUrl ? (
189- < WidthAwareView >
190- < UrlImage image = { imageUrl } hasContent = { hasContent } />
191- </ WidthAwareView >
192- ) : null }
179+ { imageUrl ? < UrlImage image = { imageUrl } hasContent = { hasContent } /> : null }
193180 { hasContent ? < UrlContent title = { url . title } description = { url . description } /> : null }
194181 </ >
195182 </ Touchable >
0 commit comments