Skip to content

Instantly share code, notes, and snippets.

@mkonicek
Created January 20, 2016 14:36
Show Gist options
  • Save mkonicek/63da303d8c77438f8a16 to your computer and use it in GitHub Desktop.
Save mkonicek/63da303d8c77438f8a16 to your computer and use it in GitHub Desktop.
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