public async Task DownloadTransactions() { if (HasMissingSecretKeys) { var missingIds = MissingSecretKeys.Keys.ToArray(); foreach (var missingId in missingIds) { if (ServiceNode.GetSecretKeys(Index, missingId).Count > 0) { MissingSecretKeys.Remove(missingId); } } } await UIApp.PubSub.PublishAsync(new QueryTodoListEvent(QueryTodoResult.DownloadingData, this)); var lastId = Math.Max(LastProcessedTransactionId, Operation.FirstTransactionId); var download = new GroupTransactionDownload(ListId, ServiceNode.GetTransactionDownloadManager(TodoServiceInfo.TodoDataChainIndex)) { MinimalTransactionId = lastId, DownloadAttachements = false }; LastDownloadResult = await download.DownloadTransactions(); if (LastDownloadResult.Ok) { LastDownloadResult.Transactions.Sort((a, b) => a.TransactionId.CompareTo(b.TransactionId)); foreach (var transaction in LastDownloadResult.Transactions) { transaction.Tag = ServiceNode; await ProcessTransaction(transaction); } await Todo.SaveAsync(); await UIApp.PubSub.PublishAsync(new QueryTodoListEvent(QueryTodoResult.LiveData, this)); } else { await UIApp.PubSub.PublishAsync(new QueryTodoListEvent(QueryTodoResult.DownloadError, this)); } }
public async Task <VerificationResult> DownloadVerificationResult(ServiceNode serviceNode, long transactionId) { try { if (serviceNode == null) { return(null); } var transaction = await serviceNode.GetTransactionDownloadManager(VerifyServiceInfo.ChainIndex).DownloadTransaction(transactionId, true, false); if (transaction.Count == 1) { transaction.Transactions[0].Tag = serviceNode; return(await GetVerificationResult(transaction.Transactions[0])); } } catch (Exception ex) { Log.IgnoreException(ex); } return(null); }
// active polling is meh, should be replace by a simple notification server, but it's ok for now async Task PollLoop() { var profileInfo = (await ProfileManager.Current.GetProfileData(AccountId, ProfileDownloadType.ForceDownload, false)).ProfileInfo; if (profileInfo != null) { ProfileInfo = profileInfo; } await DownloadInboxRecords(AccountId); await QueryMissingProfiles(); while (true) { try { await DownloadFriends(false); var save = false; var lastAccountTransaction = (await PreviousAccountTransaction.DownloadLastTransactionInfo(_client, ChainType.Data, ChainId, MessageServiceInfo.MessageDataChainIndex, AccountId))?.Item; var lastReceiverTransaction = (await Receiver.DownloadLastTransactionInfo(_client, ChainType.Data, ChainId, MessageServiceInfo.MessageDataChainIndex, AccountId))?.Item; if (_lastAccountTransaction == null) { _lastAccountTransaction = lastAccountTransaction; save = true; } if (_lastReceivedTransaction == null) { _lastReceivedTransaction = lastReceiverTransaction; save = true; } var result = new PollResult(); if (lastAccountTransaction != null) { if (lastAccountTransaction.TransactionId > _lastAccountTransaction.TransactionId) { var download = new AccountTransactionDownload(AccountId, ServiceNode.GetTransactionDownloadManager(MessageServiceInfo.MessageDataChainIndex)) { MinimalTransactionId = Math.Max(1, _lastAccountTransaction.TransactionId) }; if (await Poll(download, result)) { _lastAccountTransaction = lastAccountTransaction; save = true; } } } if (lastReceiverTransaction != null) { if (lastReceiverTransaction.TransactionId > _lastReceivedTransaction.TransactionId) { var download = new ReceiverTransactionDownload(AccountId, ServiceNode.GetTransactionDownloadManager(MessageServiceInfo.MessageDataChainIndex)) { MinimalTransactionId = Math.Max(1, _lastReceivedTransaction.TransactionId) }; if (await Poll(download, result)) { _lastReceivedTransaction = lastReceiverTransaction; save = true; } } } if (result.UpdateFriends) { await DownloadFriends(false); } foreach (var index in result.Indices) { var chat = GetChat(index, true); if (!IsNodeChat(chat)) { _chats[chat.Index] = chat; GenerateSubmitAccount(index); await GenerateDefaultExchangeKeys(); } await chat.DownloadMessages(false); } if (result.Indices.Count > 0) { await UIApp.PubSub.PublishAsync(new MessageNodeRefreshEvent(this)); } if (save) { await SaveAsync(); } await Task.Delay(5000); } catch (Exception ex) { Log.HandleException(ex); } } }
public async Task <InboxRecordDownloadEvent> DownloadInboxRecords(long accountId) { var items = new List <InboxNameRecordInfo>(); var result = MessageNodeEventResultTypes.Unknown; if (!ServiceNode.HasUnlockedServiceAccount) { result = MessageNodeEventResultTypes.NoUnlockedAccount; goto end; } var next = (await _client.DownloadNextServiceAccountKeyIndex(accountId, ChainId)).Data; if (next == null || !next.IsValid) { result = MessageNodeEventResultTypes.DownloadFailed; goto end; } var keyCount = next.Item - 1; var indices = new List <Chain.Index>(); for (short i = 0; i <= keyCount; i++) { indices.Add(MessageServiceInfo.GetInboxIndex(i)); } var data = await AccountIndex.DownloadLastTransactionInfoIndicesBatch(_client, ChainType.Data, ChainId, MessageServiceInfo.MessageDataChainIndex, accountId, indices); if (data == null) { result = MessageNodeEventResultTypes.DownloadFailed; goto end; } if (data.ResultType != ResultTypes.Ok) { result = MessageNodeEventResultTypes.InvalidAccount; goto end; } var batch = data.Item; var count = batch.Count; for (short i = 0; i < count; i++) { InboxNameRecord record = null; (var success, _, var last) = batch.GetInfo(i); if (success) { try { var transactionData = await ServiceNode.GetTransactionDownloadManager(MessageServiceInfo.MessageDataChainIndex).DownloadTransaction(last.TransactionId); if (transactionData.Ok && transactionData.Count == 1 && transactionData.Transactions[0].Transaction.TryGetFeature <Data>(Data.FeatureId, out var featureData)) { var recordData = featureData.Items[0].BinaryValue; record = new InboxNameRecord(new Unpacker(recordData)); } } catch { } } items.Add(new InboxNameRecordInfo(i, record)); } if (items.Count > 0) { result = MessageNodeEventResultTypes.Ok; if (accountId == AccountId) { InboxNameRecords = items; } } else { result = MessageNodeEventResultTypes.InvalidAccount; } end: var @event = new InboxRecordDownloadEvent(accountId, items, this, result); await UIApp.PubSub.PublishAsync(@event); return(@event); }
public StatusAccountPage(ProfileDataResult profileData, ServiceNode serviceNode, long accountId, StatusAccountProfileType profileType, long transactionId) : base("StatusAccountPage") { Subscribe <SubscriptionEvent>(Subscription); Subscribe <ProfileDataResultEvent>(ProfileData); StackLayout.Suspended = true; _transactionId = transactionId; _profileType = profileType; _serviceNode = serviceNode; _status = StatusApp.Current.GetStatus(serviceNode); _accountId = accountId; _accountIndex = Chain.Index.New().Add(_accountId).Build(); _messagesDownload = new AccountIndexTransactionDownload(accountId, StatusServiceInfo.MessageIndex, serviceNode.GetTransactionDownloadManager(StatusServiceInfo.StatusDataChainIndex)) { Count = 10 }; AddTitleRow("Title"); if (profileType == StatusAccountProfileType.Small || transactionId > 0) { var row = new StatusProfileButtonRow(serviceNode, _accountId, profileData?.ProfileInfo, profileData, async(button) => { await Navigation.PushAsync(new StatusAccountPage(profileData, serviceNode, accountId, StatusAccountProfileType.Big, transactionId)); }, false); AddRow(row); } if (profileType == StatusAccountProfileType.Big && transactionId <= 0) { if (_status != null) { AddHeaderRow("Subscription"); _subscribe = AddSwitchRow("Subscribe"); _subscribe.Switch.IsToggled = _status.IsSubscribed(_accountId); _subscribe.Switch.ToggledAsync = Subscribe_Toggled; _subscribe.SetDetailViewIcon(Icons.Check); _notification = AddSwitchRow("Notification"); _notification.Switch.IsToggled = UIApp.Current.IsPushChannelSubscribed(_accountIndex); _notification.Switch.ToggledAsync = Notification_Toggled; _notification.SetDetailViewIcon(Icons.Bell); AddFooterRow(); } if (profileData == null || profileType == StatusAccountProfileType.Big) { UIApp.Run(() => ProfileManager.Current.GetProfileData(_accountId, ProfileDownloadType.ForceDownload, true)); } } IsBusy = true; }
// TODO: Maybe add a timer to prevent refresh spamming public static async Task DownloadCoreAccountTransaction(bool queryOlder = false) { if (!HasCoreAccount) { return; } if (_busy) { return; } _busy = true; try { await _serviceNode.Client.SetTargetChain(Protocol.CoreChainId); if (_transactionDownload == null || _transactionDownload.AccountId != CurrentAccountId) { _transactionDownload = new CoreTransactionsDownload(CurrentAccountId, _serviceNode.GetTransactionDownloadManager(0)); } _transactionDownload.QueryOlder = queryOlder; var result = await _transactionDownload.DownloadTransactions(); var evt = new TransactionDownloadEvent <CoreOperation>(); evt.AddResult(result, _transactionDownload, null); await UIApp.PubSub.PublishAsync(evt); } catch (Exception ex) { Log.HandleException(ex); } _busy = false; }