package im.actor.sdk.controllers; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.style.ForegroundColorSpan; import android.view.View; import android.widget.TextView; import java.util.ArrayList; import java.util.HashSet; import im.actor.core.entity.Avatar; import im.actor.core.entity.GroupMember; import im.actor.core.viewmodel.GroupVM; import im.actor.core.viewmodel.UserPresence; import im.actor.core.viewmodel.UserVM; import im.actor.runtime.mvvm.ValueDoubleListener; import im.actor.runtime.mvvm.ValueListener; import im.actor.runtime.mvvm.ValueModel; import im.actor.sdk.ActorSDK; import im.actor.sdk.R; import im.actor.sdk.view.avatar.AvatarView; import im.actor.sdk.view.avatar.CoverAvatarView; import im.actor.runtime.mvvm.Value; import im.actor.runtime.mvvm.ValueChangedListener; import im.actor.runtime.mvvm.ValueDoubleChangedListener; import im.actor.runtime.mvvm.ValueTripleChangedListener; import static im.actor.sdk.util.ActorSDKMessenger.messenger; import static im.actor.sdk.util.ActorSDKMessenger.users; public class ActorBinder { private ArrayList<Binding> bindings = new ArrayList<Binding>(); public void bind(final TextView textView, Value<String> value) { bind(value, new ValueChangedListener<String>() { @Override public void onChanged(String val, Value<String> Value) { textView.setText(val); } }); } public void bindGlobalCounter(ValueChangedListener<Integer> callback) { callback.onChanged(messenger().getGlobalState().getGlobalCounter().get(), messenger().getGlobalState().getGlobalCounter()); bind(messenger().getGlobalState().getGlobalCounter(), callback); } public void bindGroupTyping(final TextView textView, final View container, final View titleContainer, final Value<int[]> typing) { bind(typing, new ValueChangedListener<int[]>() { @Override public void onChanged(int[] val, Value<int[]> Value) { if (val.length == 0) { container.setVisibility(View.INVISIBLE); titleContainer.setVisibility(View.VISIBLE); } else { if (val.length == 1) { textView.setText(messenger().getFormatter().formatTyping(users().get(val[0]).getName().get())); } else { textView.setText(messenger().getFormatter().formatTyping(val.length)); } container.setVisibility(View.VISIBLE); titleContainer.setVisibility(View.INVISIBLE); } } }); } public void bindPrivateTyping(final TextView textView, final View container, final View titleContainer, final Value<Boolean> typing) { bind(typing, new ValueChangedListener<Boolean>() { @Override public void onChanged(Boolean val, Value<Boolean> Value) { if (val) { textView.setText(messenger().getFormatter().formatTyping()); container.setVisibility(View.VISIBLE); titleContainer.setVisibility(View.INVISIBLE); } else { container.setVisibility(View.INVISIBLE); titleContainer.setVisibility(View.VISIBLE); } } }); } public void bind(final TextView textView, final View container, final Value<String> value) { bind(textView, container, value, null, true, ""); } public void bind(final TextView textView, final View container, final Value<String> value, final OnChangedListener callback, final boolean hide, final String defaultValue) { bind(value, new ValueChangedListener<String>() { @Override public void onChanged(String val, Value<String> Value) { if (val != null) { if (hide) { container.setVisibility(View.VISIBLE); } textView.setText(val); } else { if (hide) { container.setVisibility(View.GONE); } textView.setText(defaultValue); } if (callback != null) { callback.onChanged(val); } } }); } public Binding bind(final TextView textView, final UserVM user) { return bind(user.getPresence(), new ValueChangedListener<UserPresence>() { @Override public void onChanged(UserPresence val, Value<UserPresence> Value) { String s = messenger().getFormatter().formatPresence(val, user.getSex()); if (s == null) { s = ""; } if (user.isBot()) { s = textView.getContext().getString(R.string.members_adapter_bot_online_status); } textView.setText(s); } }); } public Binding bindOnline(final TextView textView, final UserVM user) { return bind(user.getPresence(), new ValueChangedListener<UserPresence>() { @Override public void onChanged(UserPresence val, Value<UserPresence> Value) { String s = messenger().getFormatter().formatPresence(val, user.getSex()); if (s == null) { s = ""; } if (val.getState().equals(UserPresence.State.ONLINE)) { textView.setTextColor(ActorSDK.sharedActor().style.getGroupOnlineColor()); s = "\u25CF".concat(s); } else { textView.setTextColor(ActorSDK.sharedActor().style.getTextSecondaryColor()); } if (user.isBot()) { s = textView.getContext().getString(R.string.members_adapter_bot_online_status); } textView.setText(s); } }); } public Binding bind(final View v, ValueModel<UserPresence> up) { return bind(up, new ValueChangedListener<UserPresence>() { @Override public void onChanged(UserPresence val, Value<UserPresence> valueModel) { if (val.getState().equals(UserPresence.State.ONLINE)) { v.setVisibility(View.VISIBLE); } else { v.setVisibility(View.GONE); } } }); } public Binding bind(final OnChangedListener<Boolean> callback, ValueModel<UserPresence> up) { return bind(up, new ValueChangedListener<UserPresence>() { @Override public void onChanged(UserPresence val, Value<UserPresence> valueModel) { callback.onChanged(val.getState().equals(UserPresence.State.ONLINE)); } }); } public void bind(final TextView textView, final View titleContainer, final GroupVM value) { bind(value.getPresence(), value.getMembersCount(), value.isMember(), (online, onlineModel, membersCount, membersModel, isMember, isMemberModel) -> { if (isMember) { titleContainer.setVisibility(View.VISIBLE); if (online <= 0) { SpannableStringBuilder builder = new SpannableStringBuilder( messenger().getFormatter().formatGroupMembers(membersCount)); builder.setSpan(new ForegroundColorSpan(0xB7ffffff), 0, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); textView.setText(builder); } else { SpannableStringBuilder builder = new SpannableStringBuilder( messenger().getFormatter().formatGroupMembers(membersCount) + ", "); builder.setSpan(new ForegroundColorSpan(0xB7ffffff), 0, builder.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE); builder.append(messenger().getFormatter().formatGroupOnline(online)); textView.setText(builder); } } else { titleContainer.setVisibility(View.GONE); } }); } public void bind(final AvatarView avatarView, final int id, final Value<Avatar> avatar, final Value<String> name) { bind(avatar, name, new ValueDoubleChangedListener<Avatar, String>() { @Override public void onChanged(Avatar val, Value<Avatar> Value, String val2, Value<String> Value2) { avatarView.bind(val, val2, id); } }); } public void bind(final CoverAvatarView avatarView, final Value<Avatar> avatar) { bind(avatar, new ValueChangedListener<Avatar>() { @Override public void onChanged(Avatar val, Value<Avatar> Value) { if (val != null) { avatarView.bind(val); } else { avatarView.unbind(); avatarView.setImageURI(null); } } }); } public <T> Binding bind(Value<T> value, ValueChangedListener<T> listener) { value.subscribe(listener); Binding b = new Binding(value, listener); bindings.add(b); return b; } public <T> Binding bind(Value<T> value, ValueListener<T> listener) { return bind(value, (val, valueModel) -> { listener.onChanged(val); }); } public <T1, T2> void bind(Value<T1> value1, Value<T2> value2, ValueDoubleListener<T1, T2> listener) { bind(value1, value2, (val, valueModel, val2, valueModel2) -> { listener.onChanged(val, val2); }); } public <T> Binding bind(Value<T> value, ValueChangedListener<T> listener, boolean notify) { value.subscribe(listener, notify); Binding b = new Binding(value, listener); bindings.add(b); return b; } public <T> Binding bind(Value<T> value, boolean notify, ValueChangedListener<T> listener) { value.subscribe(listener, notify); Binding binding = new Binding(value, listener); bindings.add(binding); return binding; } public <T, V> Binding[] bind(final Value<T> value1, final Value<V> value2, final ValueDoubleChangedListener<T, V> listener) { Binding[] bindings = new Binding[2]; bindings[0] = bind(value1, false, new ValueChangedListener<T>() { @Override public void onChanged(T val, Value<T> Value) { listener.onChanged(val, Value, value2.get(), value2); } }); bindings[1] = bind(value2, false, new ValueChangedListener<V>() { @Override public void onChanged(V val, Value<V> Value) { listener.onChanged(value1.get(), value1, val, Value); } }); listener.onChanged(value1.get(), value1, value2.get(), value2); return bindings; } public <T, V, S> void bind(final Value<T> value1, final Value<V> value2, final Value<S> value3, final ValueTripleChangedListener<T, V, S> listener) { bind(value1, false, new ValueChangedListener<T>() { @Override public void onChanged(T val, Value<T> Value) { listener.onChanged(val, Value, value2.get(), value2, value3.get(), value3); } }); bind(value2, false, new ValueChangedListener<V>() { @Override public void onChanged(V val, Value<V> Value) { listener.onChanged(value1.get(), value1, val, Value, value3.get(), value3); } }); bind(value3, false, new ValueChangedListener<S>() { @Override public void onChanged(S val, Value<S> Value) { listener.onChanged(value1.get(), value1, value2.get(), value2, val, Value); } }); listener.onChanged(value1.get(), value1, value2.get(), value2, value3.get(), value3); } public void unbindAll() { for (Binding b : bindings) { b.unbind(); } bindings.clear(); } public interface OnChangedListener<T> { void onChanged(T val); } public void unbind(Binding b) { b.unbind(); bindings.remove(b); } public class Binding { private Value model; private ValueChangedListener listener; private Binding(Value model, ValueChangedListener listener) { this.model = model; this.listener = listener; } public void unbind() { model.unsubscribe(listener); } } }