diff --git a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs index b16e97158..da6720b3a 100644 --- a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs +++ b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs @@ -110,5 +110,18 @@ public void ToStatus_WithTwitterPostFactory_RetweetedTweet_Test() Assert.Equal("1617126084138659840", post.RetweetedId!.Id); Assert.Equal(514241801L, post.UserId); } + + [Fact] + public void ToStatus_WithTwitterPostFactory_TweetWithVisibility_Test() + { + var rootElm = this.LoadResponseDocument("TimelineTweet_TweetWithVisibility.json"); + var timelineTweet = new TimelineTweet(rootElm); + var status = timelineTweet.ToTwitterStatus(); + var postFactory = new TwitterPostFactory(this.CreateTabInfo()); + var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet()); + + Assert.Equal("1602775353088524288", post.StatusId.Id); + Assert.Equal(357750891L, post.UserId); + } } } diff --git a/OpenTween.Tests/Api/JsonUtilsTest.cs b/OpenTween.Tests/Api/JsonUtilsTest.cs index 17fbc9dc6..2207b471c 100644 --- a/OpenTween.Tests/Api/JsonUtilsTest.cs +++ b/OpenTween.Tests/Api/JsonUtilsTest.cs @@ -19,6 +19,11 @@ // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, // Boston, MA 02110-1301, USA. +using System.IO; +using System.Runtime.Serialization.Json; +using System.Text; +using System.Xml; +using System.Xml.Linq; using Xunit; namespace OpenTween.Api @@ -34,5 +39,38 @@ public class JsonUtilsTest [InlineData("\U0001D11E", @"\uD834\uDD1E")] public void EscapeJsonString_Test(string targetText, string expectedText) => Assert.Equal(expectedText, JsonUtils.EscapeJsonString(targetText)); + + [Fact] + public void JsonXmlToString_WholeTest() + { + var json = """{"hoge":{"aaa":12345}}"""; + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); + var rootElement = XElement.Load(jsonReader); + + Assert.Equal("""{"hoge":{"aaa":12345}}""", JsonUtils.JsonXmlToString(rootElement)); + } + + [Fact] + public void JsonXmlToString_SubsetTest() + { + var json = """{"hoge":{"aaa":12345}}"""; + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); + var rootElement = XElement.Load(jsonReader); + + Assert.Equal("""{"aaa":12345}""", JsonUtils.JsonXmlToString(rootElement.Element("hoge"))); + } + + [Fact] + public void JsonXmlToString_NullTest() + { + var json = """{"hoge":null}"""; + using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json)); + using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); + var rootElement = XElement.Load(jsonReader); + + Assert.Equal("null", JsonUtils.JsonXmlToString(rootElement.Element("hoge"))); + } } } diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index f1722591e..6338e3c66 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -55,6 +55,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/OpenTween.Tests/Resources/Responses/TimelineTweet_TweetWithVisibility.json b/OpenTween.Tests/Resources/Responses/TimelineTweet_TweetWithVisibility.json new file mode 100644 index 000000000..755102d1e --- /dev/null +++ b/OpenTween.Tests/Resources/Responses/TimelineTweet_TweetWithVisibility.json @@ -0,0 +1,532 @@ +{ + "itemType": "TimelineTweet", + "__typename": "TimelineTweet", + "tweet_results": { + "result": { + "__typename": "TweetWithVisibilityResults", + "tweet": { + "rest_id": "1602775353088524288", + "core": { + "user_results": { + "result": { + "__typename": "User", + "id": "VXNlcjozNTc3NTA4OTE=", + "rest_id": "357750891", + "affiliates_highlighted_label": { + "label": { + "url": { + "url": "https://twitter.com/Twitter", + "urlType": "DeepLink" + }, + "badge": { + "url": "https://pbs.twimg.com/profile_images/1488548719062654976/u6qfBBkF_bigger.jpg" + }, + "description": "Twitter", + "userLabelType": "BusinessLabel", + "userLabelDisplayType": "Badge" + } + }, + "has_graduated_access": true, + "is_blue_verified": true, + "profile_image_shape": "Square", + "legacy": { + "can_dm": false, + "can_media_tag": true, + "created_at": "Thu Aug 18 21:08:15 +0000 2011", + "default_profile": false, + "default_profile_image": false, + "description": "because brands are good at Twitter too", + "entities": { + "description": { + "urls": [] + }, + "url": { + "urls": [ + { + "display_url": "marketing.twitter.com", + "expanded_url": "https://marketing.twitter.com", + "url": "https://t.co/p14vvM2Vul", + "indices": [ + 0, + 23 + ] + } + ] + } + }, + "fast_followers_count": 0, + "favourites_count": 4233, + "followers_count": 1039062, + "friends_count": 826, + "has_custom_timelines": true, + "is_translator": false, + "listed_count": 5052, + "location": "Twitter HQ", + "media_count": 1865, + "name": "Twitter Marketing", + "normal_followers_count": 1039062, + "pinned_tweet_ids_str": [], + "possibly_sensitive": false, + "profile_banner_url": "https://pbs.twimg.com/profile_banners/357750891/1677173802", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1628811028388610048/C8AyxJiB_normal.jpg", + "profile_interstitial_type": "", + "screen_name": "TwitterMktg", + "statuses_count": 10161, + "translator_type": "none", + "url": "https://t.co/p14vvM2Vul", + "verified": false, + "verified_type": "Business", + "want_retweets": false, + "withheld_in_countries": [] + } + } + } + }, + "card": { + "rest_id": "https://t.co/v4kIDVQjpy", + "legacy": { + "binding_values": [ + { + "key": "photo_image_full_size_large", + "value": { + "image_value": { + "height": 402, + "width": 768, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=800x419" + }, + "type": "IMAGE" + } + }, + { + "key": "thumbnail_image", + "value": { + "image_value": { + "height": 147, + "width": 280, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=280x150" + }, + "type": "IMAGE" + } + }, + { + "key": "description", + "value": { + "string_value": "We’re re-enabling Twitter Blue sign ups on iOS and web. Twitter Blue subscribers will get access to subscriber-only features* such as Edit Tweet, 1080p video uploads and reader mode.", + "type": "STRING" + } + }, + { + "key": "domain", + "value": { + "string_value": "blog.twitter.com", + "type": "STRING" + } + }, + { + "key": "thumbnail_image_large", + "value": { + "image_value": { + "height": 315, + "width": 600, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x600" + }, + "type": "IMAGE" + } + }, + { + "key": "summary_photo_image_small", + "value": { + "image_value": { + "height": 202, + "width": 386, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=386x202" + }, + "type": "IMAGE" + } + }, + { + "key": "thumbnail_image_original", + "value": { + "image_value": { + "height": 403, + "width": 768, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig" + }, + "type": "IMAGE" + } + }, + { + "key": "site", + "value": { + "scribe_key": "publisher_id", + "type": "USER", + "user_value": { + "id_str": "783214", + "path": [] + } + } + }, + { + "key": "photo_image_full_size_small", + "value": { + "image_value": { + "height": 202, + "width": 386, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=386x202" + }, + "type": "IMAGE" + } + }, + { + "key": "summary_photo_image_large", + "value": { + "image_value": { + "height": 402, + "width": 768, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=800x419" + }, + "type": "IMAGE" + } + }, + { + "key": "thumbnail_image_small", + "value": { + "image_value": { + "height": 76, + "width": 144, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=144x144" + }, + "type": "IMAGE" + } + }, + { + "key": "thumbnail_image_x_large", + "value": { + "image_value": { + "height": 403, + "width": 768, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp" + }, + "type": "IMAGE" + } + }, + { + "key": "photo_image_full_size_original", + "value": { + "image_value": { + "height": 403, + "width": 768, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig" + }, + "type": "IMAGE" + } + }, + { + "key": "vanity_url", + "value": { + "scribe_key": "vanity_url", + "string_value": "blog.twitter.com", + "type": "STRING" + } + }, + { + "key": "photo_image_full_size", + "value": { + "image_value": { + "height": 314, + "width": 600, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x314" + }, + "type": "IMAGE" + } + }, + { + "key": "thumbnail_image_color", + "value": { + "image_color_value": { + "palette": [ + { + "rgb": { + "blue": 243, + "green": 172, + "red": 69 + }, + "percentage": 100 + } + ] + }, + "type": "IMAGE_COLOR" + } + }, + { + "key": "title", + "value": { + "string_value": "Twitter Blue is back. And gold checkmarks are here!", + "type": "STRING" + } + }, + { + "key": "summary_photo_image_color", + "value": { + "image_color_value": { + "palette": [ + { + "rgb": { + "blue": 243, + "green": 172, + "red": 69 + }, + "percentage": 100 + } + ] + }, + "type": "IMAGE_COLOR" + } + }, + { + "key": "summary_photo_image_x_large", + "value": { + "image_value": { + "height": 403, + "width": 768, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp" + }, + "type": "IMAGE" + } + }, + { + "key": "summary_photo_image", + "value": { + "image_value": { + "height": 314, + "width": 600, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x314" + }, + "type": "IMAGE" + } + }, + { + "key": "photo_image_full_size_color", + "value": { + "image_color_value": { + "palette": [ + { + "rgb": { + "blue": 243, + "green": 172, + "red": 69 + }, + "percentage": 100 + } + ] + }, + "type": "IMAGE_COLOR" + } + }, + { + "key": "photo_image_full_size_x_large", + "value": { + "image_value": { + "height": 403, + "width": 768, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp" + }, + "type": "IMAGE" + } + }, + { + "key": "card_url", + "value": { + "scribe_key": "card_url", + "string_value": "https://t.co/v4kIDVQjpy", + "type": "STRING" + } + }, + { + "key": "summary_photo_image_original", + "value": { + "image_value": { + "height": 403, + "width": 768, + "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig" + }, + "type": "IMAGE" + } + } + ], + "card_platform": { + "platform": { + "audience": { + "name": "production" + }, + "device": { + "name": "Swift", + "version": "12" + } + } + }, + "name": "summary_large_image", + "url": "https://t.co/v4kIDVQjpy", + "user_refs_results": [ + { + "result": { + "__typename": "User", + "id": "VXNlcjo3ODMyMTQ=", + "rest_id": "783214", + "affiliates_highlighted_label": {}, + "has_graduated_access": true, + "is_blue_verified": true, + "profile_image_shape": "Square", + "legacy": { + "can_dm": false, + "can_media_tag": true, + "created_at": "Tue Feb 20 14:35:54 +0000 2007", + "default_profile": false, + "default_profile_image": false, + "description": "What's happening?!", + "entities": { + "description": { + "urls": [] + }, + "url": { + "urls": [ + { + "display_url": "about.twitter.com", + "expanded_url": "https://about.twitter.com/", + "url": "https://t.co/DAtOo6uuHk", + "indices": [ + 0, + 23 + ] + } + ] + } + }, + "fast_followers_count": 0, + "favourites_count": 6118, + "followers_count": 65674140, + "friends_count": 0, + "has_custom_timelines": true, + "is_translator": false, + "listed_count": 88108, + "location": "everywhere", + "media_count": 2445, + "name": "Twitter", + "normal_followers_count": 65674140, + "pinned_tweet_ids_str": [], + "possibly_sensitive": false, + "profile_banner_url": "https://pbs.twimg.com/profile_banners/783214/1646075315", + "profile_image_url_https": "https://pbs.twimg.com/profile_images/1488548719062654976/u6qfBBkF_normal.jpg", + "profile_interstitial_type": "", + "screen_name": "Twitter", + "statuses_count": 15052, + "translator_type": "regular", + "url": "https://t.co/DAtOo6uuHk", + "verified": false, + "verified_type": "Business", + "want_retweets": false, + "withheld_in_countries": [] + } + } + } + ] + } + }, + "unified_card": { + "card_fetch_state": "NoCard" + }, + "edit_control": { + "edit_tweet_ids": [ + "1602775353088524288" + ], + "editable_until_msecs": "1670968196000", + "is_edit_eligible": true, + "edits_remaining": "5" + }, + "edit_perspective": { + "favorited": false, + "retweeted": false + }, + "is_translatable": false, + "views": { + "state": "Enabled" + }, + "source": "Twitter Web App", + "legacy": { + "bookmark_count": 6, + "bookmarked": false, + "created_at": "Tue Dec 13 21:19:56 +0000 2022", + "conversation_control": { + "policy": "Community", + "conversation_owner_results": { + "result": { + "__typename": "User", + "legacy": { + "screen_name": "TwitterMktg" + } + } + } + }, + "conversation_id_str": "1602775353088524288", + "display_text_range": [ + 0, + 110 + ], + "entities": { + "user_mentions": [], + "urls": [ + { + "display_url": "blog.twitter.com/en_us/topics/p…", + "expanded_url": "https://blog.twitter.com/en_us/topics/product/2022/twitter-blue-update", + "url": "https://t.co/v4kIDVQjpy", + "indices": [ + 87, + 110 + ] + } + ], + "hashtags": [], + "symbols": [] + }, + "favorite_count": 201, + "favorited": false, + "full_text": "Twitter Blue is back. And Gold Checkmarks for advertisers are here! Read the latest: \nhttps://t.co/v4kIDVQjpy", + "is_quote_status": false, + "lang": "en", + "limited_actions": "limited_replies", + "possibly_sensitive": false, + "possibly_sensitive_editable": true, + "quote_count": 36, + "reply_count": 0, + "retweet_count": 40, + "retweeted": false, + "user_id_str": "357750891", + "id_str": "1602775353088524288" + }, + "quick_promote_eligibility": { + "eligibility": "IneligibleNotProfessional" + } + }, + "limitedActionResults": { + "limited_actions": [ + { + "action": "Reply", + "prompt": { + "__typename": "CtaLimitedActionPrompt", + "cta_type": "SeeConversation", + "headline": { + "text": "Who can reply?", + "entities": [] + }, + "subtext": { + "text": "People the author mentioned can reply", + "entities": [] + } + } + } + ] + } + } + }, + "tweetDisplayType": "Tweet" +} diff --git a/OpenTween/Api/GraphQL/ListLatestTweetsTimelineRequest.cs b/OpenTween/Api/GraphQL/ListLatestTweetsTimelineRequest.cs index ce8532b32..a44b12373 100644 --- a/OpenTween/Api/GraphQL/ListLatestTweetsTimelineRequest.cs +++ b/OpenTween/Api/GraphQL/ListLatestTweetsTimelineRequest.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Runtime.Serialization.Json; using System.Text; @@ -82,9 +83,18 @@ public async Task Send(IApiConnection apiConnection) var param = this.CreateParameters(); using var stream = await apiConnection.GetStreamAsync(EndpointUri, param); using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max); - var xElm = XElement.Load(jsonReader); - return TimelineTweet.ExtractTimelineTweets(xElm); + XElement rootElm; + try + { + rootElm = XElement.Load(jsonReader); + } + catch (IOException ex) + { + throw new WebApiException("IO Error", ex); + } + + return TimelineTweet.ExtractTimelineTweets(rootElm); } } } diff --git a/OpenTween/Api/GraphQL/TimelineTweet.cs b/OpenTween/Api/GraphQL/TimelineTweet.cs index 62949ef87..8507df49e 100644 --- a/OpenTween/Api/GraphQL/TimelineTweet.cs +++ b/OpenTween/Api/GraphQL/TimelineTweet.cs @@ -49,8 +49,24 @@ public TimelineTweet(XElement element) public TwitterStatus ToTwitterStatus() { - var tweetElm = this.Element.Element("tweet_results")?.Element("result") ?? throw CreateParseError(); - return this.ParseTweet(tweetElm); + try + { + var resultElm = this.Element.Element("tweet_results")?.Element("result") ?? throw CreateParseError(); + var tweetElm = resultElm.Element("__typename")?.Value switch + { + "Tweet" => resultElm, + "TweetWithVisibilityResults" => resultElm.Element("tweet") ?? throw CreateParseError(), + _ => throw CreateParseError(), + }; + + return this.ParseTweet(tweetElm); + } + catch (WebApiException ex) + { + ex.ResponseText = JsonUtils.JsonXmlToString(this.Element); + MyCommon.TraceOut(ex); + throw; + } } private TwitterStatus ParseTweet(XElement tweetElm) diff --git a/OpenTween/Api/JsonUtils.cs b/OpenTween/Api/JsonUtils.cs index c237fbaaf..8f610271e 100644 --- a/OpenTween/Api/JsonUtils.cs +++ b/OpenTween/Api/JsonUtils.cs @@ -21,7 +21,10 @@ #nullable enable +using System.IO; +using System.Runtime.Serialization.Json; using System.Text; +using System.Xml.Linq; namespace OpenTween.Api { @@ -44,5 +47,31 @@ public static string EscapeJsonString(string rawText) return builder.ToString(); } + + /// + /// で読み込んだをJSONとして書き出す + /// + public static string JsonXmlToString(XElement element) + { + var isRoot = element.Name == "root"; + + using var stream = new MemoryStream(); + using (var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream)) + { + if (isRoot) + { + element.WriteTo(jsonWriter); + } + else + { + jsonWriter.WriteStartElement("root"); + jsonWriter.WriteAttributeString("type", element.Attribute("type").Value); + foreach (var child in element.Elements()) + child.WriteTo(jsonWriter); + jsonWriter.WriteEndElement(); + } + } + return Encoding.UTF8.GetString(stream.ToArray()); + } } } diff --git a/OpenTween/Models/TwitterPostFactory.cs b/OpenTween/Models/TwitterPostFactory.cs index ab9676134..988db9f5b 100644 --- a/OpenTween/Models/TwitterPostFactory.cs +++ b/OpenTween/Models/TwitterPostFactory.cs @@ -75,6 +75,8 @@ public PostClass CreateFromStatus( var originalStatus = retweetedStatus ?? status; var originalStatusUser = originalStatus.User ?? TwitterUser.CreateUnknownUser(); + var isMe = statusUser.Id == selfUserId; + bool isFav = favTweet; if (isFav == false) { @@ -131,7 +133,7 @@ public PostClass CreateFromStatus( var (sourceText, sourceUri) = ParseSource(originalStatus.Source); var isOwl = false; - if (followerIds.Count > 0) + if (!isMe && followerIds.Count > 0) isOwl = !followerIds.Contains(originalStatusUser.Id); var createdAtForSorting = ParseDateTimeFromSnowflakeId(status.Id, status.CreatedAt); @@ -144,7 +146,7 @@ public PostClass CreateFromStatus( // status から生成 StatusId = new TwitterStatusId(status.IdStr), CreatedAtForSorting = createdAtForSorting, - IsMe = statusUser.Id == selfUserId, + IsMe = isMe, // originalStatus から生成 CreatedAt = createdAt, @@ -159,7 +161,7 @@ public PostClass CreateFromStatus( Source = string.Intern(sourceText), SourceUri = sourceUri, IsFav = isFav, - IsReply = retweetedStatus != null && replyToList.Any(x => x.UserId == selfUserId), + IsReply = retweetedStatus == null && replyToList.Any(x => x.UserId == selfUserId), InReplyToStatusId = originalStatus.InReplyToStatusIdStr != null ? new TwitterStatusId(originalStatus.InReplyToStatusIdStr) : null, InReplyToUser = originalStatus.InReplyToScreenName, InReplyToUserId = originalStatus.InReplyToUserId, diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index f09225087..fc5c8bde0 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("3.6.0.0")] +[assembly: AssemblyVersion("3.6.1.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 0c6fc28c3..9d0eb29a2 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -580,20 +580,17 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Ver 3.6.1(2023/07/07) + /// * CHG: graphqlエンドポイントからのレスポンスの読み込み失敗時に問題の起きたツイートをErrorLogsに書き出す機能を追加 + /// * FIX: リプライ制限されたツイートがリストのタイムラインに含まれているとエラーになる不具合を修正 (thx @wal_san!) + /// * FIX: 発言一覧で自分のツイートが片思い状態の色で描画される不具合を修正 + /// * FIX: 「ユーザー定義のURL」が未設定の状態で「ユーザー定義のURL」を開く操作をするとエラーが発生する不具合を修正 (thx @Tan90909090!) + /// * FIX: graphqlエンドポイントからのレスポンス読み込み中に発生した接続エラーが適切に処理されない不具合を修正 + /// * FIX: Replyタブにリプライが表示されない不具合を修正 + /// ///==== Ver 3.6.0(2023/07/05) /// * NEW: Cookie使用時にgraphqlエンドポイントを使用したリストのタイムライン取得に対応 - /// * FIX: 「このタブの発言をクリア」で参照されなくなった発言分のメモリが開放されない場合がある不具合を修正 - /// - ///==== Ver 3.5.0(2023/06/16) - /// * CHG: アカウント追加時にOpenTweenのAPIキーによる認可を選択肢に追加 - /// * CHG: 非対応のOSを使用している場合に起動時に警告を表示する - /// * FIX: 削除したタブの取消時に同名のタブが存在した場合のエラーが適切に処理されない不具合を修正 - /// * FIX: 発言一覧のアイコン画像の取得に失敗した場合のエラーが適切に処理されない不具合を修正 - /// * FIX: Cookieを使用する場合にUserTimelineで99件を超えて取得するとエラーが返る問題の回避策を追加 - /// - ///==== Ver 3.4.0(2023/01/29) - /// * NEW: 複数枚の画像を添付する際に画像の削除や順序の変更ができるようになりました - /// * FIX: [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: 「このタブの発言をクリア」で参照され [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 7d47a6278..c58254e3f 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,13 @@ 更新履歴 +==== Ver 3.6.1(2023/07/07) + * CHG: graphqlエンドポイントからのレスポンスの読み込み失敗時に問題の起きたツイートをErrorLogsに書き出す機能を追加 + * FIX: リプライ制限されたツイートがリストのタイムラインに含まれているとエラーになる不具合を修正 (thx @wal_san!) + * FIX: 発言一覧で自分のツイートが片思い状態の色で描画される不具合を修正 + * FIX: 「ユーザー定義のURL」が未設定の状態で「ユーザー定義のURL」を開く操作をするとエラーが発生する不具合を修正 (thx @Tan90909090!) + * FIX: graphqlエンドポイントからのレスポンス読み込み中に発生した接続エラーが適切に処理されない不具合を修正 + * FIX: Replyタブにリプライが表示されない不具合を修正 + ==== Ver 3.6.0(2023/07/05) * NEW: Cookie使用時にgraphqlエンドポイントを使用したリストのタイムライン取得に対応 * FIX: 「このタブの発言をクリア」で参照されなくなった発言分のメモリが開放されない場合がある不具合を修正 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 842a04655..8a71b44a6 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -9444,7 +9444,7 @@ private void StopRefreshAllMenuItem_CheckedChanged(object sender, EventArgs e) private async Task OpenUserAppointUrl() { - if (this.settings.Common.UserAppointUrl != null) + if (!MyCommon.IsNullOrEmpty(this.settings.Common.UserAppointUrl)) { if (this.settings.Common.UserAppointUrl.Contains("{ID}") || this.settings.Common.UserAppointUrl.Contains("{STATUS}")) { diff --git a/OpenTween/WebApiException.cs b/OpenTween/WebApiException.cs index 75eac8385..00e9ad73c 100644 --- a/OpenTween/WebApiException.cs +++ b/OpenTween/WebApiException.cs @@ -35,7 +35,7 @@ namespace OpenTween [Serializable] public class WebApiException : Exception { - public string? ResponseText { get; } = null; + public string? ResponseText { get; set; } = null; public WebApiException() { diff --git a/appveyor.yml b/appveyor.yml index 72bd68aac..9cf366c60 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 3.5.0.{build} +version: 3.6.0.{build} os: Visual Studio 2022