blob: 00af7511b8c18b2d2421cfd3f8fe4c9bd1c94818 [file] [log] [blame]
/*
* Copyright (C) 2015 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.
*/
package com.android.messaging.ui.conversationsettings;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.android.messaging.R;
import com.android.messaging.datamodel.DataModel;
import com.android.messaging.datamodel.binding.Binding;
import com.android.messaging.datamodel.binding.BindingBase;
import com.android.messaging.datamodel.data.ParticipantData;
import com.android.messaging.datamodel.data.ParticipantListItemData;
import com.android.messaging.datamodel.data.PeopleAndOptionsData;
import com.android.messaging.datamodel.data.PeopleAndOptionsData.PeopleAndOptionsDataListener;
import com.android.messaging.datamodel.data.PeopleOptionsItemData;
import com.android.messaging.datamodel.data.PersonItemData;
import com.android.messaging.ui.CompositeAdapter;
import com.android.messaging.ui.PersonItemView;
import com.android.messaging.ui.UIIntents;
import com.android.messaging.ui.conversation.ConversationActivity;
import com.android.messaging.util.NotificationsUtil;
import com.android.messaging.util.Assert;
import java.util.ArrayList;
import java.util.List;
/**
* Shows a list of participants of a conversation and displays options.
*/
public class PeopleAndOptionsFragment extends Fragment
implements PeopleAndOptionsDataListener, PeopleOptionsItemView.HostInterface {
private ListView mListView;
private OptionsListAdapter mOptionsListAdapter;
private PeopleListAdapter mPeopleListAdapter;
private List<ParticipantData> mOtherParticipants;
private final Binding<PeopleAndOptionsData> mBinding =
BindingBase.createBinding(this);
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding.getData().init(getLoaderManager(), mBinding);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.people_and_options_fragment, container, false);
mListView = (ListView) view.findViewById(android.R.id.list);
mPeopleListAdapter = new PeopleListAdapter(getActivity());
mOptionsListAdapter = new OptionsListAdapter();
final CompositeAdapter compositeAdapter = new CompositeAdapter(getActivity());
compositeAdapter.addPartition(new PeopleAndOptionsPartition(mOptionsListAdapter,
R.string.general_settings_title, false));
compositeAdapter.addPartition(new PeopleAndOptionsPartition(mPeopleListAdapter,
R.string.participant_list_title, true));
mListView.setAdapter(compositeAdapter);
return view;
}
@Override
public void onDestroy() {
super.onDestroy();
mBinding.unbind();
}
public void setConversationId(final String conversationId) {
Assert.isTrue(getView() == null);
Assert.notNull(conversationId);
mBinding.bind(DataModel.get().createPeopleAndOptionsData(conversationId, getActivity(),
this));
}
@Override
public void onOptionsCursorUpdated(final PeopleAndOptionsData data, final Cursor cursor) {
Assert.isTrue(cursor == null || cursor.getCount() == 1);
mBinding.ensureBound(data);
mOptionsListAdapter.swapCursor(cursor);
}
@Override
public void onParticipantsListLoaded(final PeopleAndOptionsData data,
final List<ParticipantData> participants) {
mBinding.ensureBound(data);
mPeopleListAdapter.updateParticipants(participants);
mOtherParticipants = participants;
final ParticipantData otherParticipant = participants.size() == 1 ?
participants.get(0) : null;
mOptionsListAdapter.setOtherParticipant(otherParticipant);
}
@Override
public void onOptionsItemViewClicked(final PeopleOptionsItemData item) {
switch (item.getItemId()) {
case PeopleOptionsItemData.SETTING_NOTIFICATION:
ArrayList<String> participantsNames = new ArrayList<String>();
for (ParticipantData participant : mOtherParticipants) {
participantsNames.add(participant.getDisplayName(true));
}
NotificationsUtil.createNotificationChannelGroup(getActivity(),
NotificationsUtil.CONVERSATION_GROUP_NAME,
R.string.notification_channel_messages_title);
NotificationsUtil.createNotificationChannel(getActivity(),
mBinding.getData().getConversationId(),
String.join(", ", participantsNames),
NotificationManager.IMPORTANCE_DEFAULT,
NotificationsUtil.CONVERSATION_GROUP_NAME);
Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getContext().getPackageName());
startActivity(intent);
break;
case PeopleOptionsItemData.SETTING_BLOCKED:
if (item.getOtherParticipant().isBlocked()) {
mBinding.getData().setDestinationBlocked(mBinding, false);
break;
}
final Resources res = getResources();
final Activity activity = getActivity();
new AlertDialog.Builder(activity)
.setTitle(res.getString(R.string.block_confirmation_title,
item.getOtherParticipant().getDisplayDestination()))
.setMessage(res.getString(R.string.block_confirmation_message))
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
mBinding.getData().setDestinationBlocked(mBinding, true);
activity.setResult(ConversationActivity.FINISH_RESULT_CODE);
activity.finish();
}
})
.create()
.show();
break;
}
}
/**
* A simple adapter that takes a conversation metadata cursor and binds
* PeopleAndOptionsItemViews to individual COLUMNS of the first cursor record. (Note
* that this is not a CursorAdapter because it treats individual columns of the cursor as
* separate options to display for the conversation, e.g. notification settings).
*/
private class OptionsListAdapter extends BaseAdapter {
private Cursor mOptionsCursor;
private ParticipantData mOtherParticipantData;
public Cursor swapCursor(final Cursor newCursor) {
final Cursor oldCursor = mOptionsCursor;
if (newCursor != oldCursor) {
mOptionsCursor = newCursor;
notifyDataSetChanged();
}
return oldCursor;
}
public void setOtherParticipant(final ParticipantData participantData) {
if (mOtherParticipantData != participantData) {
mOtherParticipantData = participantData;
notifyDataSetChanged();
}
}
@Override
public int getCount() {
int count = PeopleOptionsItemData.SETTINGS_COUNT;
if (mOtherParticipantData == null) {
count--;
}
return mOptionsCursor == null ? 0 : count;
}
@Override
public Object getItem(final int position) {
return null;
}
@Override
public long getItemId(final int position) {
return 0;
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
final PeopleOptionsItemView itemView;
if (convertView != null && convertView instanceof PeopleOptionsItemView) {
itemView = (PeopleOptionsItemView) convertView;
} else {
final LayoutInflater inflater = (LayoutInflater) getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
itemView = (PeopleOptionsItemView)
inflater.inflate(R.layout.people_options_item_view, parent, false);
}
mOptionsCursor.moveToFirst();
itemView.bind(mOptionsCursor, position, mOtherParticipantData,
PeopleAndOptionsFragment.this);
return itemView;
}
}
/**
* An adapter that takes a list of ParticipantData and displays them as a list of
* ParticipantListItemViews.
*/
private class PeopleListAdapter extends ArrayAdapter<ParticipantData> {
public PeopleListAdapter(final Context context) {
super(context, R.layout.people_list_item_view, new ArrayList<ParticipantData>());
}
public void updateParticipants(final List<ParticipantData> newList) {
clear();
addAll(newList);
notifyDataSetChanged();
}
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
PersonItemView itemView;
final ParticipantData item = getItem(position);
if (convertView != null && convertView instanceof PersonItemView) {
itemView = (PersonItemView) convertView;
} else {
final LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
itemView = (PersonItemView) inflater.inflate(R.layout.people_list_item_view, parent,
false);
}
final ParticipantListItemData itemData =
DataModel.get().createParticipantListItemData(item);
itemView.bind(itemData);
// Any click on the row should have the same effect as clicking the avatar icon
final PersonItemView itemViewClosure = itemView;
itemView.setListener(new PersonItemView.PersonItemViewListener() {
@Override
public void onPersonClicked(final PersonItemData data) {
itemViewClosure.performClickOnAvatar();
}
@Override
public boolean onPersonLongClicked(final PersonItemData data) {
if (mBinding.isBound()) {
final CopyContactDetailDialog dialog = new CopyContactDetailDialog(
getContext(), data.getDetails());
dialog.show();
return true;
}
return false;
}
});
return itemView;
}
}
/**
* Represents a partition/section in the People & Options list (e.g. "general options" and
* "people in this conversation" sections).
*/
private class PeopleAndOptionsPartition extends CompositeAdapter.Partition {
private final int mHeaderResId;
private final boolean mNeedDivider;
public PeopleAndOptionsPartition(final BaseAdapter adapter, final int headerResId,
final boolean needDivider) {
super(true /* showIfEmpty */, true /* hasHeader */, adapter);
mHeaderResId = headerResId;
mNeedDivider = needDivider;
}
@Override
public View getHeaderView(final View convertView, final ViewGroup parentView) {
View view = null;
if (convertView != null && convertView.getId() == R.id.people_and_options_header) {
view = convertView;
} else {
view = LayoutInflater.from(getActivity()).inflate(
R.layout.people_and_options_section_header, parentView, false);
}
final TextView text = (TextView) view.findViewById(R.id.header_text);
final View divider = view.findViewById(R.id.divider);
text.setText(mHeaderResId);
divider.setVisibility(mNeedDivider ? View.VISIBLE : View.GONE);
return view;
}
}
}