using System; using System.Collections.Generic; using System.Device.Location; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using Hammock; using MahApps.RESTBase; using MahApps.Twitter; using MahApps.Twitter.Delegates; using MahApps.Twitter.Models; using MahTweets.Extensions.Twitter.Mango.Extensions; using MahTweets.Mango.Core; using MahTweets.Mango.Core.Models; using MahTweets.Mango.Core.Repositories; using MahTweets.Mango.Core.Services; using WindowsPhoneEssentials.ComponentModel; namespace MahTweets.Extensions.Twitter.Mango { public class Twitter : Plugin, IMicroblog { private const string ConsumerKey = "NRvCz7KI8MRodk2E28Dmg"; private const string ConsumerSecret = "4Pm8OlyWRUmuWmG25t7yhbtoUW4A9V0CA4XO8tvg"; private readonly IContactRepository _contacts; public Twitter( IContactRepository contacts) { _contacts = contacts; } public IMicroblogConnection Connect(AccountCredentials accountCredentials, IStatusService statusService) { var client = new TwitterClient(ConsumerKey, ConsumerSecret, "http://www.mahtweets.com/mobile_oauth.html"); return new TwitterConnection(client, accountCredentials, _contacts, statusService); } } public class TwitterConnection : NotifyPropertyChanged, IMicroblogConnection { private readonly TwitterClient _client; private readonly IContactRepository _contacts; private readonly IStatusService _statusService; private readonly object _ownerLock = new object(); private volatile Contact _owner; private readonly AccountCredentials _accountCredentials; private bool _isRefreshing; private readonly object _refreshingLock = new object(); public TwitterConnection(TwitterClient client, AccountCredentials accountCredentials, IContactRepository contacts, IStatusService statusService) { _accountCredentials = accountCredentials; _client = client; _contacts = contacts; _statusService = statusService; client.SetOAuthToken(new Credentials { OAuthToken = accountCredentials.Username, OAuthTokenSecret = accountCredentials.Password }); Refresh(); } public void Dispose() { } public bool IsRefreshing { get { return _isRefreshing; } private set { _isRefreshing = value; OnPropertyChanged(()=>IsRefreshing); } } public void Refresh() { if (!IsRefreshing) { lock (_refreshingLock) { if (!IsRefreshing) { var homeTimelineTask = Task.Factory.StartNew( SynchroniseLoadMessages(_client.Statuses.BeginHomeTimeline, HomeTimelineCallback)); var mentionsTask = Task.Factory.StartNew( SynchroniseLoadMessages(_client.Statuses.BeginMentions, HomeTimelineCallback)); var dmsTask = Task.Factory.StartNew( SynchroniseLoadMessages(_client.DirectMessages.BeginDirectMessages, HomeTimelineCallback)); var sendDmsTask = Task.Factory.StartNew( SynchroniseLoadMessages(_client.DirectMessages.BeginSentDirectMessages, HomeTimelineCallback)); Task.Factory.ContinueWhenAll( new[] {homeTimelineTask, mentionsTask, dmsTask, sendDmsTask}, tasks => { IsRefreshing = false; }); } } } } public void HomeTimelineCallback(RestRequest request, RestResponse response, Object obj) { try { if (obj is List) { foreach (var t in (List)obj) { var status = t.ToStatus(_contacts); status.ToTimeline(Credentials); _statusService.OnNext(status); } } else if (obj is List) { foreach (var t in (List)obj) { var contact = _contacts.GetContact(t.Sender.ScreenName); contact.UpdateContact(t.Sender); var recipient = _contacts.GetContact(t.Recipient.ScreenName); recipient.UpdateContact(t.Recipient); var status = t.ToStatus(contact); status.Recipient = recipient; status.ToTimeline(Credentials); _statusService.OnNext(status); } } } catch (Exception ex) { //TODO better logging/error handling here Debug.WriteLine(ex); } } private static Action SynchroniseLoadMessages(Action beginGet, Action callback) { return () => { var resetEvent = new ManualResetEvent(false); beginGet((request, response, obj) => { resetEvent.Set(); callback(request, response, obj); }); resetEvent.WaitOne(30000); }; } public bool ReadOnly { get { return false; } } public void NewStatusUpdate(string text, string id, GeoCoordinate location) { } public string OwnerName { get { return Credentials.AccountName; } } public Contact Owner { get { if (_owner == null) { lock (_ownerLock) { if (_owner == null) { var contact = _contacts.GetContact(OwnerName); if (contact == null) { contact = new Contact { Name = OwnerName, Bio = "Loading..." }; _client.Account.BeginVerifyCredentials(OwnerCallback); } _owner = contact; } } } return _owner; } set { _owner = value; OnPropertyChanged(() => Owner); } } public AccountCredentials Credentials { get { return _accountCredentials; } } public void OwnerCallback(RestRequest request, RestResponse response, object obj) { if (!(obj is User)) return; var u = (User)obj; _owner = new Contact { Name = u.ScreenName, Id = u.Id.ToString(), ImageUrl = new Uri(u.ProfileImageUrl) }; OnPropertyChanged(() => Owner); } } }