package im.actor.sdk.controllers.group.view; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import com.google.i18n.phonenumbers.NumberParseException; import com.google.i18n.phonenumbers.PhoneNumberUtil; import com.google.i18n.phonenumbers.Phonenumber; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Optional; import im.actor.core.viewmodel.CommandCallback; import im.actor.core.viewmodel.GroupVM; import im.actor.core.viewmodel.UserPhone; import im.actor.runtime.actors.messages.*; import im.actor.runtime.actors.messages.Void; import im.actor.sdk.ActorSDK; import im.actor.sdk.ActorSDKLauncher; import im.actor.sdk.R; import im.actor.sdk.controllers.ActorBinder; import im.actor.sdk.controllers.Intents; import im.actor.sdk.controllers.activity.BaseActivity; import im.actor.sdk.util.AlertListBuilder; import im.actor.sdk.util.Screen; import im.actor.sdk.view.avatar.AvatarView; import im.actor.sdk.view.adapters.HolderAdapter; import im.actor.sdk.view.adapters.ViewHolder; import im.actor.core.entity.GroupMember; import im.actor.core.viewmodel.UserVM; import static im.actor.sdk.util.ActorSDKMessenger.messenger; import static im.actor.sdk.util.ActorSDKMessenger.users; public class MembersAdapter extends HolderAdapter<GroupMember> { public static final int LOAD_GAP = 10; private static final int LIMIT = 20; private ArrayList<GroupMember> members = new ArrayList<GroupMember>(); private ActorBinder BINDER = new ActorBinder(); private boolean loadInProgress = false; private boolean loaddedToEnd = false; private LoadedCallback callback; public MembersAdapter(Context context, int groupId) { super(context); this.groupId = groupId; } public void setMembers(Collection<GroupMember> members) { setMembers(members, true, true); } public void setMembers(Collection<GroupMember> members, boolean clear, boolean sort) { if (clear) { this.members.clear(); } if (sort) { GroupMember[] membersArray = members.toArray(new GroupMember[members.size()]); Arrays.sort(membersArray, (a, b) -> { if (a.isAdministrator() && !b.isAdministrator()) { return -1; } if (b.isAdministrator() && !a.isAdministrator()) { return 1; } String an = users().get(a.getUid()).getName().get(); String bn = users().get(b.getUid()).getName().get(); return an.compareTo(bn); }); this.members.addAll(Arrays.asList(membersArray)); } else { this.members.addAll(members); } notifyDataSetChanged(); } @Override protected void onBindViewHolder(ViewHolder<GroupMember> holder, GroupMember obj, int position, Context context) { super.onBindViewHolder(holder, obj, position, context); if (position >= getCount() - LOAD_GAP) { loadMore(); } } private int groupId; private boolean isInitiallyLoaded; private byte[] nextMembers; private ArrayList<Integer> rawMembers = new ArrayList<>(); public void initLoad(LoadedCallback callback) { this.callback = callback; if (!isInitiallyLoaded) { loadMore(); } } public interface LoadedCallback { void onLoaded(); void onLoadedToEnd(); } private void loadMore() { if (!loadInProgress && !loaddedToEnd) { loadInProgress = true; messenger().loadMembers(groupId, LIMIT, nextMembers).then(groupMembersSlice -> { if (!isInitiallyLoaded) { isInitiallyLoaded = true; if (callback != null) { callback.onLoaded(); } } nextMembers = groupMembersSlice.getNext(); loaddedToEnd = nextMembers == null; if (loaddedToEnd && callback != null) { callback.onLoadedToEnd(); } loadInProgress = false; setMembers(groupMembersSlice.getMembers(), false, false); }); } } @Override public int getCount() { return members.size(); } @Override public GroupMember getItem(int position) { return members.get(position); } @Override public long getItemId(int position) { return members.get(position).getUid(); } @Override protected ViewHolder<GroupMember> createHolder(GroupMember obj) { return new GroupViewHolder(); } private class GroupViewHolder extends ViewHolder<GroupMember> { private TextView userName; private View admin; private AvatarView avatarView; private TextView online; private ActorBinder.Binding onlineBinding; private UserVM user; @Override public View init(GroupMember data, ViewGroup viewGroup, Context context) { View res = ((Activity) context).getLayoutInflater().inflate(R.layout.fragment_group_item, viewGroup, false); userName = (TextView) res.findViewById(R.id.name); avatarView = (AvatarView) res.findViewById(R.id.avatar); avatarView.init(Screen.dp(42), 18); admin = res.findViewById(R.id.adminFlag); online = (TextView) res.findViewById(R.id.online); ((TextView) admin).setTextColor(ActorSDK.sharedActor().style.getGroupAdminColor()); ((TextView) res.findViewById(R.id.name)).setTextColor(ActorSDK.sharedActor().style.getTextPrimaryColor()); // res.findViewById(R.id.divider).setBackgroundColor(ActorSDK.sharedActor().style.getDividerColor()); return res; } @Override public void bind(GroupMember data, int position, Context context) { boolean needRebind = user == null || data.getUid() != user.getId(); user = users().get(data.getUid()); ActorSDK.sharedActor().getMessenger().onUserVisible(data.getUid()); onlineBinding = BINDER.bindOnline(online, user); if (needRebind) { avatarView.bind(user); } userName.setText(user.getName().get()); if (data.isAdministrator()) { admin.setVisibility(View.VISIBLE); } else { admin.setVisibility(View.GONE); } } @Override public void unbind(boolean full) { if (full) { avatarView.unbind(); } if (onlineBinding != null) { BINDER.unbind(onlineBinding); } } } @Override public void dispose() { super.dispose(); BINDER.unbindAll(); } public void onMemberClick(GroupVM groupVM, UserVM userVM, boolean isAdministrator, boolean isInvitedByMe, BaseActivity activity) { AlertListBuilder alertListBuilder = new AlertListBuilder(); final ArrayList<UserPhone> phones = userVM.getPhones().get(); alertListBuilder.addItem(activity.getString(R.string.group_context_message).replace("{0}", userVM.getName().get()), () -> activity.startActivity(Intents.openPrivateDialog(userVM.getId(), true, activity))); if (phones.size() != 0) { alertListBuilder.addItem(activity.getString(R.string.group_context_call).replace("{0}", userVM.getName().get()), () -> { if (phones.size() == 1) { activity.startActivity(Intents.call(phones.get(0).getPhone())); } else { CharSequence[] sequences = new CharSequence[phones.size()]; for (int i = 0; i < sequences.length; i++) { try { Phonenumber.PhoneNumber number = PhoneNumberUtil.getInstance().parse("+" + phones.get(i).getPhone(), "us"); sequences[i] = phones.get(i).getTitle() + ": " + PhoneNumberUtil.getInstance().format(number, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL); } catch (NumberParseException e) { e.printStackTrace(); sequences[i] = phones.get(i).getTitle() + ": +" + phones.get(i).getPhone(); } } new AlertDialog.Builder(activity) .setItems(sequences, (dialog1, which1) -> { activity.startActivity(Intents.call(phones.get(which1).getPhone())); }) .show() .setCanceledOnTouchOutside(true); } }); } alertListBuilder.addItem(activity.getString(R.string.group_context_view).replace("{0}", userVM.getName().get()), () -> ActorSDKLauncher.startProfileActivity(activity, userVM.getId())); if (groupVM.getIsCanKickAnyone().get() || (groupVM.getIsCanKickInvited().get() && isInvitedByMe)) { alertListBuilder.addItem(activity.getString(R.string.group_context_remove).replace("{0}", userVM.getName().get()), () -> { new AlertDialog.Builder(activity) .setMessage(activity.getString(R.string.alert_group_remove_text).replace("{0}", userVM.getName().get())) .setPositiveButton(R.string.alert_group_remove_yes, (dialog2, which1) -> { activity.execute(messenger().kickMember(groupVM.getId(), userVM.getId()), R.string.progress_common, new CommandCallback<Void>() { @Override public void onResult(Void res1) { } @Override public void onError(Exception e) { Toast.makeText(activity, R.string.toast_unable_kick, Toast.LENGTH_SHORT).show(); } }); }) .setNegativeButton(R.string.dialog_cancel, null) .show() .setCanceledOnTouchOutside(true); }); } if (groupVM.getIsCanEditAdmins().get() && !userVM.isBot()) { alertListBuilder.addItem(!isAdministrator ? activity.getResources().getString(R.string.group_make_admin) : activity.getResources().getString(R.string.group_revoke_admin), () -> { if (!isAdministrator) { messenger().makeAdmin(groupVM.getId(), userVM.getId()).start(new CommandCallback<Void>() { @Override public void onResult(Void res) { } @Override public void onError(Exception e) { } }); } else { messenger().revokeAdmin(groupVM.getId(), userVM.getId()).start(new CommandCallback<Void>() { @Override public void onResult(Void res) { } @Override public void onError(Exception e) { } }); } }); } alertListBuilder.build(activity) .show() .setCanceledOnTouchOutside(true); } }