From 041bfa22a99d8d6b4b17ad36c983e9e2b2444918 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Mon, 25 Jul 2022 23:08:24 -0500 Subject: Implement Web versions of the bottom sheet, toast, and progress circle --- src/App.web.tsx | 14 ++- src/state/lib/api.ts | 4 +- src/view/com/composer/Composer.tsx | 127 +++++++++++++--------------- src/view/com/feed/Feed.tsx | 6 +- src/view/com/feed/FeedItem.tsx | 2 +- src/view/com/modals/SharePost.native.tsx | 113 +++++++++++++++++++++++++ src/view/com/modals/SharePost.tsx | 57 +++++++++++++ src/view/com/modals/WebModal.tsx | 20 +++++ src/view/com/post-thread/PostThread.tsx | 6 +- src/view/com/post-thread/PostThreadItem.tsx | 2 +- src/view/com/sheets/SharePost.tsx | 114 ------------------------- src/view/com/util/ProgressCircle.native.tsx | 3 + src/view/com/util/ProgressCircle.tsx | 20 +++++ src/view/com/util/Toast.native.tsx | 2 + src/view/com/util/Toast.tsx | 62 ++++++++++++++ src/view/index.ts | 2 + 16 files changed, 355 insertions(+), 199 deletions(-) create mode 100644 src/view/com/modals/SharePost.native.tsx create mode 100644 src/view/com/modals/SharePost.tsx create mode 100644 src/view/com/modals/WebModal.tsx delete mode 100644 src/view/com/sheets/SharePost.tsx create mode 100644 src/view/com/util/ProgressCircle.native.tsx create mode 100644 src/view/com/util/ProgressCircle.tsx create mode 100644 src/view/com/util/Toast.native.tsx create mode 100644 src/view/com/util/Toast.tsx (limited to 'src') diff --git a/src/App.web.tsx b/src/App.web.tsx index 838b81ee2..9a6fedd5a 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -1,9 +1,8 @@ import React, {useState, useEffect} from 'react' -import {RootSiblingParent} from 'react-native-root-siblings' -import {GestureHandlerRootView} from 'react-native-gesture-handler' import * as view from './view/index' import {RootStoreModel, setupState, RootStoreProvider} from './state' import * as Routes from './view/routes' +import Toast from './view/com/util/Toast' function App() { const [rootStore, setRootStore] = useState( @@ -22,13 +21,10 @@ function App() { } return ( - - - - - - - + + + + ) } diff --git a/src/state/lib/api.ts b/src/state/lib/api.ts index bb3ef5d1a..df0047991 100644 --- a/src/state/lib/api.ts +++ b/src/state/lib/api.ts @@ -97,7 +97,7 @@ export async function unrepost(adx: AdxClient, user: string, uri: string) { return numDels > 0 } -type WherePred = (record: GetRecordResponseValidated) => Boolean +type WherePred = (_record: GetRecordResponseValidated) => Boolean async function deleteWhere( coll: AdxRepoCollectionClient, schema: SchemaOpt, @@ -115,7 +115,7 @@ async function deleteWhere( return toDelete.length } -type IterateAllCb = (record: GetRecordResponseValidated) => void +type IterateAllCb = (_record: GetRecordResponseValidated) => void async function iterateAll( coll: AdxRepoCollectionClient, schema: SchemaOpt, diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index c7ce3f4c7..57dc0ef86 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -1,9 +1,8 @@ import React, {useState, forwardRef, useImperativeHandle} from 'react' import {observer} from 'mobx-react-lite' import {KeyboardAvoidingView, StyleSheet, TextInput, View} from 'react-native' -import Toast from 'react-native-root-toast' -// @ts-ignore no type definition -prf -import ProgressCircle from 'react-native-progress/Circle' +import Toast from '../util/Toast' +import ProgressCircle from '../util/ProgressCircle' import {useStores} from '../../../state' import {s} from '../../lib/styles' import * as apilib from '../../../state/lib/api' @@ -12,75 +11,71 @@ const MAX_TEXT_LENGTH = 256 const WARNING_TEXT_LENGTH = 200 const DANGER_TEXT_LENGTH = 255 -export const Composer = observer( - forwardRef(function Composer( - { - replyTo, - }: { - replyTo: string | undefined - }, - ref, - ) { - const store = useStores() - const [text, setText] = useState('') +export const Composer = forwardRef(function Composer( + { + replyTo, + }: { + replyTo: string | undefined + }, + ref, +) { + const store = useStores() + const [text, setText] = useState('') - const onChangeText = (newText: string) => { - if (newText.length > MAX_TEXT_LENGTH) { - setText(newText.slice(0, MAX_TEXT_LENGTH)) - } else { - setText(newText) - } + const onChangeText = (newText: string) => { + if (newText.length > MAX_TEXT_LENGTH) { + setText(newText.slice(0, MAX_TEXT_LENGTH)) + } else { + setText(newText) } + } - useImperativeHandle(ref, () => ({ - async publish() { - if (text.trim().length === 0) { - return false - } - await apilib.post(store.api, 'alice.com', text, replyTo) - Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been created`, { - duration: Toast.durations.LONG, - position: Toast.positions.TOP, - shadow: true, - animation: true, - hideOnPress: true, - }) - return true - }, - })) + useImperativeHandle(ref, () => ({ + async publish() { + if (text.trim().length === 0) { + return false + } + await apilib.post(store.api, 'alice.com', text, replyTo) + Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been created`, { + duration: Toast.durations.LONG, + position: Toast.positions.TOP, + shadow: true, + animation: true, + hideOnPress: true, + }) + return true + }, + })) - const progressColor = - text.length > DANGER_TEXT_LENGTH - ? '#e60000' - : text.length > WARNING_TEXT_LENGTH - ? '#f7c600' - : undefined + const progressColor = + text.length > DANGER_TEXT_LENGTH + ? '#e60000' + : text.length > WARNING_TEXT_LENGTH + ? '#f7c600' + : undefined - return ( - - onChangeText(text)} - value={text} - placeholder={ - replyTo ? 'Write your reply' : "What's new in the scene?" - } - style={styles.textInput} - /> - - - - - + return ( + + onChangeText(text)} + value={text} + placeholder={replyTo ? 'Write your reply' : "What's new in the scene?"} + style={styles.textInput} + /> + + + + - - ) - }), -) + + + ) +}) const styles = StyleSheet.create({ outer: { diff --git a/src/view/com/feed/Feed.tsx b/src/view/com/feed/Feed.tsx index 8283e275e..6787b51ae 100644 --- a/src/view/com/feed/Feed.tsx +++ b/src/view/com/feed/Feed.tsx @@ -4,7 +4,7 @@ import {Text, View, FlatList} from 'react-native' import {OnNavigateContent} from '../../routes/types' import {FeedViewModel, FeedViewItemModel} from '../../../state/models/feed-view' import {FeedItem} from './FeedItem' -import {ShareBottomSheet} from '../sheets/SharePost' +import {ShareModal} from '../modals/SharePost' export const Feed = observer(function Feed({ feed, @@ -13,7 +13,7 @@ export const Feed = observer(function Feed({ feed: FeedViewModel onNavigateContent: OnNavigateContent }) { - const shareSheetRef = useRef<{open: (uri: string) => void}>() + const shareSheetRef = useRef<{open: (_uri: string) => void}>() const onPressShare = (uri: string) => { shareSheetRef.current?.open(uri) @@ -52,7 +52,7 @@ export const Feed = observer(function Feed({ /> )} {feed.isEmpty && This feed is empty!} - + ) }) diff --git a/src/view/com/feed/FeedItem.tsx b/src/view/com/feed/FeedItem.tsx index 018b58179..616fb0aca 100644 --- a/src/view/com/feed/FeedItem.tsx +++ b/src/view/com/feed/FeedItem.tsx @@ -16,7 +16,7 @@ export const FeedItem = observer(function FeedItem({ }: { item: FeedViewItemModel onNavigateContent: OnNavigateContent - onPressShare: (uri: string) => void + onPressShare: (_uri: string) => void }) { const record = item.record as unknown as bsky.Post.Record diff --git a/src/view/com/modals/SharePost.native.tsx b/src/view/com/modals/SharePost.native.tsx new file mode 100644 index 000000000..0e99bd4d1 --- /dev/null +++ b/src/view/com/modals/SharePost.native.tsx @@ -0,0 +1,113 @@ +import React, { + forwardRef, + useState, + useMemo, + useImperativeHandle, + useRef, +} from 'react' +import { + Button, + StyleSheet, + Text, + TouchableOpacity, + TouchableWithoutFeedback, + View, +} from 'react-native' +import BottomSheet, {BottomSheetBackdropProps} from '@gorhom/bottom-sheet' +import Animated, { + Extrapolate, + interpolate, + useAnimatedStyle, +} from 'react-native-reanimated' +import Toast from '../util/Toast' +import Clipboard from '@react-native-clipboard/clipboard' +import {s} from '../../lib/styles' + +export const ShareModal = forwardRef(function ShareModal({}: {}, ref) { + const [isOpen, setIsOpen] = useState(false) + const [uri, setUri] = useState('') + const bottomSheetRef = useRef(null) + + useImperativeHandle(ref, () => ({ + open(uri: string) { + console.log('sharing', uri) + setUri(uri) + setIsOpen(true) + }, + })) + + const onPressCopy = () => { + Clipboard.setString(uri) + console.log('showing') + console.log(Toast) + console.log(Toast.show) + Toast.show('Link copied', { + position: Toast.positions.TOP, + }) + } + const onShareBottomSheetChange = (snapPoint: number) => { + if (snapPoint === -1) { + console.log('unsharing') + setIsOpen(false) + } + } + const onClose = () => { + bottomSheetRef.current?.close() + } + + const CustomBackdrop = ({animatedIndex, style}: BottomSheetBackdropProps) => { + // animated variables + const opacity = useAnimatedStyle(() => ({ + opacity: interpolate( + animatedIndex.value, // current snap index + [-1, 0], // input range + [0, 0.5], // output range + Extrapolate.CLAMP, + ), + })) + + const containerStyle = useMemo( + () => [style, {backgroundColor: '#000'}, opacity], + [style, opacity], + ) + + return ( + + + + ) + } + return ( + <> + {isOpen && ( + + + Share this post + {uri} +