Resolve all remaining lint issues (#88)

* Rework 'navIdx' variables from number arrays to strings to avoid equality-check failures in react hooks

* Resolve all remaining lint issues

* Fix tests

* Use node v18 in gh action test
This commit is contained in:
Paul Frazee 2023-01-24 13:00:11 -06:00 committed by GitHub
parent 3a90114f3a
commit f36c956536
60 changed files with 478 additions and 482 deletions

View file

@ -297,7 +297,7 @@ export const ComposePost = observer(function ComposePost({
)
}
})
}, [text, pal.link])
}, [text, pal.link, pal.text])
return (
<KeyboardAvoidingView
@ -393,7 +393,7 @@ export const ComposePost = observer(function ComposePost({
ref={textInput}
multiline
scrollEnabled
onChangeText={(text: string) => onChangeText(text)}
onChangeText={(str: string) => onChangeText(str)}
onPaste={onPaste}
placeholder={selectTextInputPlaceholder}
placeholderTextColor={pal.colors.textLight}
@ -475,7 +475,7 @@ export const ComposePost = observer(function ComposePost({
)
})
const atPrefixRegex = /@([a-z0-9\.]*)$/i
const atPrefixRegex = /@([a-z0-9.]*)$/i
function extractTextAutocompletePrefix(text: string) {
const match = atPrefixRegex.exec(text)
if (match) {

View file

@ -39,7 +39,7 @@ export const SuggestedFollows = observer(
// Using default import (React.use...) instead of named import (use...) to be able to mock store's data in jest environment
const view = React.useMemo<SuggestedActorsViewModel>(
() => new SuggestedActorsViewModel(store),
[],
[store],
)
useEffect(() => {
@ -54,7 +54,7 @@ export const SuggestedFollows = observer(
if (!view.isLoading && !view.hasError && !view.hasContent) {
onNoSuggestions?.()
}
}, [view, view.isLoading, view.hasError, view.hasContent])
}, [view, view.isLoading, view.hasError, view.hasContent, onNoSuggestions])
const onPressTryAgain = () =>
view
@ -128,7 +128,7 @@ export const SuggestedFollows = observer(
keyExtractor={item => item._reactKey}
renderItem={renderItem}
style={s.flex1}
contentContainerStyle={{paddingBottom: 200}}
contentContainerStyle={s.contentContainer}
/>
</View>
)}

View file

@ -207,12 +207,7 @@ const ChooseAccountForm = ({
style={[pal.borderDark, styles.group]}
onPress={() => onSelectAccount(undefined)}>
<View style={[pal.borderDark, styles.groupContent, styles.noTopBorder]}>
<View style={s.p10}>
<View
style={[pal.btn, {width: 30, height: 30, borderRadius: 15}]}
/>
</View>
<Text style={styles.accountText}>
<Text style={[styles.accountText, styles.accountTextOther]}>
<Text type="lg" style={pal.text}>
Other account
</Text>
@ -556,7 +551,7 @@ const ForgotPasswordForm = ({
{!serviceDescription || isProcessing ? (
<ActivityIndicator />
) : !email ? (
<Text type="xl-bold" style={[pal.link, s.pr5, {opacity: 0.5}]}>
<Text type="xl-bold" style={[pal.link, s.pr5, styles.dimmed]}>
Next
</Text>
) : (
@ -691,7 +686,7 @@ const SetNewPasswordForm = ({
{isProcessing ? (
<ActivityIndicator />
) : !resetCode || !password ? (
<Text type="xl-bold" style={[pal.link, s.pr5, {opacity: 0.5}]}>
<Text type="xl-bold" style={[pal.link, s.pr5, styles.dimmed]}>
Next
</Text>
) : (
@ -810,6 +805,9 @@ const styles = StyleSheet.create({
alignItems: 'baseline',
paddingVertical: 10,
},
accountTextOther: {
paddingLeft: 12,
},
error: {
backgroundColor: colors.red4,
flexDirection: 'row',
@ -832,4 +830,5 @@ const styles = StyleSheet.create({
justifyContent: 'center',
marginRight: 5,
},
dimmed: {opacity: 0.5},
})

View file

@ -121,7 +121,7 @@ export function Component({
</View>
</View>
{error !== '' && (
<View style={{marginTop: 20}}>
<View style={styles.errorContainer}>
<ErrorMessage message={error} />
</View>
)}
@ -231,4 +231,5 @@ const styles = StyleSheet.create({
marginBottom: 36,
marginHorizontal: -14,
},
errorContainer: {marginTop: 20},
})

View file

@ -56,7 +56,7 @@ export function Component({onSelect}: {onSelect: (url: string) => void}) {
</View>
<View style={styles.group}>
<Text style={styles.label}>Other service</Text>
<View style={{flexDirection: 'row'}}>
<View style={s.flexRow}>
<BottomSheetTextInput
testID="customServerTextInput"
style={styles.textInput}

View file

@ -1,12 +1,13 @@
import React from 'react'
import {observer} from 'mobx-react-lite'
import {View, FlatList} from 'react-native'
import {FlatList, StyleSheet, View} from 'react-native'
import {NotificationsViewModel} from '../../../state/models/notifications-view'
import {FeedItem} from './FeedItem'
import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {EmptyState} from '../util/EmptyState'
import {OnScrollCb} from '../../lib/hooks/useOnMainScroll'
import {s} from '../../lib/styles'
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
@ -29,7 +30,7 @@ export const Feed = observer(function Feed({
<EmptyState
icon="bell"
message="No notifications yet!"
style={{paddingVertical: 40}}
style={styles.emptyState}
/>
)
}
@ -58,14 +59,10 @@ export const Feed = observer(function Feed({
}
}
return (
<View style={{flex: 1}}>
<View style={s.h100pct}>
{view.isLoading && !data && <NotificationFeedLoadingPlaceholder />}
{view.hasError && (
<ErrorMessage
message={view.error}
style={{margin: 6}}
onPressTryAgain={onPressTryAgain}
/>
<ErrorMessage message={view.error} onPressTryAgain={onPressTryAgain} />
)}
{data && (
<FlatList
@ -76,9 +73,13 @@ export const Feed = observer(function Feed({
onRefresh={onRefresh}
onEndReached={onEndReached}
onScroll={onScroll}
contentContainerStyle={{paddingBottom: 200}}
contentContainerStyle={s.contentContainer}
/>
)}
</View>
)
})
const styles = StyleSheet.create({
emptyState: {paddingVertical: 40},
})

View file

@ -19,14 +19,13 @@ import {TABS_ENABLED} from '../../../build-flags'
const Intro = () => (
<View style={styles.explainer}>
<Text
style={[
styles.explainerHeading,
s.normal,
{lineHeight: 60, paddingTop: 50, paddingBottom: 50},
]}>
Welcome to <Text style={[s.bold, s.blue3, {fontSize: 56}]}>Bluesky</Text>
style={[styles.explainerHeading, s.normal, styles.explainerHeadingIntro]}>
Welcome to{' '}
<Text style={[s.bold, s.blue3, styles.explainerHeadingBrand]}>
Bluesky
</Text>
</Text>
<Text style={[styles.explainerDesc, {fontSize: 24}]}>
<Text style={[styles.explainerDesc, styles.explainerDescIntro]}>
This is an early beta. Your feedback is appreciated!
</Text>
</View>
@ -161,11 +160,18 @@ const styles = StyleSheet.create({
textAlign: 'center',
marginBottom: 16,
},
explainerHeadingIntro: {
lineHeight: 60,
paddingTop: 50,
paddingBottom: 50,
},
explainerHeadingBrand: {fontSize: 56},
explainerDesc: {
fontSize: 18,
textAlign: 'center',
marginBottom: 16,
},
explainerDescIntro: {fontSize: 24},
explainerImg: {
resizeMode: 'contain',
maxWidth: '100%',

View file

@ -53,11 +53,7 @@ export const PostRepostedBy = observer(function PostRepostedBy({
if (view.hasError) {
return (
<View>
<ErrorMessage
message={view.error}
style={{margin: 6}}
onPressTryAgain={onRefresh}
/>
<ErrorMessage message={view.error} onPressTryAgain={onRefresh} />
</View>
)
}

View file

@ -7,6 +7,7 @@ import {
} from '../../../state/models/post-thread-view'
import {PostThreadItem} from './PostThreadItem'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {s} from '../../lib/styles'
export const PostThread = observer(function PostThread({
uri,
@ -60,11 +61,7 @@ export const PostThread = observer(function PostThread({
if (view.hasError) {
return (
<View>
<ErrorMessage
message={view.error}
style={{margin: 6}}
onPressTryAgain={onRefresh}
/>
<ErrorMessage message={view.error} onPressTryAgain={onRefresh} />
</View>
)
}
@ -84,8 +81,8 @@ export const PostThread = observer(function PostThread({
onRefresh={onRefresh}
onLayout={onLayout}
onScrollToIndexFailed={onScrollToIndexFailed}
style={{flex: 1}}
contentContainerStyle={{paddingBottom: 200}}
style={s.h100pct}
contentContainerStyle={s.contentContainer}
/>
)
})

View file

@ -80,7 +80,7 @@ export const PostThreadItem = observer(function PostThreadItem({
.catch(e => store.log.error('Failed to toggle upvote', e))
}
const onCopyPostText = () => {
Clipboard.setString(record.text)
Clipboard.setString(record?.text || '')
Toast.show('Copied to clipboard')
}
const onDeletePost = () => {
@ -131,8 +131,8 @@ export const PostThreadItem = observer(function PostThreadItem({
</Link>
</View>
<View style={styles.layoutContent}>
<View style={[styles.meta, {paddingTop: 5, paddingBottom: 0}]}>
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
<View style={[styles.meta, styles.metaExpandedLine1]}>
<View style={[s.flexRow, s.alignBaseline]}>
<Link
style={styles.metaItem}
href={authorHref}
@ -305,10 +305,8 @@ export const PostThreadItem = observer(function PostThreadItem({
lineHeight={1.3}
/>
</View>
) : (
<View style={{height: 5}} />
)}
<PostEmbeds embed={item.post.embed} style={{marginBottom: 10}} />
) : undefined}
<PostEmbeds embed={item.post.embed} style={s.mb10} />
<PostCtrls
itemHref={itemHref}
itemTitle={itemTitle}
@ -389,6 +387,10 @@ const styles = StyleSheet.create({
paddingTop: 2,
paddingBottom: 2,
},
metaExpandedLine1: {
paddingTop: 5,
paddingBottom: 0,
},
metaItem: {
paddingRight: 5,
maxWidth: 240,

View file

@ -48,11 +48,7 @@ export const PostVotedBy = observer(function PostVotedBy({
if (view.hasError) {
return (
<View>
<ErrorMessage
message={view.error}
style={{margin: 6}}
onPressTryAgain={onRefresh}
/>
<ErrorMessage message={view.error} onPressTryAgain={onRefresh} />
</View>
)
}

View file

@ -156,7 +156,7 @@ export const Post = observer(function Post({
timestamp={item.post.indexedAt}
/>
{replyAuthorDid !== '' && (
<View style={[s.flexRow, s.mb2, {alignItems: 'center'}]}>
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
<FontAwesomeIcon
icon="reply"
size={9}
@ -187,10 +187,8 @@ export const Post = observer(function Post({
lineHeight={1.3}
/>
</View>
) : (
<View style={{height: 5}} />
)}
<PostEmbeds embed={item.post.embed} style={{marginBottom: 10}} />
) : undefined}
<PostEmbeds embed={item.post.embed} style={s.mb10} />
<PostCtrls
itemHref={itemHref}
itemTitle={itemTitle}

View file

@ -1,6 +1,6 @@
import React, {useState, useEffect} from 'react'
import {observer} from 'mobx-react-lite'
import {View} from 'react-native'
import {StyleSheet, View} from 'react-native'
import {LoadingPlaceholder} from '../util/LoadingPlaceholder'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {Text} from '../util/text/Text'
@ -31,9 +31,9 @@ export const PostText = observer(function PostText({
if (!model || model.isLoading || model.uri !== uri) {
return (
<View>
<LoadingPlaceholder width="100%" height={8} style={{marginTop: 6}} />
<LoadingPlaceholder width="100%" height={8} style={{marginTop: 6}} />
<LoadingPlaceholder width={100} height={8} style={{marginTop: 6}} />
<LoadingPlaceholder width="100%" height={8} style={styles.mt6} />
<LoadingPlaceholder width="100%" height={8} style={styles.mt6} />
<LoadingPlaceholder width={100} height={8} style={styles.mt6} />
</View>
)
}
@ -56,3 +56,7 @@ export const PostText = observer(function PostText({
</View>
)
})
const styles = StyleSheet.create({
mt6: {marginTop: 6},
})

View file

@ -5,6 +5,7 @@ import {
View,
FlatList,
StyleProp,
StyleSheet,
ViewStyle,
} from 'react-native'
import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
@ -14,6 +15,7 @@ import {FeedModel} from '../../../state/models/feed-view'
import {FeedItem} from './FeedItem'
import {PromptButtons} from './PromptButtons'
import {OnScrollCb} from '../../lib/hooks/useOnMainScroll'
import {s} from '../../lib/styles'
const COMPOSE_PROMPT_ITEM = {_reactKey: '__prompt__'}
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
@ -47,7 +49,7 @@ export const Feed = observer(function Feed({
<EmptyState
icon="bars"
message="This feed is empty!"
style={{paddingVertical: 40}}
style={styles.emptyState}
/>
)
} else {
@ -76,7 +78,7 @@ export const Feed = observer(function Feed({
}
const FeedFooter = () =>
feed.isLoading ? (
<View style={{paddingTop: 20}}>
<View style={styles.feedFooter}>
<ActivityIndicator />
</View>
) : (
@ -87,11 +89,7 @@ export const Feed = observer(function Feed({
{!data && <PromptButtons onPressCompose={onPressCompose} />}
{feed.isLoading && !data && <PostFeedLoadingPlaceholder />}
{feed.hasError && (
<ErrorMessage
message={feed.error}
style={{margin: 6}}
onPressTryAgain={onPressTryAgain}
/>
<ErrorMessage message={feed.error} onPressTryAgain={onPressTryAgain} />
)}
{feed.hasLoaded && data && (
<FlatList
@ -101,7 +99,7 @@ export const Feed = observer(function Feed({
renderItem={renderItem}
ListFooterComponent={FeedFooter}
refreshing={feed.isRefreshing}
contentContainerStyle={{paddingBottom: 100}}
contentContainerStyle={s.contentContainer}
onScroll={onScroll}
onRefresh={onRefresh}
onEndReached={onEndReached}
@ -110,3 +108,8 @@ export const Feed = observer(function Feed({
</View>
)
})
const styles = StyleSheet.create({
feedFooter: {paddingTop: 20},
emptyState: {paddingVertical: 40},
})

View file

@ -124,7 +124,7 @@ export const FeedItem = observer(function ({
style={[
styles.bottomReplyLine,
{borderColor: pal.colors.replyLine},
isNoTop ? {top: 64} : undefined,
isNoTop ? styles.bottomReplyLineNoTop : undefined,
]}
/>
)}
@ -163,7 +163,7 @@ export const FeedItem = observer(function ({
timestamp={item.post.indexedAt}
/>
{!isChild && replyAuthorDid !== '' && (
<View style={[s.flexRow, s.mb2, {alignItems: 'center'}]}>
<View style={[s.flexRow, s.mb2, s.alignCenter]}>
<FontAwesomeIcon
icon="reply"
size={9}
@ -195,9 +195,7 @@ export const FeedItem = observer(function ({
lineHeight={1.3}
/>
</View>
) : (
<View style={{height: 5}} />
)}
) : undefined}
{item.post.embed ? (
<PostEmbeds embed={item.post.embed} style={styles.embed} />
) : null}
@ -281,6 +279,7 @@ const styles = StyleSheet.create({
bottom: 0,
borderLeftWidth: 2,
},
bottomReplyLineNoTop: {top: 64},
includeReason: {
flexDirection: 'row',
paddingLeft: 50,

View file

@ -54,11 +54,7 @@ export const ProfileFollowers = observer(function ProfileFollowers({
if (view.hasError) {
return (
<View>
<ErrorMessage
message={view.error}
style={{margin: 6}}
onPressTryAgain={onRefresh}
/>
<ErrorMessage message={view.error} onPressTryAgain={onRefresh} />
</View>
)
}

View file

@ -54,11 +54,7 @@ export const ProfileFollows = observer(function ProfileFollows({
if (view.hasError) {
return (
<View>
<ErrorMessage
message={view.error}
style={{margin: 6}}
onPressTryAgain={onRefresh}
/>
<ErrorMessage message={view.error} onPressTryAgain={onRefresh} />
</View>
)
}

View file

@ -100,22 +100,14 @@ export const ProfileHeader = observer(function ProfileHeader({
<LoadingPlaceholder width="100%" height={120} />
<View
style={[pal.view, {borderColor: pal.colors.background}, styles.avi]}>
<LoadingPlaceholder
width={80}
height={80}
style={{borderRadius: 40}}
/>
<LoadingPlaceholder width={80} height={80} style={styles.br40} />
</View>
<View style={styles.content}>
<View style={[styles.buttonsLine]}>
<LoadingPlaceholder
width={100}
height={31}
style={{borderRadius: 50}}
/>
<LoadingPlaceholder width={100} height={31} style={styles.br50} />
</View>
<View style={styles.displayNameLine}>
<Text type="title-xl" style={[pal.text, {lineHeight: 38}]}>
<Text type="title-xl" style={[pal.text, styles.title]}>
{view.displayName || view.handle}
</Text>
</View>
@ -208,7 +200,7 @@ export const ProfileHeader = observer(function ProfileHeader({
) : undefined}
</View>
<View style={styles.displayNameLine}>
<Text type="title-xl" style={[pal.text, {lineHeight: 38}]}>
<Text type="title-xl" style={[pal.text, styles.title]}>
{view.displayName || view.handle}
</Text>
</View>
@ -349,6 +341,7 @@ const styles = StyleSheet.create({
// paddingLeft: 86,
// marginBottom: 14,
},
title: {lineHeight: 38},
handleLine: {
flexDirection: 'row',
@ -369,4 +362,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
marginBottom: 5,
},
br40: {borderRadius: 40},
br50: {borderRadius: 50},
})

View file

@ -57,7 +57,7 @@ export const Link = observer(function Link({
)
})
export const TextLink = observer(function Link({
export const TextLink = observer(function TextLink({
type = 'md',
style,
href,

View file

@ -19,23 +19,15 @@ export function LoadingPlaceholder({
return (
<View
style={[
styles.loadingPlaceholder,
{
width,
height,
backgroundColor: theme.palette.default.backgroundLight,
borderRadius: 6,
overflow: 'hidden',
},
style,
]}>
<View
style={{
width,
height,
backgroundColor: theme.palette.default.backgroundLight,
}}
/>
</View>
]}
/>
)
}
@ -137,6 +129,9 @@ export function NotificationFeedLoadingPlaceholder() {
}
const styles = StyleSheet.create({
loadingPlaceholder: {
borderRadius: 6,
},
post: {
flexDirection: 'row',
padding: 10,

View file

@ -128,10 +128,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
hitSlop={HITSLOP}
onPress={opts.onPressReply}>
<CommentBottomArrow
style={[
defaultCtrlColor,
opts.big ? {marginTop: 2} : {marginTop: 1},
]}
style={[defaultCtrlColor, opts.big ? s.mt2 : styles.mt1]}
strokeWidth={3}
size={opts.big ? 20 : 15}
/>
@ -181,10 +178,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
/>
) : (
<HeartIcon
style={[
defaultCtrlColor,
opts.big ? {marginTop: 1} : undefined,
]}
style={[defaultCtrlColor, opts.big ? styles.mt1 : undefined]}
strokeWidth={3}
size={opts.big ? 20 : 16}
/>
@ -244,4 +238,7 @@ const styles = StyleSheet.create({
ctrlIconUpvoted: {
color: colors.red3,
},
mt1: {
marginTop: 1,
},
})

View file

@ -67,7 +67,7 @@ export function PostEmbeds({
<AutoSizedImage
uri={embed.images[0].thumb}
onPress={() => openLightbox(0)}
containerStyle={{borderRadius: 8}}
containerStyle={styles.singleImage}
/>
</View>
)
@ -120,6 +120,9 @@ const styles = StyleSheet.create({
imagesContainer: {
marginTop: 4,
},
singleImage: {
borderRadius: 8,
},
extOuter: {
borderWidth: 1,
borderRadius: 8,

View file

@ -41,7 +41,7 @@ export function Selector({
width: middle.width,
}
return [left, middle, right]
}, [selectedIndex, items, itemLayouts])
}, [selectedIndex, itemLayouts])
const underlineStyle = {
backgroundColor: pal.colors.text,

View file

@ -62,8 +62,8 @@ export function UserAvatar({
])
}, [onSelectNewAvatar])
const renderSvg = (size: number, initials: string) => (
<Svg width={size} height={size} viewBox="0 0 100 100">
const renderSvg = (svgSize: number, svgInitials: string) => (
<Svg width={svgSize} height={svgSize} viewBox="0 0 100 100">
<Defs>
<LinearGradient id="grad" x1="0" y1="0" x2="1" y2="1">
<Stop offset="0" stopColor={gradients.blue.start} stopOpacity="1" />
@ -78,7 +78,7 @@ export function UserAvatar({
x="50"
y="67"
textAnchor="middle">
{initials}
{svgInitials}
</Text>
</Svg>
)
@ -88,7 +88,11 @@ export function UserAvatar({
<TouchableOpacity onPress={handleEditAvatar}>
{avatar ? (
<Image
style={{width: size, height: size, borderRadius: (size / 2) | 0}}
style={{
width: size,
height: size,
borderRadius: Math.floor(size / 2),
}}
source={{uri: avatar}}
/>
) : (
@ -104,7 +108,7 @@ export function UserAvatar({
</TouchableOpacity>
) : avatar ? (
<Image
style={{width: size, height: size, borderRadius: (size / 2) | 0}}
style={{width: size, height: size, borderRadius: Math.floor(size / 2)}}
resizeMode="stretch"
source={{uri: avatar}}
/>

View file

@ -1,6 +1,6 @@
import React, {useState, useEffect} from 'react'
import {AppBskyActorGetProfile as GetProfile} from '@atproto/api'
import {StyleProp, TextStyle} from 'react-native'
import {StyleProp, StyleSheet, TextStyle} from 'react-native'
import {Link} from './Link'
import {Text} from './text/Text'
import {LoadingPlaceholder} from './LoadingPlaceholder'
@ -53,7 +53,7 @@ export function UserInfoText({
return () => {
aborted = true
}
}, [did, store.api.app.bsky])
}, [did, store.profiles])
let inner
if (didFail) {
@ -73,7 +73,7 @@ export function UserInfoText({
<LoadingPlaceholder
width={80}
height={8}
style={{position: 'relative', top: 1, left: 2}}
style={styles.loadingPlaceholder}
/>
)
}
@ -91,3 +91,7 @@ export function UserInfoText({
return inner
}
const styles = StyleSheet.create({
loadingPlaceholder: {position: 'relative', top: 1, left: 2},
})

View file

@ -11,8 +11,8 @@ import {UserAvatar} from './UserAvatar'
import {Text} from './text/Text'
import {MagnifyingGlassIcon} from '../../lib/icons'
import {useStores} from '../../../state'
import {useTheme} from '../../lib/ThemeContext'
import {usePalette} from '../../lib/hooks/usePalette'
import {colors} from '../../lib/styles'
const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10}
const BACK_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10}
@ -26,7 +26,6 @@ export const ViewHeader = observer(function ViewHeader({
subtitle?: string
canGoBack?: boolean
}) {
const theme = useTheme()
const pal = usePalette('default')
const store = useStores()
const onPressBack = () => {
@ -52,12 +51,12 @@ export const ViewHeader = observer(function ViewHeader({
testID="viewHeaderBackOrMenuBtn"
onPress={canGoBack ? onPressBack : onPressMenu}
hitSlop={BACK_HITSLOP}
style={canGoBack ? styles.backIcon : styles.backIconWide}>
style={canGoBack ? styles.backBtn : styles.backBtnWide}>
{canGoBack ? (
<FontAwesomeIcon
size={18}
icon="angle-left"
style={[{marginTop: 6}, pal.text]}
style={[styles.backIcon, pal.text]}
/>
) : (
<UserAvatar
@ -96,13 +95,10 @@ export const ViewHeader = observer(function ViewHeader({
<FontAwesomeIcon icon="signal" style={pal.text} size={16} />
<FontAwesomeIcon
icon="x"
style={{
backgroundColor: pal.colors.background,
color: theme.palette.error.background,
position: 'absolute',
right: 7,
bottom: 7,
}}
style={[
styles.littleXIcon,
{backgroundColor: pal.colors.background},
]}
size={8}
/>
</>
@ -136,15 +132,18 @@ const styles = StyleSheet.create({
fontWeight: 'normal',
},
backIcon: {
backBtn: {
width: 30,
height: 30,
},
backIconWide: {
backBtnWide: {
width: 40,
height: 30,
marginLeft: 6,
},
backIcon: {
marginTop: 6,
},
btn: {
flexDirection: 'row',
alignItems: 'center',
@ -154,4 +153,10 @@ const styles = StyleSheet.create({
borderRadius: 20,
marginLeft: 4,
},
littleXIcon: {
color: colors.red3,
position: 'absolute',
right: 7,
bottom: 7,
},
})

View file

@ -5,6 +5,7 @@ import {HorzSwipe} from './gestures/HorzSwipe'
import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue'
import {OnScrollCb} from '../../lib/hooks/useOnMainScroll'
import {clamp} from '../../../lib/numbers'
import {s} from '../../lib/styles'
const HEADER_ITEM = {_reactKey: '__header__'}
const SELECTOR_ITEM = {_reactKey: '__selector__'}
@ -54,7 +55,7 @@ export function ViewSelector({
setSelectedIndex(clamp(index, 0, sections.length))
useEffect(() => {
onSelectView?.(selectedIndex)
}, [selectedIndex])
}, [selectedIndex, onSelectView])
// rendering
// =
@ -98,7 +99,7 @@ export function ViewSelector({
onScroll={onScroll}
onRefresh={onRefresh}
onEndReached={onEndReached}
contentContainerStyle={{paddingBottom: 200}}
contentContainerStyle={s.contentContainer}
/>
</HorzSwipe>
)

View file

@ -2,6 +2,7 @@ import React, {useState} from 'react'
import {View} from 'react-native'
import {RadioButton} from './RadioButton'
import {ButtonType} from './Button'
import {s} from '../../../lib/styles'
export interface RadioGroupItem {
label: string
@ -29,7 +30,7 @@ export function RadioGroup({
{items.map((item, i) => (
<RadioButton
key={item.key}
style={i !== 0 ? {marginTop: 2} : undefined}
style={i !== 0 ? s.mt2 : undefined}
type={type}
label={item.label}
isSelected={item.key === selection}

View file

@ -9,6 +9,7 @@ import {
View,
} from 'react-native'
import {clamp} from 'lodash'
import {s} from '../../../lib/styles'
interface Props {
panX: Animated.Value
@ -111,7 +112,9 @@ export function HorzSwipe({
(Math.abs(gestureState.dx) > swipeDistanceThreshold / 4 ||
Math.abs(gestureState.vx) > swipeVelocityThreshold)
) {
const final = ((gestureState.dx / Math.abs(gestureState.dx)) * -1) | 0
const final = Math.floor(
(gestureState.dx / Math.abs(gestureState.dx)) * -1,
)
Animated.timing(panX, {
toValue: final,
duration: 100,
@ -144,7 +147,7 @@ export function HorzSwipe({
})
return (
<View {...panResponder.panHandlers} style={{flex: 1}}>
<View {...panResponder.panHandlers} style={s.h100pct}>
{children}
</View>
)

View file

@ -9,6 +9,7 @@ import {
View,
} from 'react-native'
import {clamp} from 'lodash'
import {s} from '../../../lib/styles'
export enum Dir {
None,
@ -294,7 +295,7 @@ export function SwipeAndZoom({
})
return (
<View {...panResponder.panHandlers} style={{flex: 1}}>
<View {...panResponder.panHandlers} style={s.h100pct}>
{children}
</View>
)

View file

@ -47,9 +47,9 @@ export function AutoSizedImage({
setImgInfo({width, height})
}
},
(error: any) => {
(err: any) => {
if (!aborted) {
setError(String(error))
setError(String(err))
}
},
)

View file

@ -105,7 +105,7 @@ function ImageLayoutGridInner({
<TouchableWithoutFeedback onPress={() => onPress?.(1)}>
<Image source={{uri: uris[1]}} style={size1} />
</TouchableWithoutFeedback>
<View style={{height: 5}} />
<View style={styles.hSpace} />
<TouchableWithoutFeedback onPress={() => onPress?.(2)}>
<Image source={{uri: uris[2]}} style={size1} />
</TouchableWithoutFeedback>