<commit_before>/**
 * 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.views.drawer;

import android.os.Build;
import androidx.drawerlayout.widget.DrawerLayout;
import android.view.Gravity;
import android.view.View;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.drawer.events.DrawerClosedEvent;
import com.facebook.react.views.drawer.events.DrawerOpenedEvent;
import com.facebook.react.views.drawer.events.DrawerSlideEvent;
import com.facebook.react.views.drawer.events.DrawerStateChangedEvent;
import java.lang.reflect.Method;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * View Manager for {@link ReactDrawerLayout} components.
 */
@ReactModule(name = ReactDrawerLayoutManager.REACT_CLASS)
public class ReactDrawerLayoutManager extends ViewGroupManager<ReactDrawerLayout> {

  protected static final String REACT_CLASS = "AndroidDrawerLayout";

  public static final int OPEN_DRAWER = 1;
  public static final int CLOSE_DRAWER = 2;

  @Override
  public String getName() {
    return REACT_CLASS;
  }

  @Override
  protected void addEventEmitters(ThemedReactContext reactContext, ReactDrawerLayout view) {
    view.setDrawerListener(
        new DrawerEventEmitter(
            view,
            reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher()));
  }

  @Override
  protected ReactDrawerLayout createViewInstance(ThemedReactContext context) {
    return new ReactDrawerLayout(context);
  }

  @ReactProp(name = "drawerPosition")
  public void setDrawerPosition(ReactDrawerLayout view, Dynamic drawerPosition) {
    if (drawerPosition.isNull()) {
      view.setDrawerPosition(Gravity.START);
    } else if (drawerPosition.getType() == ReadableType.Number) {
      final int drawerPositionNum = drawerPosition.asInt();

      if (Gravity.START == drawerPositionNum || Gravity.END == drawerPositionNum) {
        view.setDrawerPosition(drawerPositionNum);
      } else {
        throw new JSApplicationIllegalArgumentException("Unknown drawerPosition " + drawerPositionNum);
      }
    } else if (drawerPosition.getType() == ReadableType.String) {
      final String drawerPositionStr = drawerPosition.asString();

      if (drawerPositionStr.equals("left")) {
        view.setDrawerPosition(Gravity.START);
      } else if (drawerPositionStr.equals("right")) {
        view.setDrawerPosition(Gravity.END);
      } else {
        throw new JSApplicationIllegalArgumentException("drawerPosition must be 'left' or 'right', received" + drawerPositionStr);
      }
    } else {
      throw new JSApplicationIllegalArgumentException("drawerPosition must be a string or int");
    }
  }

  @ReactProp(name = "drawerWidth", defaultFloat = Float.NaN)
  public void getDrawerWidth(ReactDrawerLayout view, float width) {
    int widthInPx = Float.isNaN(width) ?
        ReactDrawerLayout.DEFAULT_DRAWER_WIDTH : Math.round(PixelUtil.toPixelFromDIP(width));
    view.setDrawerWidth(widthInPx);
  }

  @ReactProp(name = "drawerLockMode")
  public void setDrawerLockMode(ReactDrawerLayout view, @Nullable String drawerLockMode) {
    if (drawerLockMode == null || "unlocked".equals(drawerLockMode)) {
      view.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    } else if ("locked-closed".equals(drawerLockMode)) {
      view.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    } else if ("locked-open".equals(drawerLockMode)) {
      view.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
    } else {
      throw new JSApplicationIllegalArgumentException("Unknown drawerLockMode " + drawerLockMode);
    }
  }

