package com.netease.nim.uikit.team.activity;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.netease.nim.uikit.NimUIKit;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.cache.SimpleCallback;
import com.netease.nim.uikit.cache.TeamDataCache;
import com.netease.nim.uikit.common.activity.UI;
import com.netease.nim.uikit.common.adapter.TAdapterDelegate;
import com.netease.nim.uikit.common.adapter.TViewHolder;
import com.netease.nim.uikit.common.ui.dialog.DialogMaker;
import com.netease.nim.uikit.common.ui.widget.SwitchButton;
import com.netease.nim.uikit.common.util.sys.NetworkUtil;
import com.netease.nim.uikit.contact.core.item.ContactIdFilter;
import com.netease.nim.uikit.contact_selector.activity.ContactSelectActivity;
import com.netease.nim.uikit.model.ToolBarOptions;
import com.netease.nim.uikit.team.adapter.TeamMemberAdapter;
import com.netease.nim.uikit.team.model.TeamExtras;
import com.netease.nim.uikit.team.model.TeamRequestCode;
import com.netease.nim.uikit.team.ui.TeamInfoGridView;
import com.netease.nim.uikit.team.viewholder.TeamMemberHolder;
import com.netease.nim.uikit.uinfo.UserInfoHelper;
import com.netease.nim.uikit.uinfo.UserInfoObservable;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.RequestCallback;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.team.TeamService;
import com.netease.nimlib.sdk.team.constant.TeamFieldEnum;
import com.netease.nimlib.sdk.team.constant.TeamMemberType;
import com.netease.nimlib.sdk.team.model.Team;
import com.netease.nimlib.sdk.team.model.TeamMember;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 讨论组资料页
* <p/>
* Created by huangjun on 2015/3/3.
*/
public class NormalTeamInfoActivity extends UI implements OnClickListener, TAdapterDelegate,
TeamMemberAdapter.RemoveMemberCallback, TeamMemberAdapter.AddMemberCallback, TeamMemberHolder.TeamMemberHolderEventListener {
// constant
private static final String TAG = "TeamInfoActivity";
private static final int REQUEST_CODE_NAME = 101;
private static final int REQUEST_CODE_CONTACT_SELECT = 102;
private static final String EXTRA_ID = "EXTRA_ID";
private static final String KEY_MSG_NOTICE = "msg_notice";
// adapter & data source
private TeamMemberAdapter adapter;
private String teamId;
private Team team;
private String creator;
private List<String> memberAccounts;
private List<TeamMemberAdapter.TeamMemberItem> dataSource;
private UserInfoObservable.UserInfoObserver userInfoObserver;
// view
private TextView teamNameTextView;
private TeamInfoGridView gridView;
private ViewGroup toggleLayout;
private SwitchButton noticeBtn;
// state
private boolean isSelfAdmin = false;
private int teamCapacity = 200; // 群人数上限,暂定
/**
* 启动群资料页
*
* @param context 调用方Activity
* @param id 讨论组ID
*/
public static void start(Context context, String id) {
Intent intent = new Intent();
intent.putExtra(EXTRA_ID, id);
intent.setClass(context, NormalTeamInfoActivity.class);
((Activity) context).startActivityForResult(intent, TeamRequestCode.REQUEST_CODE);
}
/**
* ************************ TAdapterDelegate **************************
*/
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public Class<? extends TViewHolder> viewHolderAtPosition(int position) {
return TeamMemberHolder.class;
}
@Override
public boolean enabled(int position) {
return false;
}
/**
* ***************************** Life cycle *****************************
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nim_team_info_activity);
ToolBarOptions options = new ToolBarOptions();
setToolBar(R.id.toolbar, options);
parseIntentData();
initToggleBtn();
loadTeamInfo();
initAdapter();
findViews();
requestMembers();
registerObservers(true);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
registerObservers(false);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_CONTACT_SELECT && resultCode == Activity.RESULT_OK) {
final ArrayList<String> selected = data.getStringArrayListExtra(ContactSelectActivity.RESULT_DATA);
if (selected != null && !selected.isEmpty()) {
addMembersToTeam(selected);
}
}
}
/**
* ************************** 群信息变更监听 **************************
*/
/**
* 注册群信息更新监听
*
* @param register
*/
private void registerObservers(boolean register) {
if (register) {
TeamDataCache.getInstance().registerTeamDataChangedObserver(teamDataObserver);
TeamDataCache.getInstance().registerTeamMemberDataChangedObserver(teamMemberObserver);
} else {
TeamDataCache.getInstance().unregisterTeamDataChangedObserver(teamDataObserver);
TeamDataCache.getInstance().unregisterTeamMemberDataChangedObserver(teamMemberObserver);
}
registerUserInfoChangedObserver(register);
}
TeamDataCache.TeamDataChangedObserver teamDataObserver = new TeamDataCache.TeamDataChangedObserver() {
@Override
public void onUpdateTeams(List<Team> teams) {
for (Team team : teams) {
if (team.getId().equals(teamId)) {
updateTeamInfo(team);
break;
}
}
}
@Override
public void onRemoveTeam(Team team) {
if (team.getId().equals(teamId)) {
NormalTeamInfoActivity.this.team = team;
}
}
};
TeamDataCache.TeamMemberDataChangedObserver teamMemberObserver = new TeamDataCache.TeamMemberDataChangedObserver() {
@Override
public void onUpdateTeamMember(List<TeamMember> members) {
List<String> accounts = new ArrayList<>();
for (TeamMember m : members) {
if (m.getTid().equals(teamId)) {
accounts.add(m.getAccount());
}
}
if (!accounts.isEmpty()) {
addMember(accounts, false);
}
}
@Override
public void onRemoveTeamMember(TeamMember member) {
if (member.getTid().equals(teamId)) {
removeMember(member.getAccount());
}
}
};
private void parseIntentData() {
teamId = getIntent().getStringExtra(EXTRA_ID);
}
private void initToggleBtn() {
toggleLayout = findView(R.id.toggle_layout);
noticeBtn = addToggleItemView(KEY_MSG_NOTICE, R.string.team_notification_config, true);
}
private void setToggleBtn(Team team) {
if (noticeBtn != null) {
noticeBtn.setCheck(!team.mute());
}
}
private SwitchButton addToggleItemView(String key, int titleResId, boolean initState) {
ViewGroup vp = (ViewGroup) getLayoutInflater().inflate(R.layout.nim_user_profile_toggle_item, null);
ViewGroup.LayoutParams vlp = new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, (int) getResources().getDimension(R.dimen.isetting_item_height));
vp.setLayoutParams(vlp);
TextView titleText = ((TextView) vp.findViewById(R.id.user_profile_title));
titleText.setText(titleResId);
SwitchButton switchButton = (SwitchButton) vp.findViewById(R.id.user_profile_toggle);
switchButton.setCheck(initState);
switchButton.setOnChangedListener(onChangedListener);
switchButton.setTag(key);
toggleLayout.addView(vp);
return switchButton;
}
private SwitchButton.OnChangedListener onChangedListener = new SwitchButton.OnChangedListener() {
@Override
public void OnChanged(View v, final boolean checkState) {
if (!NetworkUtil.isNetAvailable(NormalTeamInfoActivity.this)) {
Toast.makeText(NormalTeamInfoActivity.this, R.string.network_is_not_available, Toast.LENGTH_SHORT).show();
noticeBtn.setCheck(!checkState);
return;
}
NIMClient.getService(TeamService.class).muteTeam(team.getId(), !checkState).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
if (checkState) {
Toast.makeText(NormalTeamInfoActivity.this, "开启消息提醒", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(NormalTeamInfoActivity.this, "关闭消息提醒", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailed(int code) {
if (code == 408) {
Toast.makeText(NormalTeamInfoActivity.this, R.string.network_is_not_available, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(NormalTeamInfoActivity.this, "on failed:" + code, Toast.LENGTH_SHORT).show();
}
noticeBtn.setCheck(!checkState);
}
@Override
public void onException(Throwable exception) {
}
});
}
};
private void loadTeamInfo() {
creator = "";
Team t = TeamDataCache.getInstance().getTeamById(teamId);
if (t != null) {
updateTeamInfo(t);
} else {
TeamDataCache.getInstance().fetchTeamById(teamId, new SimpleCallback<Team>() {
@Override
public void onResult(boolean success, Team result) {
if (success && result != null) {
updateTeamInfo(result);
} else {
onGetTeamInfoFailed();
}
}
});
}
}
private void updateTeamInfo(Team t) {
if (t == null) {
return;
}
team = t;
// title
String teamName = team.getName();
setTitle(teamName);
// team name
View nameView = findViewById(R.id.settings_item_name);
teamNameTextView = (TextView) nameView.findViewById(R.id.item_detail);
teamNameTextView.setText(teamName);
teamNameTextView.setEnabled(isSelfAdmin);
setToggleBtn(team);
}
private void onGetTeamInfoFailed() {
Toast.makeText(this, getString(R.string.normal_team_not_exist), Toast.LENGTH_SHORT).show();
finish();
}
private void initAdapter() {
memberAccounts = new ArrayList<>();
dataSource = new ArrayList<>();
adapter = new TeamMemberAdapter(this, dataSource, this, this, this);
adapter.setEventListener(this);
}
private void findViews() {
// grid view
gridView = (TeamInfoGridView) findViewById(R.id.team_members_grid_view);
gridView.setSelector(R.color.transparent);
gridView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == 0) {
adapter.notifyDataSetChanged();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
gridView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP && adapter.getMode() == TeamMemberAdapter.Mode.DELETE) {
adapter.setMode(TeamMemberAdapter.Mode.NORMAL);
adapter.notifyDataSetChanged();
return true;
}
return false;
}
});
gridView.setAdapter(adapter);
// discussion name view
View nameView = findViewById(R.id.settings_item_name);
nameView.setOnClickListener(this);
TextView nameLabel = (TextView) nameView.findViewById(R.id.item_title);
nameLabel.setText(R.string.normal_team_name);
// talk button
Button quitBtn = (Button) findViewById(R.id.quit_team);
quitBtn.setOnClickListener(this);
}
/**
* *************************** 加载&变更数据源 ********************************
*/
private void requestMembers() {
gridView.setVisibility(View.GONE);
memberAccounts.clear();
if (team != null) {
TeamDataCache.getInstance().fetchTeamMemberList(teamId, new SimpleCallback<List<TeamMember>>() {
@Override
public void onResult(boolean success, List<TeamMember> members) {
if (success && members != null && !members.isEmpty()) {
gridView.setVisibility(View.VISIBLE);
List<String> accounts = new ArrayList<>();
for (TeamMember member : members) {
// 标记创建者(群主)
if (member.getType() == TeamMemberType.Owner) {
creator = member.getAccount();
if (creator.equals(NimUIKit.getAccount())) {
isSelfAdmin = true;
}
}
accounts.add(member.getAccount());
}
addMember(accounts, true);
} else {
Toast.makeText(NormalTeamInfoActivity.this, "获取成员列表失败", Toast.LENGTH_SHORT).show();
}
}
});
}
}
private void addMember(List<String> accounts, boolean clear) {
if (accounts == null || accounts.isEmpty()) {
return;
}
if (clear) {
this.memberAccounts.clear();
}
// add
if (this.memberAccounts.isEmpty()) {
this.memberAccounts.addAll(accounts);
} else {
for (String account : accounts) {
if (!this.memberAccounts.contains(account)) {
this.memberAccounts.add(account);
}
}
}
// sort
Collections.sort(this.memberAccounts, new Comparator<String>() {
@Override
public int compare(String l, String r) {
if (creator == null) {
return 0;
}
if (creator.equals(l)) {
return -1;
}
if (creator.equals(r)) {
return 1;
}
return l.compareTo(r);
}
});
updateDataSource();
}
private void updateDataSource() {
dataSource.clear();
// member item
String identity;
for (String account : memberAccounts) {
if (creator.equals(account)) {
identity = TeamMemberHolder.OWNER;
} else {
identity = null;
}
dataSource.add(new TeamMemberAdapter.TeamMemberItem(TeamMemberAdapter.TeamMemberItemTag
.NORMAL, teamId, account, identity));
}
// add item
dataSource.add(new TeamMemberAdapter.TeamMemberItem(TeamMemberAdapter.TeamMemberItemTag.ADD, null, null, null));
// remove item
if (isSelfAdmin) {
dataSource.add(new TeamMemberAdapter.TeamMemberItem(TeamMemberAdapter.TeamMemberItemTag.DELETE, null, null,
null));
}
// refresh
if (adapter.getMode() != TeamMemberAdapter.Mode.DELETE) {
adapter.notifyDataSetChanged();
}
}
private void removeMember(String account) {
memberAccounts.remove(account);
for (TeamMemberAdapter.TeamMemberItem item : dataSource) {
if (account.equals(item.getAccount())) {
dataSource.remove(item);
break;
}
}
// 为了解决2.3系统,移除用户后刷新界面不显示的问题
if (Build.VERSION.SDK_INT < 11) {
adapter.setMode(TeamMemberAdapter.Mode.NORMAL);
}
adapter.notifyDataSetChanged();
}
/**
* ******************************* Action *********************************
*/
/**
* 邀请群成员
*/
@Override
public void onAddMember() {
ContactSelectActivity.Option option = new ContactSelectActivity.Option();
option.title = "邀请成员";
ArrayList<String> disableAccounts = new ArrayList<>();
disableAccounts.addAll(memberAccounts);
option.itemDisableFilter = new ContactIdFilter(disableAccounts);
// 限制群成员数量在群容量范围内
int capacity = teamCapacity - memberAccounts.size();
option.maxSelectNum = capacity;
option.maxSelectedTip = getString(R.string.reach_team_member_capacity, teamCapacity);
NimUIKit.startContactSelect(NormalTeamInfoActivity.this, option, REQUEST_CODE_CONTACT_SELECT);
}
/**
* 移除群成员
*/
@Override
public void onRemoveMember(final String account) {
DialogMaker.showProgressDialog(this, getString(R.string.empty), true);
NIMClient.getService(TeamService.class).removeMember(teamId, account).setCallback(new RequestCallback<Void>
() {
@Override
public void onSuccess(Void param) {
DialogMaker.dismissProgressDialog();
removeMember(account);
Toast.makeText(NormalTeamInfoActivity.this, R.string.remove_member_success, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed(int code) {
DialogMaker.dismissProgressDialog();
Toast.makeText(NormalTeamInfoActivity.this, R.string.remove_member_failed, Toast.LENGTH_SHORT).show();
}
@Override
public void onException(Throwable exception) {
DialogMaker.dismissProgressDialog();
}
});
}
/**
* 添加群成员
*/
private void addMembersToTeam(final ArrayList<String> selected) {
// add members
DialogMaker.showProgressDialog(this, getString(R.string.empty), true);
NIMClient.getService(TeamService.class).addMembers(teamId, selected).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
DialogMaker.dismissProgressDialog();
addMember(selected, false);
Toast.makeText(NormalTeamInfoActivity.this, R.string.invite_member_success, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed(int code) {
DialogMaker.dismissProgressDialog();
Toast.makeText(NormalTeamInfoActivity.this, R.string.invite_member_failed, Toast.LENGTH_SHORT).show();
}
@Override
public void onException(Throwable exception) {
DialogMaker.dismissProgressDialog();
}
});
}
/**
* 非群主退出群
*/
private void quitTeam() {
DialogMaker.showProgressDialog(this, getString(R.string.empty), true);
NIMClient.getService(TeamService.class).quitTeam(teamId).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
DialogMaker.dismissProgressDialog();
Toast.makeText(NormalTeamInfoActivity.this, R.string.quit_normal_team_success, Toast.LENGTH_SHORT).show();
setResult(Activity.RESULT_OK, new Intent().putExtra(TeamExtras.RESULT_EXTRA_REASON, TeamExtras.RESULT_EXTRA_REASON_QUIT));
NIMClient.getService(MsgService.class).deleteRecentContact2(teamId, SessionTypeEnum.Team);
finish();
}
@Override
public void onFailed(int code) {
DialogMaker.dismissProgressDialog();
Toast.makeText(NormalTeamInfoActivity.this, R.string.quit_normal_team_failed, Toast.LENGTH_SHORT).show();
}
@Override
public void onException(Throwable exception) {
DialogMaker.dismissProgressDialog();
}
});
}
/**
* ******************************* Event *********************************
*/
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.quit_team) {
quitTeam();
} else if (i == R.id.settings_item_name) {
TeamPropertySettingActivity.start(NormalTeamInfoActivity.this, teamId, TeamFieldEnum.Name, teamNameTextView.getText().toString(), REQUEST_CODE_NAME);
} else {
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && adapter.switchMode()) {
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public void onBackPressed() {
if (adapter.switchMode()) {
return;
}
super.onBackPressed();
}
@Override
public void onHeadImageViewClick(String account) {
if (NimUIKit.getContactEventListener() != null) {
NimUIKit.getContactEventListener().onAvatarClick(this, account);
}
}
private void registerUserInfoChangedObserver(boolean register) {
if (register) {
if (userInfoObserver == null) {
userInfoObserver = new UserInfoObservable.UserInfoObserver() {
@Override
public void onUserInfoChanged(List<String> accounts) {
adapter.notifyDataSetChanged();
}
};
}
UserInfoHelper.registerObserver(userInfoObserver);
} else {
UserInfoHelper.unregisterObserver(userInfoObserver);
}
}
}