Подписка на канал присутствия для каждого элемента ObservableCollection - PullRequest
0 голосов
/ 17 апреля 2020

Я создаю список пользователей чата, и мне нужно подписаться на различные каналы, по одному на каждый элемент Наблюдаемой коллекции (я не могу подписать всех на уникальный канал). Я хочу, чтобы при десериализации json, полученной из Интернета, и создании списка участников каждый элемент списка автоматически получал свою подписку и в случае успеха изменял свойство Online. Я сделал это с кодом ниже, но это не хорошо, иногда подписка работает, иногда нет, но свойство онлайн никогда не меняется.

Соответствующие части кода:

Основной класс страницы:

var result = await client.GetJson<ChatMembers>("url");
if (result.Count > 0)
{
    List = new ObservableCollection<ChatMembers>(result as List<ChatMembers>);
    CollectionViewMembers.ItemsSource = List;
}

Класс ChatMembers:

public class ChatMembers : INotifyPropertyChanged
    {
        Alerta alerta = new Alerta();
        private static Pusher _pusher = new Pusher("key", new PusherOptions()
        {
            Cluster = "us2",
            Authorizer = new HttpAuthorizer("authorizer"),
            Encrypted = true
        });

        public ChatMembers()
        {
            Task.Run(() =>
            {
                try
                {
                    _presenceChannel = (PresenceChannel)_pusher.SubscribeAsync("presence-" + ChatKey).Result;
                }
                catch (Exception e)
                {
                    Debug.WriteLine("ERROR:" + e.Message);
                }

                _presenceChannel.Subscribed += PresenceChannel_Subscribed;
                _presenceChannel.MemberAdded += PresenceChannel_MemberAdded;
                _presenceChannel.MemberRemoved += PresenceChannel_MemberRemoved;
            });
        }

        public Command Evento
        {
            // when I click on an item it shows an alert and if connected, changes the respective Online property!
            get
            {
                return new Command(arg =>{
                    var vm = (ChatMembers)arg;
                    alerta.ShowAlert("info", vm.Username, vm._presenceChannel.Name + " / " + vm._presenceChannel.IsSubscribed + " online: "+Online+ " Cor "+ColorOnline.ToString());
                    if(vm._presenceChannel.Members.Keys.Contains(vm.UserID))
                        vm.Online = true;
                    else
                        vm.Online = false;
                });
            }
        }

        private string _Username { get; set; }
        public string Username
        {
            get { return _Username; }
            set
            {
                _Username = value;
                this.NotifyPropertyChanged("Username");
            }
        }

        private string _UserID { get; set; }
        public string UserID
        {
            get { return _UserID; }
            set
            {
                _UserID = value;
                this.NotifyPropertyChanged("UserID");
            }
        }

        private string _ChatKey { get; set; }
        public string ChatKey
        {
            get { return _ChatKey; }
            set
            {
                _ChatKey = value;
                this.NotifyPropertyChanged("ChatKey");
            }
        }

        private Color _ColorOnline { get; set; }
        public Color ColorOnline
        {
            get { return _ColorOnline; }
            set
            {
                _ColorOnline = value;
                this.NotifyPropertyChanged("ColorOnline");
            }
        }

        private bool _Online { get; set; }
        public bool Online
        {
            get { return _Online; }
            set
            {
                if (value == null || value == false)
                {
                    _Online = false;
                    ColorOnline = Color.DarkGray;
                }
                else
                {
                    _Online = true;
                    ColorOnline = Color.LightGreen;
                }
                this.NotifyPropertyChanged("Online");
            }
        }

        private PresenceChannel _presenceChannel
        {
            get; set;            
        }

        void ListMembers()
        {
            var users = new List<string>();

            if (_presenceChannel.Members.Count != null && _presenceChannel.Members.Count > 0)
                foreach (var mem in _presenceChannel.Members)
                {
                    users.Add((string)mem.Key);
                }

            Console.WriteLine("[MEMBERS] " + users.Aggregate((i, j) => i + ", " + j));
        }

        public void PresenceChannel_Subscribed(object sender)
        {
            ListMembers();
        }

        public void PresenceChannel_MemberAdded(object sender, KeyValuePair<string, dynamic> member)
        {
            if (_presenceChannel.Members.Keys.Contains(UserID))
                Online = true;
        }

        public void PresenceChannel_MemberRemoved(object sender)
        {
            foreach (var mem in _presenceChannel.Members)
            {
                if (mem.Key == UserID)
                    return;
            }
            Online = false;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        void NotifyPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
...