  @Override
  public void setElevation(ReactDrawerLayout view, float elevation) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      // Facebook is using an older version of the support lib internally that doesn't support
      // setDrawerElevation so we invoke it using reflection.
      // TODO: Call the method directly when this is no longer needed.
      try {
        Method method = ReactDrawerLayout.class.getMethod("setDrawerElevation", float.class);
        method.invoke(view, PixelUtil.toPixelFromDIP(elevation));
      } catch (Exception ex) {
        FLog.w(
            ReactConstants.TAG,
            "setDrawerElevation is not available in this version of the support lib.",
            ex);
      }
    }
  }

  @Override
  public boolean needsCustomLayoutForChildren() {
    // Return true, since DrawerLayout will lay out it's own children.
    return true;
  }

  @Override
  public @Nullable Map<String, Integer> getCommandsMap() {
    return MapBuilder.of("openDrawer", OPEN_DRAWER, "closeDrawer", CLOSE_DRAWER);
  }

  @Override
  public void receiveCommand(
      ReactDrawerLayout root,
      int commandId,
      @Nullable ReadableArray args) {
    switch (commandId) {
      case OPEN_DRAWER:
        root.openDrawer();
        break;
      case CLOSE_DRAWER:
        root.closeDrawer();
        break;
    }
  }

  @Override
  public @Nullable Map getExportedViewConstants() {
    return MapBuilder.of(
        "DrawerPosition",<commit_msg>Support commands as strings in AndroidDrawerLayout<commit_after>/**
 * 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.views.drawer;

import android.os.Build;
import androidx.drawerlayout.widget.DrawerLayout;
import android.view.Gravity;
import android.view.View;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.drawer.events.DrawerClosedEvent;
import com.facebook.react.views.drawer.events.DrawerOpenedEvent;
import com.facebook.react.views.drawer.events.DrawerSlideEvent;
import com.facebook.react.views.drawer.events.DrawerStateChangedEvent;
import java.lang.reflect.Method;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * View Manager for {@link ReactDrawerLayout} components.
 */
@ReactModule(name = ReactDrawerLayoutManager.REACT_CLASS)
public class ReactDrawerLayoutManager extends ViewGroupManager<ReactDrawerLayout> {

  protected static final String REACT_CLASS = "AndroidDrawerLayout";

  public static final int OPEN_DRAWER = 1;
  public static final int CLOSE_DRAWER = 2;

  @Override
  public String getName() {
    return REACT_CLASS;
  }

  @Override
  protected void addEventEmitters(ThemedReactContext reactContext, ReactDrawerLayout view) {
    view.setDrawerListener(
        new DrawerEventEmitter(
            view,
            reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher()));
  }

  @Override
  protected ReactDrawerLayout createViewInstance(ThemedReactContext context) {
    return new ReactDrawerLayout(context);
  }

  @ReactProp(name = "drawerPosition")
  public void setDrawerPosition(ReactDrawerLayout view, Dynamic drawerPosition) {
    if (drawerPosition.isNull()) {
      view.setDrawerPosition(Gravity.START);
    } else if (drawerPosition.getType() == ReadableType.Number) {
      final int drawerPositionNum = drawerPosition.asInt();

      if (Gravity.START == drawerPositionNum || Gravity.END == drawerPositionNum) {
        view.setDrawerPosition(drawerPositionNum);
      } else {
        throw new JSApplicationIllegalArgumentException("Unknown drawerPosition " + drawerPositionNum);
      }
    } else if (drawerPosition.getType() == ReadableType.String) {
      final String drawerPositionStr = drawerPosition.asString();

      if (drawerPositionStr.equals("left")) {
        view.setDrawerPosition(Gravity.START);
      } else if (drawerPositionStr.equals("right")) {
        view.setDrawerPosition(Gravity.END);
      } else {
        throw new JSApplicationIllegalArgumentException("drawerPosition must be 'left' or 'right', received" + drawerPositionStr);
      }
    } else {
      throw new JSApplicationIllegalArgumentException("drawerPosition must be a string or int");
    }
  }

  @ReactProp(name = "drawerWidth", defaultFloat = Float.NaN)
  public void getDrawerWidth(ReactDrawerLayout view, float width) {
    int widthInPx = Float.isNaN(width) ?
        ReactDrawerLayout.DEFAULT_DRAWER_WIDTH : Math.round(PixelUtil.toPixelFromDIP(width));
    view.setDrawerWidth(widthInPx);
  }

  @ReactProp(name = "drawerLockMode")
  public void setDrawerLockMode(ReactDrawerLayout view, @Nullable String drawerLockMode) {
    if (drawerLockMode == null || "unlocked".equals(drawerLockMode)) {
      view.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
    } else if ("locked-closed".equals(drawerLockMode)) {
      view.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
    } else if ("locked-open".equals(drawerLockMode)) {
      view.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
    } else {
      throw new JSApplicationIllegalArgumentException("Unknown drawerLockMode " + drawerLockMode);
    }
  }

  @Override
  public void setElevation(ReactDrawerLayout view, float elevation) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      // Facebook is using an older version of the support lib internally that doesn't support
      // setDrawerElevation so we invoke it using reflection.
      // TODO: Call the method directly when this is no longer needed.
      try {
        Method method = ReactDrawerLayout.class.getMethod("setDrawerElevation", float.class);
        method.invoke(view, PixelUtil.toPixelFromDIP(elevation));
      } catch (Exception ex) {
        FLog.w(
            ReactConstants.TAG,
            "setDrawerElevation is not available in this version of the support lib.",
            ex);
      }
    }
  }

  @Override
  public boolean needsCustomLayoutForChildren() {
    // Return true, since DrawerLayout will lay out it's own children.
    return true;
  }

  @Override
  public @Nullable Map<String, Integer> getCommandsMap() {
    return MapBuilder.of("openDrawer", OPEN_DRAWER, "closeDrawer", CLOSE_DRAWER);
  }

  @Override
  public void receiveCommand(
      ReactDrawerLayout root,
      int commandId,
      @Nullable ReadableArray args) {
    switch (commandId) {
      case OPEN_DRAWER:
        root.openDrawer();
        break;
      case CLOSE_DRAWER:
        root.closeDrawer();
        break;
    }
  }

  @Override
  public void receiveCommand(
      ReactDrawerLayout root,
      String commandId,
      @Nullable ReadableArray args) {
    switch (commandId) {
      case "openDrawer":
        root.openDrawer();
        break;
      case "closeDrawer":
        root.closeDrawer();
        break;
    }
  }

  @Override
  public @Nullable Map getExportedViewConstants() {
    return MapBuilder.of(
        "DrawerPosition",
{'fraction_non_alphanumeric': 0.09358354502991068, 'fraction_numerical': 0.00032778824879128084, 'mean_word_length': 3.993453355155483, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3114303', 'n_tokens_mistral': 3563, 'n_tokens_neox': 3544, 'n_words': 769}