From 7a770526c626e6659a12939f8c61057a688aa623 Mon Sep 17 00:00:00 2001 From: Andres Riveros Moya Date: Wed, 25 Aug 2021 13:36:23 -0700 Subject: [PATCH] Remove DatePickerAndroid from react-native-github Summary: Changelog: [JavaScript][Removed] - Remove DatePickerAndroid from React Native Reviewed By: lunaleaps, yungsters Differential Revision: D30281952 fbshipit-source-id: 5cd0ad2ad741afeef3e6f8a39635c6baf4b79b38 --- .../DatePickerAndroid.android.js | 87 --------- .../DatePickerAndroid.ios.js | 30 --- .../DatePickerAndroidTypes.js | 30 --- .../java/com/facebook/react/tests/BUCK | 1 - .../react/tests/DatePickerDialogTestCase.java | 172 ------------------ .../js/DatePickerDialogTestModule.js | 45 ----- ReactAndroid/src/androidTest/js/TestBundle.js | 7 - .../facebook/react/modules/datepicker/BUCK | 27 --- .../datepicker/DatePickerDialogFragment.java | 137 -------------- .../datepicker/DatePickerDialogModule.java | 153 ---------------- .../modules/datepicker/DatePickerMode.java | 15 -- .../DismissableDatePickerDialog.java | 117 ------------ .../main/java/com/facebook/react/shell/BUCK | 1 - .../react/shell/MainReactPackage.java | 5 - index.js | 25 ++- 15 files changed, 15 insertions(+), 837 deletions(-) delete mode 100644 Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js delete mode 100644 Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js delete mode 100644 Libraries/Components/DatePickerAndroid/DatePickerAndroidTypes.js delete mode 100644 ReactAndroid/src/androidTest/java/com/facebook/react/tests/DatePickerDialogTestCase.java delete mode 100644 ReactAndroid/src/androidTest/js/DatePickerDialogTestModule.js delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogFragment.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerMode.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DismissableDatePickerDialog.java diff --git a/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js b/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js deleted file mode 100644 index 9f29433e1e1898..00000000000000 --- a/Libraries/Components/DatePickerAndroid/DatePickerAndroid.android.js +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @flow strict-local - */ - -import type {Options, DatePickerOpenAction} from './DatePickerAndroidTypes'; -import NativeDatePickerAndroid from './NativeDatePickerAndroid'; - -/** - * Convert a Date to a timestamp. - */ -function _toMillis(options: Options, key: string) { - const dateVal = options[key]; - // Is it a Date object? - if (typeof dateVal === 'object' && typeof dateVal.getMonth === 'function') { - options[key] = dateVal.getTime(); - } -} - -/** - * Opens the standard Android date picker dialog. - * - * ### Example - * - * ``` - * try { - * const {action, year, month, day} = await DatePickerAndroid.open({ - * // Use `new Date()` for current date. - * // May 25 2020. Month 0 is January. - * date: new Date(2020, 4, 25) - * }); - * if (action !== DatePickerAndroid.dismissedAction) { - * // Selected year, month (0-11), day - * } - * } catch ({code, message}) { - * console.warn('Cannot open date picker', message); - * } - * ``` - */ -class DatePickerAndroid { - /** - * Opens the standard Android date picker dialog. - * - * The available keys for the `options` object are: - * - * - `date` (`Date` object or timestamp in milliseconds) - date to show by default - * - `minDate` (`Date` or timestamp in milliseconds) - minimum date that can be selected - * - `maxDate` (`Date` object or timestamp in milliseconds) - maximum date that can be selected - * - `mode` (`enum('calendar', 'spinner', 'default')`) - To set the date-picker mode to calendar/spinner/default - * - 'calendar': Show a date picker in calendar mode. - * - 'spinner': Show a date picker in spinner mode. - * - 'default': Show a default native date picker(spinner/calendar) based on android versions. - * - * Returns a Promise which will be invoked an object containing `action`, `year`, `month` (0-11), - * `day` if the user picked a date. If the user dismissed the dialog, the Promise will - * still be resolved with action being `DatePickerAndroid.dismissedAction` and all the other keys - * being undefined. **Always** check whether the `action` before reading the values. - * - * Note the native date picker dialog has some UI glitches on Android 4 and lower - * when using the `minDate` and `maxDate` options. - */ - static async open(options: ?Options): Promise { - const optionsMs = options; - if (optionsMs != null) { - _toMillis(optionsMs, 'date'); - _toMillis(optionsMs, 'minDate'); - _toMillis(optionsMs, 'maxDate'); - } - return NativeDatePickerAndroid.open(options); - } - - /** - * A date has been selected. - */ - static +dateSetAction: 'dateSetAction' = 'dateSetAction'; - /** - * The dialog has been dismissed. - */ - static +dismissedAction: 'dismissedAction' = 'dismissedAction'; -} - -module.exports = DatePickerAndroid; diff --git a/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js b/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js deleted file mode 100644 index d16cb2bf610565..00000000000000 --- a/Libraries/Components/DatePickerAndroid/DatePickerAndroid.ios.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @flow strict-local - */ - -'use strict'; - -import type {Options, DatePickerOpenAction} from './DatePickerAndroidTypes'; - -class DatePickerAndroid { - static async open(options: ?Options): Promise { - throw new Error('DatePickerAndroid is not supported on this platform.'); - } - - /** - * A date has been selected. - */ - static +dateSetAction: 'dateSetAction' = 'dateSetAction'; - /** - * The dialog has been dismissed. - */ - static +dismissedAction: 'dismissedAction' = 'dismissedAction'; -} - -module.exports = DatePickerAndroid; diff --git a/Libraries/Components/DatePickerAndroid/DatePickerAndroidTypes.js b/Libraries/Components/DatePickerAndroid/DatePickerAndroidTypes.js deleted file mode 100644 index 096d7b5e8d9abb..00000000000000 --- a/Libraries/Components/DatePickerAndroid/DatePickerAndroidTypes.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - * @flow strict-local - */ - -export type Options = $ReadOnly<{| - date?: ?(Date | number), - minDate?: ?(Date | number), - maxDate?: ?(Date | number), - mode?: ?('calendar' | 'spinner' | 'default'), -|}>; - -export type DatePickerOpenAction = - | {| - action: 'dateSetAction', - year: number, - month: number, - day: number, - |} - | {| - action: 'dismissedAction', - year: void, - month: void, - day: void, - |}; diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK index 451cd7413b9686..131dd4af63c3a2 100644 --- a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK +++ b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/BUCK @@ -25,7 +25,6 @@ rn_android_library( react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/modules/appstate:appstate"), react_native_target("java/com/facebook/react/modules/core:core"), - react_native_target("java/com/facebook/react/modules/datepicker:datepicker"), react_native_target("java/com/facebook/react/modules/deviceinfo:deviceinfo"), react_native_target("java/com/facebook/react/modules/share:share"), react_native_target("java/com/facebook/react/modules/systeminfo:systeminfo"), diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/DatePickerDialogTestCase.java b/ReactAndroid/src/androidTest/java/com/facebook/react/tests/DatePickerDialogTestCase.java deleted file mode 100644 index 93d3568fa24e2e..00000000000000 --- a/ReactAndroid/src/androidTest/java/com/facebook/react/tests/DatePickerDialogTestCase.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.tests; - -import android.app.DatePickerDialog; -import android.content.DialogInterface; -import android.widget.DatePicker; -import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; -import com.facebook.react.bridge.BaseJavaModule; -import com.facebook.react.bridge.JavaScriptModule; -import com.facebook.react.bridge.ReactMethod; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.bridge.WritableNativeMap; -import com.facebook.react.modules.datepicker.DatePickerDialogModule; -import com.facebook.react.testing.ReactAppInstrumentationTestCase; -import com.facebook.react.testing.ReactInstanceSpecForTest; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.List; - -/** Test case for {@link DatePickerDialogModule} options and callbacks. */ -public class DatePickerDialogTestCase extends ReactAppInstrumentationTestCase { - - private static interface DatePickerDialogTestModule extends JavaScriptModule { - public void showDatePickerDialog(WritableMap options); - } - - private static class DatePickerDialogRecordingModule extends BaseJavaModule { - - private final List mDates = new ArrayList(); - private int mDismissed = 0; - private int mErrors = 0; - - @Override - public String getName() { - return "DatePickerDialogRecordingModule"; - } - - @ReactMethod - public void recordDate(int year, int month, int day) { - mDates.add(new Integer[] {year, month, day}); - } - - @ReactMethod - public void recordDismissed() { - mDismissed++; - } - - @ReactMethod - public void recordError() { - mErrors++; - } - - public List getDates() { - return new ArrayList(mDates); - } - - public int getDismissed() { - return mDismissed; - } - - public int getErrors() { - return mErrors; - } - } - - final DatePickerDialogRecordingModule mRecordingModule = new DatePickerDialogRecordingModule(); - - @Override - protected ReactInstanceSpecForTest createReactInstanceSpecForTest() { - return super.createReactInstanceSpecForTest().addNativeModule(mRecordingModule); - } - - @Override - protected String getReactApplicationKeyUnderTest() { - return "DatePickerDialogTestApp"; - } - - private static long getDateInMillis(int year, int month, int date) { - final Calendar c = Calendar.getInstance(); - c.set(Calendar.YEAR, year); - c.set(Calendar.MONTH, month); - c.set(Calendar.DATE, date); - return c.getTimeInMillis(); - } - - private DatePickerDialogTestModule getTestModule() { - return getReactContext().getCatalystInstance().getJSModule(DatePickerDialogTestModule.class); - } - - private DialogFragment showDialog(WritableMap options) { - getTestModule().showDatePickerDialog(options); - - waitForBridgeAndUIIdle(); - getInstrumentation().waitForIdleSync(); - - return (DialogFragment) - getActivity() - .getSupportFragmentManager() - .findFragmentByTag(DatePickerDialogModule.FRAGMENT_TAG); - } - - public void testShowBasicDatePicker() { - final Fragment datePickerFragment = showDialog(null); - - assertNotNull(datePickerFragment); - } - - public void testPresetDate() { - final WritableMap options = new WritableNativeMap(); - options.putDouble("date", getDateInMillis(2020, 5, 6)); - - final DialogFragment datePickerFragment = showDialog(options); - final DatePicker datePicker = - ((DatePickerDialog) datePickerFragment.getDialog()).getDatePicker(); - - assertEquals(2020, datePicker.getYear()); - assertEquals(5, datePicker.getMonth()); - assertEquals(6, datePicker.getDayOfMonth()); - } - - public void testCallback() throws Throwable { - final WritableMap options = new WritableNativeMap(); - options.putDouble("date", getDateInMillis(2020, 5, 6)); - - final DialogFragment datePickerFragment = showDialog(options); - - runTestOnUiThread( - new Runnable() { - @Override - public void run() { - ((DatePickerDialog) datePickerFragment.getDialog()) - .getButton(DialogInterface.BUTTON_POSITIVE) - .performClick(); - } - }); - - getInstrumentation().waitForIdleSync(); - waitForBridgeAndUIIdle(); - - assertEquals(0, mRecordingModule.getErrors()); - assertEquals(1, mRecordingModule.getDates().size()); - assertEquals(2020, (int) mRecordingModule.getDates().get(0)[0]); - assertEquals(5, (int) mRecordingModule.getDates().get(0)[1]); - assertEquals(6, (int) mRecordingModule.getDates().get(0)[2]); - } - - public void testDismissCallback() throws Throwable { - final DialogFragment datePickerFragment = showDialog(null); - - runTestOnUiThread( - new Runnable() { - @Override - public void run() { - datePickerFragment.getDialog().dismiss(); - } - }); - - getInstrumentation().waitForIdleSync(); - waitForBridgeAndUIIdle(); - - assertEquals(0, mRecordingModule.getErrors()); - assertEquals(0, mRecordingModule.getDates().size()); - assertEquals(1, mRecordingModule.getDismissed()); - } -} diff --git a/ReactAndroid/src/androidTest/js/DatePickerDialogTestModule.js b/ReactAndroid/src/androidTest/js/DatePickerDialogTestModule.js deleted file mode 100644 index 5c23e61a5ec5ae..00000000000000 --- a/ReactAndroid/src/androidTest/js/DatePickerDialogTestModule.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @format - */ - -'use strict'; - -const React = require('react'); -const {DatePickerAndroid, NativeModules, View} = require('react-native'); -const BatchedBridge = require('react-native/Libraries/BatchedBridge/BatchedBridge'); - -const {DatePickerDialogRecordingModule: RecordingModule} = NativeModules; - -class DatePickerDialogTestApp extends React.Component { - render() { - return ; - } -} - -const DatePickerDialogTestModule = { - DatePickerDialogTestApp: DatePickerDialogTestApp, - showDatePickerDialog: function(options) { - DatePickerAndroid.open(options).then( - ({action, year, month, day}) => { - if (action === DatePickerAndroid.dateSetAction) { - RecordingModule.recordDate(year, month, day); - } else if (action === DatePickerAndroid.dismissedAction) { - RecordingModule.recordDismissed(); - } - }, - ({code, message}) => RecordingModule.recordError(), - ); - }, -}; - -BatchedBridge.registerCallableModule( - 'DatePickerDialogTestModule', - DatePickerDialogTestModule, -); - -module.exports = DatePickerDialogTestModule; diff --git a/ReactAndroid/src/androidTest/js/TestBundle.js b/ReactAndroid/src/androidTest/js/TestBundle.js index 709f469b118d45..b81937503589ae 100644 --- a/ReactAndroid/src/androidTest/js/TestBundle.js +++ b/ReactAndroid/src/androidTest/js/TestBundle.js @@ -20,9 +20,7 @@ require('./TestJSLocaleModule'); require('./TestJSToJavaParametersModule'); require('./TestJavaToJSReturnValuesModule'); require('./UIManagerTestModule'); - require('./CatalystRootViewTestModule'); -require('./DatePickerDialogTestModule'); require('./MeasureLayoutTestModule'); require('./ScrollViewTestModule'); require('./ShareTestModule'); @@ -43,11 +41,6 @@ const apps = [ component: () => require('./CatalystRootViewTestModule').CatalystRootViewTestApp, }, - { - appKey: 'DatePickerDialogTestApp', - component: () => - require('./DatePickerDialogTestModule').DatePickerDialogTestApp, - }, { appKey: 'JSResponderTestApp', component: () => require('./JSResponderTestApp'), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK deleted file mode 100644 index 80a1af4bb9ac75..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK +++ /dev/null @@ -1,27 +0,0 @@ -load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_root_target", "react_native_target", "rn_android_library") - -rn_android_library( - name = "datepicker", - srcs = glob(["**/*.java"]), - autoglob = False, - is_androidx = True, - labels = ["supermodule:xplat/default/public.react_native.infra"], - provided_deps = [ - react_native_dep("third-party/android/androidx:annotation"), - react_native_dep("third-party/android/androidx:core"), - react_native_dep("third-party/android/androidx:fragment"), - react_native_dep("third-party/android/androidx:legacy-support-core-ui"), - react_native_dep("third-party/android/androidx:legacy-support-core-utils"), - ], - visibility = [ - "PUBLIC", - ], - deps = [ - react_native_dep("third-party/java/infer-annotations:infer-annotations"), - react_native_dep("third-party/java/jsr-305:jsr-305"), - react_native_target("java/com/facebook/react/bridge:bridge"), - react_native_target("java/com/facebook/react/common:common"), - react_native_target("java/com/facebook/react/module/annotations:annotations"), - ], - exported_deps = [react_native_root_target(":FBReactNativeSpec")], -) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogFragment.java b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogFragment.java deleted file mode 100644 index f3d190b4432e22..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogFragment.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.modules.datepicker; - -import android.annotation.SuppressLint; -import android.app.DatePickerDialog; -import android.app.DatePickerDialog.OnDateSetListener; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnDismissListener; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.widget.DatePicker; -import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; -import java.util.Calendar; -import java.util.Locale; - -@SuppressLint("ValidFragment") -public class DatePickerDialogFragment extends DialogFragment { - - /** Minimum date supported by {@link DatePicker}, 01 Jan 1900 */ - private static final long DEFAULT_MIN_DATE = -2208988800001l; - - @Nullable private OnDateSetListener mOnDateSetListener; - @Nullable private OnDismissListener mOnDismissListener; - - @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { - Bundle args = getArguments(); - return createDialog(args, getActivity(), mOnDateSetListener); - } - - /*package*/ static Dialog createDialog( - Bundle args, Context activityContext, @Nullable OnDateSetListener onDateSetListener) { - final Calendar c = Calendar.getInstance(); - if (args != null && args.containsKey(DatePickerDialogModule.ARG_DATE)) { - c.setTimeInMillis(args.getLong(DatePickerDialogModule.ARG_DATE)); - } - final int year = c.get(Calendar.YEAR); - final int month = c.get(Calendar.MONTH); - final int day = c.get(Calendar.DAY_OF_MONTH); - - DatePickerMode mode = DatePickerMode.DEFAULT; - if (args != null && args.getString(DatePickerDialogModule.ARG_MODE, null) != null) { - mode = - DatePickerMode.valueOf( - args.getString(DatePickerDialogModule.ARG_MODE).toUpperCase(Locale.US)); - } - - DatePickerDialog dialog = null; - - switch (mode) { - case CALENDAR: - dialog = - new DismissableDatePickerDialog( - activityContext, - activityContext - .getResources() - .getIdentifier( - "CalendarDatePickerDialog", "style", activityContext.getPackageName()), - onDateSetListener, - year, - month, - day); - break; - case SPINNER: - dialog = - new DismissableDatePickerDialog( - activityContext, - android.R.style.Theme_Holo_Light_Dialog, - onDateSetListener, - year, - month, - day); - dialog - .getWindow() - .setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); - break; - case DEFAULT: - dialog = - new DismissableDatePickerDialog(activityContext, onDateSetListener, year, month, day); - break; - } - - final DatePicker datePicker = dialog.getDatePicker(); - - if (args != null && args.containsKey(DatePickerDialogModule.ARG_MINDATE)) { - // Set minDate to the beginning of the day. We need this because of clowniness in datepicker - // that causes it to throw an exception if minDate is greater than the internal timestamp - // that it generates from the y/m/d passed in the constructor. - c.setTimeInMillis(args.getLong(DatePickerDialogModule.ARG_MINDATE)); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.SECOND, 0); - c.set(Calendar.MILLISECOND, 0); - datePicker.setMinDate(c.getTimeInMillis()); - } else { - // This is to work around a bug in DatePickerDialog where it doesn't display a title showing - // the date under certain conditions. - datePicker.setMinDate(DEFAULT_MIN_DATE); - } - if (args != null && args.containsKey(DatePickerDialogModule.ARG_MAXDATE)) { - // Set maxDate to the end of the day, same reason as for minDate. - c.setTimeInMillis(args.getLong(DatePickerDialogModule.ARG_MAXDATE)); - c.set(Calendar.HOUR_OF_DAY, 23); - c.set(Calendar.MINUTE, 59); - c.set(Calendar.SECOND, 59); - c.set(Calendar.MILLISECOND, 999); - datePicker.setMaxDate(c.getTimeInMillis()); - } - - return dialog; - } - - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - if (mOnDismissListener != null) { - mOnDismissListener.onDismiss(dialog); - } - } - - /*package*/ void setOnDateSetListener(@Nullable OnDateSetListener onDateSetListener) { - mOnDateSetListener = onDateSetListener; - } - - /*package*/ void setOnDismissListener(@Nullable OnDismissListener onDismissListener) { - mOnDismissListener = onDismissListener; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java deleted file mode 100644 index e6971464889241..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerDialogModule.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.modules.datepicker; - -import android.app.Activity; -import android.app.DatePickerDialog.OnDateSetListener; -import android.content.DialogInterface; -import android.content.DialogInterface.OnDismissListener; -import android.os.Bundle; -import android.widget.DatePicker; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.FragmentActivity; -import androidx.fragment.app.FragmentManager; -import com.facebook.fbreact.specs.NativeDatePickerAndroidSpec; -import com.facebook.react.bridge.*; -import com.facebook.react.common.annotations.VisibleForTesting; -import com.facebook.react.module.annotations.ReactModule; - -/** - * {@link NativeModule} that allows JS to show a native date picker dialog and get called back when - * the user selects a date. - */ -@ReactModule(name = DatePickerDialogModule.FRAGMENT_TAG) -public class DatePickerDialogModule extends NativeDatePickerAndroidSpec { - - @VisibleForTesting public static final String FRAGMENT_TAG = "DatePickerAndroid"; - - private static final String ERROR_NO_ACTIVITY = "E_NO_ACTIVITY"; - - /* package */ static final String ARG_DATE = "date"; - /* package */ static final String ARG_MINDATE = "minDate"; - /* package */ static final String ARG_MAXDATE = "maxDate"; - /* package */ static final String ARG_MODE = "mode"; - - /* package */ static final String ACTION_DATE_SET = "dateSetAction"; - /* package */ static final String ACTION_DISMISSED = "dismissedAction"; - - public DatePickerDialogModule(ReactApplicationContext reactContext) { - super(reactContext); - } - - public @NonNull String getName() { - return DatePickerDialogModule.FRAGMENT_TAG; - } - - private class DatePickerDialogListener implements OnDateSetListener, OnDismissListener { - - private final Promise mPromise; - private boolean mPromiseResolved = false; - - public DatePickerDialogListener(final Promise promise) { - mPromise = promise; - } - - @Override - public void onDateSet(DatePicker view, int year, int month, int day) { - if (!mPromiseResolved && getReactApplicationContext().hasActiveReactInstance()) { - WritableMap result = new WritableNativeMap(); - result.putString("action", ACTION_DATE_SET); - result.putInt("year", year); - result.putInt("month", month); - result.putInt("day", day); - mPromise.resolve(result); - mPromiseResolved = true; - } - } - - @Override - public void onDismiss(DialogInterface dialog) { - if (!mPromiseResolved && getReactApplicationContext().hasActiveReactInstance()) { - WritableMap result = new WritableNativeMap(); - result.putString("action", ACTION_DISMISSED); - mPromise.resolve(result); - mPromiseResolved = true; - } - } - } - - /** - * Show a date picker dialog. - * - * @param options a map containing options. Available keys are: - *
    - *
  • {@code date} (timestamp in milliseconds) the date to show by default - *
  • {@code minDate} (timestamp in milliseconds) the minimum date the user should be - * allowed to select - *
  • {@code maxDate} (timestamp in milliseconds) the maximum date the user should be - * allowed to select - *
  • {@code mode} To set the date picker mode to 'calendar/spinner/default' - *
- * - * @param promise This will be invoked with parameters action, year, month (0-11), day, where - * action is {@code dateSetAction} or {@code dismissedAction}, depending on what the user did. - * If the action is dismiss, year, month and date are undefined. - */ - @Override - public void open(@Nullable final ReadableMap options, final Promise promise) { - Activity raw_activity = getCurrentActivity(); - if (raw_activity == null || !(raw_activity instanceof FragmentActivity)) { - promise.reject( - ERROR_NO_ACTIVITY, - "Tried to open a DatePicker dialog while not attached to a FragmentActivity"); - return; - } - - FragmentActivity activity = (FragmentActivity) raw_activity; - - final FragmentManager fragmentManager = activity.getSupportFragmentManager(); - DialogFragment oldFragment = (DialogFragment) fragmentManager.findFragmentByTag(FRAGMENT_TAG); - if (oldFragment != null) { - oldFragment.dismiss(); - } - activity.runOnUiThread( - new Runnable() { - @Override - public void run() { - DatePickerDialogFragment fragment = new DatePickerDialogFragment(); - if (options != null) { - final Bundle args = createFragmentArguments(options); - fragment.setArguments(args); - } - final DatePickerDialogListener listener = new DatePickerDialogListener(promise); - fragment.setOnDismissListener(listener); - fragment.setOnDateSetListener(listener); - fragment.show(fragmentManager, FRAGMENT_TAG); - } - }); - } - - private Bundle createFragmentArguments(ReadableMap options) { - final Bundle args = new Bundle(); - if (options.hasKey(ARG_DATE) && !options.isNull(ARG_DATE)) { - args.putLong(ARG_DATE, (long) options.getDouble(ARG_DATE)); - } - if (options.hasKey(ARG_MINDATE) && !options.isNull(ARG_MINDATE)) { - args.putLong(ARG_MINDATE, (long) options.getDouble(ARG_MINDATE)); - } - if (options.hasKey(ARG_MAXDATE) && !options.isNull(ARG_MAXDATE)) { - args.putLong(ARG_MAXDATE, (long) options.getDouble(ARG_MAXDATE)); - } - if (options.hasKey(ARG_MODE) && !options.isNull(ARG_MODE)) { - args.putString(ARG_MODE, options.getString(ARG_MODE)); - } - return args; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerMode.java b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerMode.java deleted file mode 100644 index 3ed6f114724c8c..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DatePickerMode.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.modules.datepicker; - -/** Date picker modes */ -public enum DatePickerMode { - CALENDAR, - SPINNER, - DEFAULT -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DismissableDatePickerDialog.java b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DismissableDatePickerDialog.java deleted file mode 100644 index cfcc1fd3c77488..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/DismissableDatePickerDialog.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.modules.datepicker; - -import android.app.DatePickerDialog; -import android.content.Context; -import android.content.res.TypedArray; -import android.os.Build; -import android.util.AttributeSet; -import android.widget.DatePicker; -import androidx.annotation.Nullable; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - -public class DismissableDatePickerDialog extends DatePickerDialog { - - public DismissableDatePickerDialog( - Context context, - @Nullable DatePickerDialog.OnDateSetListener callback, - int year, - int monthOfYear, - int dayOfMonth) { - super(context, callback, year, monthOfYear, dayOfMonth); - fixSpinner(context, year, monthOfYear, dayOfMonth); - } - - public DismissableDatePickerDialog( - Context context, - int theme, - @Nullable DatePickerDialog.OnDateSetListener callback, - int year, - int monthOfYear, - int dayOfMonth) { - super(context, theme, callback, year, monthOfYear, dayOfMonth); - fixSpinner(context, year, monthOfYear, dayOfMonth); - } - - private void fixSpinner(Context context, int year, int month, int dayOfMonth) { - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N) { - try { - // Get the theme's android:datePickerMode - final int MODE_SPINNER = 2; - Class styleableClass = Class.forName("com.android.internal.R$styleable"); - Field datePickerStyleableField = styleableClass.getField("DatePicker"); - int[] datePickerStyleable = (int[]) datePickerStyleableField.get(null); - - final TypedArray a = - context.obtainStyledAttributes( - null, datePickerStyleable, android.R.attr.datePickerStyle, 0); - Field datePickerModeStyleableField = styleableClass.getField("DatePicker_datePickerMode"); - int datePickerModeStyleable = datePickerModeStyleableField.getInt(null); - final int mode = a.getInt(datePickerModeStyleable, MODE_SPINNER); - a.recycle(); - - if (mode == MODE_SPINNER) { - DatePicker datePicker = - (DatePicker) - findField(DatePickerDialog.class, DatePicker.class, "mDatePicker").get(this); - Class delegateClass = Class.forName("android.widget.DatePickerSpinnerDelegate"); - Field delegateField = findField(DatePicker.class, delegateClass, "mDelegate"); - Object delegate = delegateField.get(datePicker); - Class spinnerDelegateClass; - spinnerDelegateClass = Class.forName("android.widget.DatePickerSpinnerDelegate"); - - // In 7.0 Nougat for some reason the datePickerMode is ignored and the delegate is - // DatePickerClockDelegate - if (delegate.getClass() != spinnerDelegateClass) { - delegateField.set(datePicker, null); // throw out the DatePickerClockDelegate! - datePicker.removeAllViews(); // remove the DatePickerClockDelegate views - Method createSpinnerUIDelegate = - DatePicker.class.getDeclaredMethod( - "createSpinnerUIDelegate", - Context.class, - AttributeSet.class, - int.class, - int.class); - createSpinnerUIDelegate.setAccessible(true); - - // Instantiate a DatePickerSpinnerDelegate throughout createSpinnerUIDelegate method - delegate = - createSpinnerUIDelegate.invoke( - datePicker, context, null, android.R.attr.datePickerStyle, 0); - delegateField.set( - datePicker, delegate); // set the DatePicker.mDelegate to the spinner delegate - datePicker.setCalendarViewShown(false); - // Initialize the date for the DatePicker delegate again - datePicker.init(year, month, dayOfMonth, this); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - private static Field findField(Class objectClass, Class fieldClass, String expectedName) { - try { - Field field = objectClass.getDeclaredField(expectedName); - field.setAccessible(true); - return field; - } catch (NoSuchFieldException e) { - } // ignore - // search for it if it wasn't found under the expected ivar name - for (Field searchField : objectClass.getDeclaredFields()) { - if (searchField.getType() == fieldClass) { - searchField.setAccessible(true); - return searchField; - } - } - return null; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK b/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK index a5bb7403e8f6d5..84138c4394d914 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK @@ -34,7 +34,6 @@ rn_android_library( react_native_target("java/com/facebook/react/modules/camera:camera"), react_native_target("java/com/facebook/react/modules/clipboard:clipboard"), react_native_target("java/com/facebook/react/modules/core:core"), - react_native_target("java/com/facebook/react/modules/datepicker:datepicker"), react_native_target("java/com/facebook/react/modules/debug:debug"), react_native_target("java/com/facebook/react/modules/dialog:dialog"), react_native_target("java/com/facebook/react/modules/fresco:fresco"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java b/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java index 0dd8f31c54525c..34dc28005784dd 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java +++ b/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java @@ -23,7 +23,6 @@ import com.facebook.react.modules.blob.FileReaderModule; import com.facebook.react.modules.camera.ImageStoreManager; import com.facebook.react.modules.clipboard.ClipboardModule; -import com.facebook.react.modules.datepicker.DatePickerDialogModule; import com.facebook.react.modules.dialog.DialogModule; import com.facebook.react.modules.fresco.FrescoModule; import com.facebook.react.modules.i18nmanager.I18nManagerModule; @@ -72,7 +71,6 @@ FileReaderModule.class, AsyncStorageModule.class, ClipboardModule.class, - DatePickerDialogModule.class, DialogModule.class, FrescoModule.class, I18nManagerModule.class, @@ -117,8 +115,6 @@ public MainReactPackage(MainPackageConfig config) { return new AsyncStorageModule(context); case ClipboardModule.NAME: return new ClipboardModule(context); - case DatePickerDialogModule.FRAGMENT_TAG: - return new DatePickerDialogModule(context); case DialogModule.NAME: return new DialogModule(context); case FrescoModule.NAME: @@ -199,7 +195,6 @@ public ReactModuleInfoProvider getReactModuleInfoProvider() { FileReaderModule.class, AsyncStorageModule.class, ClipboardModule.class, - DatePickerDialogModule.class, DialogModule.class, FrescoModule.class, I18nManagerModule.class, diff --git a/index.js b/index.js index 545554b3b39ab0..7ce52d8a460371 100644 --- a/index.js +++ b/index.js @@ -55,7 +55,6 @@ import typeof AppState from './Libraries/AppState/AppState'; import typeof AsyncStorage from './Libraries/Storage/AsyncStorage'; import typeof BackHandler from './Libraries/Utilities/BackHandler'; import typeof Clipboard from './Libraries/Components/Clipboard/Clipboard'; -import typeof DatePickerAndroid from './Libraries/Components/DatePickerAndroid/DatePickerAndroid'; import typeof DeviceInfo from './Libraries/Utilities/DeviceInfo'; import typeof DevSettings from './Libraries/Utilities/DevSettings'; import typeof Dimensions from './Libraries/Utilities/Dimensions'; @@ -297,15 +296,6 @@ module.exports = { ); return require('./Libraries/Components/Clipboard/Clipboard'); }, - get DatePickerAndroid(): DatePickerAndroid { - warnOnce( - 'DatePickerAndroid-merged', - 'DatePickerAndroid has been merged with DatePickerIOS and will be removed in a future release. ' + - "It can now be installed and imported from '@react-native-community/datetimepicker' instead of 'react-native'. " + - 'See https://github.com/react-native-datetimepicker/datetimepicker', - ); - return require('./Libraries/Components/DatePickerAndroid/DatePickerAndroid'); - }, get DeviceInfo(): DeviceInfo { return require('./Libraries/Utilities/DeviceInfo'); }, @@ -717,4 +707,19 @@ if (__DEV__) { ); }, }); + /* $FlowFixMe[prop-missing] This is intentional: Flow will error when + * attempting to access DatePickerAndroid. */ + /* $FlowFixMe[invalid-export] This is intentional: Flow will error when + * attempting to access DatePickerAndroid. */ + Object.defineProperty(module.exports, 'DatePickerAndroid', { + configurable: true, + get() { + invariant( + false, + 'DatePickerAndroid has been removed from React Native. ' + + "It can now be installed and imported from '@react-native-community/datetimepicker' instead of 'react-native'. " + + 'See https://github.com/react-native-datetimepicker/datetimepicker', + ); + }, + }); }