98 lines
2.7 KiB
TypeScript
98 lines
2.7 KiB
TypeScript
import { useNavigation } from '@react-navigation/native'
|
|
import { StackNavigationProp } from '@react-navigation/stack'
|
|
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 { Layout, Sizing, Typography } from '../styles'
|
|
import { useChild } from './childContext.component'
|
|
import { Image } from './image.component'
|
|
import { RootStackParamList } from './navigation.component'
|
|
|
|
interface NewsListItemProps {
|
|
item: NewsItem
|
|
children?: ReactNode
|
|
}
|
|
|
|
type NewsListItemNavigationProp = StackNavigationProp<
|
|
RootStackParamList,
|
|
'NewsItem'
|
|
>
|
|
|
|
const { width } = Dimensions.get('window')
|
|
|
|
export const NewsListItem = ({ item, children }: NewsListItemProps) => {
|
|
const styles = useStyleSheet(themedStyles)
|
|
const navigation = useNavigation<NewsListItemNavigationProp>()
|
|
const child = useChild()
|
|
const hasDate = item.modified || item.published
|
|
|
|
const displayDate = hasDate ? moment(hasDate).fromNow() : null
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
onPress={() => navigation.navigate('NewsItem', { newsItem: item, child })}
|
|
>
|
|
<View style={styles.card}>
|
|
{width > 320 && item.fullImageUrl ? (
|
|
<Image
|
|
accessibilityIgnoresInvertColors={false}
|
|
src={item.fullImageUrl}
|
|
// @ts-expect-error Don't know why this linter breaks
|
|
style={styles.image}
|
|
/>
|
|
) : null}
|
|
<View style={styles.text}>
|
|
<View>
|
|
<Text style={styles.title}>{item.header}</Text>
|
|
<Text style={styles.subtitle}>
|
|
{item.author}
|
|
{item.author && displayDate ? ' • ' : ''}
|
|
{displayDate}
|
|
</Text>
|
|
<Text ellipsizeMode="tail" numberOfLines={2} style={styles.intro}>
|
|
{children ?? item.intro}
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</TouchableOpacity>
|
|
)
|
|
}
|
|
|
|
const themedStyles = StyleService.create({
|
|
card: {
|
|
...Layout.flex.full,
|
|
...Layout.flex.row,
|
|
borderRadius: 15,
|
|
paddingVertical: Sizing.t4,
|
|
paddingHorizontal: Sizing.t4,
|
|
marginBottom: Sizing.t3,
|
|
backgroundColor: 'background-basic-color-1',
|
|
},
|
|
text: {
|
|
...Layout.flex.full,
|
|
},
|
|
title: {
|
|
...Typography.header,
|
|
marginBottom: Sizing.t1,
|
|
color: 'text-basic-color',
|
|
},
|
|
subtitle: {
|
|
...Typography.fontSize.xs,
|
|
marginBottom: Sizing.t2,
|
|
color: 'text-hint-color',
|
|
},
|
|
intro: {
|
|
...Typography.fontSize.sm,
|
|
color: 'text-basic-color',
|
|
},
|
|
image: {
|
|
borderRadius: 50,
|
|
width: 50,
|
|
height: 50,
|
|
marginRight: Sizing.t3,
|
|
},
|
|
})
|