/// <summary> /// ファンのユーザーのリストを作成します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>ファンのユーザーのリスト</returns> private IEnumerable <UserData> CreateFanListOrDefault(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { try { return(_accountManager .Accounts[sidePanelChangedEventArgs.TabData.Tokens.UserId] .Followers .Except( GetMutualListOrDefault(sidePanelChangedEventArgs), new UserDataEqualityComparer() ) .Select(userData => { return new UserData { User = userData.User, FollowType = FollowType.Fan, Favorite = userData.Favorite }; })); } catch (ArgumentNullException) { const string errorMessage = "Fanの作成に失敗しました。LINQの引数が null です。"; Debug.WriteLine(errorMessage); return(null); } catch (KeyNotFoundException) { const string errorMessage = "フィルタに失敗しました。アカウントが追加されていません。"; _loggingService.Logs.Add(errorMessage); Debug.WriteLine(errorMessage); return(null); } }
/// <summary> /// フォローされているユーザーのリストを取得します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>フォローされているユーザーのリスト</returns> private IEnumerable <UserData> GetFollowersListOrDefault(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { if (_followers != null) { return(_followers); } else { _followers = CreateFollowersListOrDefault(sidePanelChangedEventArgs); return(_followers); } }
/// <summary> /// 相互フォローのユーザーのリストを取得します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>相互フォローのユーザーのリスト</returns> private IEnumerable <UserData> GetMutualListOrDefault(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { if (_mutual != null) { return(_mutual); } else { _mutual = CreateMutualListOrDefault(sidePanelChangedEventArgs); return(_mutual); } }
/// <summary> /// 和集合のユーザーのリストを取得します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>和集合のユーザーのリスト</returns> private IEnumerable <UserData> GetUnionListOrDefault(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { if (_union != null) { return(_union); } else { _union = CreateUnionListOrDefault(sidePanelChangedEventArgs); return(_union); } }
/// <summary> /// ファンのユーザーのリストを取得します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>ファンのユーザーのリスト</returns> private IEnumerable <UserData> GetFanListOrDefault(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { if (_fan != null) { return(_fan); } else { _fan = CreateFanListOrDefault(sidePanelChangedEventArgs); return(_fan); } }
/// <summary> /// 片思いのユーザーのリストを取得します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>片思いのユーザーのリスト</returns> private IEnumerable <UserData> GetOneWayListOrDefault(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { if (_oneWay != null) { return(_oneWay); } else { _oneWay = CreateOneWayListOrDefault(sidePanelChangedEventArgs); return(_oneWay); } }
/// <summary> /// ソートを適応したユーザーのリストを読み込み、完了後にLoadCompletedイベントを発生させます。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> private void LoadSortedCollection(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { if (_current != null) { SortCurrentList(sidePanelChangedEventArgs); LoadCompleted?.Invoke(_current); } else { LoadFilteredAndSortedCollectionAsync(sidePanelChangedEventArgs); } }
/// <summary> /// 30日間ツイートしていないユーザーのリストを取得します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>30日間ツイートしていないユーザーのリスト</returns> private async Task <IEnumerable <UserData> > GetInactiveListOrDefaultAsync(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { if (_inactive != null) { return(_inactive); } else { _inactive = await CreateInactiveListOrDefaultAsync(sidePanelChangedEventArgs).ConfigureAwait(false); return(_inactive); } }
/// <summary> /// フォローされているユーザーのリストを作成します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>フォローされているユーザーのリスト</returns> private IEnumerable <UserData> CreateFollowersListOrDefault(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { try { return(GetMutualListOrDefault(sidePanelChangedEventArgs) .Union(GetFanListOrDefault(sidePanelChangedEventArgs), new UserDataEqualityComparer())); } catch (ArgumentNullException) { const string errorMessage = "Followersの作成に失敗しました。LINQの引数が null です。"; Debug.WriteLine(errorMessage); return(null); } }
// プライベートメソッド /// <summary> /// フィルタとソートを適応したユーザーのリストを読み込み、完了後にLoadCompletedイベントを発生させます。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> private async void LoadFilteredAndSortedCollectionAsync(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { switch (sidePanelChangedEventArgs.FilterAndSortOption.FilterType) { case FilterType.OneWay: { _current = GetOneWayListOrDefault(sidePanelChangedEventArgs) ?? new List <UserData>(); SortCurrentList(sidePanelChangedEventArgs); LoadCompleted?.Invoke(_current); break; } case FilterType.Fan: { _current = GetFanListOrDefault(sidePanelChangedEventArgs) ?? new List <UserData>(); SortCurrentList(sidePanelChangedEventArgs); LoadCompleted?.Invoke(_current); break; } case FilterType.Mutual: { _current = GetMutualListOrDefault(sidePanelChangedEventArgs) ?? new List <UserData>(); SortCurrentList(sidePanelChangedEventArgs); LoadCompleted?.Invoke(_current); break; } case FilterType.Inactive: { _current = await GetInactiveListOrDefaultAsync(sidePanelChangedEventArgs).ConfigureAwait(false) ?? new List <UserData>(); SortCurrentList(sidePanelChangedEventArgs); LoadCompleted?.Invoke(_current); break; } } }
/// <summary> /// ツイートのリストのディクショナリーを返します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>ツイートのリストのディクショナリー</returns> private async Task <Dictionary <long, List <Status> > > GetUserTweetsOrDefaultAsync(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { try { return(await _accountManager .Accounts[sidePanelChangedEventArgs.TabData.Tokens.UserId] .GetUserTweetsAsync() .ConfigureAwait(false)); } catch (KeyNotFoundException) { const string errorMessage = "ツイートのリストのディクショナリーの取得に失敗しました。アカウントが追加されていません。"; _loggingService.Logs.Add(errorMessage); Debug.WriteLine(errorMessage); _current = new List <UserData>(); return(null); } }
/// <summary> /// 30日間ツイートしていないユーザーのリストを作成します。例外発生時はnullを返します。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> /// <returns>30日間ツイートしていないユーザーのリスト</returns> private async Task <IEnumerable <UserData> > CreateInactiveListOrDefaultAsync(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { var userTweets = await GetUserTweetsOrDefaultAsync(sidePanelChangedEventArgs).ConfigureAwait(false); if (userTweets == null) { const string errorMessage = "フィルタに失敗しました。アカウントが追加されていません。"; _loggingService.Logs.Add(errorMessage); Debug.WriteLine(errorMessage); return(null); } try { return(GetUnionListOrDefault(sidePanelChangedEventArgs) .Where( userData => { var result = userTweets .TryGetValue((long)userData.User.Id, out var statuses); if (!result) { _loggingService.Logs.Add(userData.User.ScreenName + "のツイートはUserTweets内に存在しません。"); Debug.WriteLine(userData.User.ScreenName + "のツイートはUserTweets内に存在しません。"); return true; } var status = statuses.ElementAtOrDefault(1); if (status != null) { return DateTimeOffset.Now.Subtract(status.CreatedAt).Days >= 30; } else { return true; } })); } catch (ArgumentNullException) { const string errorMessage = "Inactiveの作成に失敗しました。LINQの引数が null です。"; Debug.WriteLine(errorMessage); return(null); } }
/// <summary> /// 現在表示中のリストをソートします。 /// </summary> /// <param name="sidePanelChangedEventArgs">SidePanelで発生したイベントデータ</param> private async void SortCurrentList(ISidePanelChangedEventArgs sidePanelChangedEventArgs) { var filterType = sidePanelChangedEventArgs.FilterAndSortOption.FilterType; var sortKeyType = sidePanelChangedEventArgs.FilterAndSortOption.SortKeyType; var sortOrderType = sidePanelChangedEventArgs.FilterAndSortOption.SortOrderType; switch (sortKeyType) { case SortKeyType.LastTweetDay: { var userTweets = GetUserTweetsOrDefaultAsync(sidePanelChangedEventArgs); if (userTweets == null) { const string errorMessage = "ソートに失敗しました。アカウントが追加されていません。"; _loggingService.Logs.Add(errorMessage); Debug.WriteLine(errorMessage); break; } if (sortOrderType == SortOrderType.Ascending) { // HACK: 非同期処理は要調整 _current = _current.OrderBy(async userData => { var result = (await userTweets) .TryGetValue((long)userData.User.Id, out var statuses); if (result) { var status = statuses.ElementAtOrDefault(1); if (status != null) { return(status.CreatedAt.UtcDateTime); } else { // ユーザーのツイート数が少なすぎるため末尾に追加(昇順なのでUTCの最大値を返すと末尾になる) return(DateTime.MaxValue.ToUniversalTime()); } } else { // UserTweetsからツイートが見つからなかったため末尾に追加(昇順なのでUTCの最大値を返すと末尾になる) return(DateTime.MaxValue.ToUniversalTime()); } }); } else { _current = _current.OrderByDescending(async userData => { var result = (await userTweets) .TryGetValue((long)userData.User.Id, out var statuses); if (result) { var status = statuses.ElementAtOrDefault(1); if (status != null) { return(status.CreatedAt.UtcDateTime); } else { // ユーザーのツイート数が少なすぎるため末尾に追加(降順なのでUTCの最小値を返すと末尾になる) return(DateTime.MinValue.ToUniversalTime()); } } else { // UserTweetsからツイートが見つからなかったため末尾に追加(降順なのでUTCの最小値を返すと末尾になる) return(DateTime.MinValue.ToUniversalTime()); } }); } break; } case SortKeyType.FollowDay: { if (sortOrderType == SortOrderType.Ascending) { switch (filterType) { case FilterType.OneWay: { var userDatas = GetOneWayListOrDefault(sidePanelChangedEventArgs)?.Reverse(); CheckTemporaryUserDatasAndUpdateCurrentUserDataList(userDatas); break; } case FilterType.Fan: { var userDatas = GetFanListOrDefault(sidePanelChangedEventArgs)?.Reverse(); CheckTemporaryUserDatasAndUpdateCurrentUserDataList(userDatas); break; } case FilterType.Mutual: { var userDatas = GetMutualListOrDefault(sidePanelChangedEventArgs)?.Reverse(); CheckTemporaryUserDatasAndUpdateCurrentUserDataList(userDatas); break; } case FilterType.Inactive: { var userDatas = (await GetInactiveListOrDefaultAsync(sidePanelChangedEventArgs).ConfigureAwait(false))?.Reverse(); CheckTemporaryUserDatasAndUpdateCurrentUserDataList(userDatas); break; } } } else { switch (filterType) { case FilterType.OneWay: { var userDatas = GetOneWayListOrDefault(sidePanelChangedEventArgs); CheckTemporaryUserDatasAndUpdateCurrentUserDataList(userDatas); break; } case FilterType.Fan: { var userDatas = GetFanListOrDefault(sidePanelChangedEventArgs); CheckTemporaryUserDatasAndUpdateCurrentUserDataList(userDatas); break; } case FilterType.Mutual: { var userDatas = GetMutualListOrDefault(sidePanelChangedEventArgs); CheckTemporaryUserDatasAndUpdateCurrentUserDataList(userDatas); break; } case FilterType.Inactive: { var userDatas = await GetInactiveListOrDefaultAsync(sidePanelChangedEventArgs).ConfigureAwait(false); CheckTemporaryUserDatasAndUpdateCurrentUserDataList(userDatas); break; } } } break; /// <summary> /// 一時的なユーザーデータをチェックし、現在表示中のリストを更新します。 /// </summary> /// <param name="userDatas">一時的なユーザーデータのコレクション</param> void CheckTemporaryUserDatasAndUpdateCurrentUserDataList(IEnumerable <UserData> userDatas) { if (userDatas != null) { _current = userDatas; } else { const string errorMessage = "ソートに失敗しました。アカウントが追加されていません。"; _loggingService.Logs.Add(errorMessage); Debug.WriteLine(errorMessage); _current = new List <UserData>(); } } } case SortKeyType.TweetsPerDay: { var userTweets = GetUserTweetsOrDefaultAsync(sidePanelChangedEventArgs); if (userTweets == null) { const string errorMessage = "ソートに失敗しました。アカウントが追加されていません。"; _loggingService.Logs.Add(errorMessage); Debug.WriteLine(errorMessage); break; } if (sortOrderType == SortOrderType.Ascending) { // HACK: 非同期処理は要調整 _current = _current.OrderBy(async userData => { var result = (await userTweets) .TryGetValue((long)userData.User.Id, out var statuses); if (result) { var recentlyStatus = statuses.ElementAtOrDefault(1); var oldStatus = statuses.LastOrDefault(); if (recentlyStatus != null && oldStatus != null) { var days = (recentlyStatus.CreatedAt - oldStatus.CreatedAt).Days + 1; return(statuses.Count / days); } else { // ユーザーのツイート数が少なすぎるため末尾に追加(昇順なのでint型の最大値を返すと末尾になる) return(int.MaxValue); } } else { // UserTweetsからツイートが見つからなかったため末尾に追加(昇順なのでint型の最大値を返すと末尾になる) return(int.MaxValue); } }); } else { // HACK: 非同期処理は要調整 _current = _current.OrderByDescending(async userData => { var result = (await userTweets) .TryGetValue((long)userData.User.Id, out var statuses); if (result) { var recentlyStatus = statuses.ElementAtOrDefault(1); var oldStatus = statuses.LastOrDefault(); if (recentlyStatus != null && oldStatus != null) { var days = (recentlyStatus.CreatedAt - oldStatus.CreatedAt).Days + 1; return(statuses.Count / days); } else { // ユーザーのツイート数が少なすぎるため末尾に追加(降順なのでint型の最小値を返すと末尾になる) return(int.MinValue); } } else { // UserTweetsからツイートが見つからなかったため末尾に追加(降順なのでint型の最小値を返すと末尾になる) return(int.MinValue); } }); } break; } } }