From: Kimura Youichi Date: Fri, 17 May 2024 18:39:42 +0000 (+0900) Subject: TwitterUserIdクラスを追加 X-Git-Tag: OpenTween_v3.14.0^2~25^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=b80e3aa91a84e215bd55e9b4204065bdc33836aa;p=opentween%2Fopen-tween.git TwitterUserIdクラスを追加 --- diff --git a/OpenTween.Tests/Api/GraphQL/CreateTweetRequestTest.cs b/OpenTween.Tests/Api/GraphQL/CreateTweetRequestTest.cs index b01e95a7..e6c843f4 100644 --- a/OpenTween.Tests/Api/GraphQL/CreateTweetRequestTest.cs +++ b/OpenTween.Tests/Api/GraphQL/CreateTweetRequestTest.cs @@ -22,6 +22,7 @@ using System.Threading.Tasks; using Moq; using OpenTween.Connection; +using OpenTween.Models; using Xunit; namespace OpenTween.Api.GraphQL @@ -78,7 +79,7 @@ namespace OpenTween.Api.GraphQL { TweetText = "tetete", InReplyToTweetId = new("12345"), - ExcludeReplyUserIds = new[] { "11111", "22222" }, + ExcludeReplyUserIds = new TwitterUserId[] { new("11111"), new("22222") }, }; await request.Send(mock.Object); mock.VerifyAll(); diff --git a/OpenTween.Tests/Api/GraphQL/LikesRequestTest.cs b/OpenTween.Tests/Api/GraphQL/LikesRequestTest.cs index b9f57388..72eb6183 100644 --- a/OpenTween.Tests/Api/GraphQL/LikesRequestTest.cs +++ b/OpenTween.Tests/Api/GraphQL/LikesRequestTest.cs @@ -51,7 +51,7 @@ namespace OpenTween.Api.GraphQL var request = new LikesRequest { - UserId = "12345", + UserId = new("12345"), Count = 20, }; @@ -83,7 +83,7 @@ namespace OpenTween.Api.GraphQL var request = new LikesRequest { - UserId = "12345", + UserId = new("12345"), Count = 20, Cursor = new("aaa"), }; diff --git a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs index 38e6acee..3c3ed3bf 100644 --- a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs +++ b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs @@ -73,10 +73,10 @@ namespace OpenTween.Api.GraphQL var timelineTweet = new TimelineTweet(rootElm); var status = timelineTweet.ToTwitterStatus(); var postFactory = new TwitterPostFactory(this.CreateTabInfo(), new()); - var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet(), firstLoad: false); + var post = postFactory.CreateFromStatus(status, selfUserId: new("1"), new HashSet(), firstLoad: false); Assert.Equal("1613784711020826626", post.StatusId.Id); - Assert.Equal(40480664L, post.UserId); + Assert.Equal(new TwitterUserId("40480664"), post.UserId); Assert.False(post.IsPromoted); } @@ -87,10 +87,10 @@ namespace OpenTween.Api.GraphQL var timelineTweet = new TimelineTweet(rootElm); var status = timelineTweet.ToTwitterStatus(); var postFactory = new TwitterPostFactory(this.CreateTabInfo(), new()); - var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet(), firstLoad: false); + var post = postFactory.CreateFromStatus(status, selfUserId: new("1"), new HashSet(), firstLoad: false); Assert.Equal("1614587968567783424", post.StatusId.Id); - Assert.Equal(40480664L, post.UserId); + Assert.Equal(new TwitterUserId("40480664"), post.UserId); Assert.Equal(2, post.Media.Count); Assert.Equal("https://pbs.twimg.com/media/FmgrJiEaAAEU42G.png", post.Media[0].Url); Assert.Equal("OpenTweenで @opentween のツイート一覧を表示しているスクショ", post.Media[0].AltText); @@ -105,12 +105,12 @@ namespace OpenTween.Api.GraphQL var timelineTweet = new TimelineTweet(rootElm); var status = timelineTweet.ToTwitterStatus(); var postFactory = new TwitterPostFactory(this.CreateTabInfo(), new()); - var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet(), firstLoad: false); + var post = postFactory.CreateFromStatus(status, selfUserId: new("1"), new HashSet(), firstLoad: false); Assert.Equal("1617128268548964354", post.StatusId.Id); - Assert.Equal(40480664L, post.RetweetedByUserId); + Assert.Equal(new TwitterUserId("40480664"), post.RetweetedByUserId); Assert.Equal("1617126084138659840", post.RetweetedId!.Id); - Assert.Equal(514241801L, post.UserId); + Assert.Equal(new TwitterUserId("514241801"), post.UserId); } [Fact] @@ -120,10 +120,10 @@ namespace OpenTween.Api.GraphQL var timelineTweet = new TimelineTweet(rootElm); var status = timelineTweet.ToTwitterStatus(); var postFactory = new TwitterPostFactory(this.CreateTabInfo(), new()); - var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet(), firstLoad: false); + var post = postFactory.CreateFromStatus(status, selfUserId: new("1"), new HashSet(), firstLoad: false); Assert.Equal("1602775353088524288", post.StatusId.Id); - Assert.Equal(357750891L, post.UserId); + Assert.Equal(new TwitterUserId("357750891"), post.UserId); } [Fact] @@ -133,10 +133,10 @@ namespace OpenTween.Api.GraphQL var timelineTweet = new TimelineTweet(rootElm); var status = timelineTweet.ToTwitterStatus(); var postFactory = new TwitterPostFactory(this.CreateTabInfo(), new()); - var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet(), firstLoad: false); + var post = postFactory.CreateFromStatus(status, selfUserId: new("1"), new HashSet(), firstLoad: false); Assert.Equal("1511751702684499968", post.StatusId.Id); - Assert.Equal(40480664L, post.UserId); + Assert.Equal(new TwitterUserId("40480664"), post.UserId); } [Fact] @@ -146,7 +146,7 @@ namespace OpenTween.Api.GraphQL var timelineTweet = new TimelineTweet(rootElm); var status = timelineTweet.ToTwitterStatus(); var postFactory = new TwitterPostFactory(this.CreateTabInfo(), new()); - var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet(), firstLoad: false); + var post = postFactory.CreateFromStatus(status, selfUserId: new("1"), new HashSet(), firstLoad: false); Assert.Equal("1588614645866147840", post.StatusId.Id); var quotedPostId = Assert.Single(post.QuoteStatusIds); @@ -160,7 +160,7 @@ namespace OpenTween.Api.GraphQL var timelineTweet = new TimelineTweet(rootElm); var status = timelineTweet.ToTwitterStatus(); var postFactory = new TwitterPostFactory(this.CreateTabInfo(), new()); - var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet(), firstLoad: false); + var post = postFactory.CreateFromStatus(status, selfUserId: new("1"), new HashSet(), firstLoad: false); Assert.Equal("1614653321310253057", post.StatusId.Id); var quotedPostId = Assert.Single(post.QuoteStatusIds); @@ -174,10 +174,10 @@ namespace OpenTween.Api.GraphQL var timelineTweet = new TimelineTweet(rootElm); var status = timelineTweet.ToTwitterStatus(); var postFactory = new TwitterPostFactory(this.CreateTabInfo(), new()); - var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet(), firstLoad: false); + var post = postFactory.CreateFromStatus(status, selfUserId: new("1"), new HashSet(), firstLoad: false); Assert.Equal("1674737917363888129", post.StatusId.Id); - Assert.Equal(2941313791L, post.UserId); + Assert.Equal(new TwitterUserId("2941313791"), post.UserId); Assert.True(post.IsPromoted); Assert.Matches(new Regex(@"^\[Promoted\]\n"), post.TextFromApi); } diff --git a/OpenTween.Tests/Api/GraphQL/UserTweetsAndRepliesRequestTest.cs b/OpenTween.Tests/Api/GraphQL/UserTweetsAndRepliesRequestTest.cs index 575df9d3..4c319735 100644 --- a/OpenTween.Tests/Api/GraphQL/UserTweetsAndRepliesRequestTest.cs +++ b/OpenTween.Tests/Api/GraphQL/UserTweetsAndRepliesRequestTest.cs @@ -22,6 +22,7 @@ using System.Threading.Tasks; using Moq; using OpenTween.Connection; +using OpenTween.Models; using Xunit; namespace OpenTween.Api.GraphQL @@ -49,7 +50,7 @@ namespace OpenTween.Api.GraphQL }) .ReturnsAsync(apiResponse); - var request = new UserTweetsAndRepliesRequest(userId: "40480664") + var request = new UserTweetsAndRepliesRequest(userId: new("40480664")) { Count = 20, }; @@ -83,7 +84,7 @@ namespace OpenTween.Api.GraphQL }) .ReturnsAsync(apiResponse); - var request = new UserTweetsAndRepliesRequest(userId: "40480664") + var request = new UserTweetsAndRepliesRequest(userId: new("40480664")) { Count = 20, Cursor = new("aaa"), diff --git a/OpenTween.Tests/Api/TwitterApiTest.cs b/OpenTween.Tests/Api/TwitterApiTest.cs index 96fb4727..c1ac6d7f 100644 --- a/OpenTween.Tests/Api/TwitterApiTest.cs +++ b/OpenTween.Tests/Api/TwitterApiTest.cs @@ -32,6 +32,7 @@ using System.Threading.Tasks; using Moq; using OpenTween.Api.DataModel; using OpenTween.Connection; +using OpenTween.Models; using Xunit; namespace OpenTween.Api @@ -276,7 +277,7 @@ namespace OpenTween.Api replyToId: new("100"), mediaIds: new[] { 10L, 20L }, autoPopulateReplyMetadata: true, - excludeReplyUserIds: new[] { 100L, 200L }, + excludeReplyUserIds: new TwitterUserId[] { new("100"), new("200") }, attachmentUrl: "https://twitter.com/twitterapi/status/22634515958" ) .IgnoreResponse(); @@ -304,7 +305,7 @@ namespace OpenTween.Api using var twitterApi = new TwitterApi(); twitterApi.ApiConnection = mock.Object; - await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty()) + await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty()) .IgnoreResponse(); mock.VerifyAll(); @@ -770,7 +771,7 @@ namespace OpenTween.Api using var twitterApi = new TwitterApi(); twitterApi.ApiConnection = mock.Object; - await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L); + await twitterApi.DirectMessagesEventsNew(recipientId: new("12345"), text: "hogehoge", mediaId: 67890L); mock.VerifyAll(); } @@ -847,7 +848,7 @@ namespace OpenTween.Api using var twitterApi = new TwitterApi(); twitterApi.ApiConnection = mock.Object; - await twitterApi.UsersLookup(userIds: new[] { "11111", "22222" }); + await twitterApi.UsersLookup(userIds: new TwitterUserId[] { new("11111"), new("22222") }); mock.VerifyAll(); } diff --git a/OpenTween.Tests/Models/PersonIdTest.cs b/OpenTween.Tests/Models/PersonIdTest.cs new file mode 100644 index 00000000..575e2328 --- /dev/null +++ b/OpenTween.Tests/Models/PersonIdTest.cs @@ -0,0 +1,157 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using Moq; +using Xunit; + +namespace OpenTween.Models +{ + public class PersonIdTest + { + private PersonId CreatePersonId(string type, string id) + { + var mock = new Mock() { CallBase = true }; + mock.Setup(x => x.IdType).Returns(type); + mock.Setup(x => x.Id).Returns(id); + return mock.Object; + } + + [Fact] + public void CompareTo_Test() + { + var a = this.CreatePersonId("mastodon", "200"); + var b = this.CreatePersonId("twitter", "100"); + Assert.True(a.CompareTo(b) < 0); + Assert.True(b.CompareTo(a) > 0); + Assert.Equal(0, a.CompareTo(a)); + } + + [Fact] + public void CompareTo_SameIdTypeTest() + { + var a = this.CreatePersonId("twitter", "100"); + var b = this.CreatePersonId("twitter", "200"); + Assert.True(a.CompareTo(b) < 0); + Assert.True(b.CompareTo(a) > 0); + Assert.Equal(0, a.CompareTo(a)); + } + + [Fact] + public void CompareTo_IdLengthTest() + { + var a = this.CreatePersonId("twitter", "200"); + var b = this.CreatePersonId("twitter", "1000"); + Assert.True(a.CompareTo(b) < 0); + Assert.True(b.CompareTo(a) > 0); + } + + [Fact] + public void OperatorGreaterThan_Test() + { + var a = this.CreatePersonId("twitter", "100"); + var b = this.CreatePersonId("twitter", "200"); +#pragma warning disable CS1718 + Assert.False(a < a); + Assert.True(a < b); + Assert.False(b < a); + Assert.False(b < b); + Assert.True(a <= a); + Assert.True(a <= b); + Assert.False(b <= a); + Assert.True(b <= b); +#pragma warning restore CS1718 + } + + [Fact] + public void OperatorLessThan_Test() + { + var a = this.CreatePersonId("twitter", "100"); + var b = this.CreatePersonId("twitter", "200"); +#pragma warning disable CS1718 + Assert.False(a > a); + Assert.False(a > b); + Assert.True(b > a); + Assert.False(b > b); + Assert.True(a >= a); + Assert.False(a >= b); + Assert.True(b >= a); + Assert.True(b >= b); +#pragma warning restore CS1718 + } + + [Fact] + public void Equals_Test() + { + var a = this.CreatePersonId("twitter", "100"); + var b = this.CreatePersonId("twitter", "100"); + Assert.True(a.Equals(b)); + Assert.True(b.Equals(a)); + Assert.True(a == b); + Assert.True(b == a); + } + + [Fact] + public void Equals_NotSameIdTypeTest() + { + var a = this.CreatePersonId("mastodon", "100"); + var b = this.CreatePersonId("twitter", "100"); + Assert.False(a.Equals(b)); + Assert.False(b.Equals(a)); + Assert.True(a != b); + Assert.True(b != a); + } + + [Fact] + public void Equals_NotSameIdTest() + { + var a = this.CreatePersonId("twitter", "100"); + var b = this.CreatePersonId("twitter", "200"); + Assert.False(a.Equals(b)); + Assert.False(b.Equals(a)); + Assert.True(a != b); + Assert.True(b != a); + } + + [Fact] + public void GetHashCode_SameIdTest() + { + var a = this.CreatePersonId("twitter", "100"); + var b = this.CreatePersonId("twitter", "100"); + Assert.Equal(a.GetHashCode(), b.GetHashCode()); + } + + [Fact] + public void GetHashCode_NotSameIdTypeTest() + { + var a = this.CreatePersonId("mastodon", "100"); + var b = this.CreatePersonId("twitter", "100"); + Assert.NotEqual(a.GetHashCode(), b.GetHashCode()); + } + + [Fact] + public void GetHashCode_NotSameIdTest() + { + var a = this.CreatePersonId("twitter", "100"); + var b = this.CreatePersonId("twitter", "200"); + Assert.NotEqual(a.GetHashCode(), b.GetHashCode()); + } + } +} diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index c7bbfb10..291b061f 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -129,10 +129,10 @@ namespace OpenTween.Models { IsDm = true, IsMe = true, // 自分が送信した DM - UserId = 222L, // 送信先ユーザーID + UserId = new TwitterUserId("222"), // 送信先ユーザーID }; - Assert.True(post.CanDeleteBy(selfUserId: 111L)); + Assert.True(post.CanDeleteBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -142,10 +142,10 @@ namespace OpenTween.Models { IsDm = true, IsMe = false, // 自分が受け取った DM - UserId = 222L, // 送信元ユーザーID + UserId = new TwitterUserId("222"), // 送信元ユーザーID }; - Assert.True(post.CanDeleteBy(selfUserId: 111L)); + Assert.True(post.CanDeleteBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -153,10 +153,10 @@ namespace OpenTween.Models { var post = new PostClass { - UserId = 111L, // 自分のツイート + UserId = new TwitterUserId("111"), // 自分のツイート }; - Assert.True(post.CanDeleteBy(selfUserId: 111L)); + Assert.True(post.CanDeleteBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -164,10 +164,10 @@ namespace OpenTween.Models { var post = new PostClass { - UserId = 222L, // 他人のツイート + UserId = new TwitterUserId("222"), // 他人のツイート }; - Assert.False(post.CanDeleteBy(selfUserId: 111L)); + Assert.False(post.CanDeleteBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -175,11 +175,11 @@ namespace OpenTween.Models { var post = new PostClass { - RetweetedByUserId = 111L, // 自分がリツイートした - UserId = 222L, // 他人のツイート + RetweetedByUserId = new TwitterUserId("111"), // 自分がリツイートした + UserId = new TwitterUserId("222"), // 他人のツイート }; - Assert.True(post.CanDeleteBy(selfUserId: 111L)); + Assert.True(post.CanDeleteBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -187,11 +187,11 @@ namespace OpenTween.Models { var post = new PostClass { - RetweetedByUserId = 333L, // 他人がリツイートした - UserId = 222L, // 他人のツイート + RetweetedByUserId = new TwitterUserId("333"), // 他人がリツイートした + UserId = new TwitterUserId("222"), // 他人のツイート }; - Assert.False(post.CanDeleteBy(selfUserId: 111L)); + Assert.False(post.CanDeleteBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -199,11 +199,11 @@ namespace OpenTween.Models { var post = new PostClass { - RetweetedByUserId = 222L, // 他人がリツイートした - UserId = 111L, // 自分のツイート + RetweetedByUserId = new TwitterUserId("222"), // 他人がリツイートした + UserId = new TwitterUserId("111"), // 自分のツイート }; - Assert.True(post.CanDeleteBy(selfUserId: 111L)); + Assert.True(post.CanDeleteBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -213,10 +213,10 @@ namespace OpenTween.Models { IsDm = true, IsMe = false, // 自分が受け取った DM - UserId = 222L, // 送信元ユーザーID + UserId = new TwitterUserId("222"), // 送信元ユーザーID }; - Assert.False(post.CanRetweetBy(selfUserId: 111L)); + Assert.False(post.CanRetweetBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -224,10 +224,10 @@ namespace OpenTween.Models { var post = new PostClass { - UserId = 111L, // 自分のツイート + UserId = new TwitterUserId("111"), // 自分のツイート }; - Assert.True(post.CanRetweetBy(selfUserId: 111L)); + Assert.True(post.CanRetweetBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -235,11 +235,11 @@ namespace OpenTween.Models { var post = new PostClass { - UserId = 111L, // 自分のツイート + UserId = new TwitterUserId("111"), // 自分のツイート IsProtect = true, }; - Assert.True(post.CanRetweetBy(selfUserId: 111L)); + Assert.True(post.CanRetweetBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -247,11 +247,11 @@ namespace OpenTween.Models { var post = new PostClass { - UserId = 222L, // 他人のツイート + UserId = new TwitterUserId("222"), // 他人のツイート IsProtect = false, }; - Assert.True(post.CanRetweetBy(selfUserId: 111L)); + Assert.True(post.CanRetweetBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -259,11 +259,11 @@ namespace OpenTween.Models { var post = new PostClass { - UserId = 222L, // 他人のツイート + UserId = new TwitterUserId("222"), // 他人のツイート IsProtect = true, }; - Assert.False(post.CanRetweetBy(selfUserId: 111L)); + Assert.False(post.CanRetweetBy(selfUserId: new TwitterUserId("111"))); } [Fact] @@ -275,11 +275,11 @@ namespace OpenTween.Models CreatedAtForSorting = new(2023, 1, 2, 0, 0, 0), CreatedAt = new(2023, 1, 1, 0, 0, 0), ScreenName = "@aaa", - UserId = 1L, + UserId = new TwitterUserId("1"), RetweetedId = new TwitterStatusId("50"), RetweetedBy = "@bbb", - RetweetedByUserId = 2L, + RetweetedByUserId = new TwitterUserId("2"), RetweetedCount = 0, }; @@ -289,7 +289,7 @@ namespace OpenTween.Models Assert.Equal(new(2023, 1, 1, 0, 0, 0), originalPost.CreatedAt); Assert.Equal(new(2023, 1, 1, 0, 0, 0), originalPost.CreatedAtForSorting); Assert.Equal("@aaa", originalPost.ScreenName); - Assert.Equal(1L, originalPost.UserId); + Assert.Equal(new TwitterUserId("1"), originalPost.UserId); Assert.Null(originalPost.RetweetedId); Assert.Equal("", originalPost.RetweetedBy); diff --git a/OpenTween.Tests/Models/TabInformationTest.cs b/OpenTween.Tests/Models/TabInformationTest.cs index 1e6377bc..ca59d86a 100644 --- a/OpenTween.Tests/Models/TabInformationTest.cs +++ b/OpenTween.Tests/Models/TabInformationTest.cs @@ -542,11 +542,11 @@ namespace OpenTween.Models [Fact] public void IsMuted_Test() { - this.tabinfo.MuteUserIds = new HashSet { 12345L }; + this.tabinfo.MuteUserIds = new HashSet { new TwitterUserId("12345") }; var post = new PostClass { - UserId = 12345L, + UserId = new TwitterUserId("12345"), Text = "hogehoge", }; Assert.True(this.tabinfo.IsMuted(post, isHomeTimeline: true)); @@ -555,11 +555,11 @@ namespace OpenTween.Models [Fact] public void IsMuted_NotMutingTest() { - this.tabinfo.MuteUserIds = new HashSet { 12345L }; + this.tabinfo.MuteUserIds = new HashSet { new TwitterUserId("12345") }; var post = new PostClass { - UserId = 11111L, + UserId = new TwitterUserId("11111"), Text = "hogehoge", }; Assert.False(this.tabinfo.IsMuted(post, isHomeTimeline: true)); @@ -568,12 +568,12 @@ namespace OpenTween.Models [Fact] public void IsMuted_RetweetTest() { - this.tabinfo.MuteUserIds = new HashSet { 12345L }; + this.tabinfo.MuteUserIds = new HashSet { new TwitterUserId("12345") }; var post = new PostClass { - UserId = 11111L, - RetweetedByUserId = 12345L, + UserId = new TwitterUserId("11111"), + RetweetedByUserId = new TwitterUserId("12345"), Text = "hogehoge", }; Assert.True(this.tabinfo.IsMuted(post, isHomeTimeline: true)); @@ -582,12 +582,12 @@ namespace OpenTween.Models [Fact] public void IsMuted_RetweetNotMutingTest() { - this.tabinfo.MuteUserIds = new HashSet { 12345L }; + this.tabinfo.MuteUserIds = new HashSet { new TwitterUserId("12345") }; var post = new PostClass { - UserId = 11111L, - RetweetedByUserId = 22222L, + UserId = new TwitterUserId("11111"), + RetweetedByUserId = new TwitterUserId("22222"), Text = "hogehoge", }; Assert.False(this.tabinfo.IsMuted(post, isHomeTimeline: true)); @@ -596,12 +596,12 @@ namespace OpenTween.Models [Fact] public void IsMuted_ReplyTest() { - this.tabinfo.MuteUserIds = new HashSet { 12345L }; + this.tabinfo.MuteUserIds = new HashSet { new TwitterUserId("12345") }; // ミュート対象のユーザーであってもリプライの場合は対象外とする var post = new PostClass { - UserId = 12345L, + UserId = new TwitterUserId("12345"), Text = "@foo hogehoge", IsReply = true, }; @@ -611,12 +611,12 @@ namespace OpenTween.Models [Fact] public void IsMuted_NotInHomeTimelineTest() { - this.tabinfo.MuteUserIds = new HashSet { 12345L }; + this.tabinfo.MuteUserIds = new HashSet { new TwitterUserId("12345") }; // Recent以外のタブ(検索など)の場合は対象外とする var post = new PostClass { - UserId = 12345L, + UserId = new TwitterUserId("12345"), Text = "hogehoge", }; Assert.False(this.tabinfo.IsMuted(post, isHomeTimeline: false)); @@ -625,7 +625,7 @@ namespace OpenTween.Models [Fact] public void IsMuted_MuteTabRulesTest() { - this.tabinfo.MuteUserIds = new HashSet { }; + this.tabinfo.MuteUserIds = new HashSet { }; var muteTab = new MuteTabModel(); muteTab.AddFilter(new PostFilterRule @@ -637,7 +637,7 @@ namespace OpenTween.Models var post = new PostClass { - UserId = 12345L, + UserId = new TwitterUserId("12345"), ScreenName = "foo", Text = "hogehoge", }; @@ -647,7 +647,7 @@ namespace OpenTween.Models [Fact] public void IsMuted_MuteTabRules_NotInHomeTimelineTest() { - this.tabinfo.MuteUserIds = new HashSet { }; + this.tabinfo.MuteUserIds = new HashSet { }; var muteTab = new MuteTabModel(); muteTab.AddFilter(new PostFilterRule @@ -660,7 +660,7 @@ namespace OpenTween.Models // ミュートタブによるミュートはリプライも対象とする var post = new PostClass { - UserId = 12345L, + UserId = new TwitterUserId("12345"), ScreenName = "foo", Text = "@hoge hogehoge", IsReply = true, @@ -1291,14 +1291,14 @@ namespace OpenTween.Models { StatusId = new TwitterStatusId("100"), ScreenName = "aaa", - UserId = 123L, + UserId = new TwitterUserId("123"), IsOwl = true, }; this.tabinfo.AddPost(post); this.tabinfo.DistributePosts(); this.tabinfo.SubmitUpdate(); - var followerIds = new HashSet { 123L }; + var followerIds = new HashSet { new TwitterUserId("123") }; this.tabinfo.RefreshOwl(followerIds); Assert.False(post.IsOwl); @@ -1314,14 +1314,14 @@ namespace OpenTween.Models { StatusId = new TwitterStatusId("100"), ScreenName = "aaa", - UserId = 123L, + UserId = new TwitterUserId("123"), IsOwl = true, }; tab.AddPostQueue(post); this.tabinfo.DistributePosts(); this.tabinfo.SubmitUpdate(); - var followerIds = new HashSet { 123L }; + var followerIds = new HashSet { new TwitterUserId("123") }; this.tabinfo.RefreshOwl(followerIds); Assert.False(post.IsOwl); @@ -1334,14 +1334,14 @@ namespace OpenTween.Models { StatusId = new TwitterStatusId("100"), ScreenName = "aaa", - UserId = 123L, + UserId = new TwitterUserId("123"), IsOwl = false, }; this.tabinfo.AddPost(post); this.tabinfo.DistributePosts(); this.tabinfo.SubmitUpdate(); - var followerIds = new HashSet { 456L }; + var followerIds = new HashSet { new TwitterUserId("456") }; this.tabinfo.RefreshOwl(followerIds); Assert.True(post.IsOwl); diff --git a/OpenTween.Tests/Models/TwitterPostFactoryTest.cs b/OpenTween.Tests/Models/TwitterPostFactoryTest.cs index 9c74484b..8ab1b744 100644 --- a/OpenTween.Tests/Models/TwitterPostFactoryTest.cs +++ b/OpenTween.Tests/Models/TwitterPostFactoryTest.cs @@ -28,7 +28,7 @@ namespace OpenTween.Models { public class TwitterPostFactoryTest { - private static readonly ISet EmptyIdSet = new HashSet(); + private static readonly ISet EmptyIdSet = new HashSet(); private readonly Random random = new(); @@ -74,7 +74,7 @@ namespace OpenTween.Models { var factory = new TwitterPostFactory(this.CreateTabinfo(), new()); var status = this.CreateStatus(); - var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds: EmptyIdSet, firstLoad: false); + var post = factory.CreateFromStatus(status, selfUserId: new("20000"), followerIds: EmptyIdSet, firstLoad: false); Assert.Equal(new TwitterStatusId(status.IdStr), post.StatusId); Assert.Equal(new DateTimeUtc(2022, 1, 1, 0, 0, 0), post.CreatedAt); @@ -107,7 +107,7 @@ namespace OpenTween.Models Assert.Null(post.RetweetedBy); Assert.Null(post.RetweetedByUserId); - Assert.Equal(status.User.Id, post.UserId); + Assert.Equal(new TwitterUserId(status.User.IdStr), post.UserId); Assert.Equal("tetete", post.ScreenName); Assert.Equal("ててて", post.Nickname); Assert.Equal("https://example.com/profile.png", post.ImageUrl); @@ -123,7 +123,7 @@ namespace OpenTween.Models { var factory = new TwitterPostFactory(this.CreateTabinfo(), new()); var status = this.CreateStatus(); - var selfUserId = status.User.Id; + var selfUserId = new TwitterUserId(status.User.IdStr); var post = factory.CreateFromStatus(status, selfUserId, followerIds: EmptyIdSet, firstLoad: false); Assert.True(post.IsMe); @@ -134,8 +134,8 @@ namespace OpenTween.Models { var factory = new TwitterPostFactory(this.CreateTabinfo(), new()); var status = this.CreateStatus(); - var followerIds = new HashSet { status.User.Id }; - var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds, firstLoad: false); + var followerIds = new HashSet { new TwitterUserId(status.User.IdStr) }; + var post = factory.CreateFromStatus(status, selfUserId: new("20000"), followerIds, firstLoad: false); Assert.False(post.IsOwl); } @@ -145,8 +145,8 @@ namespace OpenTween.Models { var factory = new TwitterPostFactory(this.CreateTabinfo(), new()); var status = this.CreateStatus(); - var followerIds = new HashSet { 30000L }; - var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds, firstLoad: false); + var followerIds = new HashSet { new TwitterUserId("30000") }; + var post = factory.CreateFromStatus(status, selfUserId: new("20000"), followerIds, firstLoad: false); Assert.True(post.IsOwl); } @@ -161,12 +161,12 @@ namespace OpenTween.Models retweetStatus.RetweetedStatus = originalStatus; retweetStatus.Source = """Twitter Web App"""; - var post = factory.CreateFromStatus(retweetStatus, selfUserId: 20000L, followerIds: EmptyIdSet, firstLoad: false); + var post = factory.CreateFromStatus(retweetStatus, selfUserId: new("20000"), followerIds: EmptyIdSet, firstLoad: false); Assert.Equal(new TwitterStatusId(retweetStatus.IdStr), post.StatusId); - Assert.Equal(retweetStatus.User.Id, post.RetweetedByUserId); + Assert.Equal(new TwitterUserId(retweetStatus.User.IdStr), post.RetweetedByUserId); Assert.Equal(new TwitterStatusId(originalStatus.IdStr), post.RetweetedId); - Assert.Equal(originalStatus.User.Id, post.UserId); + Assert.Equal(new TwitterUserId(originalStatus.User.IdStr), post.UserId); Assert.Equal("OpenTween", post.Source); Assert.Equal("https://www.opentween.org/", post.SourceUri?.OriginalString); @@ -182,7 +182,7 @@ namespace OpenTween.Models var factory = new TwitterPostFactory(this.CreateTabinfo(), settingCommon); var status = this.CreateStatus(); - var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds: EmptyIdSet, firstLoad: true); + var post = factory.CreateFromStatus(status, selfUserId: new("20000"), followerIds: EmptyIdSet, firstLoad: true); Assert.True(post.IsRead); // 既読 } @@ -197,7 +197,7 @@ namespace OpenTween.Models var factory = new TwitterPostFactory(this.CreateTabinfo(), settingCommon); var status = this.CreateStatus(); - var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds: EmptyIdSet, firstLoad: true); + var post = factory.CreateFromStatus(status, selfUserId: new("20000"), followerIds: EmptyIdSet, firstLoad: true); Assert.False(post.IsRead); // 未読 } @@ -213,7 +213,7 @@ namespace OpenTween.Models var factory = new TwitterPostFactory(this.CreateTabinfo(), settingCommon); var status = this.CreateStatus(); status.User.Id = 20000L; - var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds: EmptyIdSet, firstLoad: false); + var post = factory.CreateFromStatus(status, selfUserId: new("20000"), followerIds: EmptyIdSet, firstLoad: false); Assert.False(post.IsRead); // 未読 } @@ -228,8 +228,8 @@ namespace OpenTween.Models var factory = new TwitterPostFactory(this.CreateTabinfo(), settingCommon); var status = this.CreateStatus(); - status.User.Id = 20000L; - var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds: EmptyIdSet, firstLoad: false); + status.User.IdStr = "20000"; + var post = factory.CreateFromStatus(status, selfUserId: new("20000"), followerIds: EmptyIdSet, firstLoad: false); Assert.True(post.IsRead); // 既読 } @@ -281,13 +281,13 @@ namespace OpenTween.Models var selfUser = this.CreateUser(); var otherUser = this.CreateUser(); var eventItem = this.CreateDirectMessage(senderId: otherUser.IdStr, recipientId: selfUser.IdStr); - var users = new Dictionary() + var users = new Dictionary() { - [selfUser.IdStr] = selfUser, - [otherUser.IdStr] = otherUser, + [new(selfUser.IdStr)] = selfUser, + [new(otherUser.IdStr)] = otherUser, }; var apps = this.CreateApps(); - var post = factory.CreateFromDirectMessageEvent(eventItem, users, apps, selfUserId: selfUser.Id, firstLoad: false); + var post = factory.CreateFromDirectMessageEvent(eventItem, users, apps, selfUserId: new(selfUser.IdStr), firstLoad: false); Assert.Equal(new TwitterDirectMessageId(eventItem.Id), post.StatusId); Assert.Equal(new DateTimeUtc(2022, 1, 1, 0, 0, 0), post.CreatedAt); @@ -320,7 +320,7 @@ namespace OpenTween.Models Assert.Null(post.RetweetedBy); Assert.Null(post.RetweetedByUserId); - Assert.Equal(otherUser.Id, post.UserId); + Assert.Equal(new TwitterUserId(otherUser.IdStr), post.UserId); Assert.Equal("tetete", post.ScreenName); Assert.Equal("ててて", post.Nickname); Assert.Equal("https://example.com/profile.png", post.ImageUrl); @@ -339,15 +339,15 @@ namespace OpenTween.Models var selfUser = this.CreateUser(); var otherUser = this.CreateUser(); var eventItem = this.CreateDirectMessage(senderId: selfUser.IdStr, recipientId: otherUser.IdStr); - var users = new Dictionary() + var users = new Dictionary() { - [selfUser.IdStr] = selfUser, - [otherUser.IdStr] = otherUser, + [new(selfUser.IdStr)] = selfUser, + [new(otherUser.IdStr)] = otherUser, }; var apps = this.CreateApps(); - var post = factory.CreateFromDirectMessageEvent(eventItem, users, apps, selfUserId: selfUser.Id, firstLoad: false); + var post = factory.CreateFromDirectMessageEvent(eventItem, users, apps, selfUserId: new(selfUser.IdStr), firstLoad: false); - Assert.Equal(otherUser.Id, post.UserId); + Assert.Equal(new TwitterUserId(otherUser.IdStr), post.UserId); Assert.False(post.IsOwl); Assert.True(post.IsMe); } @@ -367,7 +367,7 @@ namespace OpenTween.Models }, }; - _ = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds: EmptyIdSet, firstLoad: false); + _ = factory.CreateFromStatus(status, selfUserId: new("20000"), followerIds: EmptyIdSet, firstLoad: false); Assert.Equal(new[] { "#OpenTween" }, factory.GetReceivedHashtags()); Assert.Empty(factory.GetReceivedHashtags()); @@ -395,7 +395,7 @@ namespace OpenTween.Models }, }; - var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet, firstLoad: false); + var post = factory.CreateFromStatus(status, selfUserId: new("100"), followerIds: EmptyIdSet, firstLoad: false); var accessibleText = string.Format(Properties.Resources.ImageAltText, "代替テキスト"); Assert.Equal(accessibleText, post.AccessibleText); @@ -426,7 +426,7 @@ namespace OpenTween.Models }, }; - var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet, firstLoad: false); + var post = factory.CreateFromStatus(status, selfUserId: new("100"), followerIds: EmptyIdSet, firstLoad: false); Assert.Equal("pic.twitter.com/hoge", post.AccessibleText); Assert.Equal("""pic.twitter.com/hoge""", post.Text); @@ -467,7 +467,7 @@ namespace OpenTween.Models FullText = "test", }; - var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet, firstLoad: false); + var post = factory.CreateFromStatus(status, selfUserId: new("100"), followerIds: EmptyIdSet, firstLoad: false); var accessibleText = string.Format(Properties.Resources.QuoteStatus_AccessibleText, "foo", "test"); Assert.Equal(accessibleText, post.AccessibleText); @@ -502,7 +502,7 @@ namespace OpenTween.Models Expanded = "https://twitter.com/hoge/status/1234567890", }; - var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet, firstLoad: false); + var post = factory.CreateFromStatus(status, selfUserId: new("100"), followerIds: EmptyIdSet, firstLoad: false); var accessibleText = "hoge " + string.Format(Properties.Resources.QuoteStatus_AccessibleText, "foo", "test"); Assert.Equal(accessibleText, post.AccessibleText); @@ -533,7 +533,7 @@ namespace OpenTween.Models }; status.QuotedStatus = null; - var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet, firstLoad: false); + var post = factory.CreateFromStatus(status, selfUserId: new("100"), followerIds: EmptyIdSet, firstLoad: false); var accessibleText = "twitter.com/hoge/status/1…"; Assert.Equal(accessibleText, post.AccessibleText); diff --git a/OpenTween.Tests/SocialProtocol/AccountCollectionTest.cs b/OpenTween.Tests/SocialProtocol/AccountCollectionTest.cs index c75d8955..7ba90e6c 100644 --- a/OpenTween.Tests/SocialProtocol/AccountCollectionTest.cs +++ b/OpenTween.Tests/SocialProtocol/AccountCollectionTest.cs @@ -38,7 +38,7 @@ namespace OpenTween.SocialProtocol TwitterAuthType = APIAuthType.OAuth1, Token = "aaaaa", TokenSecret = "bbbbb", - UserId = this.random.Next(), + UserId = this.random.Next().ToString(), Username = "tetete", }; } @@ -59,7 +59,7 @@ namespace OpenTween.SocialProtocol accounts.LoadFromSettings(settingCommon); Assert.Single(accounts.Items); - Assert.Equal(settingCommon.UserAccounts[0].UserId, accounts.Primary.UserId); + Assert.Equal(new TwitterUserId(settingCommon.UserAccounts[0].UserId), accounts.Primary.UserId); } [Fact] @@ -78,7 +78,7 @@ namespace OpenTween.SocialProtocol accounts.LoadFromSettings(settingCommon1); var accountItem1 = Assert.Single(accounts.Items); - Assert.Equal(settingCommon1.UserAccounts[0].UserId, accounts.Primary.UserId); + Assert.Equal(new TwitterUserId(settingCommon1.UserAccounts[0].UserId), accounts.Primary.UserId); var settingCommon2 = new SettingCommon { @@ -112,7 +112,7 @@ namespace OpenTween.SocialProtocol accounts.LoadFromSettings(settingCommon1); var accountItem1 = Assert.Single(accounts.Items); - Assert.Equal(settingCommon1.UserAccounts[0].UserId, accounts.Primary.UserId); + Assert.Equal(new TwitterUserId(settingCommon1.UserAccounts[0].UserId), accounts.Primary.UserId); var settingCommon2 = new SettingCommon { @@ -126,16 +126,16 @@ namespace OpenTween.SocialProtocol accounts.LoadFromSettings(settingCommon2); var accountItem2 = Assert.Single(accounts.Items); - Assert.Equal(settingCommon2.UserAccounts[0].UserId, accounts.Primary.UserId); + Assert.Equal(new TwitterUserId(settingCommon2.UserAccounts[0].UserId), accounts.Primary.UserId); // 同一の ID は同じインスタンスを使用 Assert.Same(accountItem1, accountItem2); Assert.NotEqual( - settingCommon1.UserAccounts[0].UserId, + new TwitterUserId(settingCommon1.UserAccounts[0].UserId), accountItem2.UserId ); Assert.Equal( - settingCommon2.UserAccounts[0].UserId, + new TwitterUserId(settingCommon2.UserAccounts[0].UserId), accountItem2.UserId ); Assert.False(accountItem2.IsDisposed); diff --git a/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountStateTest.cs b/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountStateTest.cs index 0035cdf0..3ab0d6d0 100644 --- a/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountStateTest.cs +++ b/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountStateTest.cs @@ -20,6 +20,7 @@ // Boston, MA 02110-1301, USA. using OpenTween.Api.DataModel; +using OpenTween.Models; using Xunit; namespace OpenTween.SocialProtocol.Twitter @@ -42,7 +43,7 @@ namespace OpenTween.SocialProtocol.Twitter }; accountState.UpdateFromUser(twitterUser); - Assert.Equal(514241801L, accountState.UserId); + Assert.Equal(new TwitterUserId("514241801"), accountState.UserId); Assert.Equal("OpenTween", accountState.UserName); Assert.Equal(31, accountState.StatusesCount); Assert.Equal(1, accountState.FriendsCount); diff --git a/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs b/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs index 043543dd..0564b3d3 100644 --- a/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs +++ b/OpenTween.Tests/SocialProtocol/Twitter/TwitterAccountTest.cs @@ -20,6 +20,7 @@ // Boston, MA 02110-1301, USA. using System; +using OpenTween.Models; using Xunit; namespace OpenTween.SocialProtocol.Twitter @@ -38,12 +39,12 @@ namespace OpenTween.SocialProtocol.Twitter TwitterAuthType = APIAuthType.OAuth1, Token = "aaaaa", TokenSecret = "aaaaa", - UserId = 11111L, + UserId = "11111", Username = "tetete", }; var settingCommon = new SettingCommon(); account.Initialize(accountSettings, settingCommon); - Assert.Equal(11111L, account.UserId); + Assert.Equal(new TwitterUserId("11111"), account.UserId); Assert.Equal("tetete", account.UserName); Assert.Equal(APIAuthType.OAuth1, account.AuthType); Assert.Same(account.Legacy.Api.Connection, account.Connection); @@ -61,12 +62,12 @@ namespace OpenTween.SocialProtocol.Twitter TwitterAuthType = APIAuthType.OAuth1, Token = "aaaaa", TokenSecret = "aaaaa", - UserId = 11111L, + UserId = "11111", Username = "tetete", }; var settingCommon1 = new SettingCommon(); account.Initialize(accountSettings1, settingCommon1); - Assert.Equal(11111L, account.UserId); + Assert.Equal(new TwitterUserId("11111"), account.UserId); var accountSettings2 = new UserAccount { @@ -74,12 +75,12 @@ namespace OpenTween.SocialProtocol.Twitter TwitterAuthType = APIAuthType.OAuth1, Token = "bbbbb", TokenSecret = "bbbbb", - UserId = 22222L, + UserId = "22222", Username = "hoge", }; var settingCommon2 = new SettingCommon(); account.Initialize(accountSettings2, settingCommon2); - Assert.Equal(22222L, account.UserId); + Assert.Equal(new TwitterUserId("22222"), account.UserId); } [Fact] @@ -101,7 +102,7 @@ namespace OpenTween.SocialProtocol.Twitter TwitterAuthType = APIAuthType.OAuth1, Token = "aaaaa", TokenSecret = "aaaaa", - UserId = 11111L, + UserId = "11111", Username = "tetete", }; var settingCommon = new SettingCommon(); @@ -121,7 +122,7 @@ namespace OpenTween.SocialProtocol.Twitter UniqueKey = accountKey, TwitterAuthType = APIAuthType.TwitterComCookie, TwitterComCookie = "auth_token=foo; ct0=bar", - UserId = 11111L, + UserId = "11111", Username = "tetete", }; var settingCommon = new SettingCommon(); diff --git a/OpenTween.Tests/TimelineListViewCacheTest.cs b/OpenTween.Tests/TimelineListViewCacheTest.cs index 6b88e5d2..667e05f8 100644 --- a/OpenTween.Tests/TimelineListViewCacheTest.cs +++ b/OpenTween.Tests/TimelineListViewCacheTest.cs @@ -35,7 +35,7 @@ namespace OpenTween return new() { StatusId = new TwitterStatusId(this.random.Next(10000)), - UserId = this.random.Next(10000), + UserId = new TwitterUserId(this.random.Next(10000).ToString()), ScreenName = "test", Nickname = "てすと", AccessibleText = "foo", diff --git a/OpenTween.Tests/TweenMainTest.cs b/OpenTween.Tests/TweenMainTest.cs index 7feab842..180d426c 100644 --- a/OpenTween.Tests/TweenMainTest.cs +++ b/OpenTween.Tests/TweenMainTest.cs @@ -219,7 +219,7 @@ namespace OpenTween { StatusId = new TwitterStatusId("100"), Text = "hoge", - UserId = 111L, + UserId = new TwitterUserId("111"), ScreenName = "opentween", CreatedAt = new(2024, 1, 1, 0, 0, 0), }; diff --git a/OpenTween/Api/DataModel/TwitterPageable.cs b/OpenTween/Api/DataModel/TwitterPageable.cs index e7b9e57f..5a5b01e4 100644 --- a/OpenTween/Api/DataModel/TwitterPageable.cs +++ b/OpenTween/Api/DataModel/TwitterPageable.cs @@ -27,6 +27,7 @@ using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; +using OpenTween.Models; namespace OpenTween.Api.DataModel { @@ -69,14 +70,14 @@ namespace OpenTween.Api.DataModel } [DataContract] - public class TwitterIds : TwitterPageable + public class TwitterIds : TwitterPageable { [DataMember(Name = "ids")] - public long[] Ids { get; set; } + public string[] Ids { get; set; } [IgnoreDataMember] - public override long[] Items - => this.Ids; + public override TwitterUserId[] Items + => this.Ids.Select(x => new TwitterUserId(x)).ToArray(); /// public static TwitterIds ParseJson(string json) diff --git a/OpenTween/Api/GraphQL/CreateTweetRequest.cs b/OpenTween/Api/GraphQL/CreateTweetRequest.cs index 5caf3ac2..b268cb83 100644 --- a/OpenTween/Api/GraphQL/CreateTweetRequest.cs +++ b/OpenTween/Api/GraphQL/CreateTweetRequest.cs @@ -41,7 +41,7 @@ namespace OpenTween.Api.GraphQL public TwitterStatusId? InReplyToTweetId { get; set; } - public string[] ExcludeReplyUserIds { get; set; } = Array.Empty(); + public TwitterUserId[] ExcludeReplyUserIds { get; set; } = Array.Empty(); public string[] MediaIds { get; set; } = Array.Empty(); @@ -105,7 +105,7 @@ namespace OpenTween.Api.GraphQL Reply: this.InReplyToTweetId != null ? new( InReplyToTweetId: this.InReplyToTweetId.Id, - ExcludeReplyUserIds: this.ExcludeReplyUserIds + ExcludeReplyUserIds: this.ExcludeReplyUserIds.Select(x => x.Id).ToArray() ) : null, Media: this.MediaIds.Length > 0 diff --git a/OpenTween/Api/GraphQL/LikesRequest.cs b/OpenTween/Api/GraphQL/LikesRequest.cs index b03dbf44..31dd2940 100644 --- a/OpenTween/Api/GraphQL/LikesRequest.cs +++ b/OpenTween/Api/GraphQL/LikesRequest.cs @@ -25,6 +25,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using OpenTween.Connection; +using OpenTween.Models; namespace OpenTween.Api.GraphQL { @@ -34,7 +35,7 @@ namespace OpenTween.Api.GraphQL private static readonly Uri EndpointUri = new("https://twitter.com/i/api/graphql/G_zHbTiwSqLm0TAK_3sNWQ/Likes"); - public required string UserId { get; set; } + public required TwitterUserId UserId { get; set; } public int Count { get; set; } = 20; @@ -47,7 +48,7 @@ namespace OpenTween.Api.GraphQL return new() { ["variables"] = "{" + - $@"""userId"":""{JsonUtils.EscapeJsonString(this.UserId)}""," + + $@"""userId"":""{JsonUtils.EscapeJsonString(this.UserId.Id)}""," + $@"""count"":{this.Count}," + $@"""includePromotedContent"":false," + $@"""withClientEventToken"":false," + diff --git a/OpenTween/Api/GraphQL/UserTweetsAndRepliesRequest.cs b/OpenTween/Api/GraphQL/UserTweetsAndRepliesRequest.cs index 8bbf154d..f5d629fb 100644 --- a/OpenTween/Api/GraphQL/UserTweetsAndRepliesRequest.cs +++ b/OpenTween/Api/GraphQL/UserTweetsAndRepliesRequest.cs @@ -25,6 +25,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using OpenTween.Connection; +using OpenTween.Models; namespace OpenTween.Api.GraphQL { @@ -34,13 +35,13 @@ namespace OpenTween.Api.GraphQL private static readonly Uri EndpointUri = new("https://twitter.com/i/api/graphql/YlkSUg0mRBx7-EkxCvc-bw/UserTweetsAndReplies"); - public string UserId { get; set; } + public TwitterUserId UserId { get; set; } public int Count { get; set; } = 20; public TwitterGraphqlCursor? Cursor { get; set; } - public UserTweetsAndRepliesRequest(string userId) + public UserTweetsAndRepliesRequest(TwitterUserId userId) => this.UserId = userId; public Dictionary CreateParameters() @@ -50,7 +51,7 @@ namespace OpenTween.Api.GraphQL return new() { ["variables"] = "{" + - $@"""userId"":""{JsonUtils.EscapeJsonString(this.UserId)}""," + + $@"""userId"":""{JsonUtils.EscapeJsonString(this.UserId.Id)}""," + $@"""count"":{this.Count}," + $@"""includePromotedContent"":true," + $@"""withCommunity"":true," + diff --git a/OpenTween/Api/TwitterApi.cs b/OpenTween/Api/TwitterApi.cs index 07f6714a..3277b8d7 100644 --- a/OpenTween/Api/TwitterApi.cs +++ b/OpenTween/Api/TwitterApi.cs @@ -193,7 +193,7 @@ namespace OpenTween.Api TwitterStatusId? replyToId, IReadOnlyList? mediaIds, bool? autoPopulateReplyMetadata = null, - IReadOnlyList? excludeReplyUserIds = null, + IReadOnlyList? excludeReplyUserIds = null, string? attachmentUrl = null) { var param = new Dictionary @@ -613,7 +613,7 @@ namespace OpenTween.Api .ConfigureAwait(false); } - public async Task> DirectMessagesEventsNew(long recipientId, string text, long? mediaId = null) + public async Task> DirectMessagesEventsNew(TwitterUserId recipientId, string text, long? mediaId = null) { var attachment = ""; if (mediaId != null) @@ -634,7 +634,7 @@ namespace OpenTween.Api "type": "message_create", "message_create": { "target": { - "recipient_id": "{{JsonUtils.EscapeJsonString(recipientId.ToString())}}" + "recipient_id": "{{JsonUtils.EscapeJsonString(recipientId.Id)}}" }, "message_data": { "text": "{{JsonUtils.EscapeJsonString(text)}}"{{attachment}} @@ -694,14 +694,14 @@ namespace OpenTween.Api .ConfigureAwait(false); } - public async Task UsersLookup(IReadOnlyList userIds) + public async Task UsersLookup(IReadOnlyList userIds) { var request = new GetRequest { RequestUri = new("users/lookup.json", UriKind.Relative), Query = new Dictionary { - ["user_id"] = string.Join(",", userIds), + ["user_id"] = string.Join(",", userIds.Select(x => x.Id)), ["include_entities"] = "true", ["include_ext_alt_text"] = "true", ["tweet_mode"] = "extended", @@ -854,7 +854,7 @@ namespace OpenTween.Api return response.ReadAsLazyJson(); } - public async Task NoRetweetIds() + public async Task NoRetweetIds() { var request = new GetRequest { @@ -865,8 +865,10 @@ namespace OpenTween.Api using var response = await this.Connection.SendAsync(request) .ConfigureAwait(false); - return await response.ReadAsJson() + var idsStr = await response.ReadAsJson() .ConfigureAwait(false); + + return idsStr.Select(x => new TwitterUserId(x)).ToArray(); } public async Task FollowersIds(long? cursor = null) diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index aecd38fa..9f0939a5 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -191,7 +191,7 @@ namespace OpenTween using var apiConnection = new TwitterApiConnection(new TwitterCredentialCookie(appToken), new()); twitterApi.Initialize(apiConnection); var twitterUser = await twitterApi.AccountVerifyCredentials(); - newAccount.UserId = twitterUser.Id; + newAccount.UserId = twitterUser.IdStr; newAccount.Username = twitterUser.ScreenName; } else @@ -280,7 +280,7 @@ namespace OpenTween TwitterOAuth1ConsumerKey = appToken.OAuth1CustomConsumerKey?.Value ?? "", TwitterOAuth1ConsumerSecret = appToken.OAuth1CustomConsumerSecret?.Value ?? "", Username = accessTokenResponse["screen_name"], - UserId = long.Parse(accessTokenResponse["user_id"]), + UserId = accessTokenResponse["user_id"], Token = accessTokenResponse["oauth_token"], TokenSecret = accessTokenResponse["oauth_token_secret"], }; diff --git a/OpenTween/ListElement.cs b/OpenTween/ListElement.cs index 71bfe42a..5344e272 100644 --- a/OpenTween/ListElement.cs +++ b/OpenTween/ListElement.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Xml.Serialization; using OpenTween.Api.DataModel; +using OpenTween.Models; namespace OpenTween { @@ -42,7 +43,7 @@ namespace OpenTween public bool IsPublic = true; public int SubscriberCount = 0; // 購読者数 public int MemberCount = 0; // リストメンバ数 - public long UserId = 0; + public PersonId UserId = null!; public string Username = ""; public string Nickname = ""; @@ -68,7 +69,7 @@ namespace OpenTween this.Slug = listElementData.Slug; this.Nickname = listElementData.User.Name.Trim(); this.Username = listElementData.User.ScreenName; - this.UserId = listElementData.User.Id; + this.UserId = new TwitterUserId(listElementData.User.IdStr); this.tw = tw; } diff --git a/OpenTween/Models/PersonId.cs b/OpenTween/Models/PersonId.cs new file mode 100644 index 00000000..efc511ea --- /dev/null +++ b/OpenTween/Models/PersonId.cs @@ -0,0 +1,82 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Diagnostics; + +namespace OpenTween.Models +{ + [DebuggerDisplay("{IdType}:{Id}")] + public abstract class PersonId + : IEquatable, IComparable + { + public abstract string IdType { get; } + + public abstract string Id { get; } + + public virtual int CompareTo(PersonId other) + { + var compareByIdType = this.IdType.CompareTo(other.IdType); + if (compareByIdType != 0) + return compareByIdType; + + // 辞書順による比較のみだと "20" > "100" となってしまうため文字数による比較も加える + var compareByIdLength = this.Id.Length.CompareTo(other.Id.Length); + if (compareByIdLength != 0) + return compareByIdLength; + + return this.Id.CompareTo(other.Id); + } + + public virtual bool Equals(PersonId other) + => this.IdType == other.IdType && this.Id == other.Id; + + public override bool Equals(object obj) + => obj is PersonId otherId && this.Equals(otherId); + + public override int GetHashCode() + => this.IdType.GetHashCode() ^ this.Id.GetHashCode(); + + public override string ToString() + => this.Id; + + public static bool operator ==(PersonId? left, PersonId? right) + => EqualityComparer.Default.Equals(left, right); + + public static bool operator !=(PersonId? left, PersonId? right) + => !EqualityComparer.Default.Equals(left, right); + + public static bool operator <(PersonId left, PersonId right) + => Comparer.Default.Compare(left, right) < 0; + + public static bool operator <=(PersonId left, PersonId right) + => Comparer.Default.Compare(left, right) <= 0; + + public static bool operator >=(PersonId left, PersonId right) + => Comparer.Default.Compare(left, right) >= 0; + + public static bool operator >(PersonId left, PersonId right) + => Comparer.Default.Compare(left, right) > 0; + } +} diff --git a/OpenTween/Models/PostClass.cs b/OpenTween/Models/PostClass.cs index b1791c80..df607fd4 100644 --- a/OpenTween/Models/PostClass.cs +++ b/OpenTween/Models/PostClass.cs @@ -93,21 +93,21 @@ namespace OpenTween.Models public Uri? SourceUri { get; init; } - public List<(long UserId, string ScreenName)> ReplyToList { get; init; } = new(); + public List<(PersonId UserId, string ScreenName)> ReplyToList { get; init; } = new(); public bool IsMe { get; init; } public bool IsDm { get; init; } - public long UserId { get; init; } + public PersonId UserId { get; init; } = null!; public string? RetweetedBy { get; init; } public PostId? RetweetedId { get; init; } - public long? RetweetedByUserId { get; init; } + public PersonId? RetweetedByUserId { get; init; } - public long? InReplyToUserId { get; init; } + public PersonId? InReplyToUserId { get; init; } public List Media { get; init; } = new(); @@ -203,7 +203,7 @@ namespace OpenTween.Models /// /// ツイートを削除しようとするユーザーのID /// 削除可能であれば true、そうでなければ false - public bool CanDeleteBy(long selfUserId) + public bool CanDeleteBy(PersonId selfUserId) { // 自分が送った DM と自分に届いた DM のどちらも削除可能 if (this.IsDm) @@ -225,7 +225,7 @@ namespace OpenTween.Models /// /// リツイートしようとするユーザーのID /// リツイート可能であれば true、そうでなければ false - public bool CanRetweetBy(long selfUserId) + public bool CanRetweetBy(PersonId selfUserId) { // DM は常にリツイート不可 if (this.IsDm) diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index 2e8da9d0..28619c30 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -54,9 +54,9 @@ namespace OpenTween.Models public Stack RemovedTab { get; } = new(); - public ISet BlockIds { get; set; } = new HashSet(); + public ISet BlockIds { get; set; } = new HashSet(); - public ISet MuteUserIds { get; set; } = new HashSet(); + public ISet MuteUserIds { get; set; } = new HashSet(); // 発言の追加 // AddPost(複数回) -> DistributePosts -> SubmitUpdate @@ -260,7 +260,7 @@ namespace OpenTween.Models MyCommon.TabUsageType.UserTimeline => new UserTimelineTabModel(tabName, tabSetting.User!) { - UserId = tabSetting.UserId, + UserId = tabSetting.UserId is { } userId ? new TwitterUserId(userId) : null, }, MyCommon.TabUsageType.PublicSearch => new PublicSearchTabModel(tabName) @@ -643,7 +643,7 @@ namespace OpenTween.Models if (this.MuteUserIds.Contains(post.UserId)) return true; - if (post.RetweetedByUserId != null && this.MuteUserIds.Contains(post.RetweetedByUserId.Value)) + if (post.RetweetedByUserId != null && this.MuteUserIds.Contains(post.RetweetedByUserId)) return true; return false; @@ -890,7 +890,7 @@ namespace OpenTween.Models } } - public void RefreshOwl(ISet follower) + public void RefreshOwl(ISet follower) { lock (this.lockObj) { diff --git a/OpenTween/Models/TwitterPostFactory.cs b/OpenTween/Models/TwitterPostFactory.cs index 5a4efce1..a15d3ebe 100644 --- a/OpenTween/Models/TwitterPostFactory.cs +++ b/OpenTween/Models/TwitterPostFactory.cs @@ -58,13 +58,14 @@ namespace OpenTween.Models public PostClass CreateFromStatus( TwitterStatus status, - long selfUserId, - ISet followerIds, + TwitterUserId selfUserId, + ISet followerIds, bool firstLoad, bool favTweet = false ) { var statusUser = status.User ?? TwitterUser.CreateUnknownUser(); + var statusUserId = new TwitterUserId(statusUser.IdStr); // リツイートでない場合は null var retweetedStatus = (TwitterStatus?)null; @@ -80,8 +81,9 @@ namespace OpenTween.Models // リツイートであるか否かに関わらず常にオリジナルのツイート及びユーザーを指す var originalStatus = retweetedStatus ?? status; var originalStatusUser = originalStatus.User ?? TwitterUser.CreateUnknownUser(); + var originalStatusUserId = new TwitterUserId(originalStatusUser.IdStr); - var isMe = statusUser.Id == selfUserId; + var isMe = statusUserId == selfUserId; bool isFav = favTweet; if (isFav == false) @@ -140,7 +142,7 @@ namespace OpenTween.Models var isOwl = false; if (!isMe && followerIds.Count > 0) - isOwl = !followerIds.Contains(originalStatusUser.Id); + isOwl = !followerIds.Contains(originalStatusUserId); var createdAtForSorting = ParseDateTimeFromSnowflakeId(status.Id, status.CreatedAt); var createdAt = retweetedStatus != null @@ -179,10 +181,10 @@ namespace OpenTween.Models IsReply = retweetedStatus == null && replyToList.Any(x => x.UserId == selfUserId), InReplyToStatusId = originalStatus.InReplyToStatusIdStr != null ? new TwitterStatusId(originalStatus.InReplyToStatusIdStr) : null, InReplyToUser = originalStatus.InReplyToScreenName, - InReplyToUserId = originalStatus.InReplyToUserId, + InReplyToUserId = originalStatus.InReplyToUserIdStr is { } inReplyToUserId ? new TwitterUserId(inReplyToUserId) : null, // originalStatusUser から生成 - UserId = originalStatusUser.Id, + UserId = originalStatusUserId, ScreenName = screenName, Nickname = nickname, ImageUrl = imageUrl, @@ -194,7 +196,7 @@ namespace OpenTween.Models // retweeterUser から生成 RetweetedBy = retweeterUser != null ? string.Intern(retweeterUser.ScreenName) : null, - RetweetedByUserId = retweeterUser?.Id, + RetweetedByUserId = retweeterUser?.IdStr is { } retweetedByUserId ? new TwitterUserId(retweetedByUserId) : null, IsRead = this.DetermineUnreadState(isMe, firstLoad), }; @@ -202,9 +204,9 @@ namespace OpenTween.Models public PostClass CreateFromDirectMessageEvent( TwitterMessageEvent eventItem, - IReadOnlyDictionary users, + IReadOnlyDictionary users, IReadOnlyDictionary apps, - long selfUserId, + TwitterUserId selfUserId, bool firstLoad ) { @@ -242,10 +244,11 @@ namespace OpenTween.Models .ToArray(); // 以下、ユーザー情報 - var senderIsMe = eventItem.MessageCreate.SenderId == selfUserId.ToString(CultureInfo.InvariantCulture); + var senderId = new TwitterUserId(eventItem.MessageCreate.SenderId); + var senderIsMe = senderId == selfUserId; var displayUserId = senderIsMe - ? eventItem.MessageCreate.Target.RecipientId - : eventItem.MessageCreate.SenderId; + ? new TwitterUserId(eventItem.MessageCreate.Target.RecipientId) + : senderId; if (!users.TryGetValue(displayUserId, out var displayUser)) displayUser = TwitterUser.CreateUnknownUser(); @@ -293,7 +296,7 @@ namespace OpenTween.Models SourceUri = sourceUri, // displayUser から生成 - UserId = displayUser.Id, + UserId = new TwitterUserId(displayUser.IdStr), ScreenName = screenName, Nickname = nickname, ImageUrl = imageUrl, @@ -342,9 +345,9 @@ namespace OpenTween.Models return text; } - private (List<(long UserId, string ScreenName)> ReplyToList, List Media) ExtractEntities(TwitterEntities? entities) + private (List<(PersonId UserId, string ScreenName)> ReplyToList, List Media) ExtractEntities(TwitterEntities? entities) { - var atList = new List<(long UserId, string ScreenName)>(); + var atList = new List<(PersonId UserId, string ScreenName)>(); var media = new List(); if (entities == null) @@ -361,7 +364,7 @@ namespace OpenTween.Models if (entities.UserMentions != null) { foreach (var ent in entities.UserMentions) - atList.Add((ent.Id, ent.ScreenName)); + atList.Add((new TwitterUserId(ent.IdStr), ent.ScreenName)); } if (entities.Media != null) diff --git a/OpenTween/Models/TwitterUserId.cs b/OpenTween/Models/TwitterUserId.cs new file mode 100644 index 00000000..e57fc932 --- /dev/null +++ b/OpenTween/Models/TwitterUserId.cs @@ -0,0 +1,38 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +namespace OpenTween.Models +{ + public class TwitterUserId : PersonId + { + public override string IdType => "twitter_user"; + + public override string Id { get; } + + public TwitterUserId(string id) + => this.Id = id; + + public TwitterUserId(long id) + => this.Id = id.ToString(); + } +} diff --git a/OpenTween/Models/UserTimelineTabModel.cs b/OpenTween/Models/UserTimelineTabModel.cs index 0c13c613..e935b91f 100644 --- a/OpenTween/Models/UserTimelineTabModel.cs +++ b/OpenTween/Models/UserTimelineTabModel.cs @@ -45,7 +45,7 @@ namespace OpenTween.Models public string ScreenName { get; } - public string? UserId { get; set; } + public PersonId? UserId { get; set; } public UserTimelineTabModel(string tabName, string screenName) : base(tabName) diff --git a/OpenTween/PostStatusParams.cs b/OpenTween/PostStatusParams.cs index d7af5bc9..75c7d0f6 100644 --- a/OpenTween/PostStatusParams.cs +++ b/OpenTween/PostStatusParams.cs @@ -41,7 +41,7 @@ namespace OpenTween public bool AutoPopulateReplyMetadata { get; set; } - public IReadOnlyList ExcludeReplyUserIds { get; set; } = Array.Empty(); + public IReadOnlyList ExcludeReplyUserIds { get; set; } = Array.Empty(); public string? AttachmentUrl { get; set; } } diff --git a/OpenTween/Setting/Panel/BasedPanel.cs b/OpenTween/Setting/Panel/BasedPanel.cs index b4b76c1f..7b9370a6 100644 --- a/OpenTween/Setting/Panel/BasedPanel.cs +++ b/OpenTween/Setting/Panel/BasedPanel.cs @@ -102,7 +102,7 @@ namespace OpenTween.Setting.Panel } else { - settingCommon.UserId = 0; + settingCommon.UserId = ""; settingCommon.UserName = ""; settingCommon.Token = ""; settingCommon.TokenSecret = ""; diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index dbc4a942..ecd534bd 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -112,7 +112,7 @@ namespace OpenTween return password; } - public long UserId = 0; + public string UserId = ""; public List TabList = new(); public int TimelinePeriod = 180; public int ReplyPeriod = 180; @@ -339,7 +339,7 @@ namespace OpenTween this.SelectedAccountKey = selectedAccount?.UniqueKey; - if (selectedAccount?.UserId == 0) + if (selectedAccount != null && MyCommon.IsNullOrEmpty(selectedAccount.UserId)) selectedAccount.UserId = this.UserId; if (MyCommon.IsNullOrEmpty(this.Token)) @@ -352,7 +352,7 @@ namespace OpenTween public Guid UniqueKey { get; set; } = Guid.NewGuid(); public string Username = ""; - public long UserId = 0; + public string UserId = ""; public APIAuthType TwitterAuthType { get; set; } = APIAuthType.OAuth1; diff --git a/OpenTween/SocialProtocol/ISocialAccount.cs b/OpenTween/SocialProtocol/ISocialAccount.cs index 7c92acd3..68dd5391 100644 --- a/OpenTween/SocialProtocol/ISocialAccount.cs +++ b/OpenTween/SocialProtocol/ISocialAccount.cs @@ -23,6 +23,7 @@ using System; using OpenTween.Connection; +using OpenTween.Models; namespace OpenTween.SocialProtocol { @@ -32,7 +33,7 @@ namespace OpenTween.SocialProtocol public Guid UniqueKey { get; } - public long UserId { get; } + public PersonId UserId { get; } public string UserName { get; } diff --git a/OpenTween/SocialProtocol/Twitter/TwitterAccount.cs b/OpenTween/SocialProtocol/Twitter/TwitterAccount.cs index 12731d88..bd0c535b 100644 --- a/OpenTween/SocialProtocol/Twitter/TwitterAccount.cs +++ b/OpenTween/SocialProtocol/Twitter/TwitterAccount.cs @@ -24,6 +24,7 @@ using System; using System.Diagnostics; using OpenTween.Connection; +using OpenTween.Models; namespace OpenTween.SocialProtocol.Twitter { @@ -46,7 +47,7 @@ namespace OpenTween.SocialProtocol.Twitter public OpenTween.Twitter Legacy => this.twLegacy; - public long UserId + public PersonId UserId => this.AccountState.UserId; public string UserName @@ -69,8 +70,9 @@ namespace OpenTween.SocialProtocol.Twitter Debug.Assert(accountSettings.UniqueKey == this.UniqueKey, "UniqueKey must be same as current value."); var credential = accountSettings.GetTwitterCredential(); + var userId = new TwitterUserId(accountSettings.UserId); - this.AccountState = new TwitterAccountState(accountSettings.UserId, accountSettings.Username) + this.AccountState = new TwitterAccountState(userId, accountSettings.Username) { HasUnrecoverableError = credential is TwitterCredentialNone, }; diff --git a/OpenTween/SocialProtocol/Twitter/TwitterAccountState.cs b/OpenTween/SocialProtocol/Twitter/TwitterAccountState.cs index 95dd391b..3e610271 100644 --- a/OpenTween/SocialProtocol/Twitter/TwitterAccountState.cs +++ b/OpenTween/SocialProtocol/Twitter/TwitterAccountState.cs @@ -23,12 +23,13 @@ using System.Collections.Generic; using OpenTween.Api.DataModel; +using OpenTween.Models; namespace OpenTween.SocialProtocol.Twitter { public class TwitterAccountState { - public long UserId { get; private set; } + public TwitterUserId UserId { get; private set; } public string UserName { get; private set; } @@ -38,18 +39,18 @@ namespace OpenTween.SocialProtocol.Twitter public int? StatusesCount { get; private set; } - public ISet FollowerIds { get; set; } = new HashSet(); + public ISet FollowerIds { get; set; } = new HashSet(); - public ISet NoRetweetUserIds { get; set; } = new HashSet(); + public ISet NoRetweetUserIds { get; set; } = new HashSet(); public bool HasUnrecoverableError { get; set; } = true; public TwitterAccountState() - : this(0L, "") + : this(new("0"), "") { } - public TwitterAccountState(long userId, string userName) + public TwitterAccountState(TwitterUserId userId, string userName) { this.UserId = userId; this.UserName = userName; @@ -58,7 +59,7 @@ namespace OpenTween.SocialProtocol.Twitter /// ユーザー情報を更新します public void UpdateFromUser(TwitterUser self) { - this.UserId = self.Id; + this.UserId = new(self.IdStr); this.UserName = self.ScreenName; this.FollowersCount = self.FollowersCount; this.FriendsCount = self.FriendsCount; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 6e0b4bf6..2603383d 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2491,7 +2491,7 @@ namespace OpenTween private async void SettingStripMenuItem_Click(object sender, EventArgs e) { // 設定画面表示前のユーザー情報 - var previousUserId = this.settings.Common.UserId; + var previousAccountId = this.settings.Common.SelectedAccountKey; var oldIconCol = this.Use2ColumnsMode; if (this.ShowSettingDialog() == DialogResult.OK) @@ -2683,7 +2683,7 @@ namespace OpenTween this.TopMost = this.settings.Common.AlwaysTop; this.SaveConfigsAll(false); - if (this.PrimaryAccount.UserId != previousUserId) + if (this.PrimaryAccount.UniqueKey != previousAccountId) await this.DoGetFollowersMenu(); } @@ -3299,9 +3299,9 @@ namespace OpenTween /// /// 投稿時に auto_populate_reply_metadata オプションによって自動で追加されるメンションを除去します /// - private string RemoveAutoPopuratedMentions(string statusText, out long[] autoPopulatedUserIds) + private string RemoveAutoPopuratedMentions(string statusText, out PersonId[] autoPopulatedUserIds) { - var autoPopulatedUserIdList = new List(); + var autoPopulatedUserIdList = new List(); var replyToPost = this.inReplyTo != null ? this.statuses[this.inReplyTo.Value.StatusId] : null; if (replyToPost != null) @@ -3357,7 +3357,7 @@ namespace OpenTween /// /// に加えて、拡張モードで140字にカウントされない文字列の除去を行います /// - private string FormatStatusTextExtended(string statusText, out long[] autoPopulatedUserIds, out string? attachmentUrl) + private string FormatStatusTextExtended(string statusText, out PersonId[] autoPopulatedUserIds, out string? attachmentUrl) { statusText = this.RemoveAutoPopuratedMentions(statusText, out autoPopulatedUserIds); @@ -5612,7 +5612,7 @@ namespace OpenTween break; case UserTimelineTabModel userTab: tabSetting.User = userTab.ScreenName; - tabSetting.UserId = userTab.UserId; + tabSetting.UserId = userTab.UserId?.Id; break; case PublicSearchTabModel searchTab: tabSetting.SearchWords = searchTab.SearchWords; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 363f7e55..6ea96282 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -230,7 +230,7 @@ namespace OpenTween { TweetText = param.Text, InReplyToTweetId = param.InReplyToStatusId?.ToTwitterStatusId(), - ExcludeReplyUserIds = param.ExcludeReplyUserIds.Select(x => x.ToString()).ToArray(), + ExcludeReplyUserIds = param.ExcludeReplyUserIds.OfType().ToArray(), MediaIds = param.MediaIds.Select(x => x.ToString()).ToArray(), AttachmentUrl = param.AttachmentUrl, }; @@ -245,7 +245,7 @@ namespace OpenTween param.InReplyToStatusId?.ToTwitterStatusId(), param.MediaIds, param.AutoPopulateReplyMetadata, - param.ExcludeReplyUserIds, + param.ExcludeReplyUserIds.OfType().ToArray(), param.AttachmentUrl ) .ConfigureAwait(false); @@ -337,7 +337,8 @@ namespace OpenTween var recipient = await this.GetUserInfo(recipientName) .ConfigureAwait(false); - using var response = await this.Api.DirectMessagesEventsNew(recipient.Id, body, mediaId) + var recipientUserId = new TwitterUserId(recipient.IdStr); + using var response = await this.Api.DirectMessagesEventsNew(recipientUserId, body, mediaId) .ConfigureAwait(false); var messageEventSingle = await response.LoadJsonAsync() @@ -375,7 +376,7 @@ namespace OpenTween public string Username => this.AccountState.UserName; - public long UserId + public TwitterUserId UserId => this.AccountState.UserId; public bool RestrictFavCheck { get; set; } @@ -526,14 +527,14 @@ namespace OpenTween TwitterStatus[] statuses; if (this.Api.AuthType == APIAuthType.TwitterComCookie) { - var userId = tab.UserId; - if (MyCommon.IsNullOrEmpty(userId)) + var userId = tab.UserId as TwitterUserId; + if (userId == null) { var user = await this.GetUserInfo(tab.ScreenName) .ConfigureAwait(false); - userId = user.IdStr; - tab.UserId = user.IdStr; + userId = new TwitterUserId(user.IdStr); + tab.UserId = userId; } var cursor = more ? tab.CursorBottom : tab.CursorTop; @@ -546,7 +547,7 @@ namespace OpenTween .ConfigureAwait(false); statuses = response.ToTwitterStatuses() - .Where(x => x.User.IdStr == userId) // リプライツリーに含まれる他ユーザーのツイートを除外 + .Where(x => x.User.IdStr == userId.Id) // リプライツリーに含まれる他ユーザーのツイートを除外 .ToArray(); tab.CursorBottom = response.CursorBottom; @@ -595,7 +596,7 @@ namespace OpenTween } internal PostClass[] FilterNoRetweetUserPosts(PostClass[] posts) - => posts.Where(x => x.RetweetedByUserId == null || !this.AccountState.NoRetweetUserIds.Contains(x.RetweetedByUserId.Value)).ToArray(); + => posts.Where(x => x.RetweetedByUserId == null || !this.AccountState.NoRetweetUserIds.Contains(x.RetweetedByUserId)).ToArray(); public async Task GetListStatus(ListTimelineTabModel tab, bool more, bool firstLoad) { @@ -697,12 +698,12 @@ namespace OpenTween return Array.Empty(); var userIds = Enumerable.Concat( - events.Select(x => x.MessageCreate.SenderId), - events.Select(x => x.MessageCreate.Target.RecipientId) + events.Select(x => new TwitterUserId(x.MessageCreate.SenderId)), + events.Select(x => new TwitterUserId(x.MessageCreate.Target.RecipientId)) ).Distinct().ToArray(); var users = (await this.Api.UsersLookup(userIds).ConfigureAwait(false)) - .ToDictionary(x => x.IdStr); + .ToDictionary(x => new TwitterUserId(x.IdStr)); var apps = eventList.Apps ?? new Dictionary(); @@ -711,7 +712,7 @@ namespace OpenTween private PostClass[] CreateDirectMessagesEventFromJson( IReadOnlyCollection events, - IReadOnlyDictionary users, + IReadOnlyDictionary users, IReadOnlyDictionary apps, bool firstLoad) { @@ -741,7 +742,7 @@ namespace OpenTween var cursor = backward ? tab.CursorBottom : tab.CursorTop; var request = new LikesRequest { - UserId = this.UserId.ToString(CultureInfo.InvariantCulture), + UserId = this.UserId, Count = count, Cursor = cursor?.As(), }; @@ -785,7 +786,7 @@ namespace OpenTween if (MyCommon.EndingFlag) return; var cursor = -1L; - var newFollowerIds = Enumerable.Empty(); + var newFollowerIds = Enumerable.Empty(); do { var ret = await this.Api.FollowersIds(cursor) @@ -794,7 +795,7 @@ namespace OpenTween if (ret.Ids == null) throw new WebApiException("ret.ids == null"); - newFollowerIds = newFollowerIds.Concat(ret.Ids); + newFollowerIds = newFollowerIds.Concat(ret.Ids.Select(x => new TwitterUserId(x))); cursor = ret.NextCursor; } while (cursor != 0); @@ -816,7 +817,7 @@ namespace OpenTween var noRetweetUserIds = await this.Api.NoRetweetIds() .ConfigureAwait(false); - this.AccountState.NoRetweetUserIds = new HashSet(noRetweetUserIds); + this.AccountState.NoRetweetUserIds = new HashSet(noRetweetUserIds); this.GetNoRetweetSuccess = true; } @@ -941,13 +942,13 @@ namespace OpenTween if (MyCommon.EndingFlag) return; var cursor = -1L; - var newBlockIds = Enumerable.Empty(); + var newBlockIds = Enumerable.Empty(); do { var ret = await this.Api.BlocksIds(cursor) .ConfigureAwait(false); - newBlockIds = newBlockIds.Concat(ret.Ids); + newBlockIds = newBlockIds.Concat(ret.Ids.Select(x => new TwitterUserId(x))); cursor = ret.NextCursor; } while (cursor != 0); @@ -969,7 +970,7 @@ namespace OpenTween var ids = await TwitterIds.GetAllItemsAsync(x => this.Api.MutesUsersIds(x)) .ConfigureAwait(false); - TabInformations.GetInstance().MuteUserIds = ids.ToHashSet(); + TabInformations.GetInstance().MuteUserIds = ids.ToHashSet(); } public string[] GetHashList() diff --git a/OpenTween/UserInfoDialog.cs b/OpenTween/UserInfoDialog.cs index ff27d2a6..d07eff94 100644 --- a/OpenTween/UserInfoDialog.cs +++ b/OpenTween/UserInfoDialog.cs @@ -138,7 +138,8 @@ namespace OpenTween this.LinkLabelTweet.Tag = profileUrl; this.ToolTip1.SetToolTip(this.LinkLabelTweet, profileUrl); - if (this.twitter.UserId == user.Id) + var userId = new TwitterUserId(user.IdStr); + if (this.twitter.UserId == userId) { this.ButtonEdit.Enabled = true; this.ChangeIconToolStripMenuItem.Enabled = true; @@ -483,8 +484,9 @@ namespace OpenTween private async void ButtonEdit_Click(object sender, EventArgs e) { + var displayUserId = new TwitterUserId(this.displayUser.IdStr); // 自分以外のプロフィールは変更できない - if (this.twitter.UserId != this.displayUser.Id) + if (this.twitter.UserId != displayUserId) return; using (ControlTransaction.Disabled(this.ButtonEdit))