Created
January 20, 2016 14:36
-
-
Save mkonicek/63da303d8c77438f8a16 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.facebook.catalyst.modules.dialog; | |
import javax.annotation.Nullable; | |
import java.util.Map; | |
import android.app.Activity; | |
import android.app.DatePickerDialog.OnDateSetListener; | |
import android.content.DialogInterface; | |
import android.content.DialogInterface.OnDismissListener; | |
import android.os.Bundle; | |
import android.support.v4.app.FragmentActivity; | |
import android.support.v4.app.FragmentManager; | |
import android.widget.DatePicker; | |
import com.facebook.react.bridge.Callback; | |
import com.facebook.react.bridge.NativeModule; | |
import com.facebook.react.bridge.ReactApplicationContext; | |
import com.facebook.react.bridge.ReactContextBaseJavaModule; | |
import com.facebook.react.bridge.ReactMethod; | |
import com.facebook.react.bridge.ReadableMap; | |
import com.facebook.react.common.MapBuilder; | |
import com.facebook.react.common.annotations.VisibleForTesting; | |
/** | |
* {@link NativeModule} that allows JS to show a native date picker dialog and get called back when | |
* the user selects a date. | |
*/ | |
public class DatePickerDialogModule extends ReactContextBaseJavaModule { | |
@VisibleForTesting | |
public static final String FRAGMENT_TAG = "DatePickerDialogAndroid"; | |
/* 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 ACTION_DATE_SET = "dateSetAction"; | |
/* package */ static final String ACTION_DISMISSED = "dismissedAction"; | |
private class DatePickerDialogListener implements OnDateSetListener, OnDismissListener { | |
private final Callback mCallback; | |
private boolean mCallbackConsumed = false; | |
public DatePickerDialogListener(final Callback callback) { | |
mCallback = callback; | |
} | |
@Override | |
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { | |
if (!mCallbackConsumed) { | |
if (getReactApplicationContext().hasActiveCatalystInstance()) { | |
mCallback.invoke(ACTION_DATE_SET, year, monthOfYear, dayOfMonth); | |
mCallbackConsumed = true; | |
} | |
} | |
} | |
@Override | |
public void onDismiss(DialogInterface dialog) { | |
if (!mCallbackConsumed) { | |
if (getReactApplicationContext().hasActiveCatalystInstance()) { | |
mCallback.invoke(ACTION_DISMISSED); | |
mCallbackConsumed = true; | |
} | |
} | |
} | |
} | |
public DatePickerDialogModule(ReactApplicationContext reactContext) { | |
super(reactContext); | |
} | |
@Override | |
public String getName() { | |
return "DatePickerDialogAndroid"; | |
} | |
@Override | |
public @Nullable Map<String, Object> getConstants() { | |
final Map<String, Object> constants = MapBuilder.newHashMap(); | |
constants.put(ACTION_DATE_SET, ACTION_DATE_SET); | |
constants.put(ACTION_DISMISSED, ACTION_DISMISSED); | |
return constants; | |
} | |
/** | |
* Show a date picker dialog. | |
* | |
* @param options a map containing options. Available keys are: | |
* | |
* <ul> | |
* <li>{@code date} (timestamp in milliseconds) the date to show by default</li> | |
* <li> | |
* {@code minDate} (timestamp in milliseconds) the minimum date the user should be allowed | |
* to select | |
* </li> | |
* <li> | |
* {@code maxDate} (timestamp in milliseconds) the maximum date the user should be allowed | |
* to select | |
* </li> | |
* </ul> | |
* | |
* @param error the error callback | |
* @param success the success callback; this will be invoked with parameters action, year, | |
* month (0-11), dayOfMonth, 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. | |
*/ | |
@ReactMethod | |
public void open( | |
@Nullable final ReadableMap options, | |
@Nullable final Callback error, | |
@Nullable final Callback success) { | |
Activity activity = getCurrentActivity(); | |
if (activity == null || !(activity instanceof FragmentActivity)) { | |
if (error != null) { | |
error.invoke("Tried to open datepicker dialog while not attached to a FragmentActivity"); | |
} | |
return; | |
} | |
FragmentManager fragmentManager = ((FragmentActivity) activity).getSupportFragmentManager(); | |
final DatePickerDialogFragment oldFragment = | |
(DatePickerDialogFragment) fragmentManager.findFragmentByTag(FRAGMENT_TAG); | |
if (oldFragment != null) { | |
oldFragment.dismiss(); | |
} | |
final DatePickerDialogFragment fragment = new DatePickerDialogFragment(); | |
if (options != null) { | |
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)); | |
} | |
fragment.setArguments(args); | |
} | |
if (success != null) { | |
final DatePickerDialogListener listener = new DatePickerDialogListener(success); | |
fragment.setOnDismissListener(listener); | |
fragment.setOnDateSetListener(listener); | |
} | |
fragment.show(fragmentManager, FRAGMENT_TAG); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment