Refine neodb cards

Added card for games
This commit is contained in:
xmflsct 2023-03-19 22:15:51 +01:00
parent aa469c1174
commit 86e502afdd
2 changed files with 99 additions and 106 deletions

View File

@ -17,7 +17,15 @@ export const CardNeodb: React.FC<Props> = ({ card }) => {
const { colors } = useTheme() const { colors } = useTheme()
const segments = Linking.parse(card.url).path?.split('/') const segments = Linking.parse(card.url).path?.split('/')
if (!segments || !(segments[0] === 'movie' || segments[0] === 'book' || segments[0] === 'tv')) if (
!segments ||
!(
segments[0] === 'movie' ||
segments[0] === 'book' ||
(segments[0] === 'tv' && segments[1] !== 'season') ||
segments[0] === 'game'
)
)
return null return null
const [headingLines, setHeadingLines] = useState(3) const [headingLines, setHeadingLines] = useState(3)
@ -26,121 +34,104 @@ export const CardNeodb: React.FC<Props> = ({ card }) => {
if (!data) return null if (!data) return null
const pressableProps = { const Content = ({ heading, details }: { heading: string[]; details: string[] }) => (
style: { <Pressable
marginTop: StyleConstants.Spacing.M, style={{
backgroundColor: colors.shimmerDefault, marginTop: StyleConstants.Spacing.M,
borderRadius: StyleConstants.BorderRadius, backgroundColor: colors.shimmerDefault,
padding: StyleConstants.Spacing.S, borderRadius: StyleConstants.BorderRadius,
flexDirection: 'row' as 'row' padding: StyleConstants.Spacing.S,
}, flexDirection: 'row'
onPress: () => openLink(card.url)
}
const contentProps = { style: { flex: 1, gap: StyleConstants.Spacing.S } }
const itemImage = data.cover_image_url ? (
<GracefullyImage
sources={{ default: { uri: data.cover_image_url } }}
dimension={{
width: StyleConstants.Font.LineHeight.M * 4,
height: StyleConstants.Font.LineHeight.M * 5
}} }}
style={{ marginRight: StyleConstants.Spacing.S }} onPress={() => openLink(card.url)}
imageStyle={{ borderRadius: StyleConstants.BorderRadius / 2 }} >
dim {data.cover_image_url ? (
/> <GracefullyImage
) : null sources={{ default: { uri: data.cover_image_url } }}
const itemHeading = (value: string) => ( dimension={{
<CustomText width: StyleConstants.Font.LineHeight.M * 4,
fontStyle='S' height: StyleConstants.Font.LineHeight.M * 5
fontWeight='Bold' }}
style={{ color: colors.primaryDefault }} style={{ marginRight: StyleConstants.Spacing.S }}
numberOfLines={3} imageStyle={{ borderRadius: StyleConstants.BorderRadius / 2 }}
children={value} dim
onTextLayout={({ nativeEvent }) => setHeadingLines(nativeEvent.lines.length)} />
/> ) : null}
) <View style={{ flex: 1, gap: StyleConstants.Spacing.S, justifyContent: 'space-between' }}>
const itemDetails = (value: string) => ( <View style={{ gap: StyleConstants.Spacing.S }}>
<CustomText <CustomText
fontStyle='S' fontStyle='S'
style={{ color: colors.secondary }} fontWeight='Bold'
numberOfLines={4 - headingLines} style={{ color: colors.primaryDefault }}
children={value} numberOfLines={3}
/> onTextLayout={({ nativeEvent }) => setHeadingLines(nativeEvent.lines.length)}
children={heading.filter(d => d).join(' ')}
/>
<Rating rating={data.rating / 2} />
</View>
<CustomText
fontStyle='S'
style={{ color: colors.secondary }}
numberOfLines={4 - headingLines}
children={details.filter(d => d).join(' / ')}
/>
</View>
</Pressable>
) )
switch (segments[0]) { switch (segments[0]) {
case 'movie': case 'movie':
return ( return (
<Pressable {...pressableProps}> <Content
{itemImage} heading={[data.title, data.orig_title, data.year ? `(${data.year})` : null]}
<View {...contentProps}> details={[
{itemHeading( data.duration
[data.title, data.orig_title, data.year ? `(${data.year})` : null] ? parseInt(data.duration).toString() === data.duration
.filter(d => d) ? `${data.duration}分钟`
.join(' ') : data.duration
)} : null,
<Rating rating={data.rating / 2} /> data.area?.join(' '),
{itemDetails( data.genre?.join(' '),
[ data.director?.join(' ')
data.duration ]}
? parseInt(data.duration).toString() === data.duration />
? `${data.duration}分钟`
: data.duration
: null,
data.area?.join(' '),
data.genre?.join(' '),
data.director?.join(' ')
]
.filter(d => d)
.join(' / ')
)}
</View>
</Pressable>
) )
case 'book': case 'book':
return ( return (
<Pressable {...pressableProps}> <Content
{itemImage} heading={[data.title]}
<View {...contentProps}> details={[
{itemHeading(data.title)} data.author?.join(' '),
<Rating rating={data.rating / 2} /> data.pages ? `${data.pages}` : null,
{itemDetails( data.language,
[ data.pub_house
data.author?.join(' '), ]}
data.pages ? `${data.pages}` : null, />
data.language,
data.pub_house
]
.filter(d => d)
.join(' / ')
)}
</View>
</Pressable>
) )
case 'tv': case 'tv':
return ( return (
<Pressable {...pressableProps}> <Content
{itemImage} heading={[data.title, data.orig_title, data.year ? `(${data.year})` : null]}
<View {...contentProps}> details={[
{itemHeading( data.season_count ? `${data.season_count}` : null,
[data.title, data.orig_title, data.year ? `(${data.year})` : null] data.area?.join(' '),
.filter(d => d) data.genre?.join(' '),
.join(' ') data.director?.join(' ')
)} ]}
<Rating rating={data.rating / 2} /> />
{itemDetails( )
[ case 'game':
data.season_count ? `${data.season_count}` : null, return (
data.area?.join(' '), <Content
data.genre?.join(' '), heading={[data.title]}
data.director?.join(' ') details={[
] data.genre?.join(' '),
.filter(d => d) data.developer?.join(' '),
.join(' / ') data.platform?.join(' '),
)} data.release_date
</View> ]}
</Pressable> />
) )
default: default:
return null return null

View File

@ -4,6 +4,7 @@ import openLink from '@components/openLink'
import CustomText from '@components/Text' import CustomText from '@components/Text'
import { useNavigation } from '@react-navigation/native' import { useNavigation } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack' import { StackNavigationProp } from '@react-navigation/stack'
import { isDevelopment } from '@utils/helpers/checkEnvironment'
import { urlMatcher } from '@utils/helpers/urlMatcher' import { urlMatcher } from '@utils/helpers/urlMatcher'
import { TabLocalStackParamList } from '@utils/navigation/navigators' import { TabLocalStackParamList } from '@utils/navigation/navigators'
import { useAccountQuery } from '@utils/queryHooks/account' import { useAccountQuery } from '@utils/queryHooks/account'
@ -27,8 +28,9 @@ const TimelineCard: React.FC = () => {
const { i18n } = useTranslation() const { i18n } = useTranslation()
if ( if (
status.card.url.includes('://neodb.social/') && (status.card.url.includes('://neodb.social/') &&
i18n.language.toLowerCase().startsWith('zh-hans') i18n.language.toLowerCase().startsWith('zh-hans')) ||
isDevelopment
) { ) {
return <CardNeodb card={status.card} /> return <CardNeodb card={status.card} />
} }