![]() | ![]() |
public async Task RunAsync() { await _cl.LoadSettings().ConfigureAwait(false); if (await _cl.CheckAndGenerateAuth().ConfigureAwait(false)) { await _cl.RunAsync().ConfigureAwait(false); } if ((_cl.Settings.DataCenters == null) || (_cl.Settings.DataCenters.Count == 0)) { await _cl.GetConfig().ConfigureAwait(false); } _db = await TalksDatabase.GetDatabase().ConfigureAwait(false); _ldm = new LocalDataManager(_db); _cl.ProcessUpdateAsync = ProcessUpdateAsync; }
async void button_Click(object sender, EventArgs e) { _button.Enabled = false; await _presenter.SendMessage(); }
public Task<bool> SendMessage() { return SendMessageToUser(); }
public async Task<bool> SendMessageToUser() { ... try { _imv.AddMineMessage(msg); string msgText = _imv.PendingMessage; _imv.PendingMessage = ""; // messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage; var result = await _model.PerformRpcCall("messages.sendMessage", InputPeerFactory.CreatePeer(_model, PeerType.inputPeerContact, _imv.ChatId), msgText, LongRandom(r)); if (result.Success) { // messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage; msg.Id = result.Answer.ExtractValue<int>("id"); ... msg.State = BL.Messages.MessageState.Sent; _imv.IvalidateList(); await _model.ProcessSentMessage(result.Answer, _imv.ChatId, msg); return true; } else { msg.State = BL.Messages.MessageState.Failed; _imv.SendSmallMessage("Problem sending message: " + result.Error.ToString()); return false; } } catch (Exception ex) { ... } }
public Task<RpcAnswer> PerformRpcCall(string combinatorName, params object[] pars) { return _cl.PerformRpcCall(combinatorName, pars); }
public async Task<RpcAnswer> PerformRpcCall(string combinatorName, params object[] pars) { try { /*...*/ var confirm = CreateConfirm(); // WriteOnceBlock<RpcAnswer> answer = new WriteOnceBlock<RpcAnswer>(e => e); IOutputCombinator oc; if (confirm != null) { var cntrn = new MsgContainer(); cntrn.Add(rpccall); // RPC Call cntrn.Add(confirm); cntrn.Combinator = _tlc.Decompose(0x73f1f8dc); // oc = new OutputMsgContainer(uniqueId, cntrn); } else // { oc = new OutputTLCombinatorInstance(uniqueId, rpccall); } var uhoo = await SendRpcCallAsync(oc).ConfigureAwait(false); _inputAnswersBuffer.LinkTo(answer, new DataflowLinkOptions { MaxMessages = 1 }, i => i.SessionId == _em.SessionId); return await answer.ReceiveAsync(TimeSpan.FromSeconds(60)).ConfigureAwait(false); // } catch (Exception ex) { ... } }
.ConfigureAwait(false)
done to prevent deadlocks. Read more about this in the article above. BufferBlock<byte[]> _inputBufferBytes = new BufferBlock<byte[]>(); BufferBlock<InputTLCombinatorInstance> _inputBuffer = new BufferBlock<InputTLCombinatorInstance>(); ActionBlock<byte[]> _inputBufferParcer; ActionBlock<TLCombinatorInstance> _inputUpdates; ActionBlock<TLCombinatorInstance> _inputSystemMessages; TransformBlock<InputTLCombinatorInstance, RpcAnswer> _inputAnswers; BufferBlock<RpcAnswer> _inputAnswersBuffer = new BufferBlock<RpcAnswer>(); BufferBlock<RpcAnswer> _inputRejectedBuffer = new BufferBlock<RpcAnswer>(); BufferBlock<InputTLCombinatorInstance> _inputUnsorted = new BufferBlock<InputTLCombinatorInstance>(); // -- // _inputBufferParcer = new ActionBlock<byte[]>(bytes => ProcessInputBuffer(bytes)); _inputSystemMessages = new ActionBlock<TLCombinatorInstance>(tlci => ProcessSystemMessage(tlci)); _inputUpdates = new ActionBlock<TLCombinatorInstance>(tlci => ProcessUpdateAsync(tlci)); _inputAnswers = new TransformBlock<InputTLCombinatorInstance, RpcAnswer>(tlci => ProcessRpcAnswer(tlci)); // from [_inputBufferBytes] to [_inputBufferTransformer] _inputBufferBytes.LinkTo(_inputBufferParcer); // from [_inputBufferTransformer] to [_inputBuffer] //_inputBufferTransformer.LinkTo(_inputBuffer); // if System then from [_inputBuffer] to [_inputSystemMessages] _inputBuffer.LinkTo(_inputSystemMessages, tlciw => _systemCalls.Contains(tlciw.Combinator.Name)); // if Updates then from [_inputBuffer] to [_inputUpdates] _inputBuffer.LinkTo(_inputUpdates, tlciw => tlciw.Combinator.ValueType.Equals("Updates")); // if rpc_result then from [_inputBuffer] to [_inputRpcAnswers] _inputBuffer.LinkTo(_inputAnswers, tlciw => tlciw.Combinator.Name.Equals("rpc_result")); // if rpc_result then from [_inputBuffer] to [_inputRpcAnswers] //_inputBuffer.LinkTo(_inputUnsorted); // and store it [_inputAnswers] to [_inputAnswersBuffer] to process it _inputAnswers.LinkTo(_inputAnswersBuffer); _inputRejectedBuffer.LinkTo(_inputAnswersBuffer);
ActionBlock
, and rpcAnswers is first converted using TransformBlock
and then added to BufferBlock
. Classification of the packet type occurs inside the BufferBlock
based on the conditions of linking blocks. WriteOnceBlock<RpcAnswer> answer = new WriteOnceBlock<RpcAnswer>(e => e);
_inputAnswersBuffer.LinkTo(answer, new DataflowLinkOptions { MaxMessages = 1 }, i => i.SessionId == _em.SessionId);
return await answer.ReceiveAsync(TimeSpan.FromSeconds(60)).ConfigureAwait(false); //
#if __ANDROID__ public async Task GetAddressbook(Android.Content.Context context) { contacts = new AddressBook(context); #else public async Task GetAddressbook() { contacts = new AddressBook(); #endif if (!await contacts.RequestPermission()) { Trace.WriteLineIf(clientSwitch.TraceInfo, "Permission for contacts denied", "[ContactsPresenter.PopulateAddressbook]"); _view.SendSmallMessage("CONTACTS PERMISSON DENIED"); return; } else { _icv.PlainContacts = new ListItemCollection<ListItemValue>( (from c in contacts where (c.Phones.Count() > 0) select new ListItemValue(c)).ToList()); } }
__ANDROID__
introduced because a context is required to get a list of contacts on Android, but not on other OSes. #region Public Methods public Task<List<T>> GetItemsAsync<T>() where T : IBusinessEntity, new() { return Table<T>().ToListAsync(); } public Task<T> GetItemAsync<T>(int id) where T : IBusinessEntity, new() { return GetAsync<T>(id); } public async Task<bool> CheckRowExistAsync<T>(int id) where T : IBusinessEntity, new() { string tblName = typeof(T).Name; return await ExecuteScalarAsync<int>("select 1 from " + tblName + " where Id = ?", id).ConfigureAwait(false) == 1; } public async Task<int> SaveItemAsync<T>(T item) where T : IBusinessEntity, new() { if (await CheckRowExistAsync<T>(item.Id)) { return await base.UpdateAsync(item).ConfigureAwait(false); } else { return await base.InsertAsync(item).ConfigureAwait(false); } } public Task<int> DeleteItemAsync<T>(int id) where T : IBusinessEntity, new() { return DeleteAsync(new T() { Id = id }); } #endregion
public static string DatabaseFilePath { get { var sqliteFilename = "TalksDb.db3"; #if SILVERLIGHT // Windows Phone expects a local path, not absolute var path = sqliteFilename; #else #if __ANDROID__ // Just use whatever directory SpecialFolder.Personal returns string libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); #else // we need to put in /Library/ on iOS5.1 to meet Apple's iCloud terms // (they don't want non-user-generated data in Documents) string documentsPath= Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // Documents folder string libraryPath = Path.Combine(documentsPath, "..", "Library"); // Library folder #endif var path = Path.Combine(libraryPath, sqliteFilename); #endif return path; } }
App.Current.MainService
. _presenter = App.Current.MainService.CreatePresenter<ChatListPresenter>(typeof(ChatListPresenter), this);
[Activity(Label = "Settings", Theme = "@style/Theme.TalksTheme")] [MetaData("android.support.PARENT_ACTIVITY", Value = "talks.ChatListActivity")] public class SettingsActivity : SherlockActivity, IView
protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); // Set our view from the "main" layout resource SetContentView(Resource.Layout.MessagesScreen); AndroidUtils.SetRobotoFont(this, (ViewGroup)Window.DecorView); _presenter = App.Current.MainService.CreatePresenter<MessagePresenter>(typeof(MessagePresenter), this); _presenter.PlatformSpecificImageResize = AndroidResizeImage; this.ChatId = Intent.GetIntExtra("userid", 0); userName = Intent.GetStringExtra("username"); _button = FindViewById<ImageButton>(Resource.Id.bSendMessage); _button.Click += button_Click; _button.Enabled = false; _message = FindViewById<EditText>(Resource.Id.etMessageToSend); _message.TextChanged += message_TextChanged; _lv = FindViewById<ListView>(Resource.Id.lvMessages); _lv.Adapter = new Adapters.MessagesScreenAdapter(this, this.Messages); }
PhoneFragment _pf = null; CodeFragment _cf = null; SignUpFragment _suf = null; public string PhoneNumber { get { if (_pf != null) { return _pf.Phone; } else { return ""; } } } public string AuthCode { get { return _cf.Code; } } public string Name { get { return _suf.FirstName; } } public string Surname { get { return _suf.Surname; } }
public override bool OnMenuItemSelected(int featureId, Xamarin.ActionbarSherlockBinding.Views.IMenuItem item) { switch (item.ItemId) { // Respond to the action bar's Up/Home button case Android.Resource.Id.Home: NavUtils.NavigateUpFromSameTask(this); return true; case Resource.Id.messages_action_takephoto: _presenter.TakePhoto(this); return true; case Resource.Id.messages_action_gallery: _presenter.PickPhoto(this); return true; case Resource.Id.messages_action_video: _presenter.TakeVideo(this); return true; } return base.OnMenuItemSelected(featureId, item); }
#if __ANDROID__ /// <summary> /// /// </summary> /// <param name="context"></param> /// <returns></returns> public bool TakePhoto(Android.Content.Context context) { var picker = new MediaPicker(context); #else public bool TakePhoto() { var picker = new MediaPicker(); #endif if (picker.IsCameraAvailable) { picker.TakePhotoAsync(new StoreCameraMediaOptions { Name = String.Format("{0:dd_MM_yyyy_HH_mm}.jpg", DateTime.Now), Directory = "TalksPictures" }) .ContinueWith((prevTask) => { if (prevTask.IsCanceled) { _imv.SendSmallMessage("User canceled"); return; } if (PlatformSpecificImageResize != null) { string path = PlatformSpecificImageResize(prevTask.Result); // DomainModel.Message msg = new DomainModel.Message(r.Next(Int32.MaxValue), 0, _imv.ChatId, _imv.PendingMessage, "", 0); _imv.AddMineMessage(msg); } }) .ContinueWith((prevTask) => { if (!prevTask.IsCanceled) { Console.WriteLine("User ok"); } }, TaskScheduler.FromCurrentSynchronizationContext()); return true; } return false; }
Source: https://habr.com/ru/post/194404/
All Articles