From bf439240665c6f8a11ec0c9f1700be86d99b6b2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Edenstr=C3=B6m?= Date: Mon, 8 Nov 2021 18:08:40 +0100 Subject: [PATCH 1/5] feat: add image sizes using Image.getSizeWithHeaders --- .../components/image.component.tsx | 66 +++++++++++++++---- .../components/markdown.component.tsx | 8 ++- .../components/newsItem.component.tsx | 7 +- .../components/newsListItem.component.tsx | 12 +++- 4 files changed, 70 insertions(+), 23 deletions(-) diff --git a/apps/skolplattformen-sthlm/components/image.component.tsx b/apps/skolplattformen-sthlm/components/image.component.tsx index 32b05e486..eef415292 100644 --- a/apps/skolplattformen-sthlm/components/image.component.tsx +++ b/apps/skolplattformen-sthlm/components/image.component.tsx @@ -1,38 +1,76 @@ import { useApi } from '@skolplattformen/hooks' -import React, { useEffect, useState } from 'react' -import { Image as ImageBase, ImageStyle, StyleProp } from 'react-native' +import React, { useCallback, useEffect, useState } from 'react' +import { + Image as ImageBase, + ImageResizeMode, + ImageStyle, + StyleProp, + useWindowDimensions, +} from 'react-native' interface ImageProps { src: string style: StyleProp + /** + * Width of component. Defaults to window width + * Used to automatically calculate width + */ + componentWidth?: number accessibilityIgnoresInvertColors: boolean + resizeMode?: ImageResizeMode + width?: number + height?: number } export const Image = ({ src, style, + componentWidth = 0, accessibilityIgnoresInvertColors, + resizeMode = 'contain', }: ImageProps) => { const { api } = useApi() const [headers, setHeaders] = useState() + const { width: windowWidth } = useWindowDimensions() + const [dimensions, setDimensions] = useState({ width: 0, height: 0 }) - const getHeaders = async (url: string) => { - const { headers: newHeaders } = await api.getSession(url) - setHeaders(newHeaders) - } + const prefetchImageInformation = useCallback( + async (url: string) => { + const { headers: newHeaders } = await api.getSession(url) + + ImageBase.getSizeWithHeaders( + url, + newHeaders, + (w, h) => { + setDimensions({ width: w, height: h }) + setHeaders(newHeaders) + }, + (error) => console.error(error) + ) + }, + [api] + ) useEffect(() => { - getHeaders(src) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [src]) + prefetchImageInformation(src) + }, [prefetchImageInformation, src]) + + const compWidth = componentWidth || windowWidth + + const scale = compWidth / dimensions.width + const scaledWidth = Math.round(dimensions.width * scale) + const scaledHeight = Math.round(dimensions.height * scale) + + const imageSource = + resizeMode === 'cover' + ? { uri: src, headers } + : { uri: src, headers, height: scaledHeight, width: scaledWidth } - return headers ? ( + return headers && scaledWidth && scaledHeight ? ( ) : null diff --git a/apps/skolplattformen-sthlm/components/markdown.component.tsx b/apps/skolplattformen-sthlm/components/markdown.component.tsx index 78406a16c..55f22ae72 100644 --- a/apps/skolplattformen-sthlm/components/markdown.component.tsx +++ b/apps/skolplattformen-sthlm/components/markdown.component.tsx @@ -1,7 +1,8 @@ import { Text } from '@ui-kitten/components' import React from 'react' -import { Linking, StyleSheet } from 'react-native' +import { Dimensions, Linking, StyleSheet } from 'react-native' import MarkdownBase, { RenderRules } from 'react-native-markdown-display' +import { Sizing } from '../styles' import { Image } from './image.component' interface MarkdownProps { @@ -20,6 +21,9 @@ const rules: RenderRules = { accessibilityIgnoresInvertColors key={src} src={url} + // TODO: Sizing.t5 should not be hardcoded here... + // Maybe measure the width from inside the component instead? + componentWidth={Dimensions.get('window').width - Sizing.t5} style={styles.markdownImage} /> ) @@ -52,5 +56,5 @@ export const Markdown = ({ style, children }: MarkdownProps) => { } const styles = StyleSheet.create({ - markdownImage: { width: '100%', minHeight: 300 }, + markdownImage: { width: '100%' }, }) diff --git a/apps/skolplattformen-sthlm/components/newsItem.component.tsx b/apps/skolplattformen-sthlm/components/newsItem.component.tsx index edbd006e1..da3d8cfa8 100644 --- a/apps/skolplattformen-sthlm/components/newsItem.component.tsx +++ b/apps/skolplattformen-sthlm/components/newsItem.component.tsx @@ -5,7 +5,7 @@ import { StyleService, Text, useStyleSheet } from '@ui-kitten/components' import moment from 'moment' import 'moment/locale/sv' import React from 'react' -import { ScrollView, View } from 'react-native' +import { Dimensions, ImageStyle, ScrollView, View } from 'react-native' import { NativeStackNavigationOptions } from 'react-native-screens/native-stack' import { defaultStackStyling } from '../design/navigationThemes' import { Layout, Sizing, Typography } from '../styles' @@ -79,8 +79,8 @@ export const NewsItem = ({ route }: NewsItemProps) => { )} @@ -119,7 +119,6 @@ const themedStyles = StyleService.create({ }, image: { width: '100%', - minHeight: 300, marginTop: Sizing.t4, borderRadius: 15, }, diff --git a/apps/skolplattformen-sthlm/components/newsListItem.component.tsx b/apps/skolplattformen-sthlm/components/newsListItem.component.tsx index 5066a3dea..226d66866 100644 --- a/apps/skolplattformen-sthlm/components/newsListItem.component.tsx +++ b/apps/skolplattformen-sthlm/components/newsListItem.component.tsx @@ -4,7 +4,13 @@ import { NewsItem } from '@skolplattformen/api-skolplattformen' import { StyleService, useStyleSheet } from '@ui-kitten/components' import moment from 'moment' import React, { ReactNode } from 'react' -import { Dimensions, Text, TouchableOpacity, View } from 'react-native' +import { + Dimensions, + ImageStyle, + Text, + TouchableOpacity, + View, +} from 'react-native' import { Layout, Sizing, Typography } from '../styles' import { useChild } from './childContext.component' import { Image } from './image.component' @@ -39,8 +45,8 @@ export const NewsListItem = ({ item, children }: NewsListItemProps) => { ) : null} From 363824bf42b4fa2ea8eb8f788a36733766c21a06 Mon Sep 17 00:00:00 2001 From: Kajetan Kazimierczak Date: Mon, 8 Nov 2021 21:11:38 +0100 Subject: [PATCH 2/5] =?UTF-8?q?chore:=20=F0=9F=A4=96=20bild=20i=20fakeData?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/api-skolplattformen/lib/fakeData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/api-skolplattformen/lib/fakeData.ts b/libs/api-skolplattformen/lib/fakeData.ts index 0b2a32ffe..731905336 100644 --- a/libs/api-skolplattformen/lib/fakeData.ts +++ b/libs/api-skolplattformen/lib/fakeData.ts @@ -810,7 +810,7 @@ const data: any = { intro: 'Vi kommer efter att förskoleklassen är slut arrangera olika vinteraktiviteter genom fridtidsverksamheten.', body: - '## Vänligen ta med hjälm, skridskor eller stjärtlapp. Alla barn måste ha hjälm på sig samt varma kläder. Vi kommer åka i backen bakom skolbyggnaden samt använda isen som spolats vid Mullsjöskolan. Personal kommer finnas på plats samt att vi erbjuda varm dryck, frukt och lek för de barn som ej har hjälm eller lämpligt åkdon.', + '## Vänligen ta med hjälm, skridskor eller stjärtlapp.\n\n ![Bild](https://images.unsplash.com/photo-1495377701095-00261b767581?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=988&q=80)\n\n Alla barn måste ha hjälm på sig samt varma kläder. Vi kommer åka i backen bakom skolbyggnaden samt använda isen som spolats vid Mullsjöskolan. Personal kommer finnas på plats samt att vi erbjuda varm dryck, frukt och lek för de barn som ej har hjälm eller lämpligt åkdon.', imageUrl: '6607f9b923edb6f85aa4417bab43c0f8.jpg', fullImageUrl: 'https://unsplash.com/photos/yB_aiAWkm40', imageAltText: 'Nyhetsbild. Bildtext ej tillgänglig.', From 50a4ef87cb76e558775a80abfd138c46f49cdb51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Edenstr=C3=B6m?= Date: Tue, 9 Nov 2021 06:39:55 +0100 Subject: [PATCH 3/5] add rounded corners to embedded images in content --- apps/skolplattformen-sthlm/components/markdown.component.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/skolplattformen-sthlm/components/markdown.component.tsx b/apps/skolplattformen-sthlm/components/markdown.component.tsx index 55f22ae72..5e10d02c9 100644 --- a/apps/skolplattformen-sthlm/components/markdown.component.tsx +++ b/apps/skolplattformen-sthlm/components/markdown.component.tsx @@ -23,7 +23,7 @@ const rules: RenderRules = { src={url} // TODO: Sizing.t5 should not be hardcoded here... // Maybe measure the width from inside the component instead? - componentWidth={Dimensions.get('window').width - Sizing.t5} + componentWidth={Dimensions.get('window').width - Sizing.t5 * 2} style={styles.markdownImage} /> ) @@ -56,5 +56,5 @@ export const Markdown = ({ style, children }: MarkdownProps) => { } const styles = StyleSheet.create({ - markdownImage: { width: '100%' }, + markdownImage: { width: '100%', borderRadius: 15 }, }) From 0d3a7b2974072964fbb9fe2fdebf9d1d11521a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Edenstr=C3=B6m?= Date: Tue, 9 Nov 2021 06:42:54 +0100 Subject: [PATCH 4/5] add debug information --- .../components/image.component.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/skolplattformen-sthlm/components/image.component.tsx b/apps/skolplattformen-sthlm/components/image.component.tsx index eef415292..eefc6d5ef 100644 --- a/apps/skolplattformen-sthlm/components/image.component.tsx +++ b/apps/skolplattformen-sthlm/components/image.component.tsx @@ -6,6 +6,7 @@ import { ImageStyle, StyleProp, useWindowDimensions, + View, } from 'react-native' interface ImageProps { @@ -38,14 +39,19 @@ export const Image = ({ async (url: string) => { const { headers: newHeaders } = await api.getSession(url) + console.log('[IMAGE] Getting image dimensions with headers', newHeaders) + ImageBase.getSizeWithHeaders( url, newHeaders, (w, h) => { + console.log('[IMAGE] Received image dimensions', { w, h }) setDimensions({ width: w, height: h }) setHeaders(newHeaders) }, - (error) => console.error(error) + (error) => { + console.error('[Image] Failed to get image dimensions', error) + } ) }, [api] @@ -73,5 +79,7 @@ export const Image = ({ resizeMode={resizeMode} style={style} /> - ) : null + ) : ( + + ) } From 9a45aae19350481c825087e05c50bf96756c93c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Edenstr=C3=B6m?= Date: Tue, 9 Nov 2021 06:56:50 +0100 Subject: [PATCH 5/5] add more debug info --- .../components/image.component.tsx | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/apps/skolplattformen-sthlm/components/image.component.tsx b/apps/skolplattformen-sthlm/components/image.component.tsx index eefc6d5ef..2b17b1eb4 100644 --- a/apps/skolplattformen-sthlm/components/image.component.tsx +++ b/apps/skolplattformen-sthlm/components/image.component.tsx @@ -35,26 +35,39 @@ export const Image = ({ const { width: windowWidth } = useWindowDimensions() const [dimensions, setDimensions] = useState({ width: 0, height: 0 }) + const debugImageName = getDebugImageName(src) + const prefetchImageInformation = useCallback( async (url: string) => { + if (!url) return const { headers: newHeaders } = await api.getSession(url) - console.log('[IMAGE] Getting image dimensions with headers', newHeaders) + console.log('[IMAGE] Getting image dimensions with headers', { + debugImageName, + newHeaders, + }) ImageBase.getSizeWithHeaders( url, newHeaders, (w, h) => { - console.log('[IMAGE] Received image dimensions', { w, h }) + console.log('[IMAGE] Received image dimensions', { + debugImageName, + w, + h, + }) setDimensions({ width: w, height: h }) setHeaders(newHeaders) }, (error) => { - console.error('[Image] Failed to get image dimensions', error) + console.error('[Image] Failed to get image dimensions', { + debugImageName, + error, + }) } ) }, - [api] + [api, debugImageName] ) useEffect(() => { @@ -83,3 +96,13 @@ export const Image = ({ ) } + +const getDebugImageName = (src: string) => { + try { + const split = src.split('/') + return split[split.length - 1] + } catch (e: any) { + console.log('FAILED', e.message) + return null + } +}