Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54468190 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Implemented context menu actions."

parents a3f8a79f 6c2357ae
Loading
Loading
Loading
Loading
+53 −12
Original line number Diff line number Diff line
@@ -21,14 +21,23 @@ import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;

/** Floating menu which presents contact options available to the contact. */
public class ContextMenu extends LinearLayout {

  private SpeedDialUiItem speedDialUiItem;
  private ContextMenuItemListener listener;

  private TextView videoView;
  private TextView smsView;

  private SpeedDialUiItem speedDialUiItem;
  private Channel voiceChannel;
  private Channel videoChannel;
  private Channel smsChannel;

  public ContextMenu(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
  }
@@ -36,12 +45,14 @@ public class ContextMenu extends LinearLayout {
  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    findViewById(R.id.voice_call_container)
        .setOnClickListener(v -> listener.placeVoiceCall(speedDialUiItem));
    findViewById(R.id.video_call_container)
        .setOnClickListener(v -> listener.placeVideoCall(speedDialUiItem));
    findViewById(R.id.send_message_container)
        .setOnClickListener(v -> listener.openSmsConversation(speedDialUiItem));

    videoView = findViewById(R.id.video_call_container);
    videoView.setOnClickListener(v -> placeVideoCall());

    smsView = findViewById(R.id.send_message_container);
    smsView.setOnClickListener(v -> listener.openSmsConversation(smsChannel.number()));

    findViewById(R.id.voice_call_container).setOnClickListener(v -> placeVoiceCall());
    findViewById(R.id.remove_container)
        .setOnClickListener(v -> listener.removeFavoriteContact(speedDialUiItem));
    findViewById(R.id.contact_info_container)
@@ -65,6 +76,15 @@ public class ContextMenu extends LinearLayout {
    setX((float) (childLocation[0] + .5 * childLayout.getWidth() - .5 * getWidth()));
    setY(childLocation[1] - parentLocation[1] + childLayout.getHeight());

    voiceChannel = speedDialUiItem.getDeterministicVoiceChannel();
    videoChannel = speedDialUiItem.getDeterministicVideoChannel();
    videoView.setVisibility(
        videoChannel == null && !speedDialUiItem.hasVideoChannels() ? View.GONE : View.VISIBLE);

    // TODO(calderwoodra): disambig dialog for texts?
    smsChannel = voiceChannel;
    smsView.setVisibility(smsChannel == null ? View.GONE : View.VISIBLE);

    // TODO(calderwoodra): a11y
    // TODO(calderwoodra): animate this similar to the bubble menu
    setVisibility(View.VISIBLE);
@@ -81,6 +101,22 @@ public class ContextMenu extends LinearLayout {
    }
  }

  private void placeVoiceCall() {
    if (voiceChannel == null) {
      listener.disambiguateCall(speedDialUiItem);
    } else {
      listener.placeCall(voiceChannel);
    }
  }

  private void placeVideoCall() {
    if (videoChannel == null) {
      listener.disambiguateCall(speedDialUiItem);
    } else {
      listener.placeCall(videoChannel);
    }
  }

  public boolean isVisible() {
    return getVisibility() == View.VISIBLE;
  }
@@ -88,14 +124,19 @@ public class ContextMenu extends LinearLayout {
  /** Listener to report user clicks on menu items. */
  public interface ContextMenuItemListener {

    /** Called when the user selects "voice call" option from the context menu. */
    void placeVoiceCall(SpeedDialUiItem speedDialUiItem);
    /** Called when the user selects "voice call" or "video call" option from the context menu. */
    void placeCall(Channel channel);

    /** Called when the user selects "video call" option from the context menu. */
    void placeVideoCall(SpeedDialUiItem speedDialUiItem);
    /**
     * Called when the user selects "voice call" or "video call" option from the context menu, but
     * it's not clear which channel they want to call.
     *
     * <p>TODO(calderwoodra): discuss with product how we want to handle these cases
     */
    void disambiguateCall(SpeedDialUiItem speedDialUiItem);

    /** Called when the user selects "send message" from the context menu. */
    void openSmsConversation(SpeedDialUiItem speedDialUiItem);
    void openSmsConversation(String number);

    /** Called when the user selects "remove" from the context menu. */
    void removeFavoriteContact(SpeedDialUiItem speedDialUiItem);
+53 −12
Original line number Diff line number Diff line
@@ -17,8 +17,10 @@
package com.android.dialer.speeddial;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
@@ -49,6 +51,7 @@ import com.android.dialer.speeddial.draghelper.SpeedDialItemTouchHelperCallback;
import com.android.dialer.speeddial.draghelper.SpeedDialLayoutManager;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import com.android.dialer.speeddial.loader.UiItemLoaderComponent;
import com.android.dialer.util.IntentUtil;
import com.google.common.collect.ImmutableList;

/**
@@ -78,8 +81,6 @@ public class SpeedDialFragment extends Fragment {
   */
  private boolean updateSpeedDialItemsOnResume = true;

  private FavoriteContactsListener favoritesListener;

  public static SpeedDialFragment newInstance() {
    return new SpeedDialFragment();
  }
@@ -103,14 +104,14 @@ public class SpeedDialFragment extends Fragment {
    // Setup our RecyclerView
    SpeedDialLayoutManager layoutManager =
        new SpeedDialLayoutManager(getContext(), 3 /* spanCount */);
    favoritesListener =
    FavoriteContactsListener favoritesListener =
        new SpeedDialFavoritesListener(
            getActivity(),
            getChildFragmentManager(),
            rootLayout,
            contextMenu,
            contextMenuBackground,
            new SpeedDialContextMenuItemListener(),
            new SpeedDialContextMenuItemListener(getActivity(), getChildFragmentManager()),
            layoutManager);
    adapter =
        new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener);
@@ -181,6 +182,22 @@ public class SpeedDialFragment extends Fragment {
    }
  }

  @Override
  public void onPause() {
    super.onPause();
    contextMenu.hideMenu();
    contextMenuBackground.setVisibility(View.GONE);
  }

  @Override
  public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if (hidden) {
      contextMenu.hideMenu();
      contextMenuBackground.setVisibility(View.GONE);
    }
  }

  private class SpeedDialFragmentHeaderListener implements SpeedDialHeaderListener {

    @Override
@@ -294,29 +311,53 @@ public class SpeedDialFragment extends Fragment {

  private static final class SpeedDialContextMenuItemListener implements ContextMenuItemListener {

    private final FragmentActivity activity;
    private final FragmentManager childFragmentManager;

    SpeedDialContextMenuItemListener(
        FragmentActivity activity, FragmentManager childFragmentManager) {
      this.activity = activity;
      this.childFragmentManager = childFragmentManager;
    }

    @Override
    public void placeVoiceCall(SpeedDialUiItem speedDialUiItem) {
      // TODO(calderwoodra)
    public void disambiguateCall(SpeedDialUiItem speedDialUiItem) {
      // TODO(calderwoodra): show only video or voice channels in the disambig dialog
      DisambigDialog.show(speedDialUiItem, childFragmentManager);
    }

    @Override
    public void placeVideoCall(SpeedDialUiItem speedDialUiItem) {
      // TODO(calderwoodra)
    public void placeCall(Channel channel) {
      if (channel.technology() == Channel.DUO) {
        Logger.get(activity)
            .logImpression(DialerImpression.Type.LIGHTBRINGER_VIDEO_REQUESTED_FOR_FAVORITE_CONTACT);
        Intent intent = DuoComponent.get(activity).getDuo().getIntent(activity, channel.number());
        activity.startActivityForResult(intent, ActivityRequestCodes.DIALTACTS_DUO);
        return;
      }
      PreCall.start(
          activity,
          new CallIntentBuilder(channel.number(), CallInitiationType.Type.SPEED_DIAL)
              .setIsVideoCall(channel.isVideoTechnology()));
    }

    @Override
    public void openSmsConversation(SpeedDialUiItem speedDialUiItem) {
      // TODO(calderwoodra)
    public void openSmsConversation(String number) {
      activity.startActivity(IntentUtil.getSendSmsIntent(number));
    }

    @Override
    public void removeFavoriteContact(SpeedDialUiItem speedDialUiItem) {
      // TODO(calderwoodra)
      // TODO(calderwoodra): implement remove
    }

    @Override
    public void openContactInfo(SpeedDialUiItem speedDialUiItem) {
      // TODO(calderwoodra)
      activity.startActivity(
          new Intent(
              Intent.ACTION_VIEW,
              Uri.withAppendedPath(
                  Contacts.CONTENT_URI, String.valueOf(speedDialUiItem.contactId()))));
    }
  }
}
+58 −0
Original line number Diff line number Diff line
@@ -118,6 +118,64 @@ public abstract class SpeedDialUiItem {
    return builder.build();
  }

  /**
   * Returns a video channel if there is exactly one video channel or the default channel is a video
   * channel.
   */
  @Nullable
  public Channel getDeterministicVideoChannel() {
    if (defaultChannel() != null && defaultChannel().isVideoTechnology()) {
      return defaultChannel();
    }

    Channel videoChannel = null;
    for (Channel channel : channels()) {
      if (channel.isVideoTechnology()) {
        if (videoChannel != null) {
          // We found two video channels, so we can't determine which one is correct..
          return null;
        }
        videoChannel = channel;
      }
    }
    // Only found one channel, so return it
    return videoChannel;
  }

  /** Returns true if any channels are video channels. */
  public boolean hasVideoChannels() {
    for (Channel channel : channels()) {
      if (channel.isVideoTechnology()) {
        return true;
      }
    }
    return false;
  }

  /**
   * Returns a voice channel if there is exactly one voice channel or the default channel is a voice
   * channel.
   */
  @Nullable
  public Channel getDeterministicVoiceChannel() {
    if (defaultChannel() != null && !defaultChannel().isVideoTechnology()) {
      return defaultChannel();
    }

    Channel voiceChannel = null;
    for (Channel channel : channels()) {
      if (!channel.isVideoTechnology()) {
        if (voiceChannel != null) {
          // We found two voice channels, so we can't determine which one is correct..
          return null;
        }
        voiceChannel = channel;
      }
    }
    // Only found one channel, so return it
    return voiceChannel;
  }

  /**
   * The id of the corresponding SpeedDialEntry. Null if the UI item does not have an entry, for
   * example suggested contacts (isStarred() will also be false)
+30 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2017 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License
  -->

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <shape android:shape="oval">
      <solid android:color="@color/secondary_text_color"/>
      <size android:width="24dp" android:height="24dp"/>
    </shape>
  </item>
  <item
      android:width="24dp"
      android:height="24dp"
      android:gravity="center"
      android:drawable="@drawable/product_logo_avatar_anonymous_white_color_120"/>
</layer-list>
 No newline at end of file
+0 −21
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
 ~ Copyright (C) 2017 The Android Open Source Project
 ~
 ~ Licensed under the Apache License, Version 2.0 (the "License");
 ~ you may not use this file except in compliance with the License.
 ~ You may obtain a copy of the License at
 ~
 ~      http://www.apache.org/licenses/LICENSE-2.0
 ~
 ~ Unless required by applicable law or agreed to in writing, software
 ~ distributed under the License is distributed on an "AS IS" BASIS,
 ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ~ See the License for the specific language governing permissions and
 ~ limitations under the License
 -->
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/add_favorite_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
 No newline at end of file
Loading