• R/O
  • HTTP
  • SSH
  • HTTPS

open-tween: 提交

開発に使用するリポジトリ


Commit MetaInfo

修訂b0f5451e866e1294f5917bfe6417f45b4c8aeef6 (tree)
時間2023-07-05 08:44:19
作者Kimura Youichi <kim.upsilon@bucy...>
CommiterKimura Youichi

Log Message

Merge branch 'develop' into release

Change Summary

差異

--- a/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs
+++ b/OpenTween.Tests/Api/GraphQL/TimelineTweetTest.cs
@@ -110,5 +110,18 @@ namespace OpenTween.Api.GraphQL
110110 Assert.Equal("1617126084138659840", post.RetweetedId!.Id);
111111 Assert.Equal(514241801L, post.UserId);
112112 }
113+
114+ [Fact]
115+ public void ToStatus_WithTwitterPostFactory_TweetWithVisibility_Test()
116+ {
117+ var rootElm = this.LoadResponseDocument("TimelineTweet_TweetWithVisibility.json");
118+ var timelineTweet = new TimelineTweet(rootElm);
119+ var status = timelineTweet.ToTwitterStatus();
120+ var postFactory = new TwitterPostFactory(this.CreateTabInfo());
121+ var post = postFactory.CreateFromStatus(status, selfUserId: 1L, new HashSet<long>());
122+
123+ Assert.Equal("1602775353088524288", post.StatusId.Id);
124+ Assert.Equal(357750891L, post.UserId);
125+ }
113126 }
114127 }
--- a/OpenTween.Tests/Api/JsonUtilsTest.cs
+++ b/OpenTween.Tests/Api/JsonUtilsTest.cs
@@ -19,6 +19,11 @@
1919 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
2020 // Boston, MA 02110-1301, USA.
2121
22+using System.IO;
23+using System.Runtime.Serialization.Json;
24+using System.Text;
25+using System.Xml;
26+using System.Xml.Linq;
2227 using Xunit;
2328
2429 namespace OpenTween.Api
@@ -34,5 +39,38 @@ namespace OpenTween.Api
3439 [InlineData("\U0001D11E", @"\uD834\uDD1E")]
3540 public void EscapeJsonString_Test(string targetText, string expectedText)
3641 => Assert.Equal(expectedText, JsonUtils.EscapeJsonString(targetText));
42+
43+ [Fact]
44+ public void JsonXmlToString_WholeTest()
45+ {
46+ var json = """{"hoge":{"aaa":12345}}""";
47+ using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
48+ using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max);
49+ var rootElement = XElement.Load(jsonReader);
50+
51+ Assert.Equal("""{"hoge":{"aaa":12345}}""", JsonUtils.JsonXmlToString(rootElement));
52+ }
53+
54+ [Fact]
55+ public void JsonXmlToString_SubsetTest()
56+ {
57+ var json = """{"hoge":{"aaa":12345}}""";
58+ using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
59+ using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max);
60+ var rootElement = XElement.Load(jsonReader);
61+
62+ Assert.Equal("""{"aaa":12345}""", JsonUtils.JsonXmlToString(rootElement.Element("hoge")));
63+ }
64+
65+ [Fact]
66+ public void JsonXmlToString_NullTest()
67+ {
68+ var json = """{"hoge":null}""";
69+ using var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
70+ using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max);
71+ var rootElement = XElement.Load(jsonReader);
72+
73+ Assert.Equal("null", JsonUtils.JsonXmlToString(rootElement.Element("hoge")));
74+ }
3775 }
3876 }
--- a/OpenTween.Tests/OpenTween.Tests.csproj
+++ b/OpenTween.Tests/OpenTween.Tests.csproj
@@ -55,6 +55,9 @@
5555 <None Update="Resources\Responses\TimelineTweet_RetweetedTweet.json">
5656 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
5757 </None>
58+ <None Update="Resources\Responses\TimelineTweet_TweetWithVisibility.json">
59+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
60+ </None>
5861 <None Update="Resources\Responses\TimelineTweet_TweetWithMedia.json">
5962 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
6063 </None>
--- /dev/null
+++ b/OpenTween.Tests/Resources/Responses/TimelineTweet_TweetWithVisibility.json
@@ -0,0 +1,532 @@
1+{
2+ "itemType": "TimelineTweet",
3+ "__typename": "TimelineTweet",
4+ "tweet_results": {
5+ "result": {
6+ "__typename": "TweetWithVisibilityResults",
7+ "tweet": {
8+ "rest_id": "1602775353088524288",
9+ "core": {
10+ "user_results": {
11+ "result": {
12+ "__typename": "User",
13+ "id": "VXNlcjozNTc3NTA4OTE=",
14+ "rest_id": "357750891",
15+ "affiliates_highlighted_label": {
16+ "label": {
17+ "url": {
18+ "url": "https://twitter.com/Twitter",
19+ "urlType": "DeepLink"
20+ },
21+ "badge": {
22+ "url": "https://pbs.twimg.com/profile_images/1488548719062654976/u6qfBBkF_bigger.jpg"
23+ },
24+ "description": "Twitter",
25+ "userLabelType": "BusinessLabel",
26+ "userLabelDisplayType": "Badge"
27+ }
28+ },
29+ "has_graduated_access": true,
30+ "is_blue_verified": true,
31+ "profile_image_shape": "Square",
32+ "legacy": {
33+ "can_dm": false,
34+ "can_media_tag": true,
35+ "created_at": "Thu Aug 18 21:08:15 +0000 2011",
36+ "default_profile": false,
37+ "default_profile_image": false,
38+ "description": "because brands are good at Twitter too",
39+ "entities": {
40+ "description": {
41+ "urls": []
42+ },
43+ "url": {
44+ "urls": [
45+ {
46+ "display_url": "marketing.twitter.com",
47+ "expanded_url": "https://marketing.twitter.com",
48+ "url": "https://t.co/p14vvM2Vul",
49+ "indices": [
50+ 0,
51+ 23
52+ ]
53+ }
54+ ]
55+ }
56+ },
57+ "fast_followers_count": 0,
58+ "favourites_count": 4233,
59+ "followers_count": 1039062,
60+ "friends_count": 826,
61+ "has_custom_timelines": true,
62+ "is_translator": false,
63+ "listed_count": 5052,
64+ "location": "Twitter HQ",
65+ "media_count": 1865,
66+ "name": "Twitter Marketing",
67+ "normal_followers_count": 1039062,
68+ "pinned_tweet_ids_str": [],
69+ "possibly_sensitive": false,
70+ "profile_banner_url": "https://pbs.twimg.com/profile_banners/357750891/1677173802",
71+ "profile_image_url_https": "https://pbs.twimg.com/profile_images/1628811028388610048/C8AyxJiB_normal.jpg",
72+ "profile_interstitial_type": "",
73+ "screen_name": "TwitterMktg",
74+ "statuses_count": 10161,
75+ "translator_type": "none",
76+ "url": "https://t.co/p14vvM2Vul",
77+ "verified": false,
78+ "verified_type": "Business",
79+ "want_retweets": false,
80+ "withheld_in_countries": []
81+ }
82+ }
83+ }
84+ },
85+ "card": {
86+ "rest_id": "https://t.co/v4kIDVQjpy",
87+ "legacy": {
88+ "binding_values": [
89+ {
90+ "key": "photo_image_full_size_large",
91+ "value": {
92+ "image_value": {
93+ "height": 402,
94+ "width": 768,
95+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=800x419"
96+ },
97+ "type": "IMAGE"
98+ }
99+ },
100+ {
101+ "key": "thumbnail_image",
102+ "value": {
103+ "image_value": {
104+ "height": 147,
105+ "width": 280,
106+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=280x150"
107+ },
108+ "type": "IMAGE"
109+ }
110+ },
111+ {
112+ "key": "description",
113+ "value": {
114+ "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.",
115+ "type": "STRING"
116+ }
117+ },
118+ {
119+ "key": "domain",
120+ "value": {
121+ "string_value": "blog.twitter.com",
122+ "type": "STRING"
123+ }
124+ },
125+ {
126+ "key": "thumbnail_image_large",
127+ "value": {
128+ "image_value": {
129+ "height": 315,
130+ "width": 600,
131+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x600"
132+ },
133+ "type": "IMAGE"
134+ }
135+ },
136+ {
137+ "key": "summary_photo_image_small",
138+ "value": {
139+ "image_value": {
140+ "height": 202,
141+ "width": 386,
142+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=386x202"
143+ },
144+ "type": "IMAGE"
145+ }
146+ },
147+ {
148+ "key": "thumbnail_image_original",
149+ "value": {
150+ "image_value": {
151+ "height": 403,
152+ "width": 768,
153+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig"
154+ },
155+ "type": "IMAGE"
156+ }
157+ },
158+ {
159+ "key": "site",
160+ "value": {
161+ "scribe_key": "publisher_id",
162+ "type": "USER",
163+ "user_value": {
164+ "id_str": "783214",
165+ "path": []
166+ }
167+ }
168+ },
169+ {
170+ "key": "photo_image_full_size_small",
171+ "value": {
172+ "image_value": {
173+ "height": 202,
174+ "width": 386,
175+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=386x202"
176+ },
177+ "type": "IMAGE"
178+ }
179+ },
180+ {
181+ "key": "summary_photo_image_large",
182+ "value": {
183+ "image_value": {
184+ "height": 402,
185+ "width": 768,
186+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=800x419"
187+ },
188+ "type": "IMAGE"
189+ }
190+ },
191+ {
192+ "key": "thumbnail_image_small",
193+ "value": {
194+ "image_value": {
195+ "height": 76,
196+ "width": 144,
197+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=144x144"
198+ },
199+ "type": "IMAGE"
200+ }
201+ },
202+ {
203+ "key": "thumbnail_image_x_large",
204+ "value": {
205+ "image_value": {
206+ "height": 403,
207+ "width": 768,
208+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp"
209+ },
210+ "type": "IMAGE"
211+ }
212+ },
213+ {
214+ "key": "photo_image_full_size_original",
215+ "value": {
216+ "image_value": {
217+ "height": 403,
218+ "width": 768,
219+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig"
220+ },
221+ "type": "IMAGE"
222+ }
223+ },
224+ {
225+ "key": "vanity_url",
226+ "value": {
227+ "scribe_key": "vanity_url",
228+ "string_value": "blog.twitter.com",
229+ "type": "STRING"
230+ }
231+ },
232+ {
233+ "key": "photo_image_full_size",
234+ "value": {
235+ "image_value": {
236+ "height": 314,
237+ "width": 600,
238+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x314"
239+ },
240+ "type": "IMAGE"
241+ }
242+ },
243+ {
244+ "key": "thumbnail_image_color",
245+ "value": {
246+ "image_color_value": {
247+ "palette": [
248+ {
249+ "rgb": {
250+ "blue": 243,
251+ "green": 172,
252+ "red": 69
253+ },
254+ "percentage": 100
255+ }
256+ ]
257+ },
258+ "type": "IMAGE_COLOR"
259+ }
260+ },
261+ {
262+ "key": "title",
263+ "value": {
264+ "string_value": "Twitter Blue is back. And gold checkmarks are here!",
265+ "type": "STRING"
266+ }
267+ },
268+ {
269+ "key": "summary_photo_image_color",
270+ "value": {
271+ "image_color_value": {
272+ "palette": [
273+ {
274+ "rgb": {
275+ "blue": 243,
276+ "green": 172,
277+ "red": 69
278+ },
279+ "percentage": 100
280+ }
281+ ]
282+ },
283+ "type": "IMAGE_COLOR"
284+ }
285+ },
286+ {
287+ "key": "summary_photo_image_x_large",
288+ "value": {
289+ "image_value": {
290+ "height": 403,
291+ "width": 768,
292+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp"
293+ },
294+ "type": "IMAGE"
295+ }
296+ },
297+ {
298+ "key": "summary_photo_image",
299+ "value": {
300+ "image_value": {
301+ "height": 314,
302+ "width": 600,
303+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=600x314"
304+ },
305+ "type": "IMAGE"
306+ }
307+ },
308+ {
309+ "key": "photo_image_full_size_color",
310+ "value": {
311+ "image_color_value": {
312+ "palette": [
313+ {
314+ "rgb": {
315+ "blue": 243,
316+ "green": 172,
317+ "red": 69
318+ },
319+ "percentage": 100
320+ }
321+ ]
322+ },
323+ "type": "IMAGE_COLOR"
324+ }
325+ },
326+ {
327+ "key": "photo_image_full_size_x_large",
328+ "value": {
329+ "image_value": {
330+ "height": 403,
331+ "width": 768,
332+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=png&name=2048x2048_2_exp"
333+ },
334+ "type": "IMAGE"
335+ }
336+ },
337+ {
338+ "key": "card_url",
339+ "value": {
340+ "scribe_key": "card_url",
341+ "string_value": "https://t.co/v4kIDVQjpy",
342+ "type": "STRING"
343+ }
344+ },
345+ {
346+ "key": "summary_photo_image_original",
347+ "value": {
348+ "image_value": {
349+ "height": 403,
350+ "width": 768,
351+ "url": "https://pbs.twimg.com/card_img/1673535623045472256/R4An0Lxi?format=jpg&name=orig"
352+ },
353+ "type": "IMAGE"
354+ }
355+ }
356+ ],
357+ "card_platform": {
358+ "platform": {
359+ "audience": {
360+ "name": "production"
361+ },
362+ "device": {
363+ "name": "Swift",
364+ "version": "12"
365+ }
366+ }
367+ },
368+ "name": "summary_large_image",
369+ "url": "https://t.co/v4kIDVQjpy",
370+ "user_refs_results": [
371+ {
372+ "result": {
373+ "__typename": "User",
374+ "id": "VXNlcjo3ODMyMTQ=",
375+ "rest_id": "783214",
376+ "affiliates_highlighted_label": {},
377+ "has_graduated_access": true,
378+ "is_blue_verified": true,
379+ "profile_image_shape": "Square",
380+ "legacy": {
381+ "can_dm": false,
382+ "can_media_tag": true,
383+ "created_at": "Tue Feb 20 14:35:54 +0000 2007",
384+ "default_profile": false,
385+ "default_profile_image": false,
386+ "description": "What's happening?!",
387+ "entities": {
388+ "description": {
389+ "urls": []
390+ },
391+ "url": {
392+ "urls": [
393+ {
394+ "display_url": "about.twitter.com",
395+ "expanded_url": "https://about.twitter.com/",
396+ "url": "https://t.co/DAtOo6uuHk",
397+ "indices": [
398+ 0,
399+ 23
400+ ]
401+ }
402+ ]
403+ }
404+ },
405+ "fast_followers_count": 0,
406+ "favourites_count": 6118,
407+ "followers_count": 65674140,
408+ "friends_count": 0,
409+ "has_custom_timelines": true,
410+ "is_translator": false,
411+ "listed_count": 88108,
412+ "location": "everywhere",
413+ "media_count": 2445,
414+ "name": "Twitter",
415+ "normal_followers_count": 65674140,
416+ "pinned_tweet_ids_str": [],
417+ "possibly_sensitive": false,
418+ "profile_banner_url": "https://pbs.twimg.com/profile_banners/783214/1646075315",
419+ "profile_image_url_https": "https://pbs.twimg.com/profile_images/1488548719062654976/u6qfBBkF_normal.jpg",
420+ "profile_interstitial_type": "",
421+ "screen_name": "Twitter",
422+ "statuses_count": 15052,
423+ "translator_type": "regular",
424+ "url": "https://t.co/DAtOo6uuHk",
425+ "verified": false,
426+ "verified_type": "Business",
427+ "want_retweets": false,
428+ "withheld_in_countries": []
429+ }
430+ }
431+ }
432+ ]
433+ }
434+ },
435+ "unified_card": {
436+ "card_fetch_state": "NoCard"
437+ },
438+ "edit_control": {
439+ "edit_tweet_ids": [
440+ "1602775353088524288"
441+ ],
442+ "editable_until_msecs": "1670968196000",
443+ "is_edit_eligible": true,
444+ "edits_remaining": "5"
445+ },
446+ "edit_perspective": {
447+ "favorited": false,
448+ "retweeted": false
449+ },
450+ "is_translatable": false,
451+ "views": {
452+ "state": "Enabled"
453+ },
454+ "source": "<a href=\"https://mobile.twitter.com\" rel=\"nofollow\">Twitter Web App</a>",
455+ "legacy": {
456+ "bookmark_count": 6,
457+ "bookmarked": false,
458+ "created_at": "Tue Dec 13 21:19:56 +0000 2022",
459+ "conversation_control": {
460+ "policy": "Community",
461+ "conversation_owner_results": {
462+ "result": {
463+ "__typename": "User",
464+ "legacy": {
465+ "screen_name": "TwitterMktg"
466+ }
467+ }
468+ }
469+ },
470+ "conversation_id_str": "1602775353088524288",
471+ "display_text_range": [
472+ 0,
473+ 110
474+ ],
475+ "entities": {
476+ "user_mentions": [],
477+ "urls": [
478+ {
479+ "display_url": "blog.twitter.com/en_us/topics/p…",
480+ "expanded_url": "https://blog.twitter.com/en_us/topics/product/2022/twitter-blue-update",
481+ "url": "https://t.co/v4kIDVQjpy",
482+ "indices": [
483+ 87,
484+ 110
485+ ]
486+ }
487+ ],
488+ "hashtags": [],
489+ "symbols": []
490+ },
491+ "favorite_count": 201,
492+ "favorited": false,
493+ "full_text": "Twitter Blue is back. And Gold Checkmarks for advertisers are here! Read the latest: \nhttps://t.co/v4kIDVQjpy",
494+ "is_quote_status": false,
495+ "lang": "en",
496+ "limited_actions": "limited_replies",
497+ "possibly_sensitive": false,
498+ "possibly_sensitive_editable": true,
499+ "quote_count": 36,
500+ "reply_count": 0,
501+ "retweet_count": 40,
502+ "retweeted": false,
503+ "user_id_str": "357750891",
504+ "id_str": "1602775353088524288"
505+ },
506+ "quick_promote_eligibility": {
507+ "eligibility": "IneligibleNotProfessional"
508+ }
509+ },
510+ "limitedActionResults": {
511+ "limited_actions": [
512+ {
513+ "action": "Reply",
514+ "prompt": {
515+ "__typename": "CtaLimitedActionPrompt",
516+ "cta_type": "SeeConversation",
517+ "headline": {
518+ "text": "Who can reply?",
519+ "entities": []
520+ },
521+ "subtext": {
522+ "text": "People the author mentioned can reply",
523+ "entities": []
524+ }
525+ }
526+ }
527+ ]
528+ }
529+ }
530+ },
531+ "tweetDisplayType": "Tweet"
532+}
--- a/OpenTween/Api/GraphQL/ListLatestTweetsTimelineRequest.cs
+++ b/OpenTween/Api/GraphQL/ListLatestTweetsTimelineRequest.cs
@@ -23,6 +23,7 @@
2323
2424 using System;
2525 using System.Collections.Generic;
26+using System.IO;
2627 using System.Linq;
2728 using System.Runtime.Serialization.Json;
2829 using System.Text;
@@ -82,9 +83,18 @@ namespace OpenTween.Api.GraphQL
8283 var param = this.CreateParameters();
8384 using var stream = await apiConnection.GetStreamAsync(EndpointUri, param);
8485 using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(stream, XmlDictionaryReaderQuotas.Max);
85- var xElm = XElement.Load(jsonReader);
8686
87- return TimelineTweet.ExtractTimelineTweets(xElm);
87+ XElement rootElm;
88+ try
89+ {
90+ rootElm = XElement.Load(jsonReader);
91+ }
92+ catch (IOException ex)
93+ {
94+ throw new WebApiException("IO Error", ex);
95+ }
96+
97+ return TimelineTweet.ExtractTimelineTweets(rootElm);
8898 }
8999 }
90100 }
--- a/OpenTween/Api/GraphQL/TimelineTweet.cs
+++ b/OpenTween/Api/GraphQL/TimelineTweet.cs
@@ -49,8 +49,24 @@ namespace OpenTween.Api.GraphQL
4949
5050 public TwitterStatus ToTwitterStatus()
5151 {
52- var tweetElm = this.Element.Element("tweet_results")?.Element("result") ?? throw CreateParseError();
53- return this.ParseTweet(tweetElm);
52+ try
53+ {
54+ var resultElm = this.Element.Element("tweet_results")?.Element("result") ?? throw CreateParseError();
55+ var tweetElm = resultElm.Element("__typename")?.Value switch
56+ {
57+ "Tweet" => resultElm,
58+ "TweetWithVisibilityResults" => resultElm.Element("tweet") ?? throw CreateParseError(),
59+ _ => throw CreateParseError(),
60+ };
61+
62+ return this.ParseTweet(tweetElm);
63+ }
64+ catch (WebApiException ex)
65+ {
66+ ex.ResponseText = JsonUtils.JsonXmlToString(this.Element);
67+ MyCommon.TraceOut(ex);
68+ throw;
69+ }
5470 }
5571
5672 private TwitterStatus ParseTweet(XElement tweetElm)
--- a/OpenTween/Api/JsonUtils.cs
+++ b/OpenTween/Api/JsonUtils.cs
@@ -21,7 +21,10 @@
2121
2222 #nullable enable
2323
24+using System.IO;
25+using System.Runtime.Serialization.Json;
2426 using System.Text;
27+using System.Xml.Linq;
2528
2629 namespace OpenTween.Api
2730 {
@@ -44,5 +47,31 @@ namespace OpenTween.Api
4447
4548 return builder.ToString();
4649 }
50+
51+ /// <summary>
52+ /// <see cref="JsonReaderWriterFactory"/>で読み込んだ<see cref="XElement"/>をJSONとして書き出す
53+ /// </summary>
54+ public static string JsonXmlToString(XElement element)
55+ {
56+ var isRoot = element.Name == "root";
57+
58+ using var stream = new MemoryStream();
59+ using (var jsonWriter = JsonReaderWriterFactory.CreateJsonWriter(stream))
60+ {
61+ if (isRoot)
62+ {
63+ element.WriteTo(jsonWriter);
64+ }
65+ else
66+ {
67+ jsonWriter.WriteStartElement("root");
68+ jsonWriter.WriteAttributeString("type", element.Attribute("type").Value);
69+ foreach (var child in element.Elements())
70+ child.WriteTo(jsonWriter);
71+ jsonWriter.WriteEndElement();
72+ }
73+ }
74+ return Encoding.UTF8.GetString(stream.ToArray());
75+ }
4776 }
4877 }
--- a/OpenTween/Models/TwitterPostFactory.cs
+++ b/OpenTween/Models/TwitterPostFactory.cs
@@ -75,6 +75,8 @@ namespace OpenTween.Models
7575 var originalStatus = retweetedStatus ?? status;
7676 var originalStatusUser = originalStatus.User ?? TwitterUser.CreateUnknownUser();
7777
78+ var isMe = statusUser.Id == selfUserId;
79+
7880 bool isFav = favTweet;
7981 if (isFav == false)
8082 {
@@ -131,7 +133,7 @@ namespace OpenTween.Models
131133 var (sourceText, sourceUri) = ParseSource(originalStatus.Source);
132134
133135 var isOwl = false;
134- if (followerIds.Count > 0)
136+ if (!isMe && followerIds.Count > 0)
135137 isOwl = !followerIds.Contains(originalStatusUser.Id);
136138
137139 var createdAtForSorting = ParseDateTimeFromSnowflakeId(status.Id, status.CreatedAt);
@@ -144,7 +146,7 @@ namespace OpenTween.Models
144146 // status から生成
145147 StatusId = new TwitterStatusId(status.IdStr),
146148 CreatedAtForSorting = createdAtForSorting,
147- IsMe = statusUser.Id == selfUserId,
149+ IsMe = isMe,
148150
149151 // originalStatus から生成
150152 CreatedAt = createdAt,
@@ -159,7 +161,7 @@ namespace OpenTween.Models
159161 Source = string.Intern(sourceText),
160162 SourceUri = sourceUri,
161163 IsFav = isFav,
162- IsReply = retweetedStatus != null && replyToList.Any(x => x.UserId == selfUserId),
164+ IsReply = retweetedStatus == null && replyToList.Any(x => x.UserId == selfUserId),
163165 InReplyToStatusId = originalStatus.InReplyToStatusIdStr != null ? new TwitterStatusId(originalStatus.InReplyToStatusIdStr) : null,
164166 InReplyToUser = originalStatus.InReplyToScreenName,
165167 InReplyToUserId = originalStatus.InReplyToUserId,
--- a/OpenTween/Properties/AssemblyInfo.cs
+++ b/OpenTween/Properties/AssemblyInfo.cs
@@ -22,7 +22,7 @@ using System.Runtime.InteropServices;
2222 // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です
2323 [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")]
2424
25-[assembly: AssemblyVersion("3.6.0.0")]
25+[assembly: AssemblyVersion("3.6.1.0")]
2626
2727 [assembly: InternalsVisibleTo("OpenTween.Tests")]
2828 [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq
--- a/OpenTween/Properties/Resources.Designer.cs
+++ b/OpenTween/Properties/Resources.Designer.cs
@@ -580,20 +580,17 @@ namespace OpenTween.Properties {
580580 /// <summary>
581581 /// 更新履歴
582582 ///
583+ ///==== Ver 3.6.1(2023/07/07)
584+ /// * CHG: graphqlエンドポイントからのレスポンスの読み込み失敗時に問題の起きたツイートをErrorLogsに書き出す機能を追加
585+ /// * FIX: リプライ制限されたツイートがリストのタイムラインに含まれているとエラーになる不具合を修正 (thx @wal_san!)
586+ /// * FIX: 発言一覧で自分のツイートが片思い状態の色で描画される不具合を修正
587+ /// * FIX: 「ユーザー定義のURL」が未設定の状態で「ユーザー定義のURL」を開く操作をするとエラーが発生する不具合を修正 (thx @Tan90909090!)
588+ /// * FIX: graphqlエンドポイントからのレスポンス読み込み中に発生した接続エラーが適切に処理されない不具合を修正
589+ /// * FIX: Replyタブにリプライが表示されない不具合を修正
590+ ///
583591 ///==== Ver 3.6.0(2023/07/05)
584592 /// * NEW: Cookie使用時にgraphqlエンドポイントを使用したリストのタイムライン取得に対応
585- /// * FIX: 「このタブの発言をクリア」で参照されなくなった発言分のメモリが開放されない場合がある不具合を修正
586- ///
587- ///==== Ver 3.5.0(2023/06/16)
588- /// * CHG: アカウント追加時にOpenTweenのAPIキーによる認可を選択肢に追加
589- /// * CHG: 非対応のOSを使用している場合に起動時に警告を表示する
590- /// * FIX: 削除したタブの取消時に同名のタブが存在した場合のエラーが適切に処理されない不具合を修正
591- /// * FIX: 発言一覧のアイコン画像の取得に失敗した場合のエラーが適切に処理されない不具合を修正
592- /// * FIX: Cookieを使用する場合にUserTimelineで99件を超えて取得するとエラーが返る問題の回避策を追加
593- ///
594- ///==== Ver 3.4.0(2023/01/29)
595- /// * NEW: 複数枚の画像を添付する際に画像の削除や順序の変更ができるようになりました
596- /// * FIX: [残りの文字列は切り詰められました]&quot;; に類似しているローカライズされた文字列を検索します。
593+ /// * FIX: 「このタブの発言をクリア」で参照され [残りの文字列は切り詰められました]&quot;; に類似しているローカライズされた文字列を検索します。
597594 /// </summary>
598595 internal static string ChangeLog {
599596 get {
--- a/OpenTween/Resources/ChangeLog.txt
+++ b/OpenTween/Resources/ChangeLog.txt
@@ -1,5 +1,13 @@
11 更新履歴
22
3+==== Ver 3.6.1(2023/07/07)
4+ * CHG: graphqlエンドポイントからのレスポンスの読み込み失敗時に問題の起きたツイートをErrorLogsに書き出す機能を追加
5+ * FIX: リプライ制限されたツイートがリストのタイムラインに含まれているとエラーになる不具合を修正 (thx @wal_san!)
6+ * FIX: 発言一覧で自分のツイートが片思い状態の色で描画される不具合を修正
7+ * FIX: 「ユーザー定義のURL」が未設定の状態で「ユーザー定義のURL」を開く操作をするとエラーが発生する不具合を修正 (thx @Tan90909090!)
8+ * FIX: graphqlエンドポイントからのレスポンス読み込み中に発生した接続エラーが適切に処理されない不具合を修正
9+ * FIX: Replyタブにリプライが表示されない不具合を修正
10+
311 ==== Ver 3.6.0(2023/07/05)
412 * NEW: Cookie使用時にgraphqlエンドポイントを使用したリストのタイムライン取得に対応
513 * FIX: 「このタブの発言をクリア」で参照されなくなった発言分のメモリが開放されない場合がある不具合を修正
--- a/OpenTween/Tween.cs
+++ b/OpenTween/Tween.cs
@@ -9444,7 +9444,7 @@ namespace OpenTween
94449444
94459445 private async Task OpenUserAppointUrl()
94469446 {
9447- if (this.settings.Common.UserAppointUrl != null)
9447+ if (!MyCommon.IsNullOrEmpty(this.settings.Common.UserAppointUrl))
94489448 {
94499449 if (this.settings.Common.UserAppointUrl.Contains("{ID}") || this.settings.Common.UserAppointUrl.Contains("{STATUS}"))
94509450 {
--- a/OpenTween/WebApiException.cs
+++ b/OpenTween/WebApiException.cs
@@ -35,7 +35,7 @@ namespace OpenTween
3535 [Serializable]
3636 public class WebApiException : Exception
3737 {
38- public string? ResponseText { get; } = null;
38+ public string? ResponseText { get; set; } = null;
3939
4040 public WebApiException()
4141 {
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
1-version: 3.5.0.{build}
1+version: 3.6.0.{build}
22
33 os: Visual Studio 2022
44
Show on old repository browser