From 5a1a2b7291e131b949b3b2db30ebe6c24b03a713 Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Wed, 9 Nov 2022 23:30:48 -0800 Subject: [PATCH 1/8] [C-1452] Implement release-date upload field --- packages/mobile/ios/Podfile.lock | 6 + packages/mobile/package-lock.json | 16 +++ packages/mobile/package.json | 2 + .../upload-screen/fields/ReleaseDateField.tsx | 105 ++++++++++++++++++ .../src/screens/upload-screen/fields/index.ts | 1 + .../screens/AdvancedOptionsScreen.tsx | 13 ++- 6 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 packages/mobile/src/screens/upload-screen/fields/ReleaseDateField.tsx diff --git a/packages/mobile/ios/Podfile.lock b/packages/mobile/ios/Podfile.lock index 9068119b7e..44b3585690 100644 --- a/packages/mobile/ios/Podfile.lock +++ b/packages/mobile/ios/Podfile.lock @@ -454,6 +454,8 @@ PODS: - React-Core - RNCPushNotificationIOS (1.10.1): - React-Core + - RNDateTimePicker (6.5.4): + - React-Core - RNFBAnalytics (14.5.1): - Firebase/Analytics (= 8.12.1) - React-Core @@ -557,6 +559,7 @@ DEPENDENCIES: - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" - "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)" - "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)" + - "RNDateTimePicker (from `../node_modules/@react-native-community/datetimepicker`)" - "RNFBAnalytics (from `../node_modules/@react-native-firebase/analytics`)" - "RNFBApp (from `../node_modules/@react-native-firebase/app`)" - "RNFBCrashlytics (from `../node_modules/@react-native-firebase/crashlytics`)" @@ -710,6 +713,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-masked-view/masked-view" RNCPushNotificationIOS: :path: "../node_modules/@react-native-community/push-notification-ios" + RNDateTimePicker: + :path: "../node_modules/@react-native-community/datetimepicker" RNFBAnalytics: :path: "../node_modules/@react-native-firebase/analytics" RNFBApp: @@ -818,6 +823,7 @@ SPEC CHECKSUMS: RNCClipboard: f49f3de56b40d0f4104680dabadc7a1f063f4fd4 RNCMaskedView: 1f6cd0cb5e38ec01960e12fd8f95ecad809f8fbb RNCPushNotificationIOS: 089da3b657e1e3d464f38195fd2e3069608ef5af + RNDateTimePicker: 41bf71ec9c20cfe7762eb93b2c26ad2bdb4fc2e6 RNFBAnalytics: 74cd9c60531ed33e5347b2dccafa172ae1a851a4 RNFBApp: 5bae3002117e55f3c9aa0fb38175dd16c8046c90 RNFBCrashlytics: 33615211c6c6c4039ae71849091f6ac38ab65aba diff --git a/packages/mobile/package-lock.json b/packages/mobile/package-lock.json index c50d78758d..affdd7ea3e 100644 --- a/packages/mobile/package-lock.json +++ b/packages/mobile/package-lock.json @@ -5144,6 +5144,14 @@ "ora": "^3.4.0" } }, + "@react-native-community/datetimepicker": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-6.5.4.tgz", + "integrity": "sha512-6YUz6d6bEh409eG6HcL/oHmqElWtQgeHmVoVIfuJusf54ZsHr14NqHvrux0P1vBv5vcYrn9Qi8OwZZiFVyp9vw==", + "requires": { + "invariant": "^2.2.4" + } + }, "@react-native-community/eslint-config": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/@react-native-community/eslint-config/-/eslint-config-0.0.5.tgz", @@ -19278,6 +19286,14 @@ "react-native-animatable": "1.3.3" } }, + "react-native-modal-datetime-picker": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/react-native-modal-datetime-picker/-/react-native-modal-datetime-picker-14.0.0.tgz", + "integrity": "sha512-orI0BMgX9uooSZWYIILmMaZXqi8Ebr0vqsLUFL03zORpv9NvkBlLMQ8dZVdDxWUc1Lbx/N5DJskC16AOypPy8Q==", + "requires": { + "prop-types": "^15.7.2" + } + }, "react-native-music-control": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/react-native-music-control/-/react-native-music-control-1.4.0.tgz", diff --git a/packages/mobile/package.json b/packages/mobile/package.json index bd57fedca6..c40c9fe934 100644 --- a/packages/mobile/package.json +++ b/packages/mobile/package.json @@ -47,6 +47,7 @@ "@react-native-async-storage/async-storage": "1.15.14", "@react-native-clipboard/clipboard": "1.9.0", "@react-native-community/blur": "3.6.0", + "@react-native-community/datetimepicker": "^6.5.4", "@react-native-community/hooks": "2.8.1", "@react-native-community/netinfo": "9.3.0", "@react-native-community/push-notification-ios": "1.10.1", @@ -102,6 +103,7 @@ "react-native-linear-gradient": "github:react-native-linear-gradient/react-native-linear-gradient.git#9aece37cdf7d33ed52a1747b36e9e84f3c7a49ef", "react-native-markdown-display": "7.0.0-alpha.2", "react-native-modal": "11.5.4", + "react-native-modal-datetime-picker": "^14.0.0", "react-native-music-control": "1.4.0", "react-native-pager-view": "5.4.6", "react-native-permissions": "3.0.5", diff --git a/packages/mobile/src/screens/upload-screen/fields/ReleaseDateField.tsx b/packages/mobile/src/screens/upload-screen/fields/ReleaseDateField.tsx new file mode 100644 index 0000000000..1a7d15cc57 --- /dev/null +++ b/packages/mobile/src/screens/upload-screen/fields/ReleaseDateField.tsx @@ -0,0 +1,105 @@ +import { useCallback, useMemo, useState } from 'react' + +import type { Nullable } from '@audius/common' +import { useField } from 'formik' +import moment from 'moment' +import { TouchableOpacity } from 'react-native-gesture-handler' +import DateTimePickerModal from 'react-native-modal-datetime-picker' + +import { Divider, Pill, Text } from 'app/components/core' +import { makeStyles } from 'app/styles' + +const isToday = (date: Date) => { + const today = new Date() + return ( + date.getDate() === today.getDate() && + date.getMonth() === today.getMonth() && + date.getFullYear() === today.getFullYear() + ) +} + +const messages = { + label: 'Release Date', + today: 'Today' +} + +const useStyles = makeStyles(({ spacing }) => ({ + root: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + paddingHorizontal: spacing(2), + paddingTop: spacing(2), + paddingBottom: spacing(4) + }, + label: { + marginTop: spacing(1) + }, + dateText: { + marignTop: spacing(1), + textTransform: 'uppercase' + }, + divider: { + marginHorizontal: spacing(-4) + } +})) + +export const ReleaseDateField = () => { + const styles = useStyles() + const [{ value, onChange }] = useField>('release_date') + const [isOpen, setIsOpen] = useState(false) + + const releaseDate = useMemo( + () => (value ? new Date(value) : new Date()), + [value] + ) + + const handlePress = useCallback(() => { + setIsOpen(true) + }, []) + + const handleClose = useCallback(() => { + setIsOpen(false) + }, []) + + const handleChange = useCallback( + (selectedDate: Date) => { + const dateString = moment(selectedDate).toString() + console.log('hello?', dateString) + if (dateString) { + onChange('release_date')(dateString) + } + handleClose() + }, + [onChange, handleClose] + ) + + return ( + <> + + + {messages.label} + + + + {isToday(releaseDate) + ? messages.today + : moment(releaseDate).format('MM/DD/YY')} + + + + + + + ) +} diff --git a/packages/mobile/src/screens/upload-screen/fields/index.ts b/packages/mobile/src/screens/upload-screen/fields/index.ts index bb1ad6abfe..c2a0cd6a9d 100644 --- a/packages/mobile/src/screens/upload-screen/fields/index.ts +++ b/packages/mobile/src/screens/upload-screen/fields/index.ts @@ -9,3 +9,4 @@ export * from './RemixSettingsField' export * from './AdvancedOptionsField' export * from './TrackVisibilityField' export * from './SwitchField' +export * from './ReleaseDateField' diff --git a/packages/mobile/src/screens/upload-screen/screens/AdvancedOptionsScreen.tsx b/packages/mobile/src/screens/upload-screen/screens/AdvancedOptionsScreen.tsx index a3a145df0a..ebd84df0c2 100644 --- a/packages/mobile/src/screens/upload-screen/screens/AdvancedOptionsScreen.tsx +++ b/packages/mobile/src/screens/upload-screen/screens/AdvancedOptionsScreen.tsx @@ -1,8 +1,10 @@ +import { View } from 'react-native' + import IconIndent from 'app/assets/images/iconIndent.svg' import { makeStyles } from 'app/styles' import { UploadStackScreen } from '../UploadStackScreen' -import { SubmenuList, TrackVisibilityField } from '../fields' +import { ReleaseDateField, SubmenuList, TrackVisibilityField } from '../fields' const useStyles = makeStyles(({ spacing }) => ({ content: { @@ -24,9 +26,12 @@ export const AdvancedOptionsScreen = () => { bottomSection={null} variant='white' > - - - + + + + + + ) } From d57641c4b37bc3dab7bca8cfa21f1513f621356c Mon Sep 17 00:00:00 2001 From: Dylan Jeffers Date: Thu, 10 Nov 2022 11:21:26 -0800 Subject: [PATCH 2/8] Finalize --- packages/mobile/package-lock.json | 2 +- .../mobile/src/components/core/Button.tsx | 4 +- .../upload-screen/fields/ReleaseDateField.tsx | 53 +++++++++++++++++-- 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/packages/mobile/package-lock.json b/packages/mobile/package-lock.json index affdd7ea3e..07952c2613 100644 --- a/packages/mobile/package-lock.json +++ b/packages/mobile/package-lock.json @@ -8312,7 +8312,7 @@ "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" diff --git a/packages/mobile/src/components/core/Button.tsx b/packages/mobile/src/components/core/Button.tsx index 9a3cf56413..82690daf1e 100644 --- a/packages/mobile/src/components/core/Button.tsx +++ b/packages/mobile/src/components/core/Button.tsx @@ -219,6 +219,7 @@ export type ButtonProps = Omit & url?: string corners?: 'rounded' | 'pill' title: ReactNode + pressScale?: number } export const Button = (props: ButtonProps) => { @@ -241,6 +242,7 @@ export const Button = (props: ButtonProps) => { url, corners = 'rounded', disabled, + pressScale = 0.97, ...other } = props const [isPressing, setIsPressing] = useState(false) @@ -254,7 +256,7 @@ export const Button = (props: ButtonProps) => { scale, handlePressIn: handlePressInScale, handlePressOut: handlePressOutScale - } = usePressScaleAnimation(0.97, false) + } = usePressScaleAnimation(pressScale, false) const { primaryDark1, neutralLight10, neutralLight7, accentRedDark1 } = useThemeColors() diff --git a/packages/mobile/src/screens/upload-screen/fields/ReleaseDateField.tsx b/packages/mobile/src/screens/upload-screen/fields/ReleaseDateField.tsx index 1a7d15cc57..1767d6aa1d 100644 --- a/packages/mobile/src/screens/upload-screen/fields/ReleaseDateField.tsx +++ b/packages/mobile/src/screens/upload-screen/fields/ReleaseDateField.tsx @@ -1,13 +1,21 @@ import { useCallback, useMemo, useState } from 'react' import type { Nullable } from '@audius/common' +import { Theme, themeSelectors } from '@audius/common' import { useField } from 'formik' import moment from 'moment' import { TouchableOpacity } from 'react-native-gesture-handler' +import type { + CustomCancelButtonPropTypes, + CustomConfirmButtonPropTypes +} from 'react-native-modal-datetime-picker' import DateTimePickerModal from 'react-native-modal-datetime-picker' +import { useSelector } from 'react-redux' -import { Divider, Pill, Text } from 'app/components/core' +import { Button, Divider, Pill, Text } from 'app/components/core' import { makeStyles } from 'app/styles' +import { useThemeColors, useThemeVariant } from 'app/utils/theme' +const { getTheme } = themeSelectors const isToday = (date: Date) => { const today = new Date() @@ -41,13 +49,47 @@ const useStyles = makeStyles(({ spacing }) => ({ }, divider: { marginHorizontal: spacing(-4) + }, + datePickerModal: { + // Specific padding to hide the underlying "done" button with the "cancel" button + paddingBottom: 37 } })) +const ConfirmDateButton = (props: CustomConfirmButtonPropTypes) => { + const { label, onPress } = props + return ( +