private async Task GetRelatedTweetsAsync(RelatedPostsTabModel tab) { await this.workerSemaphore.WaitAsync(); try { await tab.RefreshAsync(this.tw, this._initial, this.workerProgress); this.RefreshTimeline(); } catch (WebApiException ex) { this._myStatusError = true; this.StatusLabel.Text = $"Err:{ex.Message}(GetRelatedTweets)"; } finally { this.workerSemaphore.Release(); } }
public async Task GetRelatedResult(bool read, RelatedPostsTabModel tab) { var targetPost = tab.TargetPost; var relPosts = new Dictionary<Int64, PostClass>(); if (targetPost.TextFromApi.Contains("@") && targetPost.InReplyToStatusId == null) { //検索結果対応 var p = TabInformations.GetInstance()[targetPost.StatusId]; if (p != null && p.InReplyToStatusId != null) { targetPost = p; } else { p = await this.GetStatusApi(read, targetPost.StatusId) .ConfigureAwait(false); targetPost = p; } } relPosts.Add(targetPost.StatusId, targetPost); Exception lastException = null; // in_reply_to_status_id を使用してリプライチェインを辿る var nextPost = FindTopOfReplyChain(relPosts, targetPost.StatusId); var loopCount = 1; while (nextPost.InReplyToStatusId != null && loopCount++ <= 20) { var inReplyToId = nextPost.InReplyToStatusId.Value; var inReplyToPost = TabInformations.GetInstance()[inReplyToId]; if (inReplyToPost == null) { try { inReplyToPost = await this.GetStatusApi(read, inReplyToId) .ConfigureAwait(false); } catch (WebApiException ex) { lastException = ex; break; } } relPosts.Add(inReplyToPost.StatusId, inReplyToPost); nextPost = FindTopOfReplyChain(relPosts, nextPost.StatusId); } //MRTとかに対応のためツイート内にあるツイートを指すURLを取り込む var text = targetPost.Text; var ma = Twitter.StatusUrlRegex.Matches(text).Cast<Match>() .Concat(Twitter.ThirdPartyStatusUrlRegex.Matches(text).Cast<Match>()); foreach (var _match in ma) { Int64 _statusId; if (Int64.TryParse(_match.Groups["StatusId"].Value, out _statusId)) { if (relPosts.ContainsKey(_statusId)) continue; var p = TabInformations.GetInstance()[_statusId]; if (p == null) { try { p = await this.GetStatusApi(read, _statusId) .ConfigureAwait(false); } catch (WebApiException ex) { lastException = ex; break; } } if (p != null) relPosts.Add(p.StatusId, p); } } relPosts.Values.ToList().ForEach(p => { if (p.IsMe && !read && this._readOwnPost) p.IsRead = true; else p.IsRead = read; tab.AddPostQueue(p); }); if (lastException != null) throw new WebApiException(lastException.Message, lastException); }
/// <summary> /// 指定されたツイートに対する関連発言タブを開きます /// </summary> /// <param name="post">表示する対象となるツイート</param> /// <exception cref="TabException">名前の重複が多すぎてタブを作成できない場合</exception> private async Task OpenRelatedTab(PostClass post) { var tabRelated = this._statuses.GetTabByType<RelatedPostsTabModel>(); if (tabRelated != null) { this.RemoveSpecifiedTab(tabRelated.TabName, confirm: false); } var tabName = this._statuses.MakeTabName("Related Tweets"); tabRelated = new RelatedPostsTabModel(tabName, post); tabRelated.UnreadManage = false; tabRelated.Notify = false; this._statuses.AddTab(tabRelated); this.AddNewTab(tabRelated, startup: false); TabPage tabPage; for (int i = 0; i < this.ListTab.TabPages.Count; i++) { tabPage = this.ListTab.TabPages[i]; if (tabName == tabPage.Text) { this.ListTab.SelectedIndex = i; break; } } await this.GetRelatedTweetsAsync(tabRelated); tabPage = this.ListTab.TabPages.Cast<TabPage>() .FirstOrDefault(x => x.Text == tabRelated.TabName); if (tabPage != null) { // TODO: 非同期更新中にタブが閉じられている場合を厳密に考慮したい var listView = (DetailsListView)tabPage.Tag; var targetPost = tabRelated.TargetPost; var index = tabRelated.IndexOf(targetPost.RetweetedId ?? targetPost.StatusId); if (index != -1 && index < listView.Items.Count) { listView.SelectedIndices.Add(index); listView.Items[index].Focused = true; } } }