/// <summary> /// 自身の持つリストを取得する /// </summary> private async void SetLists() { this.ExtraGrid.Clear(); this.ExtraGrid.Add(new Grid()); var lists = await AccountTokens.LoadListsAsync(this.TokenSuffix); var itemsSource = new List <ListProperties>(); foreach (var list in lists) { itemsSource.Add( new ListProperties( this, new Uri(list.User.ProfileImageUrlHttps), list.Name, list.User.Name, list.Id, list.MemberCount ) ); } this.ExtraGrid.First().Children.Add( new Views.MainWindows.Flyouts.ExtraGrid.Lists() { DataContext = itemsSource } ); }
/// <summary> /// 自身が作成したリストを取得する /// </summary> private async void LoadLists() { // 操作対象のユーザーの関わるリストの内、自分が作成したものを取得 var userAddedLists = await AccountTokens.LoadListMembershipAsync(this.TokenSuffix, this.User.Id, true); // 自分のリストを取得 var lists = await AccountTokens.LoadListOwnershipsAsync(this.TokenSuffix); if (userAddedLists == null || lists == null) { return; } foreach (var list in lists) { var isAdded = false; foreach (var l in userAddedLists.Result) { // 既に追加されているか判定 if (list.Id == l.Id) { isAdded = true; break; } } this.Lists.Add(new ListProperties(list, isAdded)); } }
/// <summary> /// ツイートの削除ボタンを押したとき /// </summary> public async void Delete() { if (!Properties.Settings.Default.IsConfirmOfDeleteStatus || await this.Confirm("このツイートを削除しますか?") == MessageDialogResult.Affirmative) { await AccountTokens.DeleteStatusAsync(this.TimelineModel.TokenSuffix, this.Id); } }
/// <summary> /// ユーザーのフォロー状況を取得 /// </summary> /// <param name="user">相手ユーザーデータ</param> private async void LoadRelationship(User user) { if (user == null) { return; } var relationship = await AccountTokens.ShowRelationshipAsync(this.TimelineModel.TokenSuffix, user.Id); if (relationship != null) { if (relationship.Source.Id == relationship.Target.Id) { this.IsOwn = true; } if (relationship.Source.IsBlocking != null) { this.IsBlocking = (bool)relationship.Source.IsBlocking; } this.IsFollowing = relationship.Source.IsFollowing; if (relationship.Source.IsFollowingRequested != null) { this.IsSendingFollowRequest = (bool)relationship.Source.IsFollowingRequested; } } }
/// <summary> /// 自身のフォローを取得する /// </summary> private async void SetUsers() { this.ExtraGrid.Clear(); this.ExtraGrid.Add(new Grid()); var users = await AccountTokens.LoadFriendsAsync(this.TokenSuffix); var itemsSource = new ObservableCollection <UserProperties>(); BindingOperations.EnableCollectionSynchronization(itemsSource, new object()); foreach (var user in users) { if (user.Id != null) { itemsSource.Add(new UserProperties(this) { Name = user.Name, ScreenName = user.ScreenName, Description = user.Description, ProfileImageUrlHttps = user.ProfileImageUrlHttps, Id = (long)user.Id }); } } this.ExtraGrid.First().Children.Add( new Views.MainWindows.Flyouts.ExtraGrid.Users() { DataContext = new UsersModel(this, itemsSource, this.TokenSuffix) } ); }
/// <summary> /// いいねボタンを押したとき /// </summary> public async void Favorite() { //お気に入り済みでなければお気に入り if (this.IsFavorited == false) { if (!Properties.Settings.Default.IsConfirmOfFavorite || await this.Confirm("このツイートをいいねしますか?") == MessageDialogResult.Affirmative) { if (await AccountTokens.CreateFavoriteStatusAsync(this.TimelineModel.TokenSuffix, this.Id)) { this.IsFavorited = true; this.FavoriteCount++; } } } //お気に入り済みならばお気に入り解除 else if (this.IsFavorited == true) { if (!Properties.Settings.Default.IsConfirmOfDestroyFavorite || await this.Confirm("このツイートのいいねを解除しますか?") == MessageDialogResult.Affirmative) { if (await AccountTokens.DestroyFavoriteStatusAsync(this.TimelineModel.TokenSuffix, this.Id)) { this.IsFavorited = false; this.FavoriteCount--; } } } }
/// <summary> /// リツイートボタンを押したとき /// </summary> public async void Retweet() { if (!this.CanRetweet) { return; } //RT済みでなければRT if (this.IsRetweeted == false) { if (!Properties.Settings.Default.IsConfirmOfRetweet || await this.Confirm("このツイートをリツイートしますか?") == MessageDialogResult.Affirmative) { if (await AccountTokens.RetweetStatusAsync(this.TimelineModel.TokenSuffix, this.Id)) { this.IsRetweeted = true; this.RetweetCount++; } } } //RT済みならばRT解除 else if (this.IsRetweeted == true) { if (!Properties.Settings.Default.IsConfirmOfUnretweet || await this.Confirm("このツイートのリツイートを解除しますか?") == MessageDialogResult.Affirmative) { if (await AccountTokens.UnretweetStatusAsync(this.TimelineModel.TokenSuffix, this.Id)) { this.IsRetweeted = false; this.RetweetCount--; } } } }
public Account(AccountProfile profile, AccountTokens tokens) { Profile = profile; Tokens = tokens; Settings = new AccountSettings(); VolatileData = new AccountVolatileData(); }
/// <summary> /// 元ツイート等の追加 /// </summary> private async void SetStatus() { // 元ツイートの取得 var mainStatus = await AccountTokens.ShowStatusAsync(this.TimelineModel.TokenSuffix, this.Id); if (mainStatus == null) { return; } var mainProperties = new TimelineItemProperties(this.TimelineModel, mainStatus, StatusType.IndividualMain); this.Statuses.Add(mainProperties); // リプライ先がある場合ProgressRingを追加 if (mainStatus.InReplyToStatusId != null) { this.Statuses.Insert(0, new TimelineItemProperties(this.TimelineModel, LoadingType.ReadMoreReplies, mainStatus.InReplyToStatusId)); } // 返信を取得するProgressRingを追加 this.Statuses.Add(new TimelineItemProperties(this.TimelineModel, LoadingType.ReadMoreRepliesToMainStatus, new SearchRepliesProperties() { Id = mainStatus.Id, ScreenName = mainStatus.User.ScreenName, MaxId = null, SinceId = mainStatus.Id + 1 })); }
public Account(Account account) { // Copy constructor excludes VolatileData (for storage) Profile = new AccountProfile(account.Profile); Tokens = new AccountTokens(account.Tokens); Settings = new AccountSettings(account.Settings); }
public AccountTokens(AccountTokens copy) { if (copy == null) { return; } AccessToken = copy.AccessToken; RefreshToken = copy.RefreshToken; }
/// <summary> /// プロフィールバナーの削除 /// </summary> /// <returns></returns> public async Task RemoveProfileBanner() { if (await AccountTokens.RemoveProfileBannerAsync(this.TokenSuffix)) { CommonMethods.Notify("プロフィールバナーの削除成功", NotificationType.Success); } else { CommonMethods.Notify("プロフィールバナーの削除失敗", NotificationType.Error); } }
/// <summary> /// 通知ボタンを押したとき /// </summary> /// <param name="isIncludeRetweets">リツイートも通知するか否か</param> public async void Notify(bool isIncludeRetweets) { var mainWindow = CommonMethods.MainWindow; if (mainWindow != null) { if (await mainWindow.ShowMessageAsync("確認", "ユーザー名:" + this.User.Name + "のツイートを通知リストに追加しますか?\n※フォロー中のユーザーのみ追加が可能です。", MessageDialogStyle.AffirmativeAndNegative) == MessageDialogResult.Affirmative) { await AccountTokens.SetNotificationsAsync(this.TimelineModel.TokenSuffix, this.User.Id, true, isIncludeRetweets); } } }
/// <summary> /// セッション生成 /// </summary> private async Task CreateSession() { this.Session = await AccountTokens.CreateAuthenticationSessionAsync(); if (this._Session != null) { this.AuthenticationUrl = this._Session.AuthorizeUri; } else { this.Message = "セッションの生成に失敗しました。\n認証ボタンを押し、再度セッションを生成してください。"; } }
/// <summary> /// 認証 /// </summary> public async void Authentication() { if (await AccountTokens.AutheticationAsync(this._Session, this.Pin)) { this.Close(); } else { this.Pin = ""; this.Message = "認証に失敗しました\nURLクリックからやり直してください"; this.Session = null; this.AuthenticationUrl = null; } }
/// <summary> /// ツイートの送信 /// </summary> public async void Create() { this.IsProgressRingVisible = true; foreach (var user in this.Users) { if (user.IsCreate) { var text = user.User.Name + "(@" + user.User.ScreenName + ")でツイートしますか?\n" + this.StatusText; if (!Properties.Settings.Default.IsConfirmOfCreateStatus || await this.Confirm(text) == MessageDialogResult.Affirmative) { if (this.IsDeleteButtonVisible && !user.Media.IsUploaded) { if (!(await user.Upload(this.Type, this.FileNames.ToList()))) { this.IsProgressRingVisible = false; return; } } if (await AccountTokens.CreateStatusAsync(user.TokenSuffix, this.StatusText, this.ReplyId, user.Media.Ids)) { user.Media.Clear(); } else { this.IsProgressRingVisible = false; return; } } else { this.IsProgressRingVisible = false; return; } } } if (Properties.Settings.Default.IsCloseAfterCreateStatusCorrect && this.IsOpen) { this.ToggleOpen(); } this.StatusText = ""; this.FileNames.Clear(); this.Type = MediaType.Undefined; this.IsSelectButtonEnabled = true; this.IsDeleteButtonVisible = false; this.IsProgressRingVisible = false; }
/// <summary> /// 画像をアップロードする /// </summary> /// <param name="tokenSuffix">アップロードするアカウント番号</param> /// <param name="filePaths">ファイルパス</param> /// <returns></returns> public async Task <bool> ImageUpload(int tokenSuffix, IReadOnlyCollection <string> filePaths) { if (this.IsUploaded) { this.Clear(); } if (filePaths == null || filePaths.Count() == 0) { return(false); } if (filePaths.Count() > 4 - this.Source.Count) { CommonMethods.Notify("画像ファイルは4枚までです", NotificationType.Error); return(false); } foreach (var filePath in filePaths) { var media = await AccountTokens.ImageUploadAsync(tokenSuffix, filePath); if (media != null && media.Size != 0) { if (this.Ids == null) { this.Ids = media.MediaId.ToString(); } else { this.Ids += "," + media.MediaId.ToString(); } this.IsEnabled = true; CommonMethods.Notify("画像アップロード完了", NotificationType.Success); this.Source.Add(new Uri(filePath)); this.Type = MediaType.Image; } else { CommonMethods.Notify("画像アップロード失敗", NotificationType.Error); return(false); } } this.IsUploaded = true; return(true); }
/// <summary> /// ミュートボタンを押したとき /// </summary> private async void Mute() { var text = this.User.Name + "(@" + this.User.ScreenName + ")をミュートしますか?"; if (!Properties.Settings.Default.IsConfirmOfMute || await this.Confirm(text) == MessageDialogResult.Affirmative) { var user = await AccountTokens.CreateMuteAsync(this.TimelineModel.TokenSuffix, this.Id); if (user != null) { CommonMethods.Notify(this.User.Name + "(@" + this.User.ScreenName + ")をミュートしました", MainWindow.NotificationType.Success); } else { CommonMethods.Notify(this.User.Name + "(@" + this.User.ScreenName + ")のミュートが正常に完了しませんでした", MainWindow.NotificationType.Error); } } }
public static void Validate(AccountTokens tokens) { try { var accessTokenIsInRange = tokens.AccessToken.Length > MinLength; var refreshTokenIsInRange = tokens.RefreshToken.Length > MinLength; var isInRange = accessTokenIsInRange && refreshTokenIsInRange; if (!isInRange) { throw new ValidationException("Access Token or RefreshToken", "Token vazio."); } } catch (Exception) { throw; } }
/// <summary> /// ユーザーのブロックを解除する /// </summary> private async void DestroyBlock() { var text = this.Name + "(@" + this.ScreenName + ")のブロックを解除しますか?"; if (!Properties.Settings.Default.IsConfirmOfDestroyBlock || await this.Confirm(text) == MessageDialogResult.Affirmative) { var user = await AccountTokens.DestroyBlockAsync(this.TimelineModel.TokenSuffix, this.Id); if (user != null) { CommonMethods.Notify(this.Name + "(@" + this.ScreenName + ")のブロックを解除しました", MainWindow.NotificationType.Success); this.LoadRelationship(user); } else { CommonMethods.Notify(this.Name + "(@" + this.ScreenName + ")のブロック解除が正常に完了しませんでした", MainWindow.NotificationType.Error); } } }
/// <summary> /// 起動時のログイン /// </summary> private async void Login() { await Task.Run(() => { while (this.AddAccount == null) { System.Threading.Thread.Sleep(100); } }); //トークンファイルが正常に読み込めなかった場合、ログイン画面を表示する try { //トークンの読み込み if (!await AccountTokens.LoadTokensAsync()) { } //列データの読み込み else if (this.Timelines.LoadColumnData()) { this.MainWindowModel.Notify("カラム読み込み完了.", NotificationType.Normal); } } catch (TwitterException e) { this.MainWindowModel.Notify("トークン認証失敗.", NotificationType.Error); DebugConsole.Write(e); return; } catch (Exception e) when(e is HttpRequestException || e is WebException) { this.MainWindowModel.Notify("ネットワークに正常に接続できませんでした\n左下の更新ボタンを押して再認証してください", NotificationType.Error); DebugConsole.Write(e); return; } catch (Exception e) { DebugConsole.Write(e); return; } }
/// <summary> /// 更新ボタンを押したとき /// </summary> public async void UpdateTimelines() { if (AccountTokens.TokensCount == 0 || AccountTokens.Users.Count == 0) { this.MainWindowModel.Notify("トークン再認証開始", NotificationType.Normal); await AccountTokens.LoadTokensAsync(); return; } if (this.Timelines.Timelines.Count == 0) { return; } foreach (var timeline in this.Timelines.Timelines) { timeline.TimelineViewModel.Clear(); await timeline.TimelineViewModel.Update(); } }
/// <summary> /// 設定の保存 /// </summary> /// <returns></returns> public async Task Save() { if (this.ProfileImageIsChanged) { if (await AccountTokens.UpdateProfileImageAsync(this.TokenSuffix, this.ProfileImage.OriginalString)) { CommonMethods.Notify("プロフィール画像の更新成功", NotificationType.Success); this.ReloadProfileImage(AccountTokens.Users[this.TokenSuffix]); } else { CommonMethods.Notify("プロフィール画像の更新失敗", NotificationType.Error); } } if (this.ProfileBannerIsChanged) { if (await AccountTokens.UpdateProfileBannerAsync(this.TokenSuffix, this.ProfileBanner.OriginalString)) { CommonMethods.Notify("プロフィールバナーの更新成功", NotificationType.Success); this.ReloadProfileBanner(AccountTokens.Users[this.TokenSuffix]); } else { CommonMethods.Notify("プロフィールバナーの更新失敗", NotificationType.Error); } } if (this.OtherProfileIsChanged) { if (await AccountTokens.UpdateProfileAsync(this.TokenSuffix, this.Name, this.Url, this.Location, this.Description)) { CommonMethods.Notify("プロフィールの更新成功", NotificationType.Success); this.ReloadProfile(AccountTokens.Users[this.TokenSuffix]); } else { CommonMethods.Notify("プロフィールの更新失敗", NotificationType.Error); } } }
/// <summary> /// 表示するリストを取得する /// </summary> public async void LoadLists() { var userLists = await AccountTokens.LoadListsAsync(this.TokenSuffix, this.User.Id); if (userLists != null) { foreach (var userList in userLists) { this.UserLists.Add(new ListProperties(userList)); } } var addedLists = await AccountTokens.LoadListMembershipAsync(this.TokenSuffix, this.User.Id); if (addedLists != null) { foreach (var addedList in addedLists) { this.AddedLists.Add(new ListProperties(addedList)); } } }
private async void Search() { if (string.IsNullOrEmpty(this.Text)) { return; } this.Users.Clear(); foreach (var user in await AccountTokens.LoadSearchedUsersAsync(this.TokenSuffix, this.Text)) { if (user.Id != null) { this.Users.Add(new UserProperties(this.AddTimeline) { Name = user.Name, ScreenName = user.ScreenName, Description = user.Description, ProfileImageUrlHttps = user.ProfileImageUrlHttps, Id = (long)user.Id }); } } }
/// <summary> /// 現在のトレンドを取得する /// </summary> private async void SetTrends() { this.ExtraGrid.Clear(); this.ExtraGrid.Add(new Grid()); var trendResult = await AccountTokens.LoadTrendsAsync(this.TokenSuffix); var itemsSource = new List <TrendProperties>(); var i = 1; foreach (var trends in trendResult) { foreach (var trend in trends) { var item = new TrendProperties(this) { Rank = i, Name = trend.Name, HasCount = trend.TweetVolume != null }; if (trend.TweetVolume != null) { item.Count = (int)trend.TweetVolume; } itemsSource.Add(item); i++; } } this.ExtraGrid.First().Children.Add( new Views.MainWindows.Flyouts.ExtraGrid.Trends() { DataContext = new TrendsModel(this, itemsSource) } ); }
/// <summary> /// 変更を適用する /// </summary> public async void Apply() { foreach (var list in this.Lists) { // 変更されていた場合 if (list.IsChanged) { CoreTweet.ListResponse listResponse = null; // リストへの追加 if (list.IsAdded) { listResponse = await AccountTokens.CreateListMemberAsync(this.TokenSuffix, list.Id, this.User.Id); } // リストからの削除 else { listResponse = await AccountTokens.DestroyListMemberAsync(this.TokenSuffix, list.Id, this.User.Id); } var mainWindow = CommonMethods.MainWindow; if (mainWindow != null) { if (listResponse == null) { list.IsAdded = list._IsAdded; (mainWindow.DataContext as MainWindowViewModel).Notify("リストの編集に失敗しました", MainWindow.NotificationType.Error); } else { list._IsAdded = list.IsAdded; (mainWindow.DataContext as MainWindowViewModel).Notify("リストの編集に成功しました", MainWindow.NotificationType.Success); } } } } }
/// <summary> /// ユーザーをフォローする /// </summary> private async void Follow() { var text = this.Name + "(@" + this.ScreenName + ")"; if (this.IsProtected) { text += "にフォローリクエストを送信しますか?"; } else { text += "をフォローしますか?"; } if (!Properties.Settings.Default.IsConfirmOfFollow || await this.Confirm(text) == MessageDialogResult.Affirmative) { var user = await AccountTokens.CreateFriendshipAsync(this.TimelineModel.TokenSuffix, this.Id); if (user != null) { if (this.IsProtected) { CommonMethods.Notify(this.Name + "(@" + this.ScreenName + ")にフォローリクエストを送信しました", MainWindow.NotificationType.Success); } else { CommonMethods.Notify(this.Name + "(@" + this.ScreenName + ")をフォローしました", MainWindow.NotificationType.Success); } this.LoadRelationship(user); } else { CommonMethods.Notify(this.Name + "(@" + this.ScreenName + ")のフォローが正常に完了しませんでした", MainWindow.NotificationType.Error); } } }
/// <summary> /// リプライ先を読み込む /// </summary> /// <param name="id">リプライ先ツイートID</param> public async void ReadMoreReplies(long?id) { if (this.IsLoadingReplies) { return; } this.IsLoadingReplies = true; while (true) { if (this.IsLoadingRepliesToMainStatus) { await Task.Run(() => { System.Threading.Thread.Sleep(3000); }); } else { break; } } long?replyId = id; for (int i = 0; i < 10; i++) { if (replyId == null) { this.Statuses.First().LoadingProperties.Visibility = Visibility.Collapsed; break; } StatusResponse mainStatusReplyStatus = null; try { mainStatusReplyStatus = await AccountTokens.ShowStatusAsync(this.TimelineModel.TokenSuffix, (long)replyId); } catch (Exception e) { DebugConsole.Write(e); this.Statuses.First().LoadingProperties.Visibility = Visibility.Collapsed; break; } if (mainStatusReplyStatus == null) { this.Statuses.First().LoadingProperties.Visibility = Visibility.Collapsed; break; } var mainStatusReplyStatusProperties = new TimelineItemProperties(this.TimelineModel, mainStatusReplyStatus, StatusType.IndividualOther); this.Statuses.Insert(1, mainStatusReplyStatusProperties); replyId = mainStatusReplyStatus.InReplyToStatusId; } this.Statuses.RemoveAt(0); if (replyId != null) { this.Statuses.Insert(0, new TimelineItemProperties(this.TimelineModel, LoadingType.ReadMoreRepliesButton, replyId)); } this.IsLoadingReplies = false; }
/// <summary> /// 初期化 /// </summary> /// <param name="id">ツイートID</param> private async void Initialize(long id) { this.Initialize(await AccountTokens.ShowStatusAsync(this.TimelineModel.TokenSuffix, id)); }