public void EnqueueRemovePost_SetIsDeletedTest() { var tab = new PublicSearchTabModel("search") { UnreadManage = true, }; var post = new PostClass { StatusId = 100L, IsRead = false }; tab.AddPostQueue(post); tab.AddSubmit(); Assert.Equal(1, tab.AllCount); Assert.Equal(1, tab.UnreadCount); tab.EnqueueRemovePost(100L, setIsDeleted: true); // この時点ではタブからの削除は行われないが、PostClass.IsDeleted は true にセットされる Assert.Equal(1, tab.AllCount); Assert.Equal(1, tab.UnreadCount); Assert.True(post.IsDeleted); var removedIds = tab.RemoveSubmit(); Assert.Equal(0, tab.AllCount); Assert.Equal(0, tab.UnreadCount); Assert.Equal(new[] { 100L }, removedIds.AsEnumerable()); }
public void EnqueueRemovePost_Test() { var tab = new PublicSearchTabModel("search") { UnreadManage = true, }; tab.AddPostQueue(new PostClass { StatusId = 100L, IsRead = false }); tab.AddPostQueue(new PostClass { StatusId = 110L, IsRead = false }); tab.AddPostQueue(new PostClass { StatusId = 120L, IsRead = false }); tab.AddSubmit(); Assert.Equal(3, tab.AllCount); Assert.Equal(3, tab.UnreadCount); tab.EnqueueRemovePost(100L, setIsDeleted: false); // この時点では削除は行われない Assert.Equal(3, tab.AllCount); Assert.Equal(3, tab.UnreadCount); var removedIds = tab.RemoveSubmit(); Assert.Equal(2, tab.AllCount); Assert.Equal(2, tab.UnreadCount); Assert.Equal(new[] { 110L, 120L }, tab.StatusIds); Assert.Equal(new[] { 100L }, removedIds.AsEnumerable()); }
private Task GetPublicSearchAsync(PublicSearchTabModel tab) { return this.GetPublicSearchAsync(tab, loadMore: false); }
private void LoadConfig() { _cfgCommon = SettingCommon.Load(); SettingCommon.Instance = this._cfgCommon; if (_cfgCommon.UserAccounts == null || _cfgCommon.UserAccounts.Count == 0) { _cfgCommon.UserAccounts = new List<UserAccount>(); if (!string.IsNullOrEmpty(_cfgCommon.UserName)) { UserAccount account = new UserAccount(); account.Username = _cfgCommon.UserName; account.UserId = _cfgCommon.UserId; account.Token = _cfgCommon.Token; account.TokenSecret = _cfgCommon.TokenSecret; _cfgCommon.UserAccounts.Add(account); } } _cfgLocal = SettingLocal.Load(); // v1.2.4 以前の設定には ScaleDimension の項目がないため、現在の DPI と同じとして扱う if (_cfgLocal.ScaleDimension.IsEmpty) _cfgLocal.ScaleDimension = this.CurrentAutoScaleDimensions; var tabsSetting = SettingTabs.Load().Tabs; foreach (var tabSetting in tabsSetting) { TabModel tab; switch (tabSetting.TabType) { case MyCommon.TabUsageType.Home: tab = new HomeTabModel(tabSetting.TabName); break; case MyCommon.TabUsageType.Mentions: tab = new MentionsTabModel(tabSetting.TabName); break; case MyCommon.TabUsageType.DirectMessage: tab = new DirectMessagesTabModel(tabSetting.TabName); break; case MyCommon.TabUsageType.Favorites: tab = new FavoritesTabModel(tabSetting.TabName); break; case MyCommon.TabUsageType.UserDefined: tab = new FilterTabModel(tabSetting.TabName); break; case MyCommon.TabUsageType.UserTimeline: tab = new UserTimelineTabModel(tabSetting.TabName, tabSetting.User); break; case MyCommon.TabUsageType.PublicSearch: tab = new PublicSearchTabModel(tabSetting.TabName) { SearchWords = tabSetting.SearchWords, SearchLang = tabSetting.SearchLang, }; break; case MyCommon.TabUsageType.Lists: tab = new ListTimelineTabModel(tabSetting.TabName, tabSetting.ListInfo); break; case MyCommon.TabUsageType.Mute: tab = new MuteTabModel(tabSetting.TabName); break; default: continue; } tab.UnreadManage = tabSetting.UnreadManage; tab.Protected = tabSetting.Protected; tab.Notify = tabSetting.Notify; tab.SoundFile = tabSetting.SoundFile; if (tab.IsDistributableTabType) { var filterTab = (FilterTabModel)tab; filterTab.FilterArray = tabSetting.FilterArray; filterTab.FilterModified = false; } if (this._statuses.ContainsTab(tab.TabName)) tab.TabName = this._statuses.MakeTabName("MyTab"); this._statuses.AddTab(tab); } if (_statuses.Tabs.Count == 0) { _statuses.AddTab(new HomeTabModel()); _statuses.AddTab(new MentionsTabModel()); _statuses.AddTab(new DirectMessagesTabModel()); _statuses.AddTab(new FavoritesTabModel()); } }
public void SetReadAllTab_MarkAsUnreadTest() { var tab1 = new PublicSearchTabModel("search1"); var tab2 = new PublicSearchTabModel("search2"); this.tabinfo.AddTab(tab1); this.tabinfo.AddTab(tab2); // search1 に追加するツイート (StatusId: 100, 150, 200; すべて既読) tab1.UnreadManage = true; tab1.AddPostQueue(new PostClass { StatusId = 100L, IsRead = true }); tab1.AddPostQueue(new PostClass { StatusId = 150L, IsRead = true }); tab1.AddPostQueue(new PostClass { StatusId = 200L, IsRead = true }); // search2 に追加するツイート (StatusId: 150, 200, 250; すべて既読) tab2.UnreadManage = true; tab2.AddPostQueue(new PostClass { StatusId = 150L, IsRead = true }); tab2.AddPostQueue(new PostClass { StatusId = 200L, IsRead = true }); tab2.AddPostQueue(new PostClass { StatusId = 250L, IsRead = true }); this.tabinfo.DistributePosts(); this.tabinfo.SubmitUpdate(); // この時点での各タブの未読件数 Assert.Equal(0, tab1.UnreadCount); Assert.Equal(0, tab2.UnreadCount); // ... ここまで長い前置き // StatusId: 200 を未読にする (search1, search2 両方に含まれる) this.tabinfo.SetReadAllTab(200L, read: false); Assert.Equal(1, tab1.UnreadCount); Assert.Equal(1, tab2.UnreadCount); // StatusId: 100 を未読にする (search1 のみに含まれる) this.tabinfo.SetReadAllTab(100L, read: false); Assert.Equal(2, tab1.UnreadCount); Assert.Equal(1, tab2.UnreadCount); }
public void EnqueueRemovePost_UnknownIdTest() { var tab = new PublicSearchTabModel("search") { UnreadManage = true, }; tab.AddPostQueue(new PostClass { StatusId = 100L, IsRead = false }); tab.AddSubmit(); Assert.Equal(1, tab.AllCount); Assert.Equal(1, tab.UnreadCount); // StatusId = 999L は存在しない tab.EnqueueRemovePost(999L, setIsDeleted: false); Assert.Equal(1, tab.AllCount); Assert.Equal(1, tab.UnreadCount); var removedIds = tab.RemoveSubmit(); Assert.Equal(1, tab.AllCount); Assert.Equal(1, tab.UnreadCount); Assert.Empty(removedIds); }
public void NextUnreadId_SortByScreenNameDescTest() { var tab = new PublicSearchTabModel("search"); tab.UnreadManage = true; // ScreenName の降順でソート tab.SetSortMode(ComparerMode.Name, SortOrder.Descending); // 画面には上から 300 → 100 → 200 の順に並ぶ tab.AddPostQueue(new PostClass { StatusId = 100L, ScreenName = "bbb", IsRead = false }); tab.AddPostQueue(new PostClass { StatusId = 200L, ScreenName = "aaa", IsRead = false }); tab.AddPostQueue(new PostClass { StatusId = 300L, ScreenName = "ccc", IsRead = false }); tab.AddSubmit(); // 昇順/降順に関わらず、ScreenName の辞書順で小さい順に未読の ID を返す Assert.Equal(200L, tab.NextUnreadId); }
private long? CreatePostsFromSearchJson(TwitterSearchResult items, PublicSearchTabModel tab, bool read, bool more) { long? minimumId = null; foreach (var status in items.Statuses) { if (minimumId == null || minimumId.Value > status.Id) minimumId = status.Id; if (!more && status.Id > tab.SinceId) tab.SinceId = status.Id; //二重取得回避 lock (LockObj) { if (tab.Contains(status.Id)) continue; } var post = CreatePostsFromStatusData(status); post.IsRead = read; if ((post.IsMe && !read) && this._readOwnPost) post.IsRead = true; tab.AddPostQueue(post); } return minimumId; }
private void AddTabMenuItem_Click(object sender, EventArgs e) { string tabName = null; MyCommon.TabUsageType tabUsage; using (InputTabName inputName = new InputTabName()) { inputName.TabName = _statuses.MakeTabName("MyTab"); inputName.IsShowUsage = true; inputName.ShowDialog(); if (inputName.DialogResult == DialogResult.Cancel) return; tabName = inputName.TabName; tabUsage = inputName.Usage; } this.TopMost = this._cfgCommon.AlwaysTop; if (!string.IsNullOrEmpty(tabName)) { //List対応 ListElement list = null; if (tabUsage == MyCommon.TabUsageType.Lists) { using (ListAvailable listAvail = new ListAvailable()) { if (listAvail.ShowDialog(this) == DialogResult.Cancel) return; if (listAvail.SelectedList == null) return; list = listAvail.SelectedList; } } TabModel tab; switch (tabUsage) { case MyCommon.TabUsageType.UserDefined: tab = new FilterTabModel(tabName); break; case MyCommon.TabUsageType.PublicSearch: tab = new PublicSearchTabModel(tabName); break; case MyCommon.TabUsageType.Lists: tab = new ListTimelineTabModel(tabName, list); break; default: return; } if (!_statuses.AddTab(tab) || !AddNewTab(tab, startup: false)) { string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName); MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } else { //成功 SaveConfigsTabs(); if (tabUsage == MyCommon.TabUsageType.PublicSearch) { ListTab.SelectedIndex = ListTab.TabPages.Count - 1; ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"].Focus(); } if (tabUsage == MyCommon.TabUsageType.Lists) { ListTab.SelectedIndex = ListTab.TabPages.Count - 1; var listTab = (ListTimelineTabModel)this._statuses.Tabs[this._curTab.Text]; this.GetListTimelineAsync(listTab); } } } }
public void SearchPostsAll_ReverseOrderTest() { var tab = new PublicSearchTabModel("search"); tab.AddPostQueue(new PostClass { StatusId = 100L, TextFromApi = "abcd", ScreenName = "", Nickname = "" }); // 0 tab.AddPostQueue(new PostClass { StatusId = 110L, TextFromApi = "efgh", ScreenName = "", Nickname = "" }); // 1 tab.AddPostQueue(new PostClass { StatusId = 120L, TextFromApi = "ijkl", ScreenName = "", Nickname = "" }); // 2 tab.AddPostQueue(new PostClass { StatusId = 130L, TextFromApi = "abc", ScreenName = "", Nickname = "" }); // 3 tab.AddPostQueue(new PostClass { StatusId = 140L, TextFromApi = "def", ScreenName = "", Nickname = "" }); // 4 tab.SetSortMode(ComparerMode.Id, SortOrder.Ascending); tab.AddSubmit(); // インデックス番号 4 から逆順に開始 → 4, 3, 2, 1, 0 の順に検索 var result = tab.SearchPostsAll(x => x.Contains("a"), startIndex: 4, reverse: true); Assert.Equal(new[] { 3, 0 }, result); // インデックス番号 2 から逆順に開始 → 2, 1, 0, 4, 3 の順に検索 result = tab.SearchPostsAll(x => x.Contains("a"), startIndex: 2, reverse: true); Assert.Equal(new[] { 0, 3 }, result); }
public void SetReadState_MarkAsUnreadTest() { var tab = new PublicSearchTabModel("search"); tab.UnreadManage = true; tab.AddPostQueue(new PostClass { StatusId = 100L, IsRead = true, // 既読 }); tab.AddSubmit(); Assert.Equal(0, tab.UnreadCount); tab.SetReadState(100L, false); // 未読にする Assert.Equal(1, tab.UnreadCount); }
public void GetUnreadIds_Test() { var tab = new PublicSearchTabModel("search"); tab.UnreadManage = true; Assert.Empty(tab.GetUnreadIds()); tab.AddPostQueue(new PostClass { StatusId = 100L, IsRead = false }); tab.AddPostQueue(new PostClass { StatusId = 200L, IsRead = true }); tab.AddSubmit(); Assert.Equal(new[] { 100L }, tab.GetUnreadIds()); tab.SetReadState(100L, true); // 既読にする Assert.Empty(tab.GetUnreadIds()); }
public void NextUnreadIndex_DisabledTest() { var tab = new PublicSearchTabModel("search"); tab.SetSortMode(ComparerMode.Id, SortOrder.Ascending); // 未読表示無効 tab.UnreadManage = false; tab.AddPostQueue(new PostClass { StatusId = 100L, IsRead = false, // 未読 }); tab.AddSubmit(); Assert.Equal(-1, tab.NextUnreadIndex); }
public void UnreadCount_DisabledTest() { var tab = new PublicSearchTabModel("search"); // 未読表示無効 tab.UnreadManage = false; tab.AddPostQueue(new PostClass { StatusId = 100L, IsRead = false, // 未読 }); tab.AddSubmit(); Assert.Equal(0, tab.UnreadCount); }
public void UnreadCount_Test() { var tab = new PublicSearchTabModel("search"); tab.UnreadManage = true; // 未読なし Assert.Equal(0, tab.UnreadCount); tab.AddPostQueue(new PostClass { StatusId = 100L, IsRead = false, // 未読 }); tab.AddSubmit(); Assert.Equal(1, tab.UnreadCount); tab.AddPostQueue(new PostClass { StatusId = 50L, IsRead = true, // 既読 }); tab.AddSubmit(); Assert.Equal(1, tab.UnreadCount); }
private Task GetPublicSearchAsync(PublicSearchTabModel tab, bool loadMore) { return this.GetPublicSearchAsync(new[] { tab }, loadMore); }
public void AddNewTabForSearch(string searchWord) { //同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了 foreach (var tb in _statuses.GetTabsByType<PublicSearchTabModel>()) { if (tb.SearchWords == searchWord && string.IsNullOrEmpty(tb.SearchLang)) { foreach (TabPage tp in ListTab.TabPages) { if (tb.TabName == tp.Text) { ListTab.SelectedTab = tp; return; } } } } //ユニークなタブ名生成 string tabName = searchWord; for (int i = 0; i <= 100; i++) { if (_statuses.ContainsTab(tabName)) tabName += "_"; else break; } //タブ追加 var tab = new PublicSearchTabModel(tabName); _statuses.AddTab(tab); AddNewTab(tab, startup: false); //追加したタブをアクティブに ListTab.SelectedIndex = ListTab.TabPages.Count - 1; //検索条件の設定 ComboBox cmb = (ComboBox)ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"]; cmb.Items.Add(searchWord); cmb.Text = searchWord; SaveConfigsTabs(); //検索実行 this.SearchButton_Click(ListTab.SelectedTab.Controls["panelSearch"].Controls["comboSearch"], null); }
public void GetterSlice_Test() { var tab = new PublicSearchTabModel("search"); tab.AddPostQueue(new PostClass { StatusId = 100L, TextFromApi = "abcd" }); // 0 tab.AddPostQueue(new PostClass { StatusId = 110L, TextFromApi = "efgh" }); // 1 tab.AddPostQueue(new PostClass { StatusId = 120L, TextFromApi = "ijkl" }); // 2 tab.SetSortMode(ComparerMode.Id, SortOrder.Ascending); tab.AddSubmit(); Assert.Equal(new[] { 100L, 110L, 120L }, tab[0, 2].Select(x => x.StatusId)); Assert.Equal(new[] { 100L }, tab[0, 0].Select(x => x.StatusId)); Assert.Equal(new[] { 120L }, tab[2, 2].Select(x => x.StatusId)); }
public async Task GetSearch(bool read, PublicSearchTabModel tab, bool more) { var count = GetApiResultCount(MyCommon.WORKERTYPE.PublicSearch, more, false); long? maxId = null; long? sinceId = null; if (more) { maxId = tab.OldestId - 1; } else { sinceId = tab.SinceId; } var searchResult = await this.Api.SearchTweets(tab.SearchWords, tab.SearchLang, count, maxId, sinceId) .ConfigureAwait(false); if (!TabInformations.GetInstance().ContainsTab(tab)) return; var minimumId = this.CreatePostsFromSearchJson(searchResult, tab, read, more); if (minimumId != null) tab.OldestId = minimumId.Value; }
public void GetterSlice_ErrorTest() { var tab = new PublicSearchTabModel("search"); tab.AddPostQueue(new PostClass { StatusId = 100L, TextFromApi = "abcd" }); // 0 tab.AddPostQueue(new PostClass { StatusId = 110L, TextFromApi = "efgh" }); // 1 tab.AddPostQueue(new PostClass { StatusId = 120L, TextFromApi = "ijkl" }); // 2 tab.SetSortMode(ComparerMode.Id, SortOrder.Ascending); tab.AddSubmit(); Assert.Throws<ArgumentOutOfRangeException>(() => tab[-2, -1]); // 範囲外 ... 範囲外 Assert.Throws<ArgumentOutOfRangeException>(() => tab[-1, 1]); // 範囲外 ... 範囲内 Assert.Throws<ArgumentOutOfRangeException>(() => tab[2, 3]); // 範囲内 ... 範囲外 Assert.Throws<ArgumentOutOfRangeException>(() => tab[3, 4]); // 範囲外 ... 範囲外 Assert.Throws<ArgumentOutOfRangeException>(() => tab[-1, 3]); // 範囲外 ... 範囲外 Assert.Throws<ArgumentException>(() => tab[2, 0]); // 範囲内だが startIndex > endIndex }
private async void ButtonAddTab_Click(object sender, EventArgs e) { string tabName = null; MyCommon.TabUsageType tabType; using (InputTabName inputName = new InputTabName()) { inputName.TabName = _sts.MakeTabName("MyTab"); inputName.IsShowUsage = true; inputName.ShowDialog(); if (inputName.DialogResult == DialogResult.Cancel) return; tabName = inputName.TabName; tabType = inputName.Usage; } if (!string.IsNullOrEmpty(tabName)) { //List対応 ListElement list = null; if (tabType == MyCommon.TabUsageType.Lists) { try { using (var dialog = new WaitingDialog(Properties.Resources.ListsGetting)) { var cancellationToken = dialog.EnableCancellation(); var task = ((TweenMain)this.Owner).TwitterInstance.GetListsApi(); await dialog.WaitForAsync(this, task); cancellationToken.ThrowIfCancellationRequested(); } } catch (OperationCanceledException) { return; } catch (WebApiException ex) { MessageBox.Show("Failed to get lists. (" + ex.Message + ")"); } using (ListAvailable listAvail = new ListAvailable()) { if (listAvail.ShowDialog(this) == DialogResult.Cancel) return; if (listAvail.SelectedList == null) return; list = listAvail.SelectedList; } } TabModel tab; switch (tabType) { case MyCommon.TabUsageType.UserDefined: tab = new FilterTabModel(tabName); break; case MyCommon.TabUsageType.PublicSearch: tab = new PublicSearchTabModel(tabName); break; case MyCommon.TabUsageType.Lists: tab = new ListTimelineTabModel(tabName, list); break; default: return; } if (!_sts.AddTab(tab) || !((TweenMain)this.Owner).AddNewTab(tab, startup: false)) { string tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName); MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } else { // タブ作成成功 // 末尾のタブを取得する var lastIdx = this.ListTabs.Items.Count - 1; var lastTab = lastIdx != -1 ? this._sts.Tabs[(string)this.ListTabs.Items[lastIdx]] : null; // 末尾がミュートタブであればその手前に追加する if (lastTab != null && lastTab.TabType == MyCommon.TabUsageType.Mute) this.ListTabs.Items.Insert(lastIdx, tabName); else this.ListTabs.Items.Add(tabName); } } }
public void NextUnreadId_SortByIdDescTest() { var tab = new PublicSearchTabModel("search"); tab.UnreadManage = true; // ID の降順でソート tab.SetSortMode(ComparerMode.Id, SortOrder.Descending); // 画面には上から 300 → 200 → 100 の順に並ぶ tab.AddPostQueue(new PostClass { StatusId = 100L, IsRead = false }); tab.AddPostQueue(new PostClass { StatusId = 200L, IsRead = false }); tab.AddPostQueue(new PostClass { StatusId = 300L, IsRead = false }); tab.AddSubmit(); // 昇順/降順に関わらず、ID の小さい順に未読の ID を返す Assert.Equal(100L, tab.NextUnreadId); }