UI improvements

This commit is contained in:
KoalaSat 2023-02-19 20:39:48 +01:00
parent c9c3eae666
commit 8c8ba8a61e
No known key found for this signature in database
GPG Key ID: 2F7F61C6146AB157
28 changed files with 170 additions and 81 deletions

View File

@ -75,6 +75,7 @@ export const GroupShare: React.FC<GroupShareProps> = ({ group }) => {
const styles = StyleSheet.create({
snackbar: {
marginBottom: 85,
width: '100%',
},
mainLayout: {
flexDirection: 'row',

View File

@ -9,12 +9,16 @@ import { AppContext } from '../../Contexts/AppContext'
import { decode, PaymentRequestObject, TagsObject } from 'bolt11'
interface LnPreviewProps {
setOpen: (open: boolean) => void
setOpen?: (open: boolean) => void
invoice?: string
setInvoice: (invoice: string | undefined) => void
}
export const LnPreview: React.FC<LnPreviewProps> = ({ invoice, setInvoice, setOpen }) => {
export const LnPreview: React.FC<LnPreviewProps> = ({
invoice,
setInvoice,
setOpen = () => {},
}) => {
const theme = useTheme()
const { t } = useTranslation('common')
const { getSatoshiSymbol } = React.useContext(AppContext)

View File

@ -46,16 +46,20 @@ interface NoteCardProps {
note?: Note
showAvatarImage?: boolean
showAnswerData?: boolean
showRelayColors?: boolean
showAction?: boolean
showActionCount?: boolean
showPreview?: boolean
showRepostPreview?: boolean
numberOfLines?: number
copyOnPress?: boolean
mode?: 'elevated' | 'outlined' | 'contained'
}
export const NoteCard: React.FC<NoteCardProps> = ({
note,
copyOnPress = true,
showRelayColors = true,
showAvatarImage = true,
showAnswerData = true,
showAction = true,
@ -177,44 +181,40 @@ export const NoteCard: React.FC<NoteCardProps> = ({
onPressUser={(user) => setDisplayUserDrawer(user.id)}
showPreview={showPreview}
numberOfLines={numberOfLines}
copyOnPress={copyOnPress}
/>
)}
{note?.repost_id && (
<>
<TouchableRipple onPress={() => navigate('Note', { noteId: note.repost_id })}>
{repost && showRepostPreview ? (
<NoteCard
note={repost}
showActionCount={false}
showPreview={showPreview}
showRepostPreview={false}
showAction={false}
showRelayColors={false}
copyOnPress={false}
/>
) : (
<TouchableRipple
<Chip
icon={() => (
<MaterialCommunityIcons
name='cached'
size={16}
color={theme.colors.onTertiaryContainer}
/>
)}
style={{
marginTop: note.content.length > 5 ? 16 : -16,
backgroundColor: theme.colors.secondaryContainer,
color: theme.colors.onTertiaryContainer,
}}
onPress={() => navigate('Note', { noteId: note.repost_id })}
>
<Chip
icon={() => (
<MaterialCommunityIcons
name='cached'
size={16}
color={theme.colors.onTertiaryContainer}
/>
)}
style={{
backgroundColor: theme.colors.secondaryContainer,
color: theme.colors.onTertiaryContainer,
}}
>
<Text style={{ color: theme.colors.onTertiaryContainer }}>
{t('noteCard.reposted')}
</Text>
</Chip>
</TouchableRipple>
<Text style={{ color: theme.colors.onTertiaryContainer }}>
{t('noteCard.reposted')}
</Text>
</Chip>
)}
</>
</TouchableRipple>
)}
</Card.Content>
</>
@ -437,6 +437,7 @@ export const NoteCard: React.FC<NoteCardProps> = ({
)}
<Card.Content style={styles.relayList}>
{relayColouring &&
showRelayColors &&
relays.map((relay, index) => (
<TouchableNativeFeedback
onPress={() => setDisplayrelayDrawer(relay.relay_url)}

View File

@ -272,7 +272,12 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
</Text>
</View>
</View>
<RBSheet ref={bottomSheetRelaysRef} closeOnDragDown={true} customStyles={bottomSheetStyles}>
<RBSheet
ref={bottomSheetRelaysRef}
closeOnDragDown={true}
customStyles={bottomSheetStyles}
dragFromTopOnly={true}
>
<View>
<Text variant='titleLarge'>{t('profileCard.relaysTitle')}</Text>
<Text variant='bodyMedium'>
@ -286,13 +291,11 @@ export const ProfileActions: React.FC<ProfileActionsProps> = ({
</>
)}
/>
<ScrollView>
<FlatList
showsVerticalScrollIndicator={false}
data={userRelays}
renderItem={renderRelayItem}
/>
</ScrollView>
<View style={styles.relaysList}>
<ScrollView>
<FlatList data={userRelays} renderItem={renderRelayItem} />
</ScrollView>
</View>
</View>
{showNotificationRelay && (
<Snackbar
@ -391,6 +394,9 @@ const styles = StyleSheet.create({
muteContainer: {
paddingRight: 16,
},
relaysList: {
maxHeight: '90%',
},
})
export default ProfileActions

View File

@ -108,6 +108,7 @@ const styles = StyleSheet.create({
},
snackbar: {
marginBottom: 85,
width: '100%',
},
usernameData: {
paddingLeft: 16,

View File

@ -33,8 +33,7 @@ export const ProfileData: React.FC<ProfileCardProps> = ({
const theme = useTheme()
const nPub = React.useMemo(() => (publicKey ? getNpub(publicKey) : ''), [publicKey])
const date = React.useMemo(
() =>
timestamp ? formatDistance(fromUnixTime(timestamp), new Date(), { addSuffix: true }) : null,
() => (timestamp ? formatDistance(fromUnixTime(timestamp), new Date()) : null),
[timestamp],
)

View File

@ -1,6 +1,6 @@
import { t } from 'i18next'
import * as React from 'react'
import { StyleSheet, View } from 'react-native'
import { Dimensions, StyleSheet, View } from 'react-native'
import Clipboard from '@react-native-clipboard/clipboard'
import { IconButton, Snackbar, Text, TouchableRipple } from 'react-native-paper'
import { User } from '../../Functions/DatabaseFunctions/Users'
@ -37,7 +37,7 @@ export const ProfileShare: React.FC<ProfileShareProps> = ({ user }) => {
<QRCode
quietZone={8}
value={`nostr:${nPub}`}
size={350}
size={Dimensions.get('window').width - 64}
logoBorderRadius={50}
logoSize={100}
logo={{ uri: user?.picture }}
@ -88,6 +88,7 @@ export const ProfileShare: React.FC<ProfileShareProps> = ({ user }) => {
const styles = StyleSheet.create({
snackbar: {
marginBottom: 85,
width: '100%',
},
mainLayout: {
flexDirection: 'row',

View File

@ -30,6 +30,7 @@ import { Event } from '../../lib/nostr/Events'
import { getUnixTime } from 'date-fns'
import { Kind } from 'nostr-tools'
import { usersToTags } from '../../Functions/RelayFunctions/Users'
import { getRawUserGroupMessages, getRawUserGroups } from '../../Functions/DatabaseFunctions/Groups'
interface RelayCardProps {
url?: string
@ -39,7 +40,8 @@ interface RelayCardProps {
export const RelayCard: React.FC<RelayCardProps> = ({ url, bottomSheetRef }) => {
const theme = useTheme()
const { publicKey } = React.useContext(UserContext)
const { updateRelayItem, relayPool, removeRelayItem } = React.useContext(RelayPoolContext)
const { updateRelayItem, relayPool, removeRelayItem, sendRelays, relays } =
React.useContext(RelayPoolContext)
const { database } = React.useContext(AppContext)
const [relay, setRelay] = React.useState<Relay>()
const [uri, setUri] = React.useState<string>()
@ -59,11 +61,14 @@ export const RelayCard: React.FC<RelayCardProps> = ({ url, bottomSheetRef }) =>
React.useEffect(() => {
if (pushUserHistoric && url && database && publicKey && relayPool) {
bottomSheetPushRelayRef.current?.forceUpdate()
getRawUserNotes(database, publicKey).then((resultNotes) => {
resultNotes.forEach((note) => {
note.content = note.content.replace("''", "'")
relayPool.sendEvent(note, url)
})
setPushDone(true)
setShowNotification('pushCompleted')
})
getRawUserReactions(database, publicKey).then((resultReactions) => {
resultReactions.forEach((reaction) => {
@ -87,8 +92,18 @@ export const RelayCard: React.FC<RelayCardProps> = ({ url, bottomSheetRef }) =>
}
relayPool?.sendEvent(event, url)
}
setPushDone(true)
})
getRawUserGroupMessages(database, publicKey).then((resultGroupMessages) => {
resultGroupMessages.forEach((groupMessage) => {
relayPool.sendEvent(groupMessage, url)
})
})
getRawUserGroups(database, publicKey).then((resultGroups) => {
resultGroups.forEach((group) => {
relayPool.sendEvent(group, url)
})
})
sendRelays(relays, url)
}
}, [pushUserHistoric])
@ -337,8 +352,13 @@ export const RelayCard: React.FC<RelayCardProps> = ({ url, bottomSheetRef }) =>
<RBSheet
ref={bottomSheetPushRelayRef}
closeOnPressMask={!pushUserHistoric || pushDone}
closeOnDragDown={true}
customStyles={bottomSheetStyles}
onClose={() => {}}
onClose={() => {
setPushDone(false)
setPushUserHistoric(false)
setCheckedPush('unchecked')
}}
>
<Text variant='titleLarge'>{t('relayCard.pushHistoricTitle')}</Text>
<Text>{t('relayCard.pushHistoricDescription')}</Text>
@ -362,11 +382,7 @@ export const RelayCard: React.FC<RelayCardProps> = ({ url, bottomSheetRef }) =>
disabled={pushUserHistoric || checkedPush !== 'checked'}
loading={pushUserHistoric && !pushDone}
>
{pushDone
? t('relayCard.pushDone')
: pushUserHistoric
? t('relayCard.pushingEvent')
: t('relayCard.pushHistoricTitle')}
{pushDone ? t('relayCard.pushDone') : t('relayCard.pushHistoricTitle')}
</Button>
<Button
mode='outlined'
@ -377,6 +393,17 @@ export const RelayCard: React.FC<RelayCardProps> = ({ url, bottomSheetRef }) =>
>
{t('relayCard.cancel')}
</Button>
{showNotification && (
<Snackbar
style={styles.snackbar}
visible={showNotification !== undefined}
duration={Snackbar.DURATION_SHORT}
onIconPress={() => setShowNotification(undefined)}
onDismiss={() => setShowNotification(undefined)}
>
{t(`relayCard.notifications.${showNotification}`)}
</Snackbar>
)}
</RBSheet>
</View>
) : (
@ -408,6 +435,7 @@ const styles = StyleSheet.create({
},
snackbar: {
marginBottom: 85,
width: '100%',
},
moreInfo: {
paddingTop: 16,

View File

@ -22,6 +22,7 @@ interface TextContentProps {
showPreview?: boolean
onPressUser?: (user: User) => void
numberOfLines?: number
copyOnPress?: boolean
}
export const TextContent: React.FC<TextContentProps> = ({
@ -30,6 +31,7 @@ export const TextContent: React.FC<TextContentProps> = ({
showPreview = true,
onPressUser = () => {},
numberOfLines,
copyOnPress = true,
}) => {
const theme = useTheme()
const { t } = useTranslation('common')
@ -265,7 +267,7 @@ export const TextContent: React.FC<TextContentProps> = ({
},
]}
childrenProps={{ allowFontScaling: false }}
onLongPress={() => Clipboard.setString(text)}
onLongPress={copyOnPress ? () => Clipboard.setString(text) : undefined}
numberOfLines={numberOfLines}
>
{text}

View File

@ -156,6 +156,7 @@ const styles = StyleSheet.create({
snackbar: {
margin: 16,
bottom: 100,
width: '100%',
},
warning: {
borderRadius: 4,

View File

@ -21,6 +21,7 @@ export interface RelayPoolContextProps {
addRelayItem: (relay: Relay) => Promise<void>
removeRelayItem: (relay: Relay) => Promise<void>
updateRelayItem: (relay: Relay) => Promise<void>
sendRelays: (relays: Relay[], url?: string) => Promise<void>
}
export interface WebsocketEvent {
@ -40,6 +41,7 @@ export const initialRelayPoolContext: RelayPoolContextProps = {
updateRelayItem: async () => await new Promise(() => {}),
relays: [],
setDisplayrelayDrawer: () => {},
sendRelays: () => {},
}
export const RelayPoolContextProvider = ({
@ -56,7 +58,7 @@ export const RelayPoolContextProvider = ({
const [relays, setRelays] = React.useState<Relay[]>([])
const [displayRelayDrawer, setDisplayrelayDrawer] = React.useState<string>()
const sendRelays: (relayList: Relay[]) => void = (relayList) => {
const sendRelays: (relayList: Relay[], url?: string) => void = (relayList, url) => {
if (publicKey && relayList.length > 0) {
const event: Event = {
content: '',
@ -65,7 +67,7 @@ export const RelayPoolContextProvider = ({
pubkey: publicKey,
tags: relayList.map((relay) => ['r', relay.url, relay.mode ?? '']),
}
relayPool?.sendEvent(event)
url ? relayPool?.sendEvent(event, url) : relayPool?.sendEvent(event)
}
}
@ -200,6 +202,7 @@ export const RelayPoolContextProvider = ({
addRelayItem,
removeRelayItem,
updateRelayItem,
sendRelays,
}}
>
{children}

View File

@ -223,3 +223,33 @@ export const getGroupMessagesMentionsCount: (
return item['COUNT(*)'] ?? 0
}
export const getRawUserGroupMessages: (
db: QuickSQLiteConnection,
pubKey: string,
) => Promise<Event[]> = async (db, pubKey) => {
const notesQuery = `SELECT * FROM nostros_group_messages
WHERE pubkey = ?
ORDER BY created_at DESC
`
const resultSet = await db.execute(notesQuery, [pubKey])
const items: object[] = getItems(resultSet)
const groupMessages: Event[] = items.map((object) => databaseToGroupMessage(object))
return groupMessages
}
export const getRawUserGroups: (
db: QuickSQLiteConnection,
pubKey: string,
) => Promise<Event[]> = async (db, pubKey) => {
const notesQuery = `SELECT * FROM nostros_groups
WHERE pubkey = ?
ORDER BY created_at DESC
`
const resultSet = await db.execute(notesQuery, [pubKey])
const items: object[] = getItems(resultSet)
const groups: Event[] = items.map((object) => databaseToGroup(object))
return groups
}

View File

@ -256,7 +256,8 @@
"globalFeedActiveUnactive": "Globaler Feed inaktiv.",
"pubkeyCopied": "Öffentlichen Schlüssel kopiert.",
"contactCopied": "Kontakt kopiert.",
"urlCopied": "URL kopiert."
"urlCopied": "URL kopiert.",
"pushCompleted": "All your data has been pushed."
}
},

View File

@ -255,7 +255,8 @@
"globalFeedActiveUnactive": "Global feed disabled.",
"pubkeyCopied": "Public key copied.",
"contactCopied": "Contact copied.",
"urlCopied": "URL copied."
"urlCopied": "URL copied.",
"pushCompleted": "All your data has been pushed."
}
},
"profileConfigPage": {
@ -316,8 +317,7 @@
},
"groupPage": {
"typeMessage": "Type message",
"replyText": "Message",
"admin": "ADMIN"
"replyText": "Message"
},
"groupHeaderIcon": {
"delete": "Leave group",

View File

@ -235,7 +235,8 @@
"globalFeedActiveUnactive": "Feed Global desactivado.",
"pubkeyCopied": "Clave pública copiada.",
"contactCopied": "Contactp copiado.",
"urlCopied": "URL copiada."
"urlCopied": "URL copiada.",
"pushCompleted": "Todos tus datos se han subido."
}
},
"relaysPage": {

View File

@ -233,7 +233,8 @@
"globalFeedActiveUnactive": "Flux global désactivé.",
"pubkeyCopied": "Clé publique copiée.",
"contactCopied": "Contact copié.",
"urlCopied": "URL copié."
"urlCopied": "URL copié.",
"pushCompleted": "All your data has been pushed."
}
},
"relaysPage": {

View File

@ -227,7 +227,8 @@
"globalFeedActiveUnactive": "Global feed disabled",
"pubkeyCopied": "Публичный ключ скопирован",
"contactCopied": "Контакт скопирован",
"urlCopied": "URL скопирован"
"urlCopied": "URL скопирован",
"pushCompleted": "All your data has been pushed."
}
},
"relaysPage": {

View File

@ -266,7 +266,8 @@
"globalFeedActiveUnactive": "已为发现页禁用",
"pubkeyCopied": "已复制私钥",
"contactCopied": "已复制联系人",
"urlCopied": "已复制链接"
"urlCopied": "已复制链接",
"pushCompleted": "All your data has been pushed."
}
},
"profileConfigPage": {

View File

@ -291,6 +291,7 @@ export const ContactsPage: React.FC = () => {
ItemSeparatorComponent={Divider}
ListEmptyComponent={ListEmptyComponentFollowing}
horizontal={false}
style={styles.list}
/>
</View>
)
@ -365,6 +366,7 @@ export const ContactsPage: React.FC = () => {
ItemSeparatorComponent={Divider}
ListEmptyComponent={ListEmptyComponentBlocked}
horizontal={false}
style={styles.list}
/>
</View>
)
@ -531,6 +533,7 @@ const styles = StyleSheet.create({
snackbar: {
margin: 16,
marginBottom: 95,
width: '100%',
},
contactRow: {
padding: 16,
@ -548,7 +551,7 @@ const styles = StyleSheet.create({
justifyContent: 'space-between',
},
fab: {
bottom: 65,
bottom: 16,
right: 16,
position: 'absolute',
},

View File

@ -247,8 +247,7 @@ export const ConversationPage: React.FC<ConversationPageProps> = ({ route }) =>
</View>
)}
<Text>
{message?.created_at &&
formatDistance(fromUnixTime(message.created_at), new Date(), { addSuffix: true })}
{message?.created_at && formatDistance(fromUnixTime(message.created_at), new Date())}
</Text>
</View>
</View>
@ -542,6 +541,7 @@ const styles = StyleSheet.create({
snackbar: {
margin: 16,
bottom: 70,
width: '100%',
},
verifyIcon: {
paddingTop: 4,

View File

@ -148,9 +148,7 @@ export const ConversationsFeed: React.FC = () => {
</View>
<View style={styles.contactInfo}>
<View style={styles.contactDate}>
<Text>
{formatDistance(fromUnixTime(item.created_at), new Date(), { addSuffix: true })}
</Text>
<Text>{formatDistance(fromUnixTime(item.created_at), new Date())}</Text>
{item.pubkey !== publicKey && !item.read && <Badge size={16}></Badge>}
</View>
</View>
@ -280,7 +278,7 @@ export const ConversationsFeed: React.FC = () => {
</View>
)}
<AnimatedFAB
style={[styles.fab, { top: Dimensions.get('window').height - 216 }]}
style={[styles.fab, { top: Dimensions.get('window').height - 191 }]}
icon='pencil-outline'
label='Label'
onPress={() => bottomSheetCreateRef.current?.open()}

View File

@ -32,9 +32,7 @@ import { handleInfinityScroll } from '../../Functions/NativeFunctions'
import NostrosAvatar from '../../Components/NostrosAvatar'
import UploadImage from '../../Components/UploadImage'
import {
getGroup,
getGroupMessages,
Group,
GroupMessage,
updateGroupRead,
} from '../../Functions/DatabaseFunctions/Groups'
@ -55,7 +53,6 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
const { relayPool, lastEventId } = useContext(RelayPoolContext)
const { publicKey, privateKey, name, picture, validNip05 } = useContext(UserContext)
const [pageSize, setPageSize] = useState<number>(initialPageSize)
const [group, setGroup] = useState<Group>()
const [groupMessages, setGroupMessages] = useState<GroupMessage[]>([])
const [sendingMessages, setSendingMessages] = useState<GroupMessage[]>([])
const [reply, setReply] = useState<GroupMessage>()
@ -86,7 +83,6 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
const loadGroupMessages: (subscribe: boolean) => void = (subscribe) => {
if (database && publicKey && route.params.groupId) {
updateGroupRead(database, route.params.groupId)
getGroup(database, route.params.groupId).then(setGroup)
getGroupMessages(database, route.params.groupId, {
order: 'DESC',
limit: pageSize,
@ -299,11 +295,6 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
)}
</View>
<View style={styles.cardContentDate}>
{item.pubkey === group?.pubkey && (
<View style={[styles.warning, { backgroundColor: '#683D00' }]}>
<Text style={{ color: '#FFDCBB' }}>{t('groupPage.admin')}</Text>
</View>
)}
{message?.pending && (
<View style={styles.cardContentPending}>
<MaterialCommunityIcons
@ -315,7 +306,7 @@ export const GroupPage: React.FC<GroupPageProps> = ({ route }) => {
)}
<Text>
{message?.created_at &&
formatDistance(fromUnixTime(message.created_at), new Date(), { addSuffix: true })}
formatDistance(fromUnixTime(message.created_at), new Date())}
</Text>
</View>
</View>
@ -617,6 +608,7 @@ const styles = StyleSheet.create({
snackbar: {
margin: 16,
bottom: 70,
width: '100%',
},
verifyIcon: {
paddingTop: 4,

View File

@ -71,6 +71,8 @@ export const GroupsFeed: React.FC = () => {
loadGroups()
}, [lastEventId, lastConfirmationtId])
useEffect(() => {}, [newMessages, newMentions])
const pastePicture: () => void = () => {
Clipboard.getString().then((value) => {
setNewGroupPicture(value ?? '')
@ -272,7 +274,7 @@ export const GroupsFeed: React.FC = () => {
estimatedItemSize={76}
/>
<AnimatedFAB
style={[styles.fab, { top: Dimensions.get('window').height - 216 }]}
style={[styles.fab, { top: Dimensions.get('window').height - 191 }]}
icon='plus'
label='Label'
onPress={() => bottomSheetFabActionRef.current?.open()}
@ -433,6 +435,7 @@ const styles = StyleSheet.create({
snackbar: {
marginLeft: 16,
bottom: 16,
width: '100%',
},
containerAvatar: {
marginTop: 10,

View File

@ -134,7 +134,7 @@ export const HomeFeed: React.FC<HomeFeedProps> = ({ navigation }) => {
<View style={styles.feed}>{renderScene[tabKey]}</View>
{privateKey && (
<AnimatedFAB
style={[styles.fab, { top: Dimensions.get('window').height - 216 }]}
style={[styles.fab, { top: Dimensions.get('window').height - 191 }]}
icon='pencil-outline'
label='Label'
onPress={() => navigate('Send')}

View File

@ -129,7 +129,7 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
</ScrollView>
{privateKey && (
<AnimatedFAB
style={[styles.fabSend, { top: Dimensions.get('window').height - 160 }]}
style={[styles.fabSend, { top: Dimensions.get('window').height - 136 }]}
icon='message-plus-outline'
label='Label'
onPress={() => {
@ -141,7 +141,7 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
/>
)}
<AnimatedFAB
style={[styles.fabHome, { top: Dimensions.get('window').height - 230 }]}
style={[styles.fabHome, { top: Dimensions.get('window').height - 211 }]}
icon='home-outline'
label='Label'
onPress={() => {
@ -156,7 +156,7 @@ export const NotePage: React.FC<NotePageProps> = ({ route }) => {
<View>
<SkeletonNote />
<AnimatedFAB
style={[styles.fabHome, { top: Dimensions.get('window').height - 230 }]}
style={[styles.fabHome, { top: Dimensions.get('window').height - 211 }]}
icon='home-outline'
label='Label'
onPress={() => {

View File

@ -222,6 +222,7 @@ const styles = StyleSheet.create({
snackbar: {
margin: 16,
bottom: 70,
width: '100%',
},
profilePicture: {
width: '80%',

View File

@ -255,7 +255,12 @@ export const RelaysPage: React.FC = () => {
</>
)}
/>
<FlatList showsVerticalScrollIndicator={false} data={relays} renderItem={renderItem} />
<FlatList
showsVerticalScrollIndicator={false}
data={relays}
renderItem={renderItem}
style={styles.relayList}
/>
</ScrollView>
<AnimatedFAB
style={styles.fab}
@ -347,6 +352,7 @@ const styles = StyleSheet.create({
snackbar: {
margin: 16,
bottom: 70,
width: '100%',
},
relayColor: {
paddingTop: 9,
@ -359,8 +365,11 @@ const styles = StyleSheet.create({
paddingLeft: 16,
textAlign: 'center',
},
relayList: {
paddingBottom: 80,
},
fab: {
bottom: 65,
bottom: 16,
right: 16,
position: 'absolute',
},

View File

@ -233,6 +233,7 @@ const styles = StyleSheet.create({
snackbar: {
margin: 16,
bottom: 100,
width: '100%',
},
textInputContainer: {
flex: 1,