public void EmptyRuleTest() { var filter = new PostFilterRule { }; var post = new PostClass { ScreenName = "hogehoge" }; Assert.Equal(MyCommon.HITRESULT.None, filter.ExecFilter(post)); }
public void CloneTest() { var post = new PostClass(); var clonePost = post.Clone(); TestUtils.CheckDeepCloning(post, clonePost); }
public void NameTest() { var filter = new FiltersClass(); PostClass post; filter.NameFilter = "hoge"; post = new PostClass { ScreenName = "hoge", Text = "test" }; Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.CopyAndMark)); filter.NameFilter = "hoge"; post = new PostClass { ScreenName = "foo", Text = "test" }; Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.None)); // NameFilter は RetweetedBy にもマッチする filter.NameFilter = "hoge"; post = new PostClass { ScreenName = "foo", Text = "test", RetweetedBy = "hoge" }; Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.CopyAndMark)); filter.NameFilter = "hoge"; post = new PostClass { ScreenName = "foo", Text = "test", RetweetedBy = "bar" }; Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.None)); // NameFilter は部分一致ではない filter.NameFilter = "hoge"; post = new PostClass { ScreenName = "hogehoge", Text = "test" }; Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.None)); // 大小文字を区別しないオプション filter.NameFilter = "hoge"; filter.CaseSensitive = false; post = new PostClass { ScreenName = "Hoge", Text = "test" }; Assert.That(filter.IsHit(post), Is.EqualTo(MyCommon.HITRESULT.CopyAndMark)); }
public void ExcludeOnlyTest() { var filter = new PostFilterRule { ExFilterName = "hogehoge" }; var post = new PostClass { ScreenName = "hogehoge" }; Assert.Equal(MyCommon.HITRESULT.Exclude, filter.ExecFilter(post)); }
public void MatchOnlyTest() { var filter = new PostFilterRule { FilterName = "hogehoge" }; var post = new PostClass { ScreenName = "hogehoge" }; Assert.Equal(MyCommon.HITRESULT.CopyAndMark, filter.ExecFilter(post)); }
public async Task ShowThumbnailAsync(PostClass post, CancellationToken cancelToken) { var loadTasks = new List<Task>(); this.scrollBar.Enabled = false; if (post.Media.Count == 0 && post.PostGeo.Lat == 0 && post.PostGeo.Lng == 0) { this.SetThumbnailCount(0); if (this.ThumbnailNotFound != null) this.ThumbnailNotFound(this, EventArgs.Empty); return; } var thumbnails = (await this.GetThumbailInfoAsync(post, cancelToken)) .ToArray(); cancelToken.ThrowIfCancellationRequested(); this.SetThumbnailCount(thumbnails.Length); if (thumbnails.Length == 0) { if (this.ThumbnailNotFound != null) this.ThumbnailNotFound(this, EventArgs.Empty); return; } for (int i = 0; i < thumbnails.Length; i++) { var thumb = thumbnails[i]; var picbox = this.pictureBox[i]; picbox.Tag = thumb; var loadTask = this.SetThumbnailImageAsync(picbox, thumb, cancelToken); loadTasks.Add(loadTask); var tooltipText = thumb.TooltipText; if (!string.IsNullOrEmpty(tooltipText)) { this.toolTip.SetToolTip(picbox, tooltipText); } cancelToken.ThrowIfCancellationRequested(); } if (thumbnails.Length > 1) this.scrollBar.Enabled = true; if (this.ThumbnailLoading != null) this.ThumbnailLoading(this, EventArgs.Empty); await Task.WhenAll(loadTasks).ConfigureAwait(false); }
public async Task ShowThumbnailAsync(PostClass post, CancellationToken cancelToken) { var loadTasks = new List<Task>(); this.scrollBar.Enabled = false; this.scrollBar.Visible = false; if (post.ExpandedUrls.Length == 0 && post.Media.Count == 0 && post.PostGeo == null) { this.SetThumbnailCount(0); return; } var thumbnails = (await this.GetThumbailInfoAsync(post, cancelToken)) .ToArray(); cancelToken.ThrowIfCancellationRequested(); this.SetThumbnailCount(thumbnails.Length); if (thumbnails.Length == 0) return; for (int i = 0; i < thumbnails.Length; i++) { var thumb = thumbnails[i]; var picbox = this.pictureBox[i]; picbox.Tag = thumb; picbox.ContextMenuStrip = this.contextMenuStrip; var loadTask = picbox.SetImageFromTask(() => thumb.LoadThumbnailImageAsync(cancelToken)); loadTasks.Add(loadTask); var tooltipText = thumb.TooltipText; if (!string.IsNullOrEmpty(tooltipText)) { this.toolTip.SetToolTip(picbox, tooltipText); picbox.AccessibleDescription = tooltipText; } cancelToken.ThrowIfCancellationRequested(); } if (thumbnails.Length > 1) { this.scrollBar.Enabled = true; this.scrollBar.Visible = true; } this.ThumbnailLoading?.Invoke(this, EventArgs.Empty); await Task.WhenAll(loadTasks).ConfigureAwait(false); }
public void CancelAsyncTest() { using (var thumbbox = new TweetThumbnail()) { var post = new PostClass(); SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); var task = thumbbox.ShowThumbnailAsync(post); thumbbox.CancelAsync(); Assert.That(task.IsCanceled, Is.True); } }
public void CancelAsyncTest() { using (var thumbbox = new TweetThumbnail()) { var post = new PostClass(); SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); var task = thumbbox.ShowThumbnailAsync(post); thumbbox.CancelAsync(); Assert.Throws<AggregateException>(() => task.Wait()); Assert.True(task.IsCanceled); } }
public void NullTest() { var filter = new PostFilterRule { FilterName = null, FilterSource = null, ExFilterName = null, ExFilterSource = null, }; var post = new PostClass { ScreenName = "hogehoge" }; Assert.Equal(MyCommon.HITRESULT.None, filter.ExecFilter(post)); Assert.Throws<ArgumentNullException>(() => filter.FilterBody = null); Assert.Throws<ArgumentNullException>(() => filter.ExFilterBody = null); }
public override Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { return Task.Run<ThumbnailInfo>(() => { var match = this.regex.Match(url); if (!match.Success) return null; return new MockThumbnailInfo { ImageUrl = url, ThumbnailUrl = match.Result(this.replaceUrl), TooltipText = this.replaceTooltip != null ? match.Result(this.replaceTooltip) : null, }; }); }
public void FormatQuoteTweetHtml_PostClassTest() { var post = new PostClass { StatusId = 12345L, Nickname = "upsilon", ScreenName = "kim_upsilon", Text = "<a href=\"https://twitter.com/twitterapi\">@twitterapi</a> hogehoge", CreatedAt = new DateTime(2015, 3, 30, 3, 30, 0), }; // PostClass.Text はリンクを除去するのみでエスケープは行わない // (TweetFormatter によって既にエスケープされた文字列が格納されているため) var expected = "<a class=\"quote-tweet-link\" href=\"//opentween/status/12345\">" + "<blockquote class=\"quote-tweet\">" + "<p>@twitterapi hogehoge</p> — upsilon (@kim_upsilon) " + DateTime.Parse("2015/03/30 3:30:00") + "</blockquote></a>"; Assert.Equal(expected, TweetDetailsView.FormatQuoteTweetHtml(post, isReply: false)); }
public void FieldNullAwareTest() { var nullPost = new PostClass { Source = null }; // Source が null であっても ArgumentNullException 等を投げない var filter1 = new PostFilterRule { FilterSource = "(hoge){2}", UseRegex = true, }; Assert.Equal(MyCommon.HITRESULT.None, filter1.ExecFilter(nullPost)); // null は空文字列と同じ扱いにする var filter2 = new PostFilterRule { FilterSource = "^$", UseRegex = true, }; Assert.Equal(MyCommon.HITRESULT.CopyAndMark, filter2.ExecFilter(nullPost)); }
public string GetStatusApi(bool read, Int64 id, ref PostClass post) { if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return string.Empty; if (MyCommon._endingFlag) return string.Empty; HttpStatusCode res = HttpStatusCode.BadRequest; var content = string.Empty; try { res = twCon.ShowStatuses(id, ref content); } catch(Exception ex) { return "Err:" + ex.Message; } switch (res) { case HttpStatusCode.OK: Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid; break; case HttpStatusCode.Unauthorized: Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid; return Properties.Resources.Unauthorized; case HttpStatusCode.BadRequest: return "Err:API Limits?"; case HttpStatusCode.Forbidden: return "Err:protected user's tweet"; default: return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")"; } TwitterDataModel.Status status; try { status = MyCommon.CreateDataFromJson<TwitterDataModel.Status>(content); } catch(SerializationException ex) { MyCommon.TraceOut(ex.Message + Environment.NewLine + content); return "Json Parse Error(DataContractJsonSerializer)"; } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); return "Invalid Json!"; } var item = CreatePostsFromStatusData(status); if (item == null) return "Err:Can't create post"; item.IsRead = read; if (item.IsMe && !read && _readOwnPost) item.IsRead = true; post = item; return string.Empty; }
public string RemoveDirectMessage(long id, PostClass post) { if (MyCommon._endingFlag) return string.Empty; if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return string.Empty; if (MyCommon.TwitterApiInfo.AccessLevel != ApiAccessLevel.None) { if (!MyCommon.TwitterApiInfo.IsDirectMessagePermission) return "Auth Err:try to re-authorization."; } HttpStatusCode res = HttpStatusCode.BadRequest; //if (post.IsMe) // _deletemessages.Add(post) //} try { res = twCon.DestroyDirectMessage(id); } catch(Exception ex) { return "Err:" + ex.Message; } switch (res) { case HttpStatusCode.OK: Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid; return string.Empty; case HttpStatusCode.Unauthorized: Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid; return Properties.Resources.Unauthorized; case HttpStatusCode.NotFound: return string.Empty; default: return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")"; } }
public string GetFavoritesApi(bool read, MyCommon.WORKERTYPE gType, bool more) { if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return string.Empty; if (MyCommon._endingFlag) return string.Empty; HttpStatusCode res; var content = string.Empty; var count = AppendSettingDialog.Instance.CountApi; if (AppendSettingDialog.Instance.UseAdditionalCount && AppendSettingDialog.Instance.FavoritesCountApi != 0) { count = AppendSettingDialog.Instance.FavoritesCountApi; } // 前ページ取得の場合はページカウンタをインクリメント、それ以外の場合はページカウンタリセット if (more) { page_++; } else { page_ = 1; } try { res = twCon.Favorites(count, page_, ref content); } catch(Exception ex) { return "Err:" + ex.Message + "(" + MethodBase.GetCurrentMethod().Name + ")"; } switch (res) { case HttpStatusCode.OK: Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid; break; case HttpStatusCode.Unauthorized: Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid; return Properties.Resources.Unauthorized; case HttpStatusCode.BadRequest: return "Err:API Limits?"; default: return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")"; } var serializer = new DataContractJsonSerializer(typeof(List<TwitterDataModel.Status>)); List<TwitterDataModel.Status> item; try { item = MyCommon.CreateDataFromJson<List<TwitterDataModel.Status>>(content); } catch(SerializationException ex) { MyCommon.TraceOut(ex.Message + Environment.NewLine + content); return "Json Parse Error(DataContractJsonSerializer)"; } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); return "Invalid Json!"; } foreach (var status in item) { var post = new PostClass(); TwitterDataModel.Entities entities; try { post.StatusId = status.Id; //二重取得回避 lock (LockObj) { if (TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites).Contains(post.StatusId)) continue; } //Retweet判定 if (status.RetweetedStatus != null) { var retweeted = status.RetweetedStatus; post.CreatedAt = MyCommon.DateTimeParse(retweeted.CreatedAt); //Id post.RetweetedId = post.StatusId; //本文 post.TextFromApi = retweeted.Text; entities = retweeted.Entities; //Source取得(htmlの場合は、中身を取り出し) post.Source = retweeted.Source; //Reply先 long inReplyToStatusId; long.TryParse(retweeted.InReplyToStatusId, out inReplyToStatusId); post.InReplyToStatusId = inReplyToStatusId; post.InReplyToUser = retweeted.InReplyToScreenName; long inReplyToUserId; long.TryParse(retweeted.InReplyToUserId, out inReplyToUserId); post.InReplyToUserId = inReplyToUserId; post.IsFav = true; //以下、ユーザー情報 var user = retweeted.User; post.UserId = user.Id; post.ScreenName = user.ScreenName; post.Nickname = user.Name.Trim(); post.ImageUrl = user.ProfileImageUrl; post.IsProtect = user.Protected; //Retweetした人 post.RetweetedBy = status.User.ScreenName; post.IsMe = post.RetweetedBy.ToLower().Equals(_uname); } else { post.CreatedAt = MyCommon.DateTimeParse(status.CreatedAt); //本文 post.TextFromApi = status.Text; entities = status.Entities; //Source取得(htmlの場合は、中身を取り出し) post.Source = status.Source; long inReplyToStatusId; long.TryParse(status.InReplyToStatusId, out inReplyToStatusId); post.InReplyToStatusId = inReplyToStatusId; post.InReplyToUser = status.InReplyToScreenName; long inReplyToUserId; long.TryParse(status.InReplyToUserId, out inReplyToUserId); post.InReplyToUserId = inReplyToUserId; post.IsFav = true; //以下、ユーザー情報 var user = status.User; post.UserId = user.Id; post.ScreenName = user.ScreenName; post.Nickname = user.Name.Trim(); post.ImageUrl = user.ProfileImageUrl; post.IsProtect = user.Protected; post.IsMe = post.ScreenName.ToLower().Equals(_uname); } //HTMLに整形 string textFromApi = post.TextFromApi; post.Text = CreateHtmlAnchor(ref textFromApi, post.ReplyToList, entities, post.Media); post.TextFromApi = textFromApi; post.TextFromApi = this.ReplaceTextFromApi(post.TextFromApi, entities); post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi); post.TextFromApi = post.TextFromApi.Replace("<3", "?"); //Source整形 CreateSource(ref post); post.IsRead = read; post.IsReply = post.ReplyToList.Contains(_uname); post.IsExcludeReply = false; if (post.IsMe) { post.IsOwl = false; } else { if (followerId.Count > 0) post.IsOwl = !followerId.Contains(post.UserId); } post.IsDm = false; } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); continue; } TabInformations.GetInstance().AddPost(post); } return string.Empty; }
public string GetSearch(bool read, TabClass tab, bool more) { if (MyCommon._endingFlag) return string.Empty; HttpStatusCode res; var content = string.Empty; var page = 0; var sinceId = 0; var count = 100; if (AppendSettingDialog.Instance.UseAdditionalCount && AppendSettingDialog.Instance.SearchCountApi != 0) { count = AppendSettingDialog.Instance.SearchCountApi; } else { count = AppendSettingDialog.Instance.CountApi; } if (more) { page = tab.GetSearchPage(count); } else { sinceId = (int)tab.SinceId; } try { // TODO:一時的に40>100件に 件数変更UI作成の必要あり res = twCon.Search(tab.SearchWords, tab.SearchLang, count, page, sinceId, ref content); } catch(Exception ex) { return "Err:" + ex.Message; } switch (res) { case HttpStatusCode.BadRequest: return "Invalid query"; case HttpStatusCode.NotFound: return "Invalid query"; case HttpStatusCode.PaymentRequired: //API Documentには420と書いてあるが、該当コードがないので402にしてある return "Search API Limit?"; case HttpStatusCode.OK: break; default: return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")"; } if (!TabInformations.GetInstance().ContainsTab(tab)) return string.Empty; content = Regex.Replace(content, @"[\x00-\x1f-[\x0a\x0d]]+", " "); var xdoc = new XmlDocument(); try { xdoc.LoadXml(content); } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); return "Invalid ATOM!"; } var nsmgr = new XmlNamespaceManager(xdoc.NameTable); nsmgr.AddNamespace("search", "http://www.w3.org/2005/Atom"); nsmgr.AddNamespace("twitter", "http://api.twitter.com/"); nsmgr.AddNamespace("georss", "http://www.georss.org/georss"); foreach (var xentryNode in xdoc.DocumentElement.SelectNodes("/search:feed/search:entry", nsmgr)) { var xentry = (XmlElement)xentryNode; var post = new PostClass(); try { post.StatusId = long.Parse(xentry["id"].InnerText.Split(':')[2]); if (TabInformations.GetInstance().ContainsKey(post.StatusId, tab.TabName)) continue; post.CreatedAt = DateTime.Parse(xentry["published"].InnerText); //本文 post.TextFromApi = xentry["title"].InnerText; //Source取得(htmlの場合は、中身を取り出し) post.Source = xentry["twitter:source"].InnerText; post.InReplyToStatusId = 0; post.InReplyToUser = string.Empty; post.InReplyToUserId = 0; post.IsFav = false; // Geoが勝手に付加されるバグがいっこうに修正されないので暫定的にGeo情報を無視する if (xentry["twitter:geo"].HasChildNodes) { var pnt = ((XmlElement)xentry.SelectSingleNode("twitter:geo/georss:point", nsmgr)).InnerText.Split(' '); post.PostGeo = new PostClass.StatusGeo {Lat = Double.Parse(pnt[0]), Lng = Double.Parse(pnt[1])}; } //以下、ユーザー情報 var xUentry = (XmlElement)xentry.SelectSingleNode("./search:author", nsmgr); post.UserId = 0; post.ScreenName = xUentry["name"].InnerText.Split(' ')[0].Trim(); post.Nickname = xUentry["name"].InnerText.Substring(post.ScreenName.Length).Trim(); if (post.Nickname.Length > 2) { post.Nickname = post.Nickname.Substring(1, post.Nickname.Length - 2); } else { post.Nickname = post.ScreenName; } post.ImageUrl = ((XmlElement)xentry.SelectSingleNode("./search:link[@type='image/png']", nsmgr)).GetAttribute("href"); post.IsProtect = false; post.IsMe = post.ScreenName.ToLower().Equals(_uname); //HTMLに整形 post.Text = CreateHtmlAnchor(HttpUtility.HtmlEncode(post.TextFromApi), post.ReplyToList, post.Media); post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi); //Source整形 CreateSource(ref post); post.IsRead = read; post.IsReply = post.ReplyToList.Contains(_uname); post.IsExcludeReply = false; post.IsOwl = false; if (post.IsMe && !read && _readOwnPost) post.IsRead = true; post.IsDm = false; post.RelTabName = tab.TabName; if (!more && post.StatusId > tab.SinceId) tab.SinceId = post.StatusId; } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); continue; } //this._dIcon.Add(post.ImageUrl, null); TabInformations.GetInstance().AddPost(post); } // TODO // 遡るための情報max_idやnext_pageの情報を保持する #if UNDEFINED__ var xNode = xdoc.DocumentElement.SelectSingleNode("/search:feed/twitter:warning", nsmgr); if (xNode != null) { return "Warn:" + xNode.InnerText + "(" + MethodBase.GetCurrentMethod().Name + ")"; } #endif return string.Empty; }
private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCount, bool newMentions) { if (notifyPosts != null && notifyPosts.Length > 0 && this.SettingDialog.ReadOwnPost && notifyPosts.All((post) => { return post.UserId == tw.UserId || post.ScreenName == tw.Username; })) { return; } //新着通知 if (BalloonRequired()) { if (notifyPosts != null && notifyPosts.Length > 0) { //Growlは一個ずつばらして通知。ただし、3ポスト以上あるときはまとめる if (SettingDialog.IsNotifyUseGrowl) { StringBuilder sb = new StringBuilder(); bool reply = false; bool dm = false; foreach (PostClass post in notifyPosts) { if (!(notifyPosts.Length > 3)) { sb.Clear(); reply = false; dm = false; } if (post.IsReply && !post.IsExcludeReply) reply = true; if (post.IsDm) dm = true; if (sb.Length > 0) sb.Append(System.Environment.NewLine); switch (SettingDialog.NameBalloon) { case MyCommon.NameBalloonEnum.UserID: sb.Append(post.ScreenName).Append(" : "); break; case MyCommon.NameBalloonEnum.NickName: sb.Append(post.Nickname).Append(" : "); break; } sb.Append(post.TextFromApi); if (notifyPosts.Length > 3) { if (notifyPosts.Last() != post) continue; } StringBuilder title = new StringBuilder(); GrowlHelper.NotifyType nt; if (SettingDialog.DispUsername) { title.Append(tw.Username); title.Append(" - "); } else { //title.Clear(); } if (dm) { //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [DM] " + Properties.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + Properties.Resources.RefreshDirectMessageText2; title.Append(Application.ProductName); title.Append(" [DM] "); title.Append(Properties.Resources.RefreshDirectMessageText1); title.Append(" "); title.Append(addCount); title.Append(Properties.Resources.RefreshDirectMessageText2); nt = GrowlHelper.NotifyType.DirectMessage; } else if (reply) { //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [Reply!] " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2; title.Append(Application.ProductName); title.Append(" [Reply!] "); title.Append(Properties.Resources.RefreshTimelineText1); title.Append(" "); title.Append(addCount); title.Append(Properties.Resources.RefreshTimelineText2); nt = GrowlHelper.NotifyType.Reply; } else { //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info; //NotifyIcon1.BalloonTipTitle += Application.ProductName + " " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2; title.Append(Application.ProductName); title.Append(" "); title.Append(Properties.Resources.RefreshTimelineText1); title.Append(" "); title.Append(addCount); title.Append(Properties.Resources.RefreshTimelineText2); nt = GrowlHelper.NotifyType.Notify; } string bText = sb.ToString(); if (string.IsNullOrEmpty(bText)) return; gh.Notify(nt, post.StatusId.ToString(), title.ToString(), bText, this.TIconDic[post.ImageUrl], post.ImageUrl); } } else { StringBuilder sb = new StringBuilder(); bool reply = false; bool dm = false; foreach (PostClass post in notifyPosts) { if (post.IsReply && !post.IsExcludeReply) reply = true; if (post.IsDm) dm = true; if (sb.Length > 0) sb.Append(System.Environment.NewLine); switch (SettingDialog.NameBalloon) { case MyCommon.NameBalloonEnum.UserID: sb.Append(post.ScreenName).Append(" : "); break; case MyCommon.NameBalloonEnum.NickName: sb.Append(post.Nickname).Append(" : "); break; } sb.Append(post.TextFromApi); } //if (SettingDialog.DispUsername) { NotifyIcon1.BalloonTipTitle = tw.Username + " - "; } else { NotifyIcon1.BalloonTipTitle = ""; } StringBuilder title = new StringBuilder(); ToolTipIcon ntIcon; if (SettingDialog.DispUsername) { title.Append(tw.Username); title.Append(" - "); } else { //title.Clear(); } if (dm) { //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [DM] " + Properties.Resources.RefreshDirectMessageText1 + " " + addCount.ToString() + Properties.Resources.RefreshDirectMessageText2; ntIcon = ToolTipIcon.Warning; title.Append(Application.ProductName); title.Append(" [DM] "); title.Append(Properties.Resources.RefreshDirectMessageText1); title.Append(" "); title.Append(addCount); title.Append(Properties.Resources.RefreshDirectMessageText2); } else if (reply) { //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; //NotifyIcon1.BalloonTipTitle += Application.ProductName + " [Reply!] " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2; ntIcon = ToolTipIcon.Warning; title.Append(Application.ProductName); title.Append(" [Reply!] "); title.Append(Properties.Resources.RefreshTimelineText1); title.Append(" "); title.Append(addCount); title.Append(Properties.Resources.RefreshTimelineText2); } else { //NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info; //NotifyIcon1.BalloonTipTitle += Application.ProductName + " " + Properties.Resources.RefreshTimelineText1 + " " + addCount.ToString() + Properties.Resources.RefreshTimelineText2; ntIcon = ToolTipIcon.Info; title.Append(Application.ProductName); title.Append(" "); title.Append(Properties.Resources.RefreshTimelineText1); title.Append(" "); title.Append(addCount); title.Append(Properties.Resources.RefreshTimelineText2); } string bText = sb.ToString(); if (string.IsNullOrEmpty(bText)) return; //NotifyIcon1.BalloonTipText = sb.ToString(); //NotifyIcon1.ShowBalloonTip(500); NotifyIcon1.BalloonTipTitle = title.ToString(); NotifyIcon1.BalloonTipText = bText; NotifyIcon1.BalloonTipIcon = ntIcon; NotifyIcon1.ShowBalloonTip(500); } } } //サウンド再生 if (!_initial && SettingDialog.PlaySound && !string.IsNullOrEmpty(soundFile)) { try { string dir = Application.StartupPath; if (Directory.Exists(Path.Combine(dir, "Sounds"))) { dir = Path.Combine(dir, "Sounds"); } using (SoundPlayer player = new SoundPlayer(Path.Combine(dir, soundFile))) { player.Play(); } } catch (Exception) { } } //mentions新着時に画面ブリンク if (!_initial && SettingDialog.BlinkNewMentions && newMentions && Form.ActiveForm == null) { Win32Api.FlashMyWindow(this.Handle, Win32Api.FlashSpecification.FlashTray, 3); } }
private void RemovePostFromFavTab(Int64[] ids) { string favTabName = _statuses.GetTabByType(MyCommon.TabUsageType.Favorites).TabName; int fidx = 0; if (_curTab.Text.Equals(favTabName)) { if (_curList.FocusedItem != null) fidx = _curList.FocusedItem.Index; else if (_curList.TopItem != null) fidx = _curList.TopItem.Index; else fidx = 0; } foreach (long i in ids) { try { _statuses.RemoveFavPost(i); } catch (Exception) { continue; } } if (_curTab != null && _curTab.Text.Equals(favTabName)) { _itemCache = null; //キャッシュ破棄 _postCache = null; _curPost = null; //_curItemIndex = -1; } foreach (TabPage tp in ListTab.TabPages) { if (tp.Text == favTabName) { ((DetailsListView)tp.Tag).VirtualListSize = _statuses.Tabs[favTabName].AllCount; break; } } if (_curTab.Text.Equals(favTabName)) { do { _curList.SelectedIndices.Clear(); } while (_curList.SelectedIndices.Count > 0); if (_statuses.Tabs[favTabName].AllCount > 0) { if (_statuses.Tabs[favTabName].AllCount - 1 > fidx && fidx > -1) { _curList.SelectedIndices.Add(fidx); } else { _curList.SelectedIndices.Add(_statuses.Tabs[favTabName].AllCount - 1); } if (_curList.SelectedIndices.Count > 0) { _curList.EnsureVisible(_curList.SelectedIndices[0]); _curList.FocusedItem = _curList.Items[_curList.SelectedIndices[0]]; } } } }
private void MyList_SelectedIndexChanged(object sender, EventArgs e) { if (_curList == null || _curList.SelectedIndices.Count != 1) return; _curItemIndex = _curList.SelectedIndices[0]; if (_curItemIndex > _curList.VirtualListSize - 1) return; try { _curPost = GetCurTabPost(_curItemIndex); } catch (ArgumentException) { return; } this.PushSelectPostChain(); if (SettingDialog.UnreadManage) _statuses.SetReadAllTab(true, _curTab.Text, _curItemIndex); //キャッシュの書き換え ChangeCacheStyleRead(true, _curItemIndex, _curTab); //既読へ(フォント、文字色) ColorizeList(); _colorize = true; }
public bool RemoveSpecifiedTab(string TabName, bool confirm) { int idx = 0; for (idx = 0; idx < ListTab.TabPages.Count; idx++) { if (ListTab.TabPages[idx].Text == TabName) break; } if (_statuses.IsDefaultTab(TabName)) return false; if (confirm) { string tmp = string.Format(Properties.Resources.RemoveSpecifiedTabText1, Environment.NewLine); if (MessageBox.Show(tmp, TabName + " " + Properties.Resources.RemoveSpecifiedTabText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Cancel) { return false; } } SetListProperty(); //他のタブに列幅等を反映 MyCommon.TabUsageType tabType = _statuses.Tabs[TabName].TabType; //オブジェクトインスタンスの削除 this.SplitContainer1.Panel1.SuspendLayout(); this.SplitContainer1.Panel2.SuspendLayout(); this.SplitContainer1.SuspendLayout(); this.ListTab.SuspendLayout(); this.SuspendLayout(); TabPage _tabPage = ListTab.TabPages[idx]; DetailsListView _listCustom = (DetailsListView)_tabPage.Tag; _tabPage.Tag = null; _tabPage.SuspendLayout(); if (this.ListTab.SelectedTab == this.ListTab.TabPages[idx]) { this.ListTab.SelectTab((this._beforeSelectedTab != null && this.ListTab.TabPages.Contains(this._beforeSelectedTab)) ? this._beforeSelectedTab : this.ListTab.TabPages[0]); } this.ListTab.Controls.Remove(_tabPage); Control pnl = null; if (tabType == MyCommon.TabUsageType.PublicSearch) { pnl = _tabPage.Controls["panelSearch"]; foreach (Control ctrl in pnl.Controls) { if (ctrl.Name == "buttonSearch") { ctrl.Click -= SearchButton_Click; } ctrl.Enter -= SearchControls_Enter; ctrl.Leave -= SearchControls_Leave; pnl.Controls.Remove(ctrl); ctrl.Dispose(); } _tabPage.Controls.Remove(pnl); } _tabPage.Controls.Remove(_listCustom); _listCustom.Columns.Clear(); _listCustom.ContextMenuStrip = null; _listCustom.SelectedIndexChanged -= MyList_SelectedIndexChanged; _listCustom.MouseDoubleClick -= MyList_MouseDoubleClick; _listCustom.ColumnClick -= MyList_ColumnClick; _listCustom.DrawColumnHeader -= MyList_DrawColumnHeader; _listCustom.DragDrop -= TweenMain_DragDrop; _listCustom.DragOver -= TweenMain_DragOver; _listCustom.DrawItem -= MyList_DrawItem; _listCustom.MouseClick -= MyList_MouseClick; _listCustom.ColumnReordered -= MyList_ColumnReordered; _listCustom.ColumnWidthChanged -= MyList_ColumnWidthChanged; _listCustom.CacheVirtualItems -= MyList_CacheVirtualItems; _listCustom.RetrieveVirtualItem -= MyList_RetrieveVirtualItem; _listCustom.DrawSubItem -= MyList_DrawSubItem; _listCustom.HScrolled -= MyList_HScrolled; TabDialog.RemoveTab(TabName); _listCustom.SmallImageList = null; _listCustom.ListViewItemSorter = null; //キャッシュのクリア if (_curTab.Equals(_tabPage)) { _curTab = null; _curItemIndex = -1; _curList = null; _curPost = null; } _itemCache = null; _itemCacheIndex = -1; _postCache = null; _tabPage.ResumeLayout(false); this.SplitContainer1.Panel1.ResumeLayout(false); this.SplitContainer1.Panel2.ResumeLayout(false); this.SplitContainer1.ResumeLayout(false); this.ListTab.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); _tabPage.Dispose(); _listCustom.Dispose(); _statuses.RemoveTab(TabName); foreach (TabPage tp in ListTab.TabPages) { DetailsListView lst = (DetailsListView)tp.Tag; if (lst.VirtualListSize != _statuses.Tabs[tp.Text].AllCount) { lst.VirtualListSize = _statuses.Tabs[tp.Text].AllCount; } } return true; }
private string CreateDirectMessagesFromJson(string content, MyCommon.WORKERTYPE gType, bool read) { List<TwitterDataModel.Directmessage> item; try { if (gType == MyCommon.WORKERTYPE.UserStream) { var itm = MyCommon.CreateDataFromJson<List<TwitterDataModel.DirectmessageEvent>>(content); item = new List<TwitterDataModel.Directmessage>(); foreach (var dat in itm) { item.Add(dat.Directmessage); } } else { item = MyCommon.CreateDataFromJson<List<TwitterDataModel.Directmessage>>(content); } } catch(SerializationException ex) { MyCommon.TraceOut(ex.Message + Environment.NewLine + content); return "Json Parse Error(DataContractJsonSerializer)"; } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); return "Invalid Json!"; } foreach (var message in item) { var post = new PostClass(); try { post.StatusId = message.Id; if (gType != MyCommon.WORKERTYPE.UserStream) { if (gType == MyCommon.WORKERTYPE.DirectMessegeRcv) { if (minDirectmessage > post.StatusId) minDirectmessage = post.StatusId; } else { if (minDirectmessageSent > post.StatusId) minDirectmessageSent = post.StatusId; } } //二重取得回避 lock (LockObj) { if (TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.DirectMessage).Contains(post.StatusId)) continue; } //sender_id //recipient_id post.CreatedAt = MyCommon.DateTimeParse(message.CreatedAt); //本文 post.TextFromApi = message.Text; //HTMLに整形 post.Text = CreateHtmlAnchor(post.TextFromApi, post.ReplyToList, post.Media); post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi); post.TextFromApi = post.TextFromApi.Replace("<3", "?"); post.IsFav = false; //以下、ユーザー情報 TwitterDataModel.User user; if (gType == MyCommon.WORKERTYPE.UserStream) { if (twCon.AuthenticatedUsername.Equals(message.Recipient.ScreenName, StringComparison.CurrentCultureIgnoreCase)) { user = message.Sender; post.IsMe = false; post.IsOwl = true; } else { user = message.Recipient; post.IsMe = true; post.IsOwl = false; } } else { if (gType == MyCommon.WORKERTYPE.DirectMessegeRcv) { user = message.Sender; post.IsMe = false; post.IsOwl = true; } else { user = message.Recipient; post.IsMe = true; post.IsOwl = false; } } post.UserId = user.Id; post.ScreenName = user.ScreenName; post.Nickname = user.Name.Trim(); post.ImageUrl = user.ProfileImageUrl; post.IsProtect = user.Protected; } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); MessageBox.Show("Parse Error(CreateDirectMessagesFromJson)"); continue; } post.IsRead = read; if (post.IsMe && !read && _readOwnPost) post.IsRead = true; post.IsReply = false; post.IsExcludeReply = false; post.IsDm = true; TabInformations.GetInstance().AddPost(post); } return string.Empty; }
protected virtual Task<IEnumerable<ThumbnailInfo>> GetThumbailInfoAsync(PostClass post, CancellationToken token) { return ThumbnailGenerator.GetThumbnailsAsync(post, token); }
//Source整形 private void CreateSource(ref PostClass post) { if (post.Source.StartsWith("<")) { if (!post.Source.Contains("</a>")) { post.Source += "</a>"; } var mS = Regex.Match(post.Source, ">(?<source>.+)<"); if (mS.Success) { post.SourceHtml = string.Copy(ShortUrl.Resolve(PreProcessUrl(post.Source), false)); post.Source = HttpUtility.HtmlDecode(mS.Result("${source}")); } else { post.Source = string.Empty; post.SourceHtml = string.Empty; } } else { if (post.Source == "web") { post.SourceHtml = Properties.Resources.WebSourceString; } else if (post.Source == "Keitai Mail") { post.SourceHtml = Properties.Resources.KeitaiMailSourceString; } else { post.SourceHtml = string.Copy(post.Source); } } }
private PostClass CreatePostsFromStatusData(TwitterDataModel.Status status) { var post = new PostClass(); TwitterDataModel.Entities entities; post.StatusId = status.Id; if (status.RetweetedStatus != null) { var retweeted = status.RetweetedStatus; post.CreatedAt = MyCommon.DateTimeParse(retweeted.CreatedAt); //Id post.RetweetedId = retweeted.Id; //本文 post.TextFromApi = retweeted.Text; entities = retweeted.Entities; //Source取得(htmlの場合は、中身を取り出し) post.Source = retweeted.Source; //Reply先 long inReplyToStatusId; long.TryParse(retweeted.InReplyToStatusId, out inReplyToStatusId); post.InReplyToStatusId = inReplyToStatusId; post.InReplyToUser = retweeted.InReplyToScreenName; long inReplyToUserId; long.TryParse(status.InReplyToUserId, out inReplyToUserId); post.InReplyToUserId = inReplyToUserId; //幻覚fav対策 var tc = TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites); post.IsFav = tc.Contains(post.RetweetedId); if (retweeted.Geo != null) post.PostGeo = new PostClass.StatusGeo {Lat = retweeted.Geo.Coordinates[0], Lng = retweeted.Geo.Coordinates[1]}; //以下、ユーザー情報 var user = retweeted.User; if (user.ScreenName == null || status.User.ScreenName == null) return null; post.UserId = user.Id; post.ScreenName = user.ScreenName; post.Nickname = user.Name.Trim(); post.ImageUrl = user.ProfileImageUrl; post.IsProtect = user.Protected; //Retweetした人 post.RetweetedBy = status.User.ScreenName; post.RetweetedByUserId = status.User.Id; post.IsMe = post.RetweetedBy.ToLower().Equals(_uname); } else { post.CreatedAt = MyCommon.DateTimeParse(status.CreatedAt); //本文 post.TextFromApi = status.Text; entities = status.Entities; //Source取得(htmlの場合は、中身を取り出し) post.Source = status.Source; long inReplyToStatusId; long.TryParse(status.InReplyToStatusId, out inReplyToStatusId); post.InReplyToStatusId = inReplyToStatusId; post.InReplyToUser = status.InReplyToScreenName; long inReplyToUserId; long.TryParse(status.InReplyToUserId, out inReplyToUserId); post.InReplyToUserId = inReplyToUserId; if (status.Geo != null) post.PostGeo = new PostClass.StatusGeo {Lat = status.Geo.Coordinates[0], Lng = status.Geo.Coordinates[1]}; //以下、ユーザー情報 var user = status.User; if (user.ScreenName == null) return null; post.UserId = user.Id; post.ScreenName = user.ScreenName; post.Nickname = user.Name.Trim(); post.ImageUrl = user.ProfileImageUrl; post.IsProtect = user.Protected; post.IsMe = post.ScreenName.ToLower().Equals(_uname); //幻覚fav対策 var tc = TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites); post.IsFav = tc.Contains(post.StatusId) && TabInformations.GetInstance()[post.StatusId].IsFav; } //HTMLに整形 string textFromApi = post.TextFromApi; post.Text = CreateHtmlAnchor(ref textFromApi, post.ReplyToList, entities, post.Media); post.TextFromApi = textFromApi; post.TextFromApi = this.ReplaceTextFromApi(post.TextFromApi, entities); post.TextFromApi = HttpUtility.HtmlDecode(post.TextFromApi); post.TextFromApi = post.TextFromApi.Replace("<3", "?"); //Source整形 CreateSource(ref post); post.IsReply = post.ReplyToList.Contains(_uname); post.IsExcludeReply = false; if (post.IsMe) { post.IsOwl = false; } else { if (followerId.Count > 0) post.IsOwl = !followerId.Contains(post.UserId); } post.IsDm = false; return post; }
private void IDRuleMenuItem_Click(object sender, EventArgs e) { string tabName = ""; //未選択なら処理終了 if (_curList.SelectedIndices.Count == 0) return; //タブ選択(or追加) if (!SelectTab(ref tabName)) return; bool mv = false; bool mk = false; MoveOrCopy(ref mv, ref mk); List<string> ids = new List<string>(); foreach (int idx in _curList.SelectedIndices) { PostClass post = _statuses[_curTab.Text, idx]; if (!ids.Contains(post.ScreenName)) { FiltersClass fc = new FiltersClass(); ids.Add(post.ScreenName); if (post.RetweetedId == 0) { fc.NameFilter = post.ScreenName; } else { fc.NameFilter = post.RetweetedBy; } fc.SearchBoth = true; fc.MoveFrom = mv; fc.SetMark = mk; fc.UseRegex = false; fc.SearchUrl = false; _statuses.Tabs[tabName].AddFilter(fc); } } if (ids.Count != 0) { List<string> atids = new List<string>(); foreach (string id in ids) { atids.Add("@" + id); } int cnt = AtIdSupl.ItemCount; AtIdSupl.AddRangeItem(atids.ToArray()); if (AtIdSupl.ItemCount != cnt) _modifySettingAtId = true; } try { this.Cursor = Cursors.WaitCursor; _itemCache = null; _postCache = null; _curPost = null; _curItemIndex = -1; _statuses.FilterAll(); foreach (TabPage tb in ListTab.TabPages) { ((DetailsListView)tb.Tag).VirtualListSize = _statuses.Tabs[tb.Text].AllCount; if (_statuses.ContainsTab(tb.Text)) { if (_statuses.Tabs[tb.Text].UnreadCount > 0) { if (SettingDialog.TabIconDisp) tb.ImageIndex = 0; } else { if (SettingDialog.TabIconDisp) tb.ImageIndex = -1; } } } if (!SettingDialog.TabIconDisp) ListTab.Refresh(); } finally { this.Cursor = Cursors.Default; } SaveConfigsTabs(); }
private string GetRelatedResultsApi(bool read, PostClass post, TabClass tab, List<PostClass> relatedPosts) { if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return string.Empty; if (MyCommon._endingFlag) return string.Empty; HttpStatusCode res = HttpStatusCode.BadRequest; var content = string.Empty; try { if (post.RetweetedId > 0) { res = twCon.GetRelatedResults(post.RetweetedId, ref content); } else { res = twCon.GetRelatedResults(post.StatusId, ref content); } } catch(Exception ex) { return "Err:" + ex.Message; } switch (res) { case HttpStatusCode.OK: Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid; break; case HttpStatusCode.Unauthorized: Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid; return Properties.Resources.Unauthorized; case HttpStatusCode.BadRequest: return "Err:API Limits?"; default: return "Err:" + res.ToString() + "(" + MethodBase.GetCurrentMethod().Name + ")"; } List<TwitterDataModel.RelatedResult> items; try { items = MyCommon.CreateDataFromJson<List<TwitterDataModel.RelatedResult>>(content); } catch(SerializationException ex) { MyCommon.TraceOut(ex.Message + Environment.NewLine + content); return "Json Parse Error(DataContractJsonSerializer)"; } catch(Exception ex) { MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name + " " + content); return "Invalid Json!"; } var targetItem = post; if (targetItem == null) { return string.Empty; } else { targetItem = targetItem.Copy(); } targetItem.RelTabName = tab.TabName; TabInformations.GetInstance().AddPost(targetItem); PostClass replyToItem = null; var replyToUserName = targetItem.InReplyToUser; if (targetItem.InReplyToStatusId > 0 && TabInformations.GetInstance()[targetItem.InReplyToStatusId] != null) { replyToItem = TabInformations.GetInstance()[targetItem.InReplyToStatusId].Copy(); replyToItem.IsRead = read; if (replyToItem.IsMe && !read && _readOwnPost) replyToItem.IsRead = true; replyToItem.RelTabName = tab.TabName; } var replyAdded = false; foreach (var relatedData in items) { foreach (var result in relatedData.Results) { var item = CreatePostsFromStatusData(result.Status); if (item == null) continue; if (targetItem.InReplyToStatusId == item.StatusId) { replyToItem = null; replyAdded = true; } item.IsRead = read; if (item.IsMe && !read && _readOwnPost) item.IsRead = true; if (tab != null) item.RelTabName = tab.TabName; //非同期アイコン取得&StatusDictionaryに追加 relatedPosts.Add(item); } } if (replyToItem != null) { relatedPosts.Add(replyToItem); } else if (targetItem.InReplyToStatusId > 0 && !replyAdded) { PostClass p = null; var rslt = string.Empty; rslt = GetStatusApi(read, targetItem.InReplyToStatusId, ref p); if (string.IsNullOrEmpty(rslt)) { p.IsRead = read; p.RelTabName = tab.TabName; relatedPosts.Add(p); } return rslt; } //発言者・返信先ユーザーの直近10発言取得 //var rslt = this.GetUserTimelineApi(read, 10, string.Empty, tab); //if (!string.IsNullOrEmpty(rslt)) return rslt; //if (!string.IsNullOrEmpty(replyToUserName)) // rslt = this.GetUserTimelineApi(read, 10, replyToUserName, tab); //} //return rslt; //MRTとかに対応のためツイート内にあるツイートを指すURLを取り込む var ma = Regex.Matches(tab.RelationTargetPost.Text, "title=\"https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/(?<StatusId>[0-9]+))\""); foreach (Match _match in ma) { Int64 _statusId; if (Int64.TryParse(_match.Groups["StatusId"].Value, out _statusId)) { PostClass p = null; var _post = TabInformations.GetInstance()[_statusId]; if (_post == null) { var result = this.GetStatusApi(read, _statusId, ref p); } else { p = _post.Copy(); } if (p != null) { p.IsRead = read; p.RelTabName = tab.TabName; relatedPosts.Add(p); } } } return string.Empty; }
private Color JudgeColor(PostClass BasePost, PostClass TargetPost) { Color cl; if (TargetPost.StatusId == BasePost.InReplyToStatusId) //@先 cl = _clAtTo; else if (TargetPost.IsMe) //自分=発言者 cl = _clSelf; else if (TargetPost.IsReply) //自分宛返信 cl = _clAtSelf; else if (BasePost.ReplyToList.Contains(TargetPost.ScreenName.ToLower())) //返信先 cl = _clAtFromTarget; else if (TargetPost.ReplyToList.Contains(BasePost.ScreenName.ToLower())) //その人への返信 cl = _clAtTarget; else if (TargetPost.ScreenName.Equals(BasePost.ScreenName, StringComparison.OrdinalIgnoreCase)) //発言者 cl = _clTarget; else //その他 cl = _clListBackcolor; return cl; }
public Task ShowThumbnailAsync(PostClass post) { return this.ShowThumbnailAsync(post, CancellationToken.None); }
private void ListTabSelect(TabPage _tab) { SetListProperty(); _itemCache = null; _itemCacheIndex = -1; _postCache = null; _curTab = _tab; _curList = (DetailsListView)_tab.Tag; if (_curList.SelectedIndices.Count > 0) { _curItemIndex = _curList.SelectedIndices[0]; _curPost = GetCurTabPost(_curItemIndex); } else { _curItemIndex = -1; _curPost = null; } _anchorPost = null; _anchorFlag = false; if (_iconCol) { ((DetailsListView)_tab.Tag).Columns[1].Text = ColumnText[2]; } else { for (int i = 0; i < _curList.Columns.Count; i++) { ((DetailsListView)_tab.Tag).Columns[i].Text = ColumnText[i]; } } }