Improve app passwords on desktop web

This commit is contained in:
Paul Frazee
2023-04-21 18:34:29 -05:00
parent e9476d2706
commit 8f8c56133e
7 changed files with 92 additions and 31 deletions
+24 -1
View File
@@ -3,6 +3,7 @@ import {observer} from 'mobx-react-lite'
import {Animated, StyleSheet, TouchableOpacity, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {useNavigation} from '@react-navigation/native'
import {CenteredView} from './Views'
import {UserAvatar} from './UserAvatar'
import {Text} from './text/Text'
import {useStores} from 'state/index'
@@ -18,10 +19,12 @@ export const ViewHeader = observer(function ({
title,
canGoBack,
hideOnScroll,
showOnDesktop,
}: {
title: string
canGoBack?: boolean
hideOnScroll?: boolean
showOnDesktop?: boolean
}) {
const pal = usePalette('default')
const store = useStores()
@@ -42,7 +45,10 @@ export const ViewHeader = observer(function ({
}, [track, store])
if (isDesktopWeb) {
return <></>
if (showOnDesktop) {
return <DesktopWebHeader title={title} />
}
return null
} else {
if (typeof canGoBack === 'undefined') {
canGoBack = navigation.canGoBack()
@@ -76,6 +82,19 @@ export const ViewHeader = observer(function ({
}
})
function DesktopWebHeader({title}: {title: string}) {
const pal = usePalette('default')
return (
<CenteredView style={[styles.header, styles.desktopHeader, pal.border]}>
<View style={styles.titleContainer} pointerEvents="none">
<Text type="title-lg" style={[pal.text, styles.title]}>
{title}
</Text>
</View>
</CenteredView>
)
}
const Container = observer(
({
children,
@@ -133,6 +152,10 @@ const styles = StyleSheet.create({
top: 0,
width: '100%',
},
desktopHeader: {
borderBottomWidth: 1,
paddingVertical: 12,
},
titleContainer: {
marginLeft: 'auto',
+63 -25
View File
@@ -1,13 +1,13 @@
import React from 'react'
import {Alert, StyleSheet, TouchableOpacity, View} from 'react-native'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {ScrollView} from 'react-native-gesture-handler'
import {Text} from '../com/util/text/Text'
import {Button} from '../com/util/forms/Button'
import * as Toast from '../com/util/Toast'
import {useStores} from 'state/index'
import {usePalette} from 'lib/hooks/usePalette'
import {isDesktopWeb} from 'platform/detection'
import {ScrollView} from 'react-native-gesture-handler'
import {withAuthRequired} from 'view/com/auth/withAuthRequired'
import {observer} from 'mobx-react-lite'
import {NativeStackScreenProps} from '@react-navigation/native-stack'
@@ -15,6 +15,7 @@ import {CommonNavigatorParams} from 'lib/routes/types'
import {useAnalytics} from 'lib/analytics'
import {useFocusEffect} from '@react-navigation/native'
import {ViewHeader} from '../com/util/ViewHeader'
import {CenteredView} from 'view/com/util/Views'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'AppPasswords'>
export const AppPasswords = withAuthRequired(
@@ -37,7 +38,9 @@ export const AppPasswords = withAuthRequired(
// no app passwords (empty) state
if (store.me.appPasswords.length === 0) {
return (
<View style={[styles.container, pal.view]} testID="appPasswordsScreen">
<CenteredView
style={[styles.container, pal.view]}
testID="appPasswordsScreen">
<AppPasswordsHeader />
<View style={[styles.empty, pal.viewLight]}>
<Text type="lg" style={[pal.text, styles.emptyText]}>
@@ -45,7 +48,7 @@ export const AppPasswords = withAuthRequired(
pressing the button below.
</Text>
</View>
<View style={styles.flex1} />
{!isDesktopWeb && <View style={styles.flex1} />}
<View style={styles.btnContainer}>
<Button
testID="appPasswordBtn"
@@ -56,15 +59,22 @@ export const AppPasswords = withAuthRequired(
onPress={onAdd}
/>
</View>
</View>
</CenteredView>
)
}
// has app passwords
return (
<View style={[styles.container, pal.view]} testID="appPasswordsScreen">
<CenteredView
style={[styles.container, pal.view]}
testID="appPasswordsScreen">
<AppPasswordsHeader />
<ScrollView style={[styles.scrollContainer, pal.border]}>
<ScrollView
style={[
styles.scrollContainer,
pal.border,
!isDesktopWeb && styles.flex1,
]}>
{store.me.appPasswords.map((password, i) => (
<AppPassword
key={password.name}
@@ -73,18 +83,32 @@ export const AppPasswords = withAuthRequired(
createdAt={password.createdAt}
/>
))}
{isDesktopWeb && (
<View style={[styles.btnContainer, styles.btnContainerDesktop]}>
<Button
testID="appPasswordBtn"
type="primary"
label="Add App Password"
style={styles.btn}
labelStyle={styles.btnLabel}
onPress={onAdd}
/>
</View>
)}
</ScrollView>
<View style={styles.btnContainer}>
<Button
testID="appPasswordBtn"
type="primary"
label="Add App Password"
style={styles.btn}
labelStyle={styles.btnLabel}
onPress={onAdd}
/>
</View>
</View>
{!isDesktopWeb && (
<View style={styles.btnContainer}>
<Button
testID="appPasswordBtn"
type="primary"
label="Add App Password"
style={styles.btn}
labelStyle={styles.btnLabel}
onPress={onAdd}
/>
</View>
)}
</CenteredView>
)
}),
)
@@ -93,10 +117,16 @@ function AppPasswordsHeader() {
const pal = usePalette('default')
return (
<>
<ViewHeader title="App Passwords" />
<Text type="sm" style={[styles.description, pal.text]}>
These app passwords can be used to log onto Bluesky in other apps
without giving them full access to your account or your password.
<ViewHeader title="App Passwords" showOnDesktop />
<Text
type="sm"
style={[
styles.description,
pal.text,
isDesktopWeb && styles.descriptionDesktop,
]}>
These passwords can be used to log onto Bluesky in other apps without
giving them full access to your account or your password.
</Text>
</>
)
@@ -140,10 +170,11 @@ function AppPassword({
testID={testID}
style={[styles.item, pal.border]}
onPress={onDelete}>
<Text type={'md-bold'} style={pal.text}>
<Text type="md-bold" style={pal.text}>
{name}
</Text>
<Text type={'md'} style={pal.text}>
<View style={styles.flex1} />
<Text type="md" style={[pal.text, styles.pr10]}>
{new Date(createdAt).toDateString()}
</Text>
<FontAwesomeIcon icon={['far', 'trash-can']} style={styles.trashIcon} />
@@ -166,9 +197,11 @@ const styles = StyleSheet.create({
paddingHorizontal: 20,
marginBottom: 14,
},
descriptionDesktop: {
marginTop: 14,
},
scrollContainer: {
flex: 1,
borderTopWidth: 1,
marginTop: 4,
marginBottom: 16,
@@ -191,16 +224,21 @@ const styles = StyleSheet.create({
item: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
borderBottomWidth: 1,
paddingHorizontal: 20,
paddingVertical: 14,
},
pr10: {
marginRight: 10,
},
btnContainer: {
flexDirection: 'row',
justifyContent: 'center',
},
btnContainerDesktop: {
marginTop: 14,
},
btn: {
flexDirection: 'row',
alignItems: 'center',
+1 -1
View File
@@ -22,7 +22,7 @@ export const PostLikedByScreen = withAuthRequired(({route}: Props) => {
return (
<View>
<ViewHeader title="Liked by" />
<ViewHeader title="Liked by" showOnDesktop />
<PostLikedByComponent uri={uri} />
</View>
)
+1 -1
View File
@@ -22,7 +22,7 @@ export const PostRepostedByScreen = withAuthRequired(({route}: Props) => {
return (
<View>
<ViewHeader title="Reposted by" />
<ViewHeader title="Reposted by" showOnDesktop />
<PostRepostedByComponent uri={uri} />
</View>
)
+1 -1
View File
@@ -20,7 +20,7 @@ export const ProfileFollowersScreen = withAuthRequired(({route}: Props) => {
return (
<View>
<ViewHeader title="Followers" />
<ViewHeader title="Followers" showOnDesktop />
<ProfileFollowersComponent name={name} />
</View>
)
+1 -1
View File
@@ -20,7 +20,7 @@ export const ProfileFollowsScreen = withAuthRequired(({route}: Props) => {
return (
<View>
<ViewHeader title="Following" />
<ViewHeader title="Following" showOnDesktop />
<ProfileFollowsComponent name={name} />
</View>
)
+1 -1
View File
@@ -140,7 +140,7 @@ export const SettingsScreen = withAuthRequired(
return (
<View style={[s.hContentRegion]} testID="settingsScreen">
<ViewHeader title="Settings" />
<ViewHeader title="Settings" showOnDesktop />
<ScrollView style={s.hContentRegion} scrollIndicatorInsets={{right: 1}}>
<View style={styles.spacer20} />
<View style={[s.flexRow, styles.heading]}>