public Task FavoritePost(PostId postId);
public Task UnfavoritePost(PostId postId);
+
+ public Task<PostClass?> RetweetPost(PostId postId);
}
}
// OpenTween - Client of Twitter
-// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
+// (c) 2008-2011 Moz (@syo68k)
+// (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
+// (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
+// (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
+// (c) 2011 Egtra (@egtra) <http://dev.activebasic.com/egtra/>
+// (c) 2013 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
//
// This file is part of OpenTween.
.ConfigureAwait(false);
}
+ public async Task<PostClass?> RetweetPost(PostId postId)
+ {
+ var statusId = this.AssertTwitterStatusId(postId);
+ var request = new CreateRetweetRequest
+ {
+ TweetId = statusId,
+ };
+
+ await request.Send(this.account.Connection)
+ .ConfigureAwait(false);
+
+ // graphql のレスポンスには PostClass 生成に必要な情報が不足しているため null を返す
+ return null;
+ }
+
private TwitterStatusId AssertTwitterStatusId(PostId postId)
{
return postId is TwitterStatusId statusId
// OpenTween - Client of Twitter
-// Copyright (c) 2024 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
+// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) <kiri.feather@gmail.com>
+// (c) 2008-2011 Moz (@syo68k)
+// (c) 2008-2011 takeshik (@takeshik) <http://www.takeshik.org/>
+// (c) 2010-2011 anis774 (@anis774) <http://d.hatena.ne.jp/anis774/>
+// (c) 2010-2011 fantasticswallow (@f_swallow) <http://twitter.com/f_swallow>
+// (c) 2011 Egtra (@egtra) <http://dev.activebasic.com/egtra/>
+// (c) 2013 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
//
// This file is part of OpenTween.
.ConfigureAwait(false);
}
+ public async Task<PostClass?> RetweetPost(PostId postId)
+ {
+ var statusId = this.AssertTwitterStatusId(postId);
+
+ using var response = await this.account.Legacy.Api.StatusesRetweet(statusId)
+ .ConfigureAwait(false);
+
+ var status = await response.LoadJsonAsync()
+ .ConfigureAwait(false);
+
+ // Retweet判定
+ if (status.RetweetedStatus == null)
+ throw new WebApiException("Invalid Json!");
+
+ // Retweetしたものを返す
+ return this.CreatePostFromJson(status);
+ }
+
private TwitterStatusId AssertTwitterStatusId(PostId postId)
{
return postId is TwitterStatusId statusId
? statusId
: throw new WebApiException($"Not supported type: {postId.GetType()}");
}
+
+ private PostClass CreatePostFromJson(TwitterStatus status)
+ => this.account.Legacy.CreatePostsFromStatusData(status, firstLoad: false, favTweet: false);
}
}
await this.RefreshTabAsync<HomeTabModel>();
}
- private async Task RetweetAsync(IReadOnlyList<PostId> statusIds)
+ private async Task RetweetAsync(IReadOnlyList<PostClass> posts)
{
await this.workerSemaphore.WaitAsync();
var progress = new Progress<string>(x => this.StatusLabel.Text = x);
this.RefreshTasktrayIcon();
- await this.RetweetAsyncInternal(progress, this.workerCts.Token, statusIds);
+ await this.RetweetAsyncInternal(progress, this.workerCts.Token, posts);
}
catch (WebApiException ex)
{
}
}
- private async Task RetweetAsyncInternal(IProgress<string> p, CancellationToken ct, IReadOnlyList<PostId> statusIds)
+ private async Task RetweetAsyncInternal(IProgress<string> p, CancellationToken ct, IReadOnlyList<PostClass> posts)
{
if (ct.IsCancellationRequested)
return;
p.Report("Posting...");
- var posts = new List<PostClass>();
+ var retweetedPosts = new List<PostClass>();
await Task.Run(async () =>
{
- foreach (var statusId in statusIds)
+ foreach (var post in posts)
{
- var post = await this.tw.PostRetweet(statusId).ConfigureAwait(false);
- if (post != null) posts.Add(post);
+ var statusId = post.RetweetedId ?? post.StatusId;
+
+ var retweetedPost = await this.CurrentTabAccount.Mutation.RetweetPost(statusId)
+ .ConfigureAwait(false);
+
+ if (retweetedPost != null)
+ retweetedPosts.Add(retweetedPost);
}
});
// 自分のRTはTLの更新では取得できない場合があるので、
// 投稿時取得の有無に関わらず追加しておく
- posts.ForEach(post => this.statuses.AddPost(post));
+ retweetedPosts.ForEach(post => this.statuses.AddPost(post));
if (this.settings.Common.PostAndGet)
{
}
}
- var statusIds = selectedPosts.Select(x => x.StatusId).ToList();
-
- await this.RetweetAsync(statusIds);
+ await this.RetweetAsync(selectedPosts);
}
}
dmTab.AddPostQueue(post);
}
- public async Task<PostClass?> PostRetweet(PostId id)
- {
- this.CheckAccountState();
-
- // データ部分の生成
- var post = TabInformations.GetInstance()[id];
- if (post == null)
- throw new WebApiException("Err:Target isn't found.");
-
- var target = post.RetweetedId ?? id; // 再RTの場合は元発言をRT
-
- if (this.Api.AuthType == APIAuthType.TwitterComCookie)
- {
- var request = new CreateRetweetRequest
- {
- TweetId = target.ToTwitterStatusId(),
- };
- await request.Send(this.Api.Connection).ConfigureAwait(false);
- return null;
- }
-
- using var response = await this.Api.StatusesRetweet(target.ToTwitterStatusId())
- .ConfigureAwait(false);
-
- var status = await response.LoadJsonAsync()
- .ConfigureAwait(false);
-
- // 二重取得回避
- lock (this.lockObj)
- {
- var statusId = new TwitterStatusId(status.IdStr);
- if (TabInformations.GetInstance().ContainsKey(statusId))
- return null;
- }
-
- // Retweet判定
- if (status.RetweetedStatus == null)
- throw new WebApiException("Invalid Json!");
-
- // Retweetしたものを返す
- var retweetPost = this.CreatePostsFromStatusData(status, firstLoad: false);
-
- return retweetPost;
- }
-
public async Task DeleteRetweet(PostClass post)
{
if (post.RetweetedId == null)
private PostClass CreatePostsFromStatusData(TwitterStatus status, bool firstLoad)
=> this.CreatePostsFromStatusData(status, firstLoad, favTweet: false);
- private PostClass CreatePostsFromStatusData(TwitterStatus status, bool firstLoad, bool favTweet)
+ internal PostClass CreatePostsFromStatusData(TwitterStatus status, bool firstLoad, bool favTweet)
{
var post = this.postFactory.CreateFromStatus(status, this.UserId, this.Api.AccountState.FollowerIds, firstLoad, favTweet);
_ = this.urlExpander.Expand(post);