{
public class ApiLimitTest
{
- public static readonly TheoryData<object, bool> Equals_TestCase = new TheoryData<object, bool>
+ public static readonly TheoryData<object?, bool> Equals_TestCase = new TheoryData<object?, bool>
{
{ new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)), true },
{ new ApiLimit(350, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)), false },
[Theory]
[MemberData(nameof(Equals_TestCase))]
- public void EqualsTest(object obj2, bool expected)
+ public void EqualsTest(object? obj2, bool expected)
{
var obj1 = new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0));
Assert.Equal(TwitterApiAccessLevel.Anonymous, apiStatus.AccessLevel);
}
- public static readonly TheoryData<IDictionary<string, string>, ApiLimit> ParseRateLimit_TestCase = new TheoryData<IDictionary<string, string>, ApiLimit>
+ public static readonly TheoryData<Dictionary<string, string>, ApiLimit?> ParseRateLimit_TestCase = new TheoryData<Dictionary<string, string>, ApiLimit?>
{
{
new Dictionary<string, string> {
[Theory]
[MemberData(nameof(ParseRateLimit_TestCase))]
- public void ParseRateLimitTest(IDictionary<string, string> header, ApiLimit expected)
+ public void ParseRateLimitTest(IDictionary<string, string> header, ApiLimit? expected)
{
var limit = TwitterApiStatus.ParseRateLimit(header, "X-RateLimit-");
Assert.Equal(expected, limit);
}
- public static readonly TheoryData<IDictionary<string, string>, ApiLimit> ParseMediaRateLimit_TestCase = new TheoryData<IDictionary<string, string>, ApiLimit>
+ public static readonly TheoryData<Dictionary<string, string>, ApiLimit?> ParseMediaRateLimit_TestCase = new TheoryData<Dictionary<string, string>, ApiLimit?>
{
{
new Dictionary<string, string> {
[Theory]
[MemberData(nameof(ParseMediaRateLimit_TestCase))]
- public void ParseMediaRateLimitTest(IDictionary<string, string> header, ApiLimit expected)
+ public void ParseMediaRateLimitTest(IDictionary<string, string> header, ApiLimit? expected)
{
var limit = TwitterApiStatus.ParseRateLimit(header, "X-MediaRateLimit-");
Assert.Equal(expected, limit);
}
- public static readonly TheoryData<IDictionary<string, string>, TwitterApiAccessLevel?> ParseAccessLevel_TestCase = new TheoryData<IDictionary<string, string>, TwitterApiAccessLevel?>
+ public static readonly TheoryData<Dictionary<string, string>, TwitterApiAccessLevel?> ParseAccessLevel_TestCase = new TheoryData<Dictionary<string, string>, TwitterApiAccessLevel?>
{
{
new Dictionary<string, string> { {"X-Access-Level", "read"} },
() => status.UpdateFromHeader(header, "/statuses/home_timeline")
);
- var rateLimit = status.AccessLimit["/statuses/home_timeline"];
+ var rateLimit = status.AccessLimit["/statuses/home_timeline"]!;
Assert.Equal(150, rateLimit.AccessLimitCount);
Assert.Equal(100, rateLimit.AccessLimitRemain);
Assert.Equal(new DateTimeUtc(2013, 1, 1, 0, 0, 0), rateLimit.AccessLimitResetDate);
- var mediaLimit = status.MediaUploadLimit;
+ var mediaLimit = status.MediaUploadLimit!;
Assert.Equal(30, mediaLimit.AccessLimitCount);
Assert.Equal(20, mediaLimit.AccessLimitRemain);
Assert.Equal(new DateTimeUtc(2013, 1, 2, 0, 0, 0), mediaLimit.AccessLimitResetDate);
() => status.UpdateFromHeader(response.Headers, "/statuses/home_timeline")
);
- var rateLimit = status.AccessLimit["/statuses/home_timeline"];
+ var rateLimit = status.AccessLimit["/statuses/home_timeline"]!;
Assert.Equal(150, rateLimit.AccessLimitCount);
Assert.Equal(100, rateLimit.AccessLimitRemain);
Assert.Equal(new DateTimeUtc(2013, 1, 1, 0, 0, 0), rateLimit.AccessLimitResetDate);
- var mediaLimit = status.MediaUploadLimit;
+ var mediaLimit = status.MediaUploadLimit!;
Assert.Equal(30, mediaLimit.AccessLimitCount);
Assert.Equal(20, mediaLimit.AccessLimitRemain);
Assert.Equal(new DateTimeUtc(2013, 1, 2, 0, 0, 0), mediaLimit.AccessLimitResetDate);
() => status.UpdateFromJson(TwitterRateLimits.ParseJson(json))
);
- var rateLimit = status.AccessLimit["/statuses/home_timeline"];
+ var rateLimit = status.AccessLimit["/statuses/home_timeline"]!;
Assert.Equal(150, rateLimit.AccessLimitCount);
Assert.Equal(100, rateLimit.AccessLimitRemain);
Assert.Equal(new DateTimeUtc(2013, 1, 1, 0, 0, 0), rateLimit.AccessLimitResetDate);
// エラーレスポンスの JSON に含まれるエラーコードに基づいてメッセージを出力する
Assert.Equal("DuplicateStatus", exception.Message);
- Assert.Equal(TwitterErrorCode.DuplicateStatus, exception.ErrorResponse.Errors[0].Code);
- Assert.Equal("Status is a duplicate.", exception.ErrorResponse.Errors[0].Message);
+ Assert.Equal(TwitterErrorCode.DuplicateStatus, exception.Errors[0].Code);
+ Assert.Equal("Status is a duplicate.", exception.Errors[0].Message);
Assert.Equal(0, mockHandler.QueueCount);
}
[Fact]
public void ToCodepoints_ErrorTest()
- => Assert.Throws<ArgumentNullException>(() => ((string)null).ToCodepoints());
+ => Assert.Throws<ArgumentNullException>(() => ((string)null!).ToCodepoints());
[Theory]
[InlineData("", 0, 0, 0)]
[Fact]
public void GetCodepointCount_ErrorTest()
{
- Assert.Throws<ArgumentNullException>(() => ((string)null).GetCodepointCount(0, 0));
+ Assert.Throws<ArgumentNullException>(() => ((string)null!).GetCodepointCount(0, 0));
Assert.Throws<ArgumentOutOfRangeException>(() => "abc".GetCodepointCount(-1, 3));
Assert.Throws<ArgumentOutOfRangeException>(() => "abc".GetCodepointCount(0, 4));
Assert.Throws<ArgumentOutOfRangeException>(() => "abc".GetCodepointCount(4, 5));
Assert.Throws<ArgumentException>(() => set.CopyTo(array, 3));
Assert.Throws<ArgumentException>(() => set.CopyTo(array, 5));
Assert.Throws<ArgumentOutOfRangeException>(() => set.CopyTo(array, -1));
- Assert.Throws<ArgumentNullException>(() => set.CopyTo(null, 0));
+ Assert.Throws<ArgumentNullException>(() => set.CopyTo(null!, 0));
}
[Fact]
Assert.Throws<ArgumentException>(() => dict.CopyTo(array, 3));
Assert.Throws<ArgumentException>(() => dict.CopyTo(array, 5));
Assert.Throws<ArgumentOutOfRangeException>(() => dict.CopyTo(array, -1));
- Assert.Throws<ArgumentNullException>(() => dict.CopyTo(null, 0));
+ Assert.Throws<ArgumentNullException>(() => dict.CopyTo(null!, 0));
}
[Fact]
Assert.False(mediaSelector.Visible);
Assert.False(mediaSelector.Enabled);
- Assert.True(displayImage.IsDisposed);
+ Assert.True(displayImage!.IsDisposed);
}
[Fact]
// 2 ページ目
var page2Image = mediaSelector.ImageSelectedPicture.Image;
- Assert.True(page1Image.IsDisposed); // 前ページの画像が破棄されているか
+ Assert.True(page1Image!.IsDisposed); // 前ページの画像が破棄されているか
mediaSelector.ImagePageCombo.SelectedIndex = 2;
// 3 ページ目 (新規ページ)
- Assert.True(page2Image.IsDisposed); // 前ページの画像が破棄されているか
+ Assert.True(page2Image!.IsDisposed); // 前ページの画像が破棄されているか
}
[Fact]
}
// 最初に入力されていたファイルパスの表示用の MemoryImage は破棄される
- Assert.True(image1.IsDisposed);
+ Assert.True(image1!.IsDisposed);
}
[Fact]
}
// 最初に入力されていたファイルパスの表示用の MemoryImage は破棄される
- Assert.True(image1.IsDisposed);
+ Assert.True(image1!.IsDisposed);
// 参照されなくなった MemoryImageMediaItem も破棄される
Assert.True(mediaItem.IsDisposed);
{
get
{
- var retweetedId = this.RetweetedId.Value;
+ var retweetedId = this.RetweetedId!.Value;
- return PostClassTest.TestCases.ContainsKey(retweetedId) ?
- PostClassTest.TestCases[retweetedId] :
- null;
+ return PostClassTest.TestCases[retweetedId];
}
}
}
}
[Theory]
- [InlineData(null, null)]
[InlineData("", "")]
[InlineData("aaa\nbbb", "aaa bbb")]
public void TextSingleLineTest(string text, string expected)
class FakeExpandedUrlInfo : PostClass.ExpandedUrlInfo
{
- public TaskCompletionSource<string> fakeResult;
+ public TaskCompletionSource<string> fakeResult = new TaskCompletionSource<string>();
public FakeExpandedUrlInfo(string url, string expandedUrl, bool deepExpand)
: base(url, expandedUrl, deepExpand)
}
protected override async Task DeepExpandAsync()
- {
- this.fakeResult = new TaskCompletionSource<string>();
- this._expandedUrl = await this.fakeResult.Task;
- }
+ => this._expandedUrl = await this.fakeResult.Task;
}
[Fact]
Assert.Equal(MyCommon.HITRESULT.None, filter.ExecFilter(post));
- Assert.Throws<ArgumentNullException>(() => filter.FilterBody = null);
- Assert.Throws<ArgumentNullException>(() => filter.ExFilterBody = null);
+ Assert.Throws<ArgumentNullException>(() => filter.FilterBody = null!);
+ Assert.Throws<ArgumentNullException>(() => filter.ExFilterBody = null!);
}
[Fact]
public void FieldNullAwareTest()
{
- var nullPost = new PostClass { Source = null };
+ var nullPost = new PostClass { Source = null! };
// Source が null であっても ArgumentNullException 等を投げない
var filter1 = new PostFilterRule
// OpenTween v1.1.2 時点の FiltersClass クラス
public sealed class FiltersClass
{
- public string NameFilter { get; set; }
- public string ExNameFilter { get; set; }
- public string[] BodyFilterArray { get; set; }
- public string[] ExBodyFilterArray { get; set; }
+ public string? NameFilter { get; set; }
+ public string? ExNameFilter { get; set; }
+ public string[] BodyFilterArray { get; set; } = Array.Empty<string>();
+ public string[] ExBodyFilterArray { get; set; } = Array.Empty<string>();
public bool SearchBoth { get; set; }
public bool ExSearchBoth { get; set; }
public bool MoveFrom { get; set; }
public bool ExUseRegex { get; set; }
public bool IsRt { get; set; }
public bool IsExRt { get; set; }
- public string Source { get; set; }
- public string ExSource { get; set; }
+ public string? Source { get; set; }
+ public string? ExSource { get; set; }
}
[Fact]
public TabInformationTest()
{
- this.tabinfo = Activator.CreateInstance(typeof(TabInformations), true) as TabInformations;
+ this.tabinfo = (TabInformations)Activator.CreateInstance(typeof(TabInformations), true);
// TabInformation.GetInstance() で取得できるようにする
var field = typeof(TabInformations).GetField("_instance",
[Fact]
public void SubmitUpdate_RemoveSubmit_Test()
{
- var homeTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.tabinfo.HomeTab;
this.tabinfo.AddPost(new PostClass { StatusId = 100L });
this.tabinfo.DistributePosts();
[Fact]
public void SubmitUpdate_RemoveSubmit_NotOrphaned_Test()
{
- var homeTab = this.tabinfo.GetTabByType<HomeTabModel>();
- var favTab = this.tabinfo.GetTabByType<FavoritesTabModel>();
+ var homeTab = this.tabinfo.HomeTab;
+ var favTab = this.tabinfo.FavoriteTab;
this.tabinfo.AddPost(new PostClass { StatusId = 100L, IsFav = true });
this.tabinfo.DistributePosts();
[Fact]
public void SubmitUpdate_NotifyPriorityTest()
{
- var homeTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.tabinfo.HomeTab;
homeTab.UnreadManage = true;
homeTab.SoundFile = "home.wav";
- var replyTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Mentions);
+ var replyTab = this.tabinfo.MentionTab;
replyTab.UnreadManage = true;
replyTab.SoundFile = "reply.wav";
- var dmTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.DirectMessage);
+ var dmTab = this.tabinfo.DirectMessageTab;
dmTab.UnreadManage = true;
dmTab.SoundFile = "dm.wav";
[Fact]
public void SubmitUpdate_IgnoreEmptySoundPath_Test()
{
- var homeTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.tabinfo.HomeTab;
homeTab.UnreadManage = true;
homeTab.SoundFile = "home.wav";
- var replyTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Mentions);
+ var replyTab = this.tabinfo.MentionTab;
replyTab.UnreadManage = true;
replyTab.SoundFile = "";
[Fact]
public void FilterAll_CopyFilterTest()
{
- var homeTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.tabinfo.HomeTab;
var myTab1 = new FilterTabModel("MyTab1");
this.tabinfo.AddTab(myTab1);
[Fact]
public void FilterAll_CopyAndMarkFilterTest()
{
- var homeTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.tabinfo.HomeTab;
var myTab1 = new FilterTabModel("MyTab1");
this.tabinfo.AddTab(myTab1);
Assert.Equal(new[] { 200L }, myTab1.StatusIds);
// [statusId: 200] は IsMark が true の状態になる
- Assert.True(this.tabinfo[200L].IsMark);
+ Assert.True(this.tabinfo[200L]!.IsMark);
}
[Fact]
public void FilterAll_MoveFilterTest()
{
- var homeTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.tabinfo.HomeTab;
var myTab1 = new FilterTabModel("MyTab1");
this.tabinfo.AddTab(myTab1);
[Fact]
public void FilterAll_MoveFilterTest2()
{
- var homeTab = this.tabinfo.GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.tabinfo.HomeTab;
var myTab1 = new FilterTabModel("MyTab1");
var myTab2 = new FilterTabModel("MyTab2");
[Fact]
public void FilterAll_ExcludeReplyFilterTest()
{
- var homeTab = this.tabinfo.GetTabByType<HomeTabModel>();
- var replyTab = this.tabinfo.GetTabByType<MentionsTabModel>();
+ var homeTab = this.tabinfo.HomeTab;
+ var replyTab = this.tabinfo.MentionTab;
var filter = new PostFilterRule
{
Assert.Equal(new[] { 200L, 300L }, replyTab.StatusIds, AnyOrderComparer<long>.Instance);
// [statusId: 100] は IsExcludeReply が true の状態になっている
- Assert.True(this.tabinfo[100L].IsExcludeReply);
+ Assert.True(this.tabinfo[100L]!.IsExcludeReply);
// Reply のフィルタを変更する
filter.ExFilterName = "bbb";
Assert.Equal(new[] { 100L, 300L }, replyTab.StatusIds, AnyOrderComparer<long>.Instance);
// [statusId: 100] は IsExcludeReply が false の状態になる
- Assert.False(this.tabinfo[100L].IsExcludeReply);
+ Assert.False(this.tabinfo[100L]!.IsExcludeReply);
// [statusId: 200] は IsExcludeReply が true の状態になる
- Assert.True(this.tabinfo[200L].IsExcludeReply);
+ Assert.True(this.tabinfo[200L]!.IsExcludeReply);
}
class TestPostFilterRule : PostFilterRule
<RootNamespace>OpenTween</RootNamespace>
<TargetFramework>net472</TargetFramework>
<LangVersion>8.0</LangVersion>
+ <Nullable>enable</Nullable>
<DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences>
</PropertyGroup>
<ItemGroup>
public TabsDialogTest()
{
- this.tabinfo = Activator.CreateInstance(typeof(TabInformations), true) as TabInformations;
+ this.tabinfo = (TabInformations)Activator.CreateInstance(typeof(TabInformations), true);
// タブを追加
this.tabinfo.AddTab(new HomeTabModel("Recent"));
using (var dialog = new TabsDialog(this.tabinfo))
{
// MultiSelect = false (default)
- var firstItem = dialog.TabList.Items[0] as TabsDialog.TabListItem;
+ var firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0];
Assert.Null(firstItem.Tab); // 「(新規タブ)」
Assert.Equal(SelectionMode.One, dialog.TabList.SelectionMode);
dialog.MultiSelect = true;
- firstItem = dialog.TabList.Items[0] as TabsDialog.TabListItem;
+ firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0];
Assert.NotNull(firstItem.Tab);
Assert.Equal(SelectionMode.MultiExtended, dialog.TabList.SelectionMode);
dialog.MultiSelect = false;
- firstItem = dialog.TabList.Items[0] as TabsDialog.TabListItem;
+ firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0];
Assert.Null(firstItem.Tab);
Assert.Equal(SelectionMode.One, dialog.TabList.SelectionMode);
}
{
dialog.MultiSelect = false;
- var item = dialog.TabList.Items[0] as TabsDialog.TabListItem;
+ var item = (TabsDialog.TabListItem)dialog.TabList.Items[0];
Assert.Null(item.Tab);
- item = dialog.TabList.Items[1] as TabsDialog.TabListItem;
+ item = (TabsDialog.TabListItem)dialog.TabList.Items[1];
Assert.Equal(this.tabinfo.Tabs["Reply"], item.Tab);
- item = dialog.TabList.Items[2] as TabsDialog.TabListItem;
+ item = (TabsDialog.TabListItem)dialog.TabList.Items[2];
Assert.Equal(this.tabinfo.Tabs["MyTab1"], item.Tab);
}
}
public static async Task NotRaisesAsync<T>(Action<EventHandler<T>> attach, Action<EventHandler<T>> detach, Func<Task> testCode)
where T : EventArgs
{
- T raisedEvent = null;
+ T? raisedEvent = null;
void handler(object s, T e)
=> raisedEvent = e;
var location = FoursquareCheckin.ParseIntoLocation(jsonBytes);
Assert.NotNull(location);
- Assert.Equal(34.35067978344854, location.Latitude);
+ Assert.Equal(34.35067978344854, location!.Latitude);
Assert.Equal(134.04693603515625, location.Longitude);
}
Thread.CurrentThread.CurrentCulture = origCulture;
Assert.NotNull(location);
- Assert.Equal(34.35067978344854, location.Latitude);
+ Assert.Equal(34.35067978344854, location!.Latitude);
Assert.Equal(134.04693603515625, location.Longitude);
}
this.LoadRegexAsync().Wait();
}
- public string GetApiBase()
+ public string? GetApiBase()
=> this.ApiBase;
protected override Task<byte[]> FetchRegexAsync(string apiBase)
await service.LoadRegexAsync();
Assert.Null(service.GetApiBase());
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.Null(thumbinfo);
}
public async Task MatchTest()
{
var service = new TestImgAzyobuziNet();
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.azyobuzi.net/api/redirect?size=large&uri=http%3A%2F%2Fexample.com%2Fabcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
public async Task NotMatchTest()
{
var service = new TestImgAzyobuziNet();
- var thumbinfo = await service.GetThumbnailInfoAsync("http://hogehoge.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://hogehoge.com/abcd", new PostClass(), CancellationToken.None);
Assert.Null(thumbinfo);
}
var service = new TestImgAzyobuziNet();
service.Enabled = false;
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.Null(thumbinfo);
}
using System.Threading;
using System.Threading.Tasks;
using Moq;
+using OpenTween.Models;
using Xunit;
using Xunit.Extensions;
{
class TestMetaThumbnailService : MetaThumbnailService
{
- public string FakeHtml { get; set; }
+ public string FakeHtml { get; set; } = "";
public TestMetaThumbnailService(string urlPattern)
: base(null, urlPattern)
</body>
</html>
";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
<p>hogehoge
";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
<p>hogehoge
";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
<p>hogehoge
";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
<p>hogehoge
";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
<p>hogehoge
";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
<p>hogehoge
";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
<p>hogehoge
";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.Null(thumbinfo);
}
using System.Threading;
using System.Threading.Tasks;
using Moq;
+using OpenTween.Models;
using Xunit;
using Xunit.Extensions;
{
var service = new SimpleThumbnailService(@"http://example.com/(.+)", @"http://img.example.com/$1");
- var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://example.com/abcd", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://example.com/abcd", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://example.com/abcd", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.example.com/abcd", thumbinfo.ThumbnailImageUrl);
Assert.Null(thumbinfo.TooltipText);
}
{
var service = new SimpleThumbnailService(@"http://example.com/(.+)", @"http://img.example.com/\1");
- var thumbinfo = await service.GetThumbnailInfoAsync("http://hogehoge.com/abcd", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://hogehoge.com/abcd", new PostClass(), CancellationToken.None);
Assert.Null(thumbinfo);
}
using System.Threading.Tasks;
using System.Xml.Linq;
using Moq;
+using OpenTween.Models;
using Xunit;
using Xunit.Extensions;
{
class TestTinami : Tinami
{
- public string FakeXml { get; set; }
+ public string FakeXml { get; set; } = "";
public TestTinami()
: base(null)
</image>
</content>
</rsp>";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://www.tinami.com/view/12345", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://www.tinami.com/view/12345", new PostClass(), CancellationToken.None);
Assert.NotNull(thumbinfo);
- Assert.Equal("http://www.tinami.com/view/12345", thumbinfo.MediaPageUrl);
+ Assert.Equal("http://www.tinami.com/view/12345", thumbinfo!.MediaPageUrl);
Assert.Equal("http://img.tinami.com/hogehoge_150.gif", thumbinfo.ThumbnailImageUrl);
Assert.Equal("説明", thumbinfo.TooltipText);
}
<rsp stat='user_only'>
<err msg='この作品は登録ユーザー限定の作品です。'/>
</rsp>";
- var thumbinfo = await service.GetThumbnailInfoAsync("http://www.tinami.com/view/12345", null, CancellationToken.None);
+ var thumbinfo = await service.GetThumbnailInfoAsync("http://www.tinami.com/view/12345", new PostClass(), CancellationToken.None);
Assert.Null(thumbinfo);
}
using System.Threading;
using System.Threading.Tasks;
using System.Web;
+using OpenTween.Models;
using Xunit;
namespace OpenTween.Thumbnail.Services
var service = new Tumblr(http);
var url = "http://hoge.tumblr.com/post/1234567/tetetete";
- await service.GetThumbnailInfoAsync(url, null, CancellationToken.None)
+ await service.GetThumbnailInfoAsync(url, new PostClass(), CancellationToken.None)
.ConfigureAwait(false);
}
// Tumblrのカスタムドメイン名を使ってるっぽいURL
var url = "http://tumblr.example.com/post/1234567/tetetete";
- await service.GetThumbnailInfoAsync(url, null, CancellationToken.None)
+ await service.GetThumbnailInfoAsync(url, new PostClass(), CancellationToken.None)
.ConfigureAwait(false);
}
{
var data = new DataObject("UniformResourceLocatorW", memstream);
- var expected = ("https://twitter.com/", (string)null);
+ var expected = ("https://twitter.com/", (string?)null);
Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data));
}
}
public void AutoLinkHtml_EntityNullTest()
{
var text = "てすとてすとー";
- TwitterEntities entities = null;
+ TwitterEntities? entities = null;
var expected = "てすとてすとー";
Assert.Equal(expected, TweetFormatter.AutoLinkHtml(text, entities));
public void AutoLinkHtml_EntityNullTest3()
{
var text = "てすとてすとー";
- IEnumerable<TwitterEntity> entities = null;
-
- var expected = "てすとてすとー";
- Assert.Equal(expected, TweetFormatter.AutoLinkHtml(text, entities));
- }
-
- [Fact]
- public void AutoLinkHtml_EntityNullTest4()
- {
- var text = "てすとてすとー";
- IEnumerable<TwitterEntity> entities = new TwitterEntity[] { null };
+ IEnumerable<TwitterEntity>? entities = null;
var expected = "てすとてすとー";
Assert.Equal(expected, TweetFormatter.AutoLinkHtml(text, entities));
public void AutoLinkHtml_BreakLineTest()
{
var text = "てすと\nてすと\nてすと";
- TwitterEntities entities = null;
+ TwitterEntities? entities = null;
var expected = "てすと<br>てすと<br>てすと";
Assert.Equal(expected, TweetFormatter.AutoLinkHtml(text, entities));
{
private readonly Regex regex;
private readonly string replaceUrl;
- private readonly string replaceTooltip;
+ private readonly string? replaceTooltip;
- public TestThumbnailService(string pattern, string replaceUrl, string replaceTooltip)
+ public TestThumbnailService(string pattern, string replaceUrl, string? replaceTooltip)
{
this.regex = new Regex(pattern);
this.replaceUrl = replaceUrl;
this.replaceTooltip = replaceTooltip;
}
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
var match = this.regex.Match(url);
var picbox = method.Invoke(thumbBox, new[] { "pictureBox1" }) as PictureBox;
Assert.NotNull(picbox);
- Assert.Equal("pictureBox1", picbox.Name);
+ Assert.Equal("pictureBox1", picbox!.Name);
Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode);
Assert.False(picbox.WaitOnLoad);
Assert.Equal(DockStyle.Fill, picbox.Dock);
},
},
};
- var quotedStatus = (TwitterStatus)null;
+ var quotedStatus = (TwitterStatus?)null;
var expectedText = "twitter.com/hoge/status/1…";
{
var sourceHtml = "web";
- var expected = ("web", (Uri)null);
+ var expected = ("web", (Uri?)null);
Assert.Equal(expected, Twitter.ParseSource(sourceHtml));
}
// 参照: https://twitter.com/kim_upsilon/status/595156014032244738
var sourceHtml = "";
- var expected = ("", (Uri)null);
+ var expected = ("", (Uri?)null);
Assert.Equal(expected, Twitter.ParseSource(sourceHtml));
}
[Fact]
public void ParseSource_NullTest()
{
- string sourceHtml = null;
+ string? sourceHtml = null;
- var expected = ("", (Uri)null);
+ var expected = ("", (Uri?)null);
Assert.Equal(expected, Twitter.ParseSource(sourceHtml));
}
{
var sourceHtml = "<<hogehoge>>";
- var expected = ("<<hogehoge>>", (Uri)null);
+ var expected = ("<<hogehoge>>", (Uri?)null);
Assert.Equal(expected, Twitter.ParseSource(sourceHtml));
}
// 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.Linq;
this.UpdatedAt = updatedAt;
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> this.Equals(obj as ApiLimit);
- public bool Equals(ApiLimit obj)
+ public bool Equals(ApiLimit? obj)
=> obj != null && this.AccessLimitCount == obj.AccessLimitCount &&
this.AccessLimitRemain == obj.AccessLimitRemain && this.AccessLimitResetDate == obj.AccessLimitResetDate;
// 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.Linq;
{
public static readonly Uri ApiBase = new Uri("https://api-ssl.bitly.com/");
- public string EndUserAccessToken { get; set; }
+ public string EndUserAccessToken { get; set; } = "";
- public string EndUserLoginName { get; set; }
- public string EndUserApiKey { get; set; }
+ public string EndUserLoginName { get; set; } = "";
+ public string EndUserApiKey { get; set; } = "";
private HttpClient http => this.localHttpClient ?? Networking.Http;
- private readonly HttpClient localHttpClient;
+ private readonly HttpClient? localHttpClient;
public BitlyApi()
: this(null)
{
}
- public BitlyApi(HttpClient http)
+ public BitlyApi(HttpClient? http)
=> this.localHttpClient = http;
- public async Task<Uri> ShortenAsync(Uri srcUri, string domain = null)
+ public async Task<Uri> ShortenAsync(Uri srcUri, string? domain = null)
{
var query = new Dictionary<string, string>
{
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections;
using System.Collections.Generic;
public class TwitterEntities : IEnumerable<TwitterEntity>
{
[DataMember(Name = "hashtags", IsRequired = false)]
- public TwitterEntityHashtag[] Hashtags { get; set; }
+ public TwitterEntityHashtag[]? Hashtags { get; set; }
[DataMember(Name = "media", IsRequired = false)]
- public TwitterEntityMedia[] Media { get; set; }
+ public TwitterEntityMedia[]? Media { get; set; }
[DataMember(Name = "symbols", IsRequired = false)]
- public TwitterEntitySymbol[] Symbols { get; set; }
+ public TwitterEntitySymbol[]? Symbols { get; set; }
[DataMember(Name = "urls", IsRequired = false)]
- public TwitterEntityUrl[] Urls { get; set; }
+ public TwitterEntityUrl[]? Urls { get; set; }
[DataMember(Name = "user_mentions", IsRequired = false)]
- public TwitterEntityMention[] UserMentions { get; set; }
+ public TwitterEntityMention[]? UserMentions { get; set; }
public IEnumerator<TwitterEntity> GetEnumerator()
{
public class TwitterEntityMedia : TwitterEntityUrl
{
[DataMember(Name = "additional_media_info", IsRequired = false)]
- public TwitterMediaAdditionalInfo AdditionalMediaInfo { get; set; }
+ public TwitterMediaAdditionalInfo? AdditionalMediaInfo { get; set; }
[DataMember(Name = "id")]
public long Id { get; set; }
public string Type { get; set; }
[DataMember(Name = "video_info", IsRequired = false)]
- public TwitterMediaVideoInfo VideoInfo { get; set; }
+ public TwitterMediaVideoInfo? VideoInfo { get; set; }
[DataMember(Name = "ext_alt_text", IsRequired = false)]
- public string AltText { get; set; }
+ public string? AltText { get; set; }
}
[DataContract]
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
public TwitterMessageEvent[] Events { get; set; }
[DataMember(Name = "next_cursor", IsRequired = false)]
- public string NextCursor { get; set; }
+ public string? NextCursor { get; set; }
}
[DataContract]
public class Data
{
[DataMember(Name = "attachment", IsRequired = false)]
- public MessageAttachment Attachment { get; set; }
+ public MessageAttachment? Attachment { get; set; }
[DataContract]
public class MessageAttachment
public string SenderId { get; set; }
[DataMember(Name = "source_app_id", IsRequired = false)]
- public string SourceAppId { get; set; }
+ public string? SourceAppId { get; set; }
[DataMember(Name = "target")]
public MessageTarget Target { get; set; }
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
public class TwitterStatus
{
[DataMember(Name = "coordinates", IsRequired = false)]
- public GeoJsonPoint Coordinates { get; set; }
+ public GeoJsonPoint? Coordinates { get; set; }
[DataMember(Name = "created_at")]
public string CreatedAt { get; set; }
public TwitterEntities Entities { get; set; }
[DataMember(Name = "extended_entities", IsRequired = false)]
- public TwitterEntities ExtendedEntities { get; set; }
+ public TwitterEntities? ExtendedEntities { get; set; }
[DataMember(Name = "favorite_count")]
public int? FavoriteCount { get; set; }
public string IdStr { get; set; }
[DataMember(Name = "in_reply_to_screen_name")]
- public string InReplyToScreenName { get; set; } // Nullable
+ public string? InReplyToScreenName { get; set; }
[DataMember(Name = "in_reply_to_status_id")]
public long? InReplyToStatusId { get; set; }
[DataMember(Name = "in_reply_to_status_id_str")]
- public string InReplyToStatusIdStr { get; set; } // Nullable
+ public string? InReplyToStatusIdStr { get; set; }
[DataMember(Name = "in_reply_to_user_id")]
public long? InReplyToUserId { get; set; }
[DataMember(Name = "in_reply_to_user_id_str")]
- public string InReplyToUserIdStr { get; set; } // Nullable
+ public string? InReplyToUserIdStr { get; set; }
[DataMember(Name = "is_quote_status")]
public bool IsQuoteStatus { get; set; }
[DataMember(Name = "lang")]
- public string Lang { get; set; } // Nullable
+ public string? Lang { get; set; }
[DataMember(Name = "place", IsRequired = false)]
- public TwitterPlace Place { get; set; }
+ public TwitterPlace? Place { get; set; }
[DataMember(Name = "possibly_sensitive")]
public bool? PossiblySensitive { get; set; }
public long? QuotedStatusId { get; set; }
[DataMember(Name = "quoted_status_id_str", IsRequired = false)]
- public string QuotedStatusIdStr { get; set; }
+ public string? QuotedStatusIdStr { get; set; }
[DataMember(Name = "quoted_status", IsRequired = false)]
- public TwitterStatus QuotedStatus { get; set; }
+ public TwitterStatus? QuotedStatus { get; set; }
[DataMember(Name = "quoted_status_permalink", IsRequired = false)]
- public TwitterQuotedStatusPermalink QuotedStatusPermalink { get; set; } // https://twittercommunity.com/t/105473
+ public TwitterQuotedStatusPermalink? QuotedStatusPermalink { get; set; } // https://twittercommunity.com/t/105473
[DataMember(Name = "reply_count")]
public int ReplyCount { get; set; }
public bool Retweeted { get; set; }
[DataMember(Name = "retweeted_status", IsRequired = false)]
- public TwitterStatus RetweetedStatus { get; set; }
+ public TwitterStatus? RetweetedStatus { get; set; }
[DataMember(Name = "source")]
public string Source { get; set; }
public class TwitterStatusCompat
{
[DataMember(Name = "coordinates", IsRequired = false)]
- public GeoJsonPoint Coordinates { get; set; }
+ public GeoJsonPoint? Coordinates { get; set; }
[DataMember(Name = "created_at")]
public string CreatedAt { get; set; }
public TwitterEntities Entities { get; set; }
[DataMember(Name = "extended_entities", IsRequired = false)]
- public TwitterEntities ExtendedEntities { get; set; }
+ public TwitterEntities? ExtendedEntities { get; set; }
[DataMember(Name = "extended_tweet", IsRequired = false)]
- public TwitterStatusCompat.Extended ExtendedTweet { get; set; }
+ public TwitterStatusCompat.Extended? ExtendedTweet { get; set; }
[DataContract]
public class Extended
public TwitterEntities Entities { get; set; }
[DataMember(Name = "extended_entities", IsRequired = false)]
- public TwitterEntities ExtendedEntities { get; set; }
+ public TwitterEntities? ExtendedEntities { get; set; }
[DataMember(Name = "full_text")]
public string FullText { get; set; }
public string IdStr { get; set; }
[DataMember(Name = "in_reply_to_screen_name")]
- public string InReplyToScreenName { get; set; } // Nullable
+ public string? InReplyToScreenName { get; set; }
[DataMember(Name = "in_reply_to_status_id")]
public long? InReplyToStatusId { get; set; }
[DataMember(Name = "in_reply_to_status_id_str")]
- public string InReplyToStatusIdStr { get; set; } // Nullable
+ public string? InReplyToStatusIdStr { get; set; }
[DataMember(Name = "in_reply_to_user_id")]
public long? InReplyToUserId { get; set; }
[DataMember(Name = "in_reply_to_user_id_str")]
- public string InReplyToUserIdStr { get; set; } // Nullable
+ public string? InReplyToUserIdStr { get; set; }
[DataMember(Name = "is_quote_status")]
public bool IsQuoteStatus { get; set; }
[DataMember(Name = "lang")]
- public string Lang { get; set; } // Nullable
+ public string? Lang { get; set; }
[DataMember(Name = "place", IsRequired = false)]
- public TwitterPlace Place { get; set; }
+ public TwitterPlace? Place { get; set; }
[DataMember(Name = "possibly_sensitive")]
public bool? PossiblySensitive { get; set; }
public long? QuotedStatusId { get; set; }
[DataMember(Name = "quoted_status_id_str", IsRequired = false)]
- public string QuotedStatusIdStr { get; set; }
+ public string? QuotedStatusIdStr { get; set; }
[DataMember(Name = "quoted_status", IsRequired = false)]
- public TwitterStatusCompat QuotedStatus { get; set; }
+ public TwitterStatusCompat? QuotedStatus { get; set; }
[DataMember(Name = "quoted_status_permalink", IsRequired = false)]
- public TwitterQuotedStatusPermalink QuotedStatusPermalink { get; set; } // https://twittercommunity.com/t/105473
+ public TwitterQuotedStatusPermalink? QuotedStatusPermalink { get; set; } // https://twittercommunity.com/t/105473
[DataMember(Name = "reply_count")]
public int ReplyCount { get; set; }
public bool Retweeted { get; set; }
[DataMember(Name = "retweeted_status", IsRequired = false)]
- public TwitterStatusCompat RetweetedStatus { get; set; }
+ public TwitterStatusCompat? RetweetedStatus { get; set; }
[DataMember(Name = "source")]
public string Source { get; set; }
public class TwitterDirectMessage
{
[DataMember(Name = "entities", IsRequired = false)]
- public TwitterEntities Entities { get; set; }
+ public TwitterEntities? Entities { get; set; }
[DataMember(Name = "created_at")]
public string CreatedAt { get; set; }
public string SenderScreenName { get; set; }
[DataMember(Name = "sender", IsRequired = false)]
- public TwitterUser Sender { get; set; }
+ public TwitterUser? Sender { get; set; }
[DataMember(Name = "recipient_id")]
public long RecipientId { get; set; }
public string RecipientScreenName { get; set; }
[DataMember(Name = "recipient", IsRequired = false)]
- public TwitterUser Recipient { get; set; }
+ public TwitterUser? Recipient { get; set; }
/// <exception cref="SerializationException"/>
public static TwitterDirectMessage ParseJson(string json)
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System.Runtime.Serialization;
namespace OpenTween.Api.DataModel
}
[DataMember(Name = "direct_message", IsRequired = false)]
- public DeletedId DirectMessage { get; set; } // Nullable
+ public DeletedId? DirectMessage { get; set; }
[DataMember(Name = "status", IsRequired = false)]
- public DeletedId Status { get; set; } // Nullable
+ public DeletedId? Status { get; set; }
public static StreamMessageDelete ParseJson(string json)
=> MyCommon.CreateDataFromJson<StreamMessageDelete>(json);
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System.Runtime.Serialization;
namespace OpenTween.Api.DataModel
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.Linq;
}
[DataMember(Name = "image", IsRequired = false)]
- public ImageInfo Image { get; set; }
+ public ImageInfo? Image { get; set; }
[DataMember(Name = "media_id")]
public long MediaId { get; set; }
}
[DataMember(Name = "error", IsRequired = false)]
- public MediaProcessingError Error { get; set; }
+ public MediaProcessingError? Error { get; set; }
[DataMember(Name = "progress_percent")]
public int ProgressPercent { get; set; }
}
[DataMember(Name = "processing_info", IsRequired = false)]
- public MediaProcessingInfo ProcessingInfo { get; set; }
+ public MediaProcessingInfo? ProcessingInfo { get; set; }
[DataMember(Name = "size", IsRequired = false)]
public long? Size { get; set; }
}
[DataMember(Name = "video", IsRequired = false)]
- public VideoInfo Video { get; set; }
+ public VideoInfo? Video { get; set; }
/// <exception cref="SerializationException"/>
public static TwitterUploadMediaResult ParseJson(string json)
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
using System.IO;
public string CreatedAt { get; set; }
[DataMember(Name = "description")]
- public string Description { get; set; } // Nullable
+ public string? Description { get; set; }
[DataMember(Name = "default_profile")]
public bool DefaultProfile { get; set; }
public bool DefaultProfileImage { get; set; }
[DataMember(Name = "entities", IsRequired = false)]
- public TwitterUser.TwitterUserEntity Entities { get; set; }
+ public TwitterUser.TwitterUserEntity? Entities { get; set; }
[DataContract]
public class TwitterUserEntity
{
[DataMember(Name = "url", IsRequired = false)]
- public TwitterEntities Url { get; set; }
+ public TwitterEntities? Url { get; set; }
[DataMember(Name = "description", IsRequired = false)]
- public TwitterEntities Description { get; set; }
+ public TwitterEntities? Description { get; set; }
}
[DataMember(Name = "favourites_count")]
public int? ListedCount { get; set; }
[DataMember(Name = "location")]
- public string Location { get; set; } // Nullable
+ public string? Location { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
public bool ShowAllInlineMedia { get; set; }
[DataMember(Name = "status", IsRequired = false)]
- public TwitterStatus Status { get; set; } // Nullable
+ public TwitterStatus? Status { get; set; }
[DataMember(Name = "statuses_count")]
public int StatusesCount { get; set; }
[DataMember(Name = "url")]
- public string Url { get; set; } // Nullable
+ public string? Url { get; set; }
[DataMember(Name = "verified")]
public bool Verified { get; set; }
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System.Text;
namespace OpenTween.Api
// 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.Linq;
public static readonly Uri IssueTokenEndpoint = new Uri("https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
public static readonly Uri TranslateEndpoint = new Uri("https://api.cognitive.microsofttranslator.com/translate");
- public string AccessToken { get; internal set; }
- public DateTimeUtc RefreshAccessTokenAt { get; internal set; }
+ public string AccessToken { get; internal set; } = "";
+ public DateTimeUtc RefreshAccessTokenAt { get; internal set; } = DateTimeUtc.MinValue;
private HttpClient Http => this.localHttpClient ?? Networking.Http;
- private readonly HttpClient localHttpClient;
+ private readonly HttpClient? localHttpClient;
public MicrosoftTranslatorApi()
: this(null)
{
}
- public MicrosoftTranslatorApi(HttpClient http)
+ public MicrosoftTranslatorApi(HttpClient? http)
=> this.localHttpClient = http;
- public async Task<string> TranslateAsync(string text, string langTo, string langFrom = null)
+ public async Task<string> TranslateAsync(string text, string langTo, string? langFrom = null)
{
await this.UpdateAccessTokenIfExpired()
.ConfigureAwait(false);
public async Task UpdateAccessTokenIfExpired()
{
- if (this.AccessToken != null && this.RefreshAccessTokenAt > DateTimeUtc.Now)
+ if (!string.IsNullOrEmpty(this.AccessToken) && this.RefreshAccessTokenAt > DateTimeUtc.Now)
return;
var (accessToken, expiresIn) = await this.GetAccessTokenAsync()
// 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.IO;
public sealed class TwitterApi : IDisposable
{
public long CurrentUserId { get; private set; }
- public string CurrentScreenName { get; private set; }
+ public string CurrentScreenName { get; private set; } = "";
- public IApiConnection Connection => this.apiConnection;
+ public IApiConnection Connection => this.apiConnection ?? throw new InvalidOperationException();
- internal IApiConnection apiConnection;
+ internal IApiConnection? apiConnection;
public void Initialize(string accessToken, string accessSecret, long userId, string screenName)
{
if (sinceId != null)
param["since_id"] = sinceId.ToString();
- return this.apiConnection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/home_timeline");
+ return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/home_timeline");
}
public Task<TwitterStatus[]> StatusesMentionsTimeline(int? count = null, long? maxId = null, long? sinceId = null)
if (sinceId != null)
param["since_id"] = sinceId.ToString();
- return this.apiConnection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/mentions_timeline");
+ return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/mentions_timeline");
}
public Task<TwitterStatus[]> StatusesUserTimeline(string screenName, int? count = null, long? maxId = null, long? sinceId = null)
if (sinceId != null)
param["since_id"] = sinceId.ToString();
- return this.apiConnection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/user_timeline");
+ return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/user_timeline");
}
public Task<TwitterStatus> StatusesShow(long statusId)
["tweet_mode"] = "extended",
};
- return this.apiConnection.GetAsync<TwitterStatus>(endpoint, param, "/statuses/show/:id");
+ return this.Connection.GetAsync<TwitterStatus>(endpoint, param, "/statuses/show/:id");
}
- public Task<LazyJson<TwitterStatus>> StatusesUpdate(string status, long? replyToId, IReadOnlyList<long> mediaIds,
- bool? autoPopulateReplyMetadata = null, IReadOnlyList<long> excludeReplyUserIds = null, string attachmentUrl = null)
+ public Task<LazyJson<TwitterStatus>> StatusesUpdate(string status, long? replyToId, IReadOnlyList<long>? mediaIds,
+ bool? autoPopulateReplyMetadata = null, IReadOnlyList<long>? excludeReplyUserIds = null, string? attachmentUrl = null)
{
var endpoint = new Uri("statuses/update.json", UriKind.Relative);
var param = new Dictionary<string, string>
if (attachmentUrl != null)
param["attachment_url"] = attachmentUrl;
- return this.apiConnection.PostLazyAsync<TwitterStatus>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterStatus>(endpoint, param);
}
public Task<LazyJson<TwitterStatus>> StatusesDestroy(long statusId)
["id"] = statusId.ToString(),
};
- return this.apiConnection.PostLazyAsync<TwitterStatus>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterStatus>(endpoint, param);
}
public Task<LazyJson<TwitterStatus>> StatusesRetweet(long statusId)
["tweet_mode"] = "extended",
};
- return this.apiConnection.PostLazyAsync<TwitterStatus>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterStatus>(endpoint, param);
}
- public Task<TwitterSearchResult> SearchTweets(string query, string lang = null, int? count = null, long? maxId = null, long? sinceId = null)
+ public Task<TwitterSearchResult> SearchTweets(string query, string? lang = null, int? count = null, long? maxId = null, long? sinceId = null)
{
var endpoint = new Uri("search/tweets.json", UriKind.Relative);
var param = new Dictionary<string, string>
if (sinceId != null)
param["since_id"] = sinceId.ToString();
- return this.apiConnection.GetAsync<TwitterSearchResult>(endpoint, param, "/search/tweets");
+ return this.Connection.GetAsync<TwitterSearchResult>(endpoint, param, "/search/tweets");
}
public Task<TwitterLists> ListsOwnerships(string screenName, long? cursor = null, int? count = null)
if (count != null)
param["count"] = count.ToString();
- return this.apiConnection.GetAsync<TwitterLists>(endpoint, param, "/lists/ownerships");
+ return this.Connection.GetAsync<TwitterLists>(endpoint, param, "/lists/ownerships");
}
public Task<TwitterLists> ListsSubscriptions(string screenName, long? cursor = null, int? count = null)
if (count != null)
param["count"] = count.ToString();
- return this.apiConnection.GetAsync<TwitterLists>(endpoint, param, "/lists/subscriptions");
+ return this.Connection.GetAsync<TwitterLists>(endpoint, param, "/lists/subscriptions");
}
public Task<TwitterLists> ListsMemberships(string screenName, long? cursor = null, int? count = null, bool? filterToOwnedLists = null)
if (filterToOwnedLists != null)
param["filter_to_owned_lists"] = filterToOwnedLists.Value ? "true" : "false";
- return this.apiConnection.GetAsync<TwitterLists>(endpoint, param, "/lists/memberships");
+ return this.Connection.GetAsync<TwitterLists>(endpoint, param, "/lists/memberships");
}
- public Task<LazyJson<TwitterList>> ListsCreate(string name, string description = null, bool? @private = null)
+ public Task<LazyJson<TwitterList>> ListsCreate(string name, string? description = null, bool? @private = null)
{
var endpoint = new Uri("lists/create.json", UriKind.Relative);
var param = new Dictionary<string, string>
if (@private != null)
param["mode"] = @private.Value ? "private" : "public";
- return this.apiConnection.PostLazyAsync<TwitterList>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterList>(endpoint, param);
}
- public Task<LazyJson<TwitterList>> ListsUpdate(long listId, string name = null, string description = null, bool? @private = null)
+ public Task<LazyJson<TwitterList>> ListsUpdate(long listId, string? name = null, string? description = null, bool? @private = null)
{
var endpoint = new Uri("lists/update.json", UriKind.Relative);
var param = new Dictionary<string, string>
if (@private != null)
param["mode"] = @private.Value ? "private" : "public";
- return this.apiConnection.PostLazyAsync<TwitterList>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterList>(endpoint, param);
}
public Task<LazyJson<TwitterList>> ListsDestroy(long listId)
["list_id"] = listId.ToString(),
};
- return this.apiConnection.PostLazyAsync<TwitterList>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterList>(endpoint, param);
}
public Task<TwitterStatus[]> ListsStatuses(long listId, int? count = null, long? maxId = null, long? sinceId = null, bool? includeRTs = null)
if (includeRTs != null)
param["include_rts"] = includeRTs.Value ? "true" : "false";
- return this.apiConnection.GetAsync<TwitterStatus[]>(endpoint, param, "/lists/statuses");
+ return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/lists/statuses");
}
public Task<TwitterUsers> ListsMembers(long listId, long? cursor = null)
if (cursor != null)
param["cursor"] = cursor.ToString();
- return this.apiConnection.GetAsync<TwitterUsers>(endpoint, param, "/lists/members");
+ return this.Connection.GetAsync<TwitterUsers>(endpoint, param, "/lists/members");
}
public Task<TwitterUser> ListsMembersShow(long listId, string screenName)
["tweet_mode"] = "extended",
};
- return this.apiConnection.GetAsync<TwitterUser>(endpoint, param, "/lists/members/show");
+ return this.Connection.GetAsync<TwitterUser>(endpoint, param, "/lists/members/show");
}
public Task<LazyJson<TwitterUser>> ListsMembersCreate(long listId, string screenName)
["tweet_mode"] = "extended",
};
- return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterUser>(endpoint, param);
}
public Task<LazyJson<TwitterUser>> ListsMembersDestroy(long listId, string screenName)
["tweet_mode"] = "extended",
};
- return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterUser>(endpoint, param);
}
- public Task<TwitterMessageEventList> DirectMessagesEventsList(int? count = null, string cursor = null)
+ public Task<TwitterMessageEventList> DirectMessagesEventsList(int? count = null, string? cursor = null)
{
var endpoint = new Uri("direct_messages/events/list.json", UriKind.Relative);
var param = new Dictionary<string, string>();
if (cursor != null)
param["cursor"] = cursor;
- return this.apiConnection.GetAsync<TwitterMessageEventList>(endpoint, param, "/direct_messages/events/list");
+ return this.Connection.GetAsync<TwitterMessageEventList>(endpoint, param, "/direct_messages/events/list");
}
public Task<LazyJson<TwitterMessageEventSingle>> DirectMessagesEventsNew(long recipientId, string text, long? mediaId = null)
}}
}}";
- return this.apiConnection.PostJsonAsync<TwitterMessageEventSingle>(endpoint, json);
+ return this.Connection.PostJsonAsync<TwitterMessageEventSingle>(endpoint, json);
}
public Task DirectMessagesEventsDestroy(string eventId)
// なぜか application/x-www-form-urlencoded でパラメーターを送ると Bad Request になる謎仕様
endpoint = new Uri(endpoint.OriginalString + "?" + MyCommon.BuildQueryString(param), UriKind.Relative);
- return this.apiConnection.DeleteAsync(endpoint);
+ return this.Connection.DeleteAsync(endpoint);
}
public Task<TwitterUser> UsersShow(string screenName)
["tweet_mode"] = "extended",
};
- return this.apiConnection.GetAsync<TwitterUser>(endpoint, param, "/users/show/:id");
+ return this.Connection.GetAsync<TwitterUser>(endpoint, param, "/users/show/:id");
}
public Task<TwitterUser[]> UsersLookup(IReadOnlyList<string> userIds)
["tweet_mode"] = "extended",
};
- return this.apiConnection.GetAsync<TwitterUser[]>(endpoint, param, "/users/lookup");
+ return this.Connection.GetAsync<TwitterUser[]>(endpoint, param, "/users/lookup");
}
public Task<LazyJson<TwitterUser>> UsersReportSpam(string screenName)
["tweet_mode"] = "extended",
};
- return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterUser>(endpoint, param);
}
public Task<TwitterStatus[]> FavoritesList(int? count = null, long? maxId = null, long? sinceId = null)
if (sinceId != null)
param["since_id"] = sinceId.ToString();
- return this.apiConnection.GetAsync<TwitterStatus[]>(endpoint, param, "/favorites/list");
+ return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/favorites/list");
}
public Task<LazyJson<TwitterStatus>> FavoritesCreate(long statusId)
["tweet_mode"] = "extended",
};
- return this.apiConnection.PostLazyAsync<TwitterStatus>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterStatus>(endpoint, param);
}
public Task<LazyJson<TwitterStatus>> FavoritesDestroy(long statusId)
["tweet_mode"] = "extended",
};
- return this.apiConnection.PostLazyAsync<TwitterStatus>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterStatus>(endpoint, param);
}
public Task<TwitterFriendship> FriendshipsShow(string sourceScreenName, string targetScreenName)
["target_screen_name"] = targetScreenName,
};
- return this.apiConnection.GetAsync<TwitterFriendship>(endpoint, param, "/friendships/show");
+ return this.Connection.GetAsync<TwitterFriendship>(endpoint, param, "/friendships/show");
}
public Task<LazyJson<TwitterFriendship>> FriendshipsCreate(string screenName)
["screen_name"] = screenName,
};
- return this.apiConnection.PostLazyAsync<TwitterFriendship>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterFriendship>(endpoint, param);
}
public Task<LazyJson<TwitterFriendship>> FriendshipsDestroy(string screenName)
["screen_name"] = screenName,
};
- return this.apiConnection.PostLazyAsync<TwitterFriendship>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterFriendship>(endpoint, param);
}
public Task<long[]> NoRetweetIds()
{
var endpoint = new Uri("friendships/no_retweets/ids.json", UriKind.Relative);
- return this.apiConnection.GetAsync<long[]>(endpoint, null, "/friendships/no_retweets/ids");
+ return this.Connection.GetAsync<long[]>(endpoint, null, "/friendships/no_retweets/ids");
}
public Task<TwitterIds> FollowersIds(long? cursor = null)
if (cursor != null)
param["cursor"] = cursor.ToString();
- return this.apiConnection.GetAsync<TwitterIds>(endpoint, param, "/followers/ids");
+ return this.Connection.GetAsync<TwitterIds>(endpoint, param, "/followers/ids");
}
public Task<TwitterIds> MutesUsersIds(long? cursor = null)
if (cursor != null)
param["cursor"] = cursor.ToString();
- return this.apiConnection.GetAsync<TwitterIds>(endpoint, param, "/mutes/users/ids");
+ return this.Connection.GetAsync<TwitterIds>(endpoint, param, "/mutes/users/ids");
}
public Task<TwitterIds> BlocksIds(long? cursor = null)
if (cursor != null)
param["cursor"] = cursor.ToString();
- return this.apiConnection.GetAsync<TwitterIds>(endpoint, param, "/blocks/ids");
+ return this.Connection.GetAsync<TwitterIds>(endpoint, param, "/blocks/ids");
}
public Task<LazyJson<TwitterUser>> BlocksCreate(string screenName)
["tweet_mode"] = "extended",
};
- return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterUser>(endpoint, param);
}
public Task<LazyJson<TwitterUser>> BlocksDestroy(string screenName)
["tweet_mode"] = "extended",
};
- return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterUser>(endpoint, param);
}
public async Task<TwitterUser> AccountVerifyCredentials()
["tweet_mode"] = "extended",
};
- var user = await this.apiConnection.GetAsync<TwitterUser>(endpoint, param, "/account/verify_credentials")
+ var user = await this.Connection.GetAsync<TwitterUser>(endpoint, param, "/account/verify_credentials")
.ConfigureAwait(false);
this.CurrentUserId = user.Id;
return user;
}
- public Task<LazyJson<TwitterUser>> AccountUpdateProfile(string name, string url, string location, string description)
+ public Task<LazyJson<TwitterUser>> AccountUpdateProfile(string name, string url, string? location, string? description)
{
var endpoint = new Uri("account/update_profile.json", UriKind.Relative);
var param = new Dictionary<string, string>
param["description"] = escapedDescription;
}
- return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterUser>(endpoint, param);
}
public Task<LazyJson<TwitterUser>> AccountUpdateProfileImage(IMediaItem image)
["image"] = image,
};
- return this.apiConnection.PostLazyAsync<TwitterUser>(endpoint, param, paramMedia);
+ return this.Connection.PostLazyAsync<TwitterUser>(endpoint, param, paramMedia);
}
public Task<TwitterRateLimits> ApplicationRateLimitStatus()
{
var endpoint = new Uri("application/rate_limit_status.json", UriKind.Relative);
- return this.apiConnection.GetAsync<TwitterRateLimits>(endpoint, null, "/application/rate_limit_status");
+ return this.Connection.GetAsync<TwitterRateLimits>(endpoint, null, "/application/rate_limit_status");
}
public Task<TwitterConfiguration> Configuration()
{
var endpoint = new Uri("help/configuration.json", UriKind.Relative);
- return this.apiConnection.GetAsync<TwitterConfiguration>(endpoint, null, "/help/configuration");
+ return this.Connection.GetAsync<TwitterConfiguration>(endpoint, null, "/help/configuration");
}
- public Task<LazyJson<TwitterUploadMediaInit>> MediaUploadInit(long totalBytes, string mediaType, string mediaCategory = null)
+ public Task<LazyJson<TwitterUploadMediaInit>> MediaUploadInit(long totalBytes, string mediaType, string? mediaCategory = null)
{
var endpoint = new Uri("https://upload.twitter.com/1.1/media/upload.json");
var param = new Dictionary<string, string>
if (mediaCategory != null)
param["media_category"] = mediaCategory;
- return this.apiConnection.PostLazyAsync<TwitterUploadMediaInit>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterUploadMediaInit>(endpoint, param);
}
public Task MediaUploadAppend(long mediaId, int segmentIndex, IMediaItem media)
["media"] = media,
};
- return this.apiConnection.PostAsync(endpoint, param, paramMedia);
+ return this.Connection.PostAsync(endpoint, param, paramMedia);
}
public Task<LazyJson<TwitterUploadMediaResult>> MediaUploadFinalize(long mediaId)
["media_id"] = mediaId.ToString(),
};
- return this.apiConnection.PostLazyAsync<TwitterUploadMediaResult>(endpoint, param);
+ return this.Connection.PostLazyAsync<TwitterUploadMediaResult>(endpoint, param);
}
public Task<TwitterUploadMediaResult> MediaUploadStatus(long mediaId)
["media_id"] = mediaId.ToString(),
};
- return this.apiConnection.GetAsync<TwitterUploadMediaResult>(endpoint, param, endpointName: null);
+ return this.Connection.GetAsync<TwitterUploadMediaResult>(endpoint, param, endpointName: null);
}
public Task MediaMetadataCreate(long mediaId, string altText)
var escapedAltText = JsonUtils.EscapeJsonString(altText);
var json = $@"{{""media_id"": ""{mediaId}"", ""alt_text"": {{""text"": ""{escapedAltText}""}}}}";
- return this.apiConnection.PostJsonAsync(endpoint, json);
+ return this.Connection.PostJsonAsync(endpoint, json);
}
- public TwitterStreamObservable UserStreams(string replies = null, string track = null)
+ public TwitterStreamObservable UserStreams(string? replies = null, string? track = null)
{
var endpoint = new Uri("https://userstream.twitter.com/1.1/user.json");
var param = new Dictionary<string, string>();
param["track"] = track;
Task<Stream> openStream()
- => this.apiConnection.GetStreamingStreamAsync(endpoint, param);
+ => this.Connection.GetStreamingStreamAsync(endpoint, param);
return new TwitterStreamObservable(openStream);
}
- public OAuthEchoHandler CreateOAuthEchoHandler(Uri authServiceProvider, Uri realm = null)
- => ((TwitterApiConnection)this.apiConnection).CreateOAuthEchoHandler(authServiceProvider, realm);
+ public OAuthEchoHandler CreateOAuthEchoHandler(Uri authServiceProvider, Uri? realm = null)
+ => ((TwitterApiConnection)this.Connection).CreateOAuthEchoHandler(authServiceProvider, realm);
public void Dispose()
=> this.apiConnection?.Dispose();
// 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.Linq;
public class TwitterApiException : WebApiException
{
public HttpStatusCode StatusCode { get; }
- public TwitterError ErrorResponse { get; }
+ public TwitterError? ErrorResponse { get; }
+
+ public TwitterErrorItem[] Errors
+ => this.ErrorResponse != null ? this.ErrorResponse.Errors : Array.Empty<TwitterErrorItem>();
public TwitterApiException()
{
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
{
public TwitterApiAccessLevel AccessLevel { get; set; }
public EndpointLimits AccessLimit { get; }
- public ApiLimit MediaUploadLimit { get; set; }
+ public ApiLimit? MediaUploadLimit { get; set; }
public class AccessLimitUpdatedEventArgs : EventArgs
{
- public string EndpointName { get; }
+ public string? EndpointName { get; }
- public AccessLimitUpdatedEventArgs(string endpointName)
+ public AccessLimitUpdatedEventArgs(string? endpointName)
=> this.EndpointName = endpointName;
}
public event EventHandler<AccessLimitUpdatedEventArgs> AccessLimitUpdated;
this.MediaUploadLimit = null;
}
- internal static ApiLimit ParseRateLimit(IDictionary<string, string> header, string prefix)
+ internal static ApiLimit? ParseRateLimit(IDictionary<string, string> header, string prefix)
{
var limitCount = (int?)ParseHeaderValue(header, prefix + "Limit");
var limitRemain = (int?)ParseHeaderValue(header, prefix + "Remaining");
public EndpointLimits(TwitterApiStatus owner)
=> this.Owner = owner;
- public ApiLimit this[string endpoint]
+ public ApiLimit? this[string endpoint]
{
get => this.innerDict.TryGetValue(endpoint, out var limit) ? limit : null;
set
{
- this.innerDict[endpoint] = value;
+ if (value == null)
+ this.innerDict.TryRemove(endpoint, out var _);
+ else
+ this.innerDict[endpoint] = value;
+
this.Owner.OnAccessLimitUpdated(new AccessLimitUpdatedEventArgs(endpoint));
}
}
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using OpenTween.Api.DataModel;
using System;
using System.IO;
// 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.ComponentModel;
foreach (var endpoint in _tlEndpoints)
{
var apiLimit = MyCommon.TwitterApiInfo.AccessLimit[endpoint];
+ if (apiLimit == null)
+ continue;
+
AddListViewItem(endpoint, apiLimit, group);
}
private void UpdateEndpointLimit(string endpoint)
{
- var item = this.ListViewApi.Items.Cast<ListViewItem>().FirstOrDefault(x => x.SubItems[0].Text == endpoint);
- if (item != null)
+ var apiLimit = MyCommon.TwitterApiInfo.AccessLimit[endpoint];
+ if (apiLimit != null)
{
- var apiLimit = MyCommon.TwitterApiInfo.AccessLimit[endpoint];
+ var item = this.ListViewApi.Items.Cast<ListViewItem>().Single(x => x.SubItems[0].Text == endpoint);
item.SubItems[1].Text = apiLimit.AccessLimitRemain + "/" + apiLimit.AccessLimitCount;
item.SubItems[2].Text = apiLimit.AccessLimitResetDate.ToLocalTimeString();
}
}
else
{
- var endpoint = (e as TwitterApiStatus.AccessLimitUpdatedEventArgs).EndpointName;
- UpdateEndpointLimit(endpoint);
+ var endpoint = ((TwitterApiStatus.AccessLimitUpdatedEventArgs)e).EndpointName;
+ if (endpoint != null)
+ UpdateEndpointLimit(endpoint);
}
}
catch (ObjectDisposedException)
// 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.ComponentModel;
{
public event EventHandler<IntervalChangedEventArgs> IntervalChanged;
- internal Twitter tw;
- internal TwitterApi twitterApi;
+ internal Twitter tw = null!;
+ internal TwitterApi twitterApi = null!;
public AppendSettingDialog()
{
TwitterApiConnection.RestApiHost = this.ConnectionPanel.TwitterAPIText.Text.Trim();
}
- private async Task<UserAccount> PinAuth()
+ private async Task<UserAccount?> PinAuth()
{
var requestToken = await TwitterApiConnection.GetRequestTokenAsync();
// 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.IO;
}
}
- private static Process GetPreviousProcess()
+ private static Process? GetPreviousProcess()
{
var currentProcess = Process.GetCurrentProcess();
try
// 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.Linq;
// 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.ComponentModel;
// 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.ComponentModel;
/// <param name="owner">親ウィンドウ</param>
/// <param name="authUri">認証URL</param>
/// <returns>PIN文字列</returns>
- public static string DoAuth(IWin32Window owner, Uri authUri)
+ public static string? DoAuth(IWin32Window owner, Uri authUri)
{
using var dialog = new AuthDialog();
dialog.AuthUrl = authUri.AbsoluteUri;
// 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.Net.Http;
{
}
- public Bing(HttpClient http)
+ public Bing(HttpClient? http)
=> this.translatorApi = new MicrosoftTranslatorApi(http);
/// <summary>
/// Microsoft Translator API を使用した翻訳を非同期に行います
/// </summary>
/// <exception cref="HttpRequestException"/>
- public async Task<string> TranslateAsync(string text, string langFrom, string langTo)
+ public async Task<string> TranslateAsync(string text, string? langFrom, string langTo)
=> await this.translatorApi.TranslateAsync(text, langTo, langFrom)
.ConfigureAwait(false);
// 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.IO;
{
public interface IApiConnection : IDisposable
{
- Task<T> GetAsync<T>(Uri uri, IDictionary<string, string> param, string endpointName);
+ Task<T> GetAsync<T>(Uri uri, IDictionary<string, string>? param, string? endpointName);
- Task<Stream> GetStreamAsync(Uri uri, IDictionary<string, string> param);
+ Task<Stream> GetStreamAsync(Uri uri, IDictionary<string, string>? param);
- Task<Stream> GetStreamingStreamAsync(Uri uri, IDictionary<string, string> param);
+ Task<Stream> GetStreamingStreamAsync(Uri uri, IDictionary<string, string>? param);
- Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string> param);
+ Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param);
- Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string> param, IDictionary<string, IMediaItem> media);
+ Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param, IDictionary<string, IMediaItem>? media);
- Task PostAsync(Uri uri, IDictionary<string, string> param, IDictionary<string, IMediaItem> media);
+ Task PostAsync(Uri uri, IDictionary<string, string>? param, IDictionary<string, IMediaItem>? media);
Task PostJsonAsync(Uri uri, string json);
// 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.IO;
// 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.IO;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable annotations
+
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Net.Http;
using System.Runtime.Serialization;
/// </summary>
public sealed class LazyJson<T> : IDisposable
{
- public HttpResponseMessage Response { get; }
+ public HttpResponseMessage? Response { get; }
private T instance;
private bool completed = false;
public async Task<T> LoadJsonAsync()
{
if (this.completed)
- return this.instance;
+ return this.instance!;
using var content = this.Response.Content;
var responseText = await content.ReadAsStringAsync()
// 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.IO;
// 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.CodeAnalysis;
/// <summary>
/// 通信に使用するプロキシ
/// </summary>
- public static IWebProxy Proxy { get; private set; } = null;
+ public static IWebProxy? Proxy { get; private set; } = null;
/// <summary>
/// OpenTween 内で共通して使用する HttpClient インスタンス
public static void SetWebProxy(ProxyType proxyType, string proxyAddress, int proxyPort,
string proxyUser, string proxyPassword)
{
- IWebProxy proxy;
+ IWebProxy? proxy;
switch (proxyType)
{
case ProxyType.None:
private class ForceIPv4Handler : DelegatingHandler
{
- private readonly IPAddress ipv4Address;
+ private readonly IPAddress? ipv4Address;
public ForceIPv4Handler(HttpMessageHandler innerHandler)
: base(innerHandler)
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
- var requestUri = request.RequestUri;
- if (requestUri.Host == "pbs.twimg.com")
+ if (this.ipv4Address != null)
{
- var rewriteUriStr = requestUri.GetLeftPart(UriPartial.Scheme) + this.ipv4Address + requestUri.PathAndQuery;
- request.RequestUri = new Uri(rewriteUriStr);
- request.Headers.Host = "pbs.twimg.com";
+ var requestUri = request.RequestUri;
+ if (requestUri.Host == "pbs.twimg.com")
+ {
+ var rewriteUriStr = requestUri.GetLeftPart(UriPartial.Scheme) + this.ipv4Address + requestUri.PathAndQuery;
+ request.RequestUri = new Uri(rewriteUriStr);
+ request.Headers.Host = "pbs.twimg.com";
+ }
}
return base.SendAsync(request, cancellationToken);
// 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.Linq;
}
public static OAuthEchoHandler CreateHandler(HttpMessageHandler innerHandler, Uri authServiceProvider,
- string consumerKey, string consumerSecret, string accessToken, string accessSecret, Uri realm = null)
+ string consumerKey, string consumerSecret, string accessToken, string accessSecret, Uri? realm = null)
{
var credential = OAuthUtility.CreateAuthorization("GET", authServiceProvider, null,
consumerKey, consumerSecret, accessToken, accessSecret, realm?.AbsoluteUri);
// 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.CodeAnalysis;
/// <summary>
/// OAuthの署名の対象となるパラメータを抽出します
/// </summary>
- internal static async Task<IEnumerable<KeyValuePair<string, string>>> GetParameters(Uri requestUri, HttpContent content)
+ internal static async Task<IEnumerable<KeyValuePair<string, string>>> GetParameters(Uri requestUri, HttpContent? content)
{
var parameters = Enumerable.Empty<KeyValuePair<string, string>>();
// 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.Linq;
/// <param name="token">アクセストークン、もしくはリクエストトークン。未取得なら空文字列</param>
/// <param name="tokenSecret">アクセストークンシークレット。認証処理では空文字列</param>
/// <param name="realm">realm (必要な場合のみ)</param>
- public static string CreateAuthorization(string httpMethod, Uri requestUri, IEnumerable<KeyValuePair<string, string>> query,
+ public static string CreateAuthorization(string httpMethod, Uri requestUri, IEnumerable<KeyValuePair<string, string>>? query,
string consumerKey, string consumerSecret, string token, string tokenSecret,
- string realm = null)
+ string? realm = null)
{
// OAuth共通情報取得
var parameter = GetOAuthParameter(consumerKey, token);
/// <param name="uri">アクセス先Uri</param>
/// <param name="parameter">クエリ、もしくはPOSTデータ</param>
/// <returns>署名文字列</returns>
- public static string CreateSignature(string consumerSecret, string tokenSecret, string method, Uri uri, Dictionary<string, string> parameter)
+ public static string CreateSignature(string consumerSecret, string? tokenSecret, string method, Uri uri, Dictionary<string, string> parameter)
{
// パラメタをソート済みディクショナリに詰替(OAuthの仕様)
var sorted = new SortedDictionary<string, string>(parameter);
// 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.IO;
public string AccessToken { get; }
public string AccessSecret { get; }
- internal HttpClient http;
- internal HttpClient httpUpload;
- internal HttpClient httpStreaming;
+ internal HttpClient http = null!;
+ internal HttpClient httpUpload = null!;
+ internal HttpClient httpStreaming = null!;
public TwitterApiConnection(string accessToken, string accessSecret)
{
this.httpStreaming.Timeout = Timeout.InfiniteTimeSpan;
}
- public async Task<T> GetAsync<T>(Uri uri, IDictionary<string, string> param, string endpointName)
+ public async Task<T> GetAsync<T>(Uri uri, IDictionary<string, string>? param, string? endpointName)
{
// レートリミット規制中はAPIリクエストを送信せずに直ちにエラーを発生させる
if (endpointName != null)
}
}
- public async Task<Stream> GetStreamAsync(Uri uri, IDictionary<string, string> param)
+ public async Task<Stream> GetStreamAsync(Uri uri, IDictionary<string, string>? param)
{
var requestUri = new Uri(RestApiBase, uri);
}
}
- public async Task<Stream> GetStreamingStreamAsync(Uri uri, IDictionary<string, string> param)
+ public async Task<Stream> GetStreamingStreamAsync(Uri uri, IDictionary<string, string>? param)
{
var requestUri = new Uri(RestApiBase, uri);
}
}
- public async Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string> param)
+ public async Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param)
{
var requestUri = new Uri(RestApiBase, uri);
var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
using var postContent = new FormUrlEncodedContent(param);
request.Content = postContent;
- HttpResponseMessage response = null;
+ HttpResponseMessage? response = null;
try
{
response = await this.http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
}
}
- public async Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string> param, IDictionary<string, IMediaItem> media)
+ public async Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string>? param, IDictionary<string, IMediaItem>? media)
{
var requestUri = new Uri(RestApiBase, uri);
var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
request.Content = postContent;
- HttpResponseMessage response = null;
+ HttpResponseMessage? response = null;
try
{
response = await this.httpUpload.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
}
}
- public async Task PostAsync(Uri uri, IDictionary<string, string> param, IDictionary<string, IMediaItem> media)
+ public async Task PostAsync(Uri uri, IDictionary<string, string>? param, IDictionary<string, IMediaItem>? media)
{
var requestUri = new Uri(RestApiBase, uri);
var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
using var postContent = new StringContent(json, Encoding.UTF8, "application/json");
request.Content = postContent;
- HttpResponseMessage response = null;
+ HttpResponseMessage? response = null;
try
{
response = await this.http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
}
}
- public OAuthEchoHandler CreateOAuthEchoHandler(Uri authServiceProvider, Uri realm = null)
+ public OAuthEchoHandler CreateOAuthEchoHandler(Uri authServiceProvider, Uri? realm = null)
{
var uri = new Uri(RestApiBase, authServiceProvider);
return (response["oauth_token"], response["oauth_token_secret"]);
}
- public static Uri GetAuthorizeUri((string Token, string TokenSecret) requestToken, string screenName = null)
+ public static Uri GetAuthorizeUri((string Token, string TokenSecret) requestToken, string? screenName = null)
{
var param = new Dictionary<string, string>
{
// 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.Drawing;
return mediaId;
}
- private async Task<long> UploadMediaItem(IMediaItem mediaItem, string mediaCategory)
+ private async Task<long> UploadMediaItem(IMediaItem mediaItem, string? mediaCategory)
{
- async Task<long> UploadInternal(IMediaItem media, string category)
+ async Task<long> UploadInternal(IMediaItem media, string? category)
{
var mediaId = await this.tw.UploadMedia(media, category)
.ConfigureAwait(false);
if (SettingManager.Common.AlphaPNGWorkaround && this.AddAlphaChannelIfNeeded(origImage.Image, out var newImage))
{
- using var newMediaItem = new MemoryImageMediaItem(newImage);
+ using var newMediaItem = new MemoryImageMediaItem(newImage!);
newMediaItem.AltText = mediaItem.AltText;
return await UploadInternal(newMediaItem, mediaCategory);
/// PNG 以外の画像や、すでにアルファチャンネルを持つ PNG 画像に対しては何もしません。
/// </remarks>
/// <returns>加工が行われた場合は true、そうでない場合は false</returns>
- private bool AddAlphaChannelIfNeeded(Image origImage, out MemoryImage newImage)
+ private bool AddAlphaChannelIfNeeded(Image origImage, out MemoryImage? newImage)
{
newImage = null;
// 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.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Globalization;
// 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.Linq;
{
private Rectangle changeBounds;
- public ContextMenuStrip ColumnHeaderContextMenuStrip { get; set; }
+ public ContextMenuStrip? ColumnHeaderContextMenuStrip { get; set; }
public event EventHandler VScrolled;
public event EventHandler HScrolled;
// 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.ComponentModel;
{
public partial class EventViewerDialog : OTBaseForm
{
- public List<Twitter.FormattedEvent> EventSource { get; set; }
+ public List<Twitter.FormattedEvent> EventSource { get; set; } = new List<Twitter.FormattedEvent>();
- private Twitter.FormattedEvent[] _filterdEventSource;
+ private Twitter.FormattedEvent[] _filterdEventSource = Array.Empty<Twitter.FormattedEvent>();
- private ListViewItem[] _ItemCache = null;
+ private ListViewItem[]? _ItemCache = null;
private int _itemCacheIndex;
- private TabPage _curTab = null;
+ private TabPage _curTab = null!;
public EventViewerDialog()
{
// 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.Globalization;
// 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.ComponentModel;
}
private EnableButtonMode _ruleEnableButtonMode = FilterDialog.EnableButtonMode.NotSelected;
- public TabModel SelectedTab
+ public TabModel? SelectedTab
=> this.selectedTabIndex != -1 ? this.tabs[this.selectedTabIndex] : null;
public FilterDialog()
if (rslt == DialogResult.Cancel) return;
var indices = ListFilters.SelectedIndices.Cast<int>().Reverse().ToArray(); // 後ろの要素から削除
- var tab = (FilterTabModel)this.SelectedTab;
+ var tab = (FilterTabModel)this.SelectedTab!;
using (ControlTransaction.Update(ListFilters))
{
return;
}
- var tab = (FilterTabModel)this.SelectedTab;
+ var tab = (FilterTabModel)this.SelectedTab!;
var i = ListFilters.SelectedIndex;
PostFilterRule ft;
if (e.KeyCode == Keys.Escape)
{
if (EditFilterGroup.Enabled)
- ButtonCancel_Click(null, null);
+ ButtonCancel_Click(this.ButtonCancel, EventArgs.Empty);
else
- ButtonClose_Click(null, null);
+ ButtonClose_Click(this.ButtonClose, EventArgs.Empty);
}
}
{
this.selectedTabIndex = this.ListTabs.SelectedIndex;
- if (ListTabs.SelectedIndex > -1)
- SetFilters(this.SelectedTab);
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null)
+ SetFilters(selectedTab);
else
ListFilters.Items.Clear();
}
private async void ButtonAddTab_Click(object sender, EventArgs e)
{
- string tabName = null;
+ string? tabName = null;
MyCommon.TabUsageType tabType;
using (var inputName = new InputTabName())
{
if (!string.IsNullOrEmpty(tabName))
{
//List対応
- ListElement list = null;
+ ListElement? list = null;
if (tabType == MyCommon.TabUsageType.Lists)
{
try
tab = new PublicSearchTabModel(tabName);
break;
case MyCommon.TabUsageType.Lists:
- tab = new ListTimelineTabModel(tabName, list);
+ tab = new ListTimelineTabModel(tabName, list!);
break;
default:
return;
private void ButtonDeleteTab_Click(object sender, EventArgs e)
{
- if (ListTabs.SelectedIndex > -1)
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null)
{
- var tb = this.SelectedTab.TabName;
+ var tb = selectedTab.TabName;
var idx = ListTabs.SelectedIndex;
if (((TweenMain)this.Owner).RemoveSpecifiedTab(tb, true))
{
private void ButtonRenameTab_Click(object sender, EventArgs e)
{
- if (ListTabs.SelectedIndex > -1)
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null)
{
- var origTabName = this.SelectedTab.TabName;
+ var origTabName = selectedTab.TabName;
if (((TweenMain)this.Owner).TabRename(origTabName, out _))
this.RefreshListTabs();
}
private void CheckManageRead_CheckedChanged(object sender, EventArgs e)
{
- if (ListTabs.SelectedIndex > -1)
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null)
{
((TweenMain)this.Owner).ChangeTabUnreadManage(
- this.SelectedTab.TabName,
+ selectedTab.TabName,
CheckManageRead.Checked);
}
}
private void CheckLocked_CheckedChanged(object sender, EventArgs e)
{
- if (ListTabs.SelectedIndex > -1)
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null)
{
- this.SelectedTab.Protected = CheckProtected.Checked;
+ selectedTab.Protected = CheckProtected.Checked;
ButtonDeleteTab.Enabled = !CheckProtected.Checked;
}
}
private void CheckNotifyNew_CheckedChanged(object sender, EventArgs e)
{
- if (ListTabs.SelectedIndex > -1)
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null)
{
- this.SelectedTab.Notify = CheckNotifyNew.Checked;
+ selectedTab.Notify = CheckNotifyNew.Checked;
}
}
private void ComboSound_SelectedIndexChanged(object sender, EventArgs e)
{
- if (ListTabs.SelectedIndex > -1)
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null)
{
var filename = "";
if (ComboSound.SelectedIndex > -1) filename = ComboSound.SelectedItem.ToString();
- this.SelectedTab.SoundFile = filename;
+ selectedTab.SoundFile = filename;
}
}
private void MoveSelectedRules(bool up)
{
- var tabIdx = ListTabs.SelectedIndex;
- if (tabIdx == -1 ||
- ListFilters.SelectedIndices.Count == 0) return;
+ var selectedTab = this.SelectedTab;
+ if (selectedTab == null || ListFilters.SelectedIndices.Count == 0)
+ return;
var indices = ListFilters.SelectedIndices.Cast<int>().ToArray();
}
var lastSelIdx = indices[0] + diff;
- var tab = (FilterTabModel)this.SelectedTab;
+ var tab = (FilterTabModel)selectedTab;
try
{
private void ButtonRuleCopy_Click(object sender, EventArgs e)
{
- if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null && ListFilters.SelectedItem != null)
{
- TabModel[] selectedTabs;
+ TabModel[] destinationTabs;
using (var dialog = new TabsDialog(_sts))
{
dialog.MultiSelect = true;
if (dialog.ShowDialog(this) == DialogResult.Cancel) return;
- selectedTabs = dialog.SelectedTabs;
+ destinationTabs = dialog.SelectedTabs;
}
- var currentTab = (FilterTabModel)this.SelectedTab;
+ var currentTab = (FilterTabModel)selectedTab;
var filters = new List<PostFilterRule>();
foreach (int idx in ListFilters.SelectedIndices)
{
filters.Add(currentTab.FilterArray[idx].Clone());
}
- foreach (var tb in selectedTabs.Cast<FilterTabModel>())
+ foreach (var tb in destinationTabs.Cast<FilterTabModel>())
{
if (tb.TabName == currentTab.TabName) continue;
tb.AddFilter(flt.Clone());
}
}
- SetFilters(this.SelectedTab);
+ SetFilters(selectedTab);
}
}
private void ButtonRuleMove_Click(object sender, EventArgs e)
{
- if (ListTabs.SelectedIndex > -1 && ListFilters.SelectedItem != null)
+ var selectedTab = this.SelectedTab;
+ if (selectedTab != null && ListFilters.SelectedItem != null)
{
- TabModel[] selectedTabs;
+ TabModel[] destinationTabs;
using (var dialog = new TabsDialog(_sts))
{
dialog.MultiSelect = true;
if (dialog.ShowDialog(this) == DialogResult.Cancel) return;
- selectedTabs = dialog.SelectedTabs;
+ destinationTabs = dialog.SelectedTabs;
}
- var currentTab = (FilterTabModel)this.SelectedTab;
+ var currentTab = (FilterTabModel)selectedTab;
var filters = new List<PostFilterRule>();
foreach (int idx in ListFilters.SelectedIndices)
{
filters.Add(currentTab.FilterArray[idx].Clone());
}
- if (selectedTabs.Length == 1 && selectedTabs[0].TabName == currentTab.TabName) return;
- foreach (var tb in selectedTabs.Cast<FilterTabModel>())
+ if (destinationTabs.Length == 1 && destinationTabs[0].TabName == currentTab.TabName) return;
+ foreach (var tb in destinationTabs.Cast<FilterTabModel>())
{
if (tb.TabName == currentTab.TabName) continue;
ListFilters.Items.RemoveAt(idx);
}
}
- SetFilters(this.SelectedTab);
+ SetFilters(selectedTab);
}
}
// 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.Linq;
{
public class GrowlHelper
{
- private Assembly _connector = null;
- private Assembly _core = null;
+ private Assembly? _connector = null;
+ private Assembly? _core = null;
- private object _growlNTreply;
- private object _growlNTdm;
- private object _growlNTnew;
- private object _growlNTusevent;
- private object _growlApp;
+ private object? _growlNTreply;
+ private object? _growlNTdm;
+ private object? _growlNTnew;
+ private object? _growlNTusevent;
+ private object? _growlApp;
- private object _targetConnector;
+ private object? _targetConnector;
bool _initialized = false;
public class NotifyCallbackEventArgs : EventArgs
return true;
}
- public void Notify(NotifyType notificationType, string id, string title, string text, Image icon = null, string url = "")
+ public void Notify(NotifyType notificationType, string id, string title, string text, Image? icon = null, string url = "")
{
if (!_initialized) return;
var notificationName = "";
notificationName = "USERSTREAM_EVENT";
break;
}
- object n;
+ object? n;
if (icon != null || !string.IsNullOrEmpty(url))
{
- var gCore = _core.GetType("Growl.CoreLibrary.Resource");
- object res;
+ var gCore = _core!.GetType("Growl.CoreLibrary.Resource");
+ object? res;
if (icon != null)
{
res = gCore.InvokeMember("op_Implicit",
CultureInfo.InvariantCulture);
}
var priority =
- _connector.GetType("Growl.Connector.Priority").InvokeMember(
+ _connector!.GetType("Growl.Connector.Priority").InvokeMember(
"Normal", BindingFlags.GetField, null, null, null, CultureInfo.InvariantCulture);
- n = _connector.GetType("Growl.Connector.Notification").InvokeMember(
+ n = _connector!.GetType("Growl.Connector.Notification").InvokeMember(
"Notification",
BindingFlags.CreateInstance,
null,
}
else
{
- n = _connector.GetType("Growl.Connector.Notification").InvokeMember(
+ n = _connector!.GetType("Growl.Connector.Notification").InvokeMember(
"Notification",
BindingFlags.CreateInstance,
null,
null, BindingFlags.CreateInstance, null, _connector,
new object[] { "some fake information", notificationName },
CultureInfo.InvariantCulture);
- _targetConnector.GetType().InvokeMember("Notify", BindingFlags.InvokeMethod, null, _targetConnector, new object[] { n, cc }, CultureInfo.InvariantCulture);
+ _targetConnector!.GetType().InvokeMember("Notify", BindingFlags.InvokeMethod, null, _targetConnector, new object[] { n, cc }, CultureInfo.InvariantCulture);
}
private void GrowlCallbackHandler(object response, object callbackData, object state)
{
// 定数取得
var vCLICK =
- _core.GetType("Growl.CoreLibrary.CallbackResult").GetField(
+ _core!.GetType("Growl.CoreLibrary.CallbackResult").GetField(
"CLICK",
BindingFlags.Public | BindingFlags.Static).GetRawConstantValue();
// 実際の値
// 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.ComponentModel;
foreach (var l in list)
{
- var src = l as string;
+ var src = (string)l;
if (string.IsNullOrEmpty(src))
{
idx += 1;
}
private void HistoryHashList_DoubleClick(object sender, EventArgs e)
- => this.OK_Button_Click(null, null);
+ => this.OK_Button_Click(this.OK_Button, EventArgs.Empty);
public void ToggleHash()
{
private void HistoryHashList_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
- this.DeleteButton_Click(null, null);
+ this.DeleteButton_Click(this.DeleteButton, EventArgs.Empty);
else if (e.KeyCode == Keys.Insert)
- this.AddButton_Click(null, null);
+ this.AddButton_Click(this.AddButton, EventArgs.Empty);
}
private bool AdjustHashtags(ref string hashtag, bool isShowWarn)
{
e.Handled = true;
if (this.GroupDetail.Enabled)
- this.PermOK_Button_Click(null, null);
+ this.PermOK_Button_Click(this.PermOK_Button, EventArgs.Empty);
else
- this.OK_Button_Click(null, null);
+ this.OK_Button_Click(this.OK_Button, EventArgs.Empty);
}
else if (e.KeyCode == Keys.Escape)
{
e.Handled = true;
if (this.GroupDetail.Enabled)
- this.PermCancel_Button_Click(null, null);
+ this.PermCancel_Button_Click(this.PermCancel_Button, EventArgs.Empty);
else
- this.Cancel_Button_Click(null, null);
+ this.Cancel_Button_Click(this.Cancel_Button, EventArgs.Empty);
}
}
// 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.Linq;
// 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.Linq;
if (cachedImageTask != null)
{
if (force)
- {
this.innerDictionary.Remove(address);
- cachedImageTask = null;
- }
else
return cachedImageTask;
}
.ConfigureAwait(false);
}
- public MemoryImage TryGetFromCache(string address)
+ public MemoryImage? TryGetFromCache(string address)
{
lock (this.lockObject)
{
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Net.Http;
using System.Runtime.Serialization;
[Serializable]
public class ImageListViewItem : ListViewItem
{
- protected readonly ImageCache imageCache;
- protected readonly string imageUrl;
+ protected readonly ImageCache? imageCache;
+ protected readonly string? imageUrl;
/// <summary>
/// 状態表示に使用するアイコンのインデックスを取得・設定する。
public int StateIndex { get; set; }
private readonly WeakReference imageReference = new WeakReference(null);
- private Task imageTask = null;
+ private Task? imageTask = null;
public event EventHandler ImageDownloaded;
{
}
- public ImageListViewItem(string[] items, ImageCache imageCache, string imageUrl)
+ public ImageListViewItem(string[] items, ImageCache? imageCache, string? imageUrl)
: base(items)
{
this.imageCache = imageCache;
this.imageUrl = imageUrl;
this.StateIndex = -1;
- var image = imageCache?.TryGetFromCache(imageUrl);
+ var image = imageUrl != null ? imageCache?.TryGetFromCache(imageUrl) : null;
if (image != null)
this.imageReference.Target = image;
private async Task GetImageAsyncInternal(bool force)
{
- if (string.IsNullOrEmpty(this.imageUrl))
+ if (string.IsNullOrEmpty(this.imageUrl) || this.imageCache == null)
return;
if (!force && this.imageReference.Target != null)
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections;
using System.Collections.Generic;
// 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.ComponentModel;
public static DialogResult Show(string text, out string inputText)
=> Show(null, text, "", out inputText);
- public static DialogResult Show(IWin32Window owner, string text, out string inputText)
+ public static DialogResult Show(IWin32Window? owner, string text, out string inputText)
=> Show(owner, text, "", out inputText);
public static DialogResult Show(string text, string caption, out string inputText)
=> Show(null, text, caption, out inputText);
- public static DialogResult Show(IWin32Window owner, string text, string caption, out string inputText)
+ public static DialogResult Show(IWin32Window? owner, string text, string caption, out string inputText)
{
using var dialog = new InputDialog();
dialog.labelMain.Text = text;
// 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.ComponentModel;
// 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.Linq;
using System.Text;
using System.Collections;
+using System.Diagnostics.CodeAnalysis;
namespace OpenTween
{
{
if (!this.innerDict.TryGetValue(item.Key, out var node)) return false;
- return node.Value.Value.Equals(item.Value);
+ return EqualityComparer<TValue>.Default.Equals(node.Value.Value, item.Value);
}
public bool Remove(TKey key)
{
if (!this.innerDict.TryGetValue(item.Key, out var node)) return false;
- if (!node.Value.Value.Equals(item.Value)) return false;
+ if (!EqualityComparer<TValue>.Default.Equals(node.Value.Value, item.Value))
+ return false;
this.innerList.Remove(node);
return this.innerDict.Remove(item.Key);
}
- public bool TryGetValue(TKey key, out TValue value)
+ public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
{
var ret = this.innerDict.TryGetValue(key, out var node);
if (!ret)
{
- value = default;
+ value = default!;
return false;
}
// 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.ComponentModel;
{
public partial class ListAvailable : OTBaseForm
{
- public ListElement SelectedList { get; private set; }
+ public ListElement? SelectedList { get; private set; }
public ListAvailable()
=> this.InitializeComponent();
private void ListsList_SelectedIndexChanged(object sender, EventArgs e)
{
- ListElement lst;
+ ListElement? lst;
if (this.ListsList.SelectedIndex > -1)
{
lst = (ListElement)this.ListsList.SelectedItem;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Xml.Serialization;
public string Username = "";
public string Nickname = "";
- protected Twitter _tw;
+ protected Twitter _tw = null!;
- private List<UserInfo> _members = null;
+ private List<UserInfo> _members = new List<UserInfo>();
[XmlIgnore]
public long Cursor { get; private set; } = -1;
[XmlIgnore]
public List<UserInfo> Members
- {
- get
- {
- if (this._members == null) this._members = new List<UserInfo>();
- return this._members;
- }
- }
+ => this._members;
public async Task RefreshMembers()
{
// 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.ComponentModel;
}
this.ListsList.Items.Clear();
- this.ListManage_Load(null, EventArgs.Empty);
+ this.ListManage_Load(this, EventArgs.Empty);
this.EditCheckBox.AutoCheck = true;
this.EditCheckBox.Checked = false;
}
this.DeleteUserButton.Enabled = true;
- await this.LoadUserIconAsync(user.ImageUrl, user.Id);
+ if (user.ImageUrl != null)
+ await this.LoadUserIconAsync(user.ImageUrl, user.Id);
}
}
// 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.ComponentModel;
public string LoginName => this.textboxLoginName.Text;
public string Password => this.textboxPassword.Text;
- public Func<Task<bool>> LoginCallback { get; set; } = null;
+ public Func<Task<bool>>? LoginCallback { get; set; } = null;
public bool LoginSuccessed { get; set; } = false;
public LoginDialog()
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Drawing;
using System.IO;
/// <summary>
/// 代替テキスト (アップロード先が対応している必要がある)
/// </summary>
- string AltText { get; set; }
+ string? AltText { get; set; }
/// <summary>
/// 表示用の MemoryImage を作成する
public class FileMediaItem : IMediaItem
{
public FileInfo FileInfo { get; }
- public string AltText { get; set; }
+ public string? AltText { get; set; }
public FileMediaItem(string path)
=> this.FileInfo = new FileInfo(path);
}
public string Path { get; }
- public string AltText { get; set; }
+ public string? AltText { get; set; }
public string Name
=> this.Path.Substring(PathPrefix.Length);
public Stream OpenRead()
{
- MemoryStream memstream = null;
+ MemoryStream? memstream = null;
try
{
// コピーを作成する
// 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.ComponentModel;
using System.Windows.Forms;
using OpenTween.Api.DataModel;
using OpenTween.Connection;
+using System.Diagnostics.CodeAnalysis;
namespace OpenTween
{
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public OpenFileDialog FilePickDialog { get; set; }
+ public OpenFileDialog? FilePickDialog { get; set; }
/// <summary>
/// 選択されている投稿先名を取得する。
/// </summary>
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public IMediaUploadService SelectedService
+ public IMediaUploadService? SelectedService
{
get
{
private class SelectedMedia
{
- public IMediaItem Item { get; set; }
+ public IMediaItem? Item { get; set; }
public MyCommon.UploadFileType Type { get; set; }
public string Text { get; set; }
- public SelectedMedia(IMediaItem item, MyCommon.UploadFileType type, string text)
+ public SelectedMedia(IMediaItem? item, MyCommon.UploadFileType type, string text)
{
this.Item = item;
this.Type = type;
=> this.Text;
}
- private Dictionary<string, IMediaUploadService> pictureService;
+ private Dictionary<string, IMediaUploadService> pictureService = new Dictionary<string, IMediaUploadService>();
private void CreateServices(Twitter tw, TwitterConfiguration twitterConfig)
{
this.pictureService?.Clear();
- this.pictureService = null;
this.pictureService = new Dictionary<string, IMediaUploadService> {
["Twitter"] = new TwitterPhoto(tw, twitterConfig),
/// <summary>
/// 選択された投稿先名と投稿する MediaItem を取得する。MediaItem は不要になったら呼び出し側にて破棄すること。
/// </summary>
- public bool TryGetSelectedMedia(out string imageService, out IMediaItem[] mediaItems)
+ public bool TryGetSelectedMedia([NotNullWhen(true)] out string? imageService, [NotNullWhen(true)] out IMediaItem[]? mediaItems)
{
var validItems = ImagePageCombo.Items.Cast<SelectedMedia>()
.Where(x => x.IsValid).Select(x => x.Item).OfType<IMediaItem>().ToArray();
return false;
}
- private MemoryImageMediaItem CreateMemoryImageMediaItem(Image image, bool noMsgBox)
+ private MemoryImageMediaItem? CreateMemoryImageMediaItem(Image image, bool noMsgBox)
{
if (image == null) return null;
- MemoryImage memoryImage = null;
+ MemoryImage? memoryImage = null;
try
{
// image から png 形式の MemoryImage を生成
}
}
- private IMediaItem CreateFileMediaItem(string path, bool noMsgBox)
+ private IMediaItem? CreateFileMediaItem(string path, bool noMsgBox)
{
if (string.IsNullOrEmpty(path)) return null;
ImageFromSelectedFile(item, noMsgBox);
}
- private void DisposeMediaItem(IMediaItem item)
+ private void DisposeMediaItem(IMediaItem? item)
{
var disposableItem = item as IDisposable;
disposableItem?.Dispose();
ValidateNewFileMediaItem(ImagefilePathText.Text.Trim(), AlternativeTextBox.Text.Trim(), false);
}
- private void ImageFromSelectedFile(IMediaItem item, bool noMsgBox)
+ private void ImageFromSelectedFile(IMediaItem? item, bool noMsgBox)
=> this.ImageFromSelectedFile(-1, item, noMsgBox);
- private void ImageFromSelectedFile(int index, IMediaItem item, bool noMsgBox)
+ private void ImageFromSelectedFile(int index, IMediaItem? item, bool noMsgBox)
{
var valid = false;
}
private void UpdateAltTextPanelVisible()
- => this.AlternativeTextPanel.Visible = this.SelectedService.CanUseAltText;
+ => this.AlternativeTextPanel.Visible = this.SelectedService switch
+ {
+ null => false,
+ var service => service.CanUseAltText,
+ };
private void ImageServiceCombo_SelectedIndexChanged(object sender, EventArgs e)
{
this.SelectedServiceChanged?.Invoke(this, EventArgs.Empty);
}
- private void SetImagePageCombo(SelectedMedia media = null)
+ private void SetImagePageCombo(SelectedMedia? media = null)
{
using (ControlTransaction.Update(ImagePageCombo))
{
// 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.Linq;
return Convert.ToBase64String(hash).GetHashCode();
}
- public override bool Equals(object other)
+ public override bool Equals(object? other)
=> this.Equals(other as MemoryImage);
- public bool Equals(MemoryImage other)
+ public bool Equals(MemoryImage? other)
{
if (object.ReferenceEquals(this, other))
return true;
/// <exception cref="InvalidImageException">不正な画像データが入力された場合</exception>
public static MemoryImage CopyFromStream(Stream stream)
{
- MemoryStream memstream = null;
+ MemoryStream? memstream = null;
try
{
memstream = new MemoryStream();
/// <exception cref="InvalidImageException">不正な画像データが入力された場合</exception>
public async static Task<MemoryImage> CopyFromStreamAsync(Stream stream)
{
- MemoryStream memstream = null;
+ MemoryStream? memstream = null;
try
{
memstream = new MemoryStream();
/// <exception cref="InvalidImageException">不正な画像データが入力された場合</exception>
public static MemoryImage CopyFromBytes(byte[] bytes)
{
- MemoryStream memstream = null;
+ MemoryStream? memstream = null;
try
{
memstream = new MemoryStream(bytes);
/// <returns>作成された MemoryImage</returns>
public static MemoryImage CopyFromImage(Image image)
{
- MemoryStream memstream = null;
+ MemoryStream? memstream = null;
try
{
memstream = new MemoryStream();
// 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.Linq;
// 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.Linq;
// 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.Linq;
// 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.ComponentModel;
public override Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress<string> progress)
{
- var homeTab = TabInformations.GetInstance().GetTabByType<HomeTabModel>();
+ var homeTab = TabInformations.GetInstance().HomeTab;
return homeTab.RefreshAsync(tw, backward, startup, progress);
}
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
namespace OpenTween.Models
{
bool Contains(string tabName);
- bool TryGetValue(string tabName, out TabModel tab);
+ bool TryGetValue(string tabName, [NotNullWhen(true)] out TabModel? tab);
}
}
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
// 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.Linq;
// 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.Linq;
// 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.Linq;
public class MediaInfo
{
public string Url { get; }
- public string AltText { get; }
- public string VideoUrl { get; }
+ public string? AltText { get; }
+ public string? VideoUrl { get; }
public MediaInfo(string url)
: this(url, altText: null, videoUrl: null)
{
}
- public MediaInfo(string url, string altText, string videoUrl)
+ public MediaInfo(string url, string? altText, string? videoUrl)
{
this.Url = url;
this.AltText = altText;
this.VideoUrl = !string.IsNullOrEmpty(videoUrl) ? videoUrl : null;
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> obj is MediaInfo info && info.Url == this.Url && info.VideoUrl == this.VideoUrl;
public override int GetHashCode()
// 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.Linq;
// 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.Linq;
// 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.CodeAnalysis;
using System.Linq;
using System.Net;
using System.Text;
public static bool operator !=(StatusGeo left, StatusGeo right)
=> !left.Equals(right);
}
- public string Nickname { get; set; }
- public string TextFromApi { get; set; }
+
+ public string Nickname { get; set; } = "";
+ public string TextFromApi { get; set; } = "";
/// <summary>スクリーンリーダーでの読み上げを考慮したテキスト</summary>
- public string AccessibleText { get; set; }
+ public string AccessibleText { get; set; } = "";
- public string ImageUrl { get; set; }
- public string ScreenName { get; set; }
+ public string ImageUrl { get; set; } = "";
+ public string ScreenName { get; set; } = "";
public DateTimeUtc CreatedAt { get; set; }
public long StatusId { get; set; }
private bool _IsFav;
}
set => this._text = value;
}
- private string _text;
+ private string _text = "";
public bool IsRead { get; set; }
public bool IsReply { get; set; }
private bool _IsProtect;
public bool IsOwl { get; set; }
private bool _IsMark;
- public string InReplyToUser { get; set; }
+ public string? InReplyToUser { get; set; }
private long? _InReplyToStatusId;
- public string Source { get; set; }
- public Uri SourceUri { get; set; }
+ public string Source { get; set; } = "";
+ public Uri? SourceUri { get; set; }
public List<(long UserId, string ScreenName)> ReplyToList { get; set; }
public bool IsMe { get; set; }
public bool IsDm { get; set; }
public long UserId { get; set; }
public bool FilterHit { get; set; }
- public string RetweetedBy { get; set; }
+ public string? RetweetedBy { get; set; }
public long? RetweetedId { get; set; }
private bool _IsDeleted = false;
private StatusGeo? _postGeo = null;
public PostClass()
{
- RetweetedBy = "";
Media = new List<MediaInfo>();
ReplyToList = new List<(long, string)>();
QuoteStatusIds = Array.Empty<long>();
}
public string TextSingleLine
- => this.TextFromApi?.Replace("\n", " ");
+ => this.TextFromApi.Replace("\n", " ");
public bool IsFav
{
}
}
- protected virtual PostClass RetweetSource
- => TabInformations.GetInstance().RetweetSource(this.RetweetedId.Value);
+ protected virtual PostClass? RetweetSource
+ => this.RetweetedId != null ? TabInformations.GetInstance().RetweetSource(this.RetweetedId.Value) : null;
public StatusGeo? PostGeo
{
object ICloneable.Clone()
=> this.Clone();
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (obj == null || this.GetType() != obj.GetType()) return false;
return this.Equals((PostClass)obj);
}
- public bool Equals(PostClass other)
+ public bool Equals(PostClass? other)
{
if (other == null) return false;
return (this.Nickname == other.Nickname) &&
// 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.ComponentModel;
/// コンパイルされた振り分けルール
/// </summary>
[XmlIgnore]
- protected Func<PostClass, MyCommon.HITRESULT> FilterDelegate;
+ protected Func<PostClass, MyCommon.HITRESULT>? FilterDelegate;
/// <summary>
/// 振り分けルールの概要
private bool _enabled;
[XmlElement("NameFilter")]
- public string FilterName
+ public string? FilterName
{
get => this._FilterName;
set => this.SetProperty(ref this._FilterName, value);
}
- private string _FilterName;
+ private string? _FilterName;
[XmlElement("ExNameFilter")]
- public string ExFilterName
+ public string? ExFilterName
{
get => this._ExFilterName;
set => this.SetProperty(ref this._ExFilterName, value);
}
- private string _ExFilterName;
+ private string? _ExFilterName;
[XmlArray("BodyFilterArray")]
public string[] FilterBody
private bool _ExFilterRt;
[XmlElement("Source")]
- public string FilterSource
+ public string? FilterSource
{
get => this._FilterSource;
set => this.SetProperty(ref this._FilterSource, value);
}
- private string _FilterSource;
+ private string? _FilterSource;
[XmlElement("ExSource")]
- public string ExFilterSource
+ public string? ExFilterSource
{
get => this._ExFilterSource;
set => this.SetProperty(ref this._ExFilterSource, value);
}
- private string _ExFilterSource;
+ private string? _ExFilterSource;
public PostFilterRule()
{
this.IsDirty = false;
}
- protected virtual Expression MakeFiltersExpr(
+ protected virtual Expression? MakeFiltersExpr(
ParameterExpression postParam,
- string filterName, string[] filterBody, string filterSource, bool filterRt,
+ string? filterName, string[] filterBody, string? filterSource, bool filterRt,
bool useRegex, bool caseSensitive, bool useNameField, bool useLambda, bool filterByUrl)
{
var filterExprs = new List<Expression>();
this.Compile();
}
- return this.FilterDelegate(post);
+ return this.FilterDelegate!(post);
}
public PostFilterRule Clone()
!string.IsNullOrEmpty(this.ExFilterSource) ||
this.ExFilterRt;
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> this.Equals(obj as PostFilterRule);
- public bool Equals(PostFilterRule other)
+ public bool Equals(PostFilterRule? other)
{
if (other == null)
return false;
// 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.Linq;
// 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.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System.Collections.ObjectModel;
+using System.Diagnostics.CodeAnalysis;
namespace OpenTween.Models
{
public int IndexOf(string tabName)
=> this.IndexOf(this[tabName]);
- public bool TryGetValue(string tabName, out TabModel tab)
+ public bool TryGetValue(string tabName, [NotNullWhen(true)] out TabModel? tab)
=> this.Dictionary.TryGetValue(tabName, out tab);
protected override string GetKeyForItem(TabModel tab)
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
public IReadOnlyTabCollection Tabs
=> this.tabs;
- public MuteTabModel MuteTab { get; private set; }
+ public MuteTabModel MuteTab { get; private set; } = new MuteTabModel();
public ConcurrentDictionary<long, PostClass> Posts { get; } = new ConcurrentDictionary<long, PostClass>();
get => this._lists;
set
{
- if (value != null && value.Count > 0)
+ if (value.Count > 0)
{
foreach (var tb in this.GetTabsByType<ListTimelineTabModel>())
{
{
if (tab is MuteTabModel muteTab)
{
- if (this.MuteTab != null)
- return false;
-
this.MuteTab = muteTab;
return true;
}
lock (LockObj)
{
var tb = GetTabByName(TabName);
- if (tb.IsDefaultTabType) return; //念のため
+ if (tb == null || tb.IsDefaultTabType) return; //念のため
if (!tb.IsInnerStorageTabType)
{
- var homeTab = GetTabByType(MyCommon.TabUsageType.Home);
- var dmTab = GetTabByType(MyCommon.TabUsageType.DirectMessage);
+ var homeTab = this.HomeTab;
+ var dmTab = this.DirectMessageTab;
for (var idx = 0; idx < tb.AllCount; ++idx)
{
// }
// }
// }
- public PostClass RetweetSource(long Id)
+ public PostClass? RetweetSource(long Id)
=> this.Posts.TryGetValue(Id, out var status) ? status : null;
public void ScrubGeoReserve(long id, long upToStatusId)
{
lock (this.LockObj)
{
- var homeTab = this.GetTabByType(MyCommon.TabUsageType.Home);
- var replyTab = this.GetTabByType(MyCommon.TabUsageType.Mentions);
- var favTab = this.GetTabByType(MyCommon.TabUsageType.Favorites);
+ var homeTab = this.HomeTab;
+ var replyTab = this.MentionTab;
+ var favTab = this.FavoriteTab;
var distributableTabs = this.GetTabsByType<FilterTabModel>()
.ToArray();
private int UpdateRetweetCount(PostClass retweetPost)
{
+ if (retweetPost.RetweetedId == null)
+ throw new InvalidOperationException();
+
var retweetedId = retweetPost.RetweetedId.Value;
return this.retweetsCount.AddOrUpdate(retweetedId, 1, (k, v) => v >= 10 ? 1 : v + 1);
/// </summary>
public void SetReadHomeTab()
{
- var homeTab = this.GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.HomeTab;
lock (LockObj)
{
}
}
- public PostClass this[long ID]
+ public PostClass? this[long ID]
{
get
{
{
lock (LockObj)
{
- var homeTab = GetTabByType(MyCommon.TabUsageType.Home);
+ var homeTab = this.HomeTab;
var detachedIdsAll = Enumerable.Empty<long>();
foreach (var tab in this.Tabs.OfType<FilterTabModel>().ToArray())
}
}
- public TabModel GetTabByType(MyCommon.TabUsageType tabType)
+ public HomeTabModel HomeTab
+ => this.GetTabByType<HomeTabModel>()!;
+
+ public DirectMessagesTabModel DirectMessageTab
+ => this.GetTabByType<DirectMessagesTabModel>()!;
+
+ public MentionsTabModel MentionTab
+ => this.GetTabByType<MentionsTabModel>()!;
+
+ public FavoritesTabModel FavoriteTab
+ => this.GetTabByType<FavoritesTabModel>()!;
+
+ public TabModel? GetTabByType(MyCommon.TabUsageType tabType)
{
//Home,Mentions,DM,Favは1つに制限する
//その他のタイプを指定されたら、最初に合致したものを返す
}
}
- public T GetTabByType<T>() where T : TabModel
+ public T? GetTabByType<T>() where T : TabModel
{
lock (this.LockObj)
return this.Tabs.OfType<T>().FirstOrDefault();
}
}
- public TabModel GetTabByName(string tabName)
+ public TabModel? GetTabByName(string tabName)
{
lock (LockObj)
{
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
public PostClass[] SelectedPosts
=> this.selectedStatusIds.Select(x => this.Posts[x]).ToArray();
- public PostClass SelectedPost
+ public PostClass? SelectedPost
=> this.selectedStatusIds.Select(x => this.Posts[x]).FirstOrDefault();
public int SelectedIndex
{
default:
case ComparerMode.Data:
- postComparison = (x, y) => Comparer<string>.Default.Compare(x?.TextFromApi, y?.TextFromApi);
+ postComparison = (x, y) => Comparer<string?>.Default.Compare(x?.TextFromApi, y?.TextFromApi);
break;
case ComparerMode.Name:
- postComparison = (x, y) => Comparer<string>.Default.Compare(x?.ScreenName, y?.ScreenName);
+ postComparison = (x, y) => Comparer<string?>.Default.Compare(x?.ScreenName, y?.ScreenName);
break;
case ComparerMode.Nickname:
- postComparison = (x, y) => Comparer<string>.Default.Compare(x?.Nickname, y?.Nickname);
+ postComparison = (x, y) => Comparer<string?>.Default.Compare(x?.Nickname, y?.Nickname);
break;
case ComparerMode.Source:
- postComparison = (x, y) => Comparer<string>.Default.Compare(x?.Source, y?.Source);
+ postComparison = (x, y) => Comparer<string?>.Default.Compare(x?.Source, y?.Source);
break;
}
// 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.Linq;
// 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.Linq;
// 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.Drawing;
// 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.Linq;
//}
}
- public static readonly object Block = null;
+ public static readonly object? Block = null;
public static bool TraceFlag = false;
#if DEBUG
}
}
- private static void OpenErrorReportDialog(Form owner, ErrorReport report)
+ private static void OpenErrorReportDialog(Form? owner, ErrorReport report)
{
if (owner != null && owner.InvokeRequired)
{
/// </summary>
/// <param name="inputUrl">展開対象のURL</param>
/// <returns>IDNが含まれていた場合はPunycodeに展開したURLをを返します。Punycode展開時にエラーが発生した場合はnullを返します。</returns>
- public static string IDNEncode(string inputUrl)
+ public static string? IDNEncode(string inputUrl)
{
try
{
des.Key = ResizeBytesArray(bytesKey, des.Key.Length);
des.IV = ResizeBytesArray(bytesKey, des.IV.Length);
- MemoryStream msOut = null;
- ICryptoTransform desdecrypt = null;
+ MemoryStream? msOut = null;
+ ICryptoTransform? desdecrypt = null;
try
{
//Base64で文字列をバイト配列に戻す
var bytesIn = Convert.FromBase64String(str);
- MemoryStream msIn = null;
- ICryptoTransform desdecrypt = null;
- CryptoStream cryptStreem = null;
+ MemoryStream? msIn = null;
+ ICryptoTransform? desdecrypt = null;
+ CryptoStream? cryptStreem = null;
try
{
public static bool IsAnimatedGif(string filename)
{
- Image img = null;
+ Image? img = null;
try
{
img = Image.FromFile(filename);
/// <returns>
/// 生成されたバージョン番号の文字列
/// </returns>
- public static string GetReadableVersion(string versionStr = null)
+ public static string GetReadableVersion(string? versionStr = null)
{
var version = Version.Parse(versionStr ?? MyCommon.FileVersion);
// 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.ComponentModel;
{
public partial class MyLists : OTBaseForm
{
- private readonly TwitterApi twitterApi;
- private readonly string contextScreenName;
+ private readonly TwitterApi twitterApi = null!;
+ private readonly string contextScreenName = null!;
/// <summary>自分が所有しているリスト</summary>
private ListElement[] ownedLists = Array.Empty<ListElement>();
this.twitterApi.ListsOwnerships(this.twitterApi.CurrentScreenName, cursor: x, count: 1000))
.ConfigureAwait(false);
- this.ownedLists = ownedListData.Select(x => new ListElement(x, null)).ToArray();
+ this.ownedLists = ownedListData.Select(x => new ListElement(x, null!)).ToArray();
var listsUserAddedTo = await TwitterLists.GetAllItemsAsync(x =>
this.twitterApi.ListsMemberships(this.contextScreenName, cursor: x, count: 1000, filterToOwnedLists: true))
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.ComponentModel;
using System.Diagnostics;
private struct InternetProxyInfo
{
public InternetOpenType dwAccessType;
- public string proxy;
- public string proxyBypass;
+ public string? proxy;
+ public string? proxyBypass;
}
private enum InternetOpenType
PROXY = 3, // Custom
}
- private static void RefreshProxySettings(string strProxy)
+ private static void RefreshProxySettings(string? strProxy)
{
InternetProxyInfo ipi;
public static void SetProxy(ProxyType pType, string host, int port)
{
- string proxy = null;
+ string? proxy = null;
switch (pType)
{
case ProxyType.IE:
// 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.ComponentModel;
--- /dev/null
+// OpenTween - Client of Twitter
+// Copyright (c) 2019 kim_upsilon (@kim_upsilon) <https://upsilo.net/~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 <http://www.gnu.org/licenses/>, or write to
+// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
+// Boston, MA 02110-1301, USA.
+
+#nullable enable
+
+namespace System.Diagnostics.CodeAnalysis
+{
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class NotNullWhenAttribute : Attribute
+ {
+ public bool ReturnValue { get; }
+
+ public NotNullWhenAttribute(bool returnValue)
+ => this.ReturnValue = returnValue;
+ }
+
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ internal sealed class MaybeNullWhenAttribute : Attribute
+ {
+ public bool ReturnValue { get; }
+
+ public MaybeNullWhenAttribute(bool returnValue)
+ => this.ReturnValue = returnValue;
+ }
+}
// 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.ComponentModel;
/// <remarks>
/// SettingLocal.xml に FontUIGlobalStr 要素を追加する事で変更できます
/// </remarks>
- public static Font GlobalFont { get; set; }
+ public static Font? GlobalFont { get; set; }
/// <summary>
/// デザイン時のスケールと現在のスケールの比
// 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.Linq;
{
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public new MemoryImage Image
+ public new MemoryImage? Image
{
get => this.memoryImage;
set
this.RestoreSizeMode();
}
}
- private MemoryImage memoryImage;
+ private MemoryImage? memoryImage;
[Localizable(true)]
[DefaultValue(PictureBoxSizeMode.Normal)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- public new string ImageLocation
+ public new string? ImageLocation
{
get => null;
set { }
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Windows.Forms;
using System.Collections.Generic;
<Compile Include="Models\UserTimelineTabModel.cs" />
<Compile Include="MouseWheelMessageFilter.cs" />
<Compile Include="NotifyPropertyChangedBase.cs" />
+ <Compile Include="NullableAttributes.cs" />
<Compile Include="PostStatusParams.cs" />
<Compile Include="ReaderWriterLockTransaction.cs" />
<Compile Include="SendErrorReportForm.cs">
// 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.ComponentModel;
{
public partial class OpenURL : OTBaseForm
{
- private string _selUrl;
+ private string? _selUrl;
public OpenURL()
=> this.InitializeComponent();
get
{
if (UrlList.SelectedItems.Count == 1)
- return _selUrl;
+ return _selUrl!;
else
return "";
}
if (e.Control && e.KeyCode == Keys.Oem4)
{
e.SuppressKeyPress = true;
- Cancel_Button_Click(null, null);
+ Cancel_Button_Click(this.Cancel_Button, EventArgs.Empty);
}
}
}
// 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.Linq;
{
public class PostStatusParams
{
- public string Text { get; set; }
+ public string Text { get; set; } = "";
public long? InReplyToStatusId { get; set; }
- public IReadOnlyList<long> MediaIds { get; set; }
+ public IReadOnlyList<long> MediaIds { get; set; } = Array.Empty<long>();
public bool AutoPopulateReplyMetadata { get; set; }
- public IReadOnlyList<long> ExcludeReplyUserIds { get; set; }
- public string AttachmentUrl { get; set; }
+ public IReadOnlyList<long> ExcludeReplyUserIds { get; set; } = Array.Empty<long>();
+ public string? AttachmentUrl { get; set; }
}
}
// 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.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
// 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.ComponentModel;
}
}
- private SearchOptions resultOptoins = null;
- public SearchOptions ResultOptions
+ private SearchOptions? resultOptions = null;
+ public SearchOptions? ResultOptions
{
- get => this.resultOptoins;
+ get => this.resultOptions;
set
{
- this.resultOptoins = value;
+ this.resultOptions = value;
if (value == null)
{
// 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.ComponentModel;
this.bindingSource.DataSource = value;
}
}
- private ErrorReport _errorReport;
+ private ErrorReport _errorReport = null!;
public SendErrorReportForm()
=> this.InitializeComponent();
this.UpdateEncodedReport();
}
}
- private string _reportText;
+ private string _reportText = "";
public bool AnonymousReport
{
get => this._encodedReportForDM;
private set => this.SetProperty(ref this._encodedReportForDM, value);
}
- private string _encodedReportForDM;
+ private string _encodedReportForDM = "";
- private readonly Twitter tw;
+ private readonly Twitter? tw;
private readonly string originalReportText;
public ErrorReport(string reportText)
{
}
- public ErrorReport(Twitter tw, string reportText)
+ public ErrorReport(Twitter? tw, string reportText)
{
this.tw = tw;
this.originalReportText = reportText;
}
public async Task SendByDmAsync()
- => await this.tw.SendDirectMessage(this.EncodedReportForDM);
+ {
+ if (!this.CheckDmAvailable())
+ return;
+
+ await this.tw!.SendDirectMessage(this.EncodedReportForDM);
+ }
private void UpdateEncodedReport()
{
this.EncodedReportForDM = $"D {destScreenName} ErrorReport: {encodedReport}";
}
- this.CanSendByDM = this.tw.GetTextLengthRemain(this.EncodedReportForDM) >= 0;
+ this.CanSendByDM = this.tw!.GetTextLengthRemain(this.EncodedReportForDM) >= 0;
}
private bool CheckDmAvailable()
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
private class EventCheckboxTblElement
{
- public CheckBox CheckBox;
+ public CheckBox CheckBox = null!;
public MyCommon.EVENTTYPE Type;
}
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
const string DialogText = "Bitly Login";
dialog.Text = DialogText;
- string accessToken = null;
+ string? accessToken = null;
dialog.LoginCallback = async () =>
{
try
// 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.ComponentModel;
// 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.ComponentModel;
// 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.ComponentModel;
// 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.Linq;
// 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.Linq;
/// XML に含まれていた場合に破棄せず保持するため必要となる。
/// </remarks>
[XmlAnyElement]
- public XmlElement[] ExtraElements;
+ public XmlElement[] ExtraElements = Array.Empty<XmlElement>();
private static readonly object lockObj = new object();
return;
var retryCount = 0;
- Exception lastException = null;
+ Exception? lastException = null;
var filePath = GetSettingFilePath(fileId);
do
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
=> SaveSettings(this);
#endregion
- public List<UserAccount> UserAccounts;
+ public List<UserAccount> UserAccounts = new List<UserAccount>();
public string UserName = "";
[XmlIgnore]
}
public long UserId = 0;
- public List<string> TabList;
+ public List<string> TabList = new List<string>();
public int TimelinePeriod = 90;
public int ReplyPeriod = 180;
public int DMPeriod = 600;
/// <summary>アップデート通知を無視するバージョン番号</summary>
[XmlIgnore]
- public Version SkipUpdateVersion
+ public Version? SkipUpdateVersion
{
get => string.IsNullOrEmpty(this.SkipUpdateVersionStr) ? null : Version.Parse(this.SkipUpdateVersionStr);
set => this.SkipUpdateVersionStr = value == null ? "" : value.ToString();
}
[XmlElement(ElementName = nameof(SkipUpdateVersion))]
- public string SkipUpdateVersionStr { get; set; }
+ public string SkipUpdateVersionStr { get; set; } = "";
}
public class UserAccount
// 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.Linq;
}
[XmlIgnore]
- public Font FontUIGlobal = null;
+ public Font? FontUIGlobal = null;
/// <summary>
/// [隠し設定] UI フォントを指定します
/// <remarks>
/// フォントによっては一部レイアウトが崩れるためこっそり追加
/// </remarks>
- public string FontUIGlobalStr
+ public string? FontUIGlobalStr
{
- get => this.FontToString(this.FontUIGlobal);
- set => this.FontUIGlobal = this.StringToFont(value);
+ get => this.FontUIGlobal != null ? this.FontToString(this.FontUIGlobal) : null;
+ set => this.FontUIGlobal = value != null ? this.StringToFont(value) : null;
}
[XmlIgnore]
private readonly FontConverter fontConverter = new FontConverter();
protected string FontToString(Font font)
- => font != null ? this.fontConverter.ConvertToString(font) : null;
+ => this.fontConverter.ConvertToString(font);
protected Font StringToFont(string str)
- => str != null ? (Font)this.fontConverter.ConvertFromString(str) : null;
+ => (Font)this.fontConverter.ConvertFromString(str);
[XmlIgnore]
private readonly ColorConverter colorConverter = new ColorConverter();
{
if (disposing)
{
- this.FontUnread.Dispose();
- this.FontRead.Dispose();
- this.FontDetail.Dispose();
- this.FontInputFont.Dispose();
+ this.FontUnread?.Dispose();
+ this.FontRead?.Dispose();
+ this.FontDetail?.Dispose();
+ this.FontInputFont?.Dispose();
}
}
}
// 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.Linq;
// 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.Linq;
public class SettingTabItem
{
/// <summary>タブの表示名</summary>
- public string TabName { get; set; }
+ public string TabName { get; set; } = "";
/// <summary>タブの種類</summary>
public MyCommon.TabUsageType TabType { get; set; }
public bool Notify { get; set; }
/// <summary>通知音</summary>
- public string SoundFile { get; set; }
+ public string SoundFile { get; set; } = "";
/// <summary>
/// 振り分けルール (<see cref="MyCommon.TabUsageType.UserDefined"/> で使用)
/// <summary>
/// 表示するユーザーのスクリーンネーム (<see cref="MyCommon.TabUsageType.UserTimeline"/> で使用)
/// </summary>
- public string User { get; set; }
+ public string? User { get; set; }
/// <summary>
/// 検索文字列 (<see cref="MyCommon.TabUsageType.PublicSearch"/> で使用)
/// <summary>
/// 表示するリスト (<see cref="MyCommon.TabUsageType.Lists"/> で使用)
/// </summary>
- public ListElement ListInfo { get; set; }
+ public ListElement? ListInfo { get; set; }
}
}
}
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
/// </summary>
public int PurgeCount { get; set; }
- public string BitlyAccessToken { get; set; }
- public string BitlyId { get; set; }
- public string BitlyKey { get; set; }
+ public string BitlyAccessToken { get; set; } = "";
+ public string BitlyId { get; set; } = "";
+ public string BitlyKey { get; set; } = "";
private HttpClient http;
private readonly ConcurrentDictionary<Uri, Uri> urlCache = new ConcurrentDictionary<Uri, Uri>();
if (!ShortUrlHosts.Contains(uri.Host) && !IsIrregularShortUrl(uri))
return uri;
- if (this.urlCache.TryGetValue(uri, out var expanded))
+ Uri? expanded;
+ if (this.urlCache.TryGetValue(uri, out expanded))
return expanded;
if (this.urlCache.Count > this.PurgeCount)
return false;
}
- private async Task<Uri> GetRedirectTo(Uri url)
+ private async Task<Uri?> GetRedirectTo(Uri url)
{
url = this.UpgradeToHttpsIfAvailable(url);
// 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.Linq;
// 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.Linq;
// 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.ComponentModel;
protected internal class TabListItem
{
- public TabModel Tab { get; set; }
- public string Label { get; set; }
+ public TabModel? Tab { get; set; }
+ public string Label { get; set; } = "";
public override string ToString()
=> this.Label;
this.OK_Button.Enabled = true;
}
- public TabModel SelectedTab
+ public TabModel? SelectedTab
=> this.TabList.SelectedItem is TabListItem item ? item.Tab : null;
public TabModel[] SelectedTabs
=> this.TabList.SelectedItems
.Cast<TabListItem>()
.Select(x => x.Tab)
+ .OfType<TabModel>()
.ToArray();
}
}
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Threading;
using System.Threading.Tasks;
// 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.Linq;
{
public double Latitude { get; set; }
public double Longitude { get; set; }
- public string LocateInfo { get; set; }
}
public enum MapProvider
{
public abstract Task<ThumbnailInfo> GetThumbnailInfoAsync(PostClass.StatusGeo geo);
- private static MapThumb defaultInstance = null;
+ private static MapThumb defaultInstance = null!;
public static MapThumb GetDefaultInstance()
{
if (MapThumb.defaultInstance == null || MapThumb.defaultInstance.GetType() != classType)
{
- MapThumb.defaultInstance = Activator.CreateInstance(classType) as MapThumb;
+ MapThumb.defaultInstance = (MapThumb)Activator.CreateInstance(classType);
}
return MapThumb.defaultInstance;
// 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.Linq;
// 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.Drawing;
}
}
- MemoryImage result = null;
+ MemoryImage? result = null;
try
{
result = MemoryImage.CopyFromImage(bitmap);
using var stream = await http.GetStreamAsync(tileUrl)
.ConfigureAwait(false);
- MemoryImage result = null;
+ MemoryImage? result = null;
try
{
result = await MemoryImage.CopyFromStreamAsync(stream).ConfigureAwait(false);
// 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.Globalization;
protected HttpClient http
=> this.localHttpClient ?? Networking.Http;
- private readonly HttpClient localHttpClient;
+ private readonly HttpClient? localHttpClient;
public FoursquareCheckin()
: this(null)
{
}
- public FoursquareCheckin(HttpClient http)
+ public FoursquareCheckin(HttpClient? http)
=> this.localHttpClient = http;
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
// ツイートに位置情報が付与されている場合は何もしない
if (post.PostGeo != null)
/// <summary>
/// Foursquare のチェックイン URL から位置情報を取得します
/// </summary>
- public async Task<GlobalLocation> FetchCheckinLocation(string url, CancellationToken token)
+ public async Task<GlobalLocation?> FetchCheckinLocation(string url, CancellationToken token)
{
var match = UrlPatternRegex.Match(url);
if (!match.Success)
/// <summary>
/// Foursquare のチェックイン URL から位置情報を取得します (古い形式の URL)
/// </summary>
- public async Task<GlobalLocation> FetchCheckinLocationLegacy(string url, CancellationToken token)
+ public async Task<GlobalLocation?> FetchCheckinLocationLegacy(string url, CancellationToken token)
{
var match = LegacyUrlPatternRegex.Match(url);
}
}
- internal static GlobalLocation ParseIntoLocation(byte[] jsonBytes)
+ internal static GlobalLocation? ParseIntoLocation(byte[] jsonBytes)
{
using var jsonReader = JsonReaderWriterFactory.CreateJsonReader(jsonBytes, XmlDictionaryReaderQuotas.Max);
var xElm = XElement.Load(jsonReader);
// 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.Linq;
{
abstract class IThumbnailService
{
- public abstract Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token);
+ public abstract Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token);
}
}
// 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.Linq;
"Gyazo",
};
- protected string ApiBase;
- protected IEnumerable<Regex> UrlRegex = null;
+ protected string? ApiBase;
+ protected IEnumerable<Regex>? UrlRegex = null;
protected Timer UpdateTimer;
protected HttpClient http
=> this.localHttpClient ?? Networking.Http;
- private readonly HttpClient localHttpClient;
+ private readonly HttpClient? localHttpClient;
private readonly object LockObj = new object();
{
}
- public ImgAzyobuziNet(HttpClient http)
+ public ImgAzyobuziNet(HttpClient? http)
: this(http, autoupdate: false)
{
}
- public ImgAzyobuziNet(HttpClient http, bool autoupdate)
+ public ImgAzyobuziNet(HttpClient? http, bool autoupdate)
{
this.UpdateTimer = new Timer(async _ => await this.LoadRegexAsync());
this.AutoUpdate = autoupdate;
.ConfigureAwait(false);
}
- public override Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
return Task.Run(() =>
{
// 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.Linq;
protected HttpClient http
=> this.localHttpClient ?? Networking.Http;
- private readonly HttpClient localHttpClient;
+ private readonly HttpClient? localHttpClient;
protected readonly Regex regex;
protected readonly string[] propertyNames;
{
}
- public MetaThumbnailService(string urlPattern, string[] propNames)
+ public MetaThumbnailService(string urlPattern, string[]? propNames)
: this(null, urlPattern, propNames)
{
}
- public MetaThumbnailService(HttpClient http, string urlPattern)
+ public MetaThumbnailService(HttpClient? http, string urlPattern)
: this(http, urlPattern, null)
{
}
- public MetaThumbnailService(HttpClient http, string urlPattern, string[] propNames)
+ public MetaThumbnailService(HttpClient? http, string urlPattern, string[]? propNames)
{
this.localHttpClient = http;
this.regex = new Regex(urlPattern);
this.propertyNames = propNames ?? MetaThumbnailService.PropertyNames;
}
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
if (!this.regex.IsMatch(url))
return null;
return null;
}
- protected virtual string GetThumbnailUrl(string html)
+ protected virtual string? GetThumbnailUrl(string html)
{
foreach (var pattern in MetaThumbnailService.MetaPatterns)
{
// 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.Globalization;
public static readonly Regex UrlPatternRegex =
new Regex(@"^https?://(?:(www|ext)\.nicovideo\.jp/watch|nico\.ms)/(?<id>(?:sm|nm)?[0-9]+)(\?.+)?$");
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
var match = Nicovideo.UrlPatternRegex.Match(url);
if (!match.Success)
// 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.Linq;
{
}
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
var thumb = await base.GetThumbnailInfoAsync(url, post, token)
.ConfigureAwait(false);
// 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.Linq;
{
}
- public Pixiv(HttpClient http)
+ public Pixiv(HttpClient? http)
: base(http, Pixiv.UrlPattern)
{
}
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
var thumb = await base.GetThumbnailInfoAsync(url, post, token)
.ConfigureAwait(false);
// 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.Linq;
{
protected Regex regex;
protected string thumb_replacement;
- protected string fullsize_replacement;
+ protected string? fullsize_replacement;
public SimpleThumbnailService(string pattern, string replacement)
: this(pattern, replacement, null)
{
}
- public SimpleThumbnailService(string pattern, string replacement, string file_replacement)
+ public SimpleThumbnailService(string pattern, string replacement, string? file_replacement)
{
this.regex = new Regex(pattern, RegexOptions.IgnoreCase);
this.thumb_replacement = replacement;
this.fullsize_replacement = file_replacement;
}
- public override Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
return Task.Run(() =>
{
}, token);
}
- protected string ReplaceUrl(string url)
+ protected string? ReplaceUrl(string url)
=> this.ReplaceUrl(url, this.thumb_replacement);
- protected string ReplaceUrl(string url, string replacement)
+ protected string? ReplaceUrl(string url, string? replacement)
{
if (replacement == null) return null;
var match = this.regex.Match(url);
// 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.Linq;
protected HttpClient http
=> this.localHttpClient ?? Networking.Http;
- private readonly HttpClient localHttpClient;
+ private readonly HttpClient? localHttpClient;
public Tinami()
: this(null)
{
}
- public Tinami(HttpClient http)
+ public Tinami(HttpClient? http)
=> this.localHttpClient = http;
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
var match = Tinami.UrlPatternRegex.Match(url);
if (!match.Success)
// 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.IO;
{
internal static Func<IApiConnection> GetApiConnection;
- public override Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
- return Task.Run<ThumbnailInfo>(() =>
+ return Task.Run<ThumbnailInfo?>(() =>
{
if (GetApiConnection == null)
return null;
// 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.Linq;
protected HttpClient http
=> this.localHttpClient ?? Networking.Http;
- private readonly HttpClient localHttpClient;
+ private readonly HttpClient? localHttpClient;
public Tumblr()
: this(null)
{
}
- public Tumblr(HttpClient http)
+ public Tumblr(HttpClient? http)
=> this.localHttpClient = http;
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
var match = Tumblr.UrlPatternRegex.Match(url);
if (!match.Success)
// 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.Linq;
{
}
- public TwitterComVideo(HttpClient http)
+ public TwitterComVideo(HttpClient? http)
: base(http, TwitterComVideo.UrlPattern)
{
}
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
// 前処理で動画用URLが準備されていればそれを使う
var mediaInfo = post.Media.FirstOrDefault(x => x.Url == url);
// 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.Linq;
protected HttpClient http
=> this.localHttpClient ?? Networking.Http;
- private readonly HttpClient localHttpClient;
+ private readonly HttpClient? localHttpClient;
public Vimeo()
: this(null)
{
}
- public Vimeo(HttpClient http)
+ public Vimeo(HttpClient? http)
=> this.localHttpClient = http;
- public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
var match = Vimeo.UrlPatternRegex.Match(url);
if (!match.Success)
// 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.Linq;
public static readonly Regex UrlPatternRegex =
new Regex(@"^https?://(?:((?:www|m)\.youtube\.com)|(youtu\.be))/(watch\?v=)?(?<videoid>([\w\-]+))");
- public override Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public override Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
return Task.Run(() =>
{
// 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.Linq;
return thumbnails;
}
- public static async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+ public static async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
foreach (var generator in ThumbnailGenerator.Services)
{
// 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.Linq;
/// 例えば Youtube のサムネイルの場合、動画そのものの URL ではなく
/// https://www.youtube.com/watch?v=****** 形式の URL が含まれる
/// </remarks>
- public string MediaPageUrl { get; set; }
+ public string MediaPageUrl { get; set; } = "";
/// <summary>サムネイルとして表示する画像の URL</summary>
/// <remarks>
/// ここに含まれる URL は直接画像として表示可能である必要がある
/// </remarks>
- public string ThumbnailImageUrl { get; set; }
+ public string ThumbnailImageUrl { get; set; } = "";
/// <summary>最も高解像度な画像の URL</summary>
/// <remarks>
/// サムネイルとしては不適だが、より高解像度な画像を表示する場面に使用できる
/// URL があればここに含まれる
/// </remarks>
- public string FullSizeImageUrl { get; set; }
+ public string? FullSizeImageUrl { get; set; }
/// <summary>ツールチップとして表示するテキスト</summary>
/// <remarks>
/// サムネイル画像にマウスオーバーした際に表示されるテキスト
/// </remarks>
- public string TooltipText { get; set; }
+ public string? TooltipText { get; set; }
/// <summary>
/// 対象となるメディアが動画や音声など再生可能なものであるか否か
public async virtual Task<MemoryImage> LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken)
{
- MemoryImage image = null;
+ MemoryImage? image = null;
try
{
using var response = await http.GetAsync(this.ThumbnailImageUrl, cancellationToken)
}
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
=> this.Equals(obj as ThumbnailInfo);
- public bool Equals(ThumbnailInfo other)
+ public bool Equals(ThumbnailInfo? other)
=> other != null &&
other.MediaPageUrl == this.MediaPageUrl &&
other.ThumbnailImageUrl == this.ThumbnailImageUrl &&
// 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.Threading;
public TimeSpan UpdateIntervalConfig { get; set; } = Timeout.InfiniteTimeSpan;
public TimeSpan UpdateAfterSystemResume { get; set; } = Timeout.InfiniteTimeSpan;
- public Func<Task> UpdateHome;
- public Func<Task> UpdateMention;
- public Func<Task> UpdateDm;
- public Func<Task> UpdatePublicSearch;
- public Func<Task> UpdateUser;
- public Func<Task> UpdateList;
- public Func<Task> UpdateConfig;
+ public Func<Task>? UpdateHome;
+ public Func<Task>? UpdateMention;
+ public Func<Task>? UpdateDm;
+ public Func<Task>? UpdatePublicSearch;
+ public Func<Task>? UpdateUser;
+ public Func<Task>? UpdateList;
+ public Func<Task>? UpdateConfig;
[Flags]
private enum UpdateTask
// 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.Linq;
/// API 実行回数制限の値
/// </summary>
[Browsable(false)]
- public ApiLimit ApiLimit
+ public ApiLimit? ApiLimit
{
get => this._ApiLimit;
private set
this.Invalidate();
}
}
- private ApiLimit _ApiLimit = null;
+ private ApiLimit? _ApiLimit = null;
/// <summary>
/// API エンドポイント名
/// </summary>
[Browsable(false)]
- public string ApiEndpoint
+ public string? ApiEndpoint
{
get => this._ApiEndpoint;
set
}
}
}
- private string _ApiEndpoint = null;
+ private string? _ApiEndpoint = null;
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
// 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.Linq;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
//コンパイル後コマンド
//"c:\Program Files\Microsoft.NET\SDK\v2.0\Bin\sgen.exe" /f /a:"$(TargetPath)"
//"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /f /a:"$(TargetPath)"
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Globalization;
using System.IO;
/// <summary>タブドラッグ中フラグ(DoDragDropを実行するかの判定用)</summary>
private bool _tabDrag;
- private TabPage _beforeSelectedTab; // タブが削除されたときに前回選択されていたときのタブを選択する為に保持
+ private TabPage? _beforeSelectedTab; // タブが削除されたときに前回選択されていたときのタブを選択する為に保持
private Point _tabMouseDownPoint;
/// <summary>右クリックしたタブの名前(Tabコントロール機能不足対応)</summary>
- private string _rclickTabName;
+ private string? _rclickTabName;
private readonly object _syncObject = new object(); // ロック用
+ "--></style>"
+ "</head><body><p>";
private const string detailHtmlFormatFooterColor = "</p></body></html>";
- private string detailHtmlFormatHeader;
- private string detailHtmlFormatFooter;
+ private string detailHtmlFormatHeader = null!;
+ private string detailHtmlFormatFooter = null!;
private bool _myStatusError = false;
private bool _myStatusOnline = false;
//twitter解析部
private readonly TwitterApi twitterApi = new TwitterApi();
- private Twitter tw;
+ private Twitter tw = null!;
//Growl呼び出し部
private readonly GrowlHelper gh = new GrowlHelper(ApplicationSettings.ApplicationName);
private readonly OpenURL UrlDialog = new OpenURL();
/// <summary>@id補助</summary>
- public AtIdSupplement AtIdSupl;
+ public AtIdSupplement AtIdSupl = null!;
/// <summary>Hashtag補助</summary>
- public AtIdSupplement HashSupl;
+ public AtIdSupplement HashSupl = null!;
- public HashtagManage HashMgr;
- private EventViewerDialog evtDialog;
+ public HashtagManage HashMgr = null!;
+ private EventViewerDialog evtDialog = null!;
//表示フォント、色、アイコン
/// <summary>未読用フォント</summary>
- private Font _fntUnread;
+ private Font _fntUnread = null!;
/// <summary>未読用文字色</summary>
private Color _clUnread;
/// <summary>既読用フォント</summary>
- private Font _fntReaded;
+ private Font _fntReaded = null!;
/// <summary>既読用文字色</summary>
private Color _clReaded;
private readonly Color _clHighLight = Color.FromKnownColor(KnownColor.HighlightText);
/// <summary>発言詳細部用フォント</summary>
- private Font _fntDetail;
+ private Font _fntDetail = null!;
/// <summary>発言詳細部用色</summary>
private Color _clDetail;
private Color _clInputFont;
/// <summary>入力欄フォント</summary>
- private Font _fntInputFont;
+ private Font _fntInputFont = null!;
/// <summary>アイコン画像リスト</summary>
- private ImageCache IconCache;
+ private ImageCache IconCache = null!;
/// <summary>タスクトレイアイコン:通常時 (At.ico)</summary>
- private Icon NIconAt;
+ private Icon NIconAt = null!;
/// <summary>タスクトレイアイコン:通信エラー時 (AtRed.ico)</summary>
- private Icon NIconAtRed;
+ private Icon NIconAtRed = null!;
/// <summary>タスクトレイアイコン:オフライン時 (AtSmoke.ico)</summary>
- private Icon NIconAtSmoke;
+ private Icon NIconAtSmoke = null!;
/// <summary>タスクトレイアイコン:更新中 (Refresh.ico)</summary>
private Icon[] NIconRefresh = new Icon[4];
/// <summary>未読のあるタブ用アイコン (Tab.ico)</summary>
- private Icon TabIcon;
+ private Icon TabIcon = null!;
/// <summary>画面左上のアイコン (Main.ico)</summary>
- private Icon MainIcon;
+ private Icon MainIcon = null!;
- private Icon ReplyIcon;
- private Icon ReplyIconBlink;
+ private Icon ReplyIcon = null!;
+ private Icon ReplyIconBlink = null!;
- private readonly ImageList _listViewImageList = new ImageList(); // ListViewItemの高さ変更用
+ private readonly ImageList _listViewImageList = new ImageList(); //ListViewItemの高さ変更用
- private PostClass _anchorPost;
- private bool _anchorFlag; // true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画)
+ private PostClass? _anchorPost;
+ private bool _anchorFlag; //true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画)
/// <summary>発言履歴</summary>
private readonly List<StatusTextHistory> _history = new List<StatusTextHistory>();
// 以下DrawItem関連
private readonly SolidBrush _brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
- private SolidBrush _brsBackColorMine;
- private SolidBrush _brsBackColorAt;
- private SolidBrush _brsBackColorYou;
- private SolidBrush _brsBackColorAtYou;
- private SolidBrush _brsBackColorAtFromTarget;
- private SolidBrush _brsBackColorAtTo;
- private SolidBrush _brsBackColorNone;
+ private SolidBrush _brsBackColorMine = null!;
+ private SolidBrush _brsBackColorAt = null!;
+ private SolidBrush _brsBackColorYou = null!;
+ private SolidBrush _brsBackColorAtYou = null!;
+ private SolidBrush _brsBackColorAtFromTarget = null!;
+ private SolidBrush _brsBackColorAtTo = null!;
+ private SolidBrush _brsBackColorNone = null!;
/// <summary>Listにフォーカスないときの選択行の背景色</summary>
private readonly SolidBrush _brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace));
private readonly StringFormat sfTab = new StringFormat();
//////////////////////////////////////////////////////////////////////////////////////////////////////////
- private TabInformations _statuses;
+ private TabInformations _statuses = null!;
/// <summary>
/// 現在表示している発言一覧の <see cref="ListView"/> に対するキャッシュ
/// 使用する場合には <see cref="_listItemCache"/> に対して直接メソッド等を呼び出さずに
/// 一旦ローカル変数に代入してから参照すること。
/// </remarks>
- private ListViewItemCache _listItemCache = null;
+ private ListViewItemCache? _listItemCache = null;
internal class ListViewItemCache
{
/// <summary>アイテムをキャッシュする対象の <see cref="ListView"/></summary>
- public ListView TargetList { get; set; }
+ public ListView TargetList { get; set; } = null!;
/// <summary>キャッシュする範囲の開始インデックス</summary>
public int StartIndex { get; set; }
public int EndIndex { get; set; }
/// <summary>キャッシュされた範囲に対応する <see cref="ListViewItem"/> と <see cref="PostClass"/> の組</summary>
- public (ListViewItem, PostClass)[] Cache { get; set; }
+ public (ListViewItem, PostClass)[] Cache { get; set; } = null!;
/// <summary>キャッシュされたアイテムの件数</summary>
public int Count
/// <summary>指定されたインデックスの <see cref="ListViewItem"/> と <see cref="PostClass"/> をキャッシュから取得することを試みます</summary>
/// <returns>取得に成功すれば true、それ以外は false</returns>
- public bool TryGetValue(int index, out ListViewItem item, out PostClass post)
+ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [NotNullWhen(true)] out PostClass? post)
{
if (this.Contains(index))
{
private const int MAX_WORKER_THREADS = 20;
private readonly SemaphoreSlim workerSemaphore = new SemaphoreSlim(MAX_WORKER_THREADS);
private readonly CancellationTokenSource workerCts = new CancellationTokenSource();
- private readonly IProgress<string> workerProgress;
+ private readonly IProgress<string> workerProgress = null!;
private int UnreadCounter = -1;
private int UnreadAtCounter = -1;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
private readonly TimelineScheduler timelineScheduler = new TimelineScheduler();
- private ThrottlingTimer RefreshThrottlingTimer;
- private ThrottlingTimer colorizeDebouncer;
- private ThrottlingTimer selectionDebouncer;
- private ThrottlingTimer saveConfigDebouncer;
+ private ThrottlingTimer RefreshThrottlingTimer = null!;
+ private ThrottlingTimer colorizeDebouncer = null!;
+ private ThrottlingTimer selectionDebouncer = null!;
+ private ThrottlingTimer saveConfigDebouncer = null!;
- private string recommendedStatusFooter;
+ private string recommendedStatusFooter = null!;
private bool urlMultibyteSplit = false;
private bool preventSmsCommand = true;
public string After;
}
- private List<urlUndo> urlUndoBuffer = null;
+ private List<urlUndo>? urlUndoBuffer = null;
private readonly struct ReplyChain
{
}
/// <summary>[, ]でのリプライ移動の履歴</summary>
- private Stack<ReplyChain> replyChains;
+ private Stack<ReplyChain>? replyChains;
/// <summary>ポスト選択履歴</summary>
- private readonly Stack<(TabModel, PostClass)> selectPostChains = new Stack<(TabModel, PostClass)>();
+ private readonly Stack<(TabModel, PostClass?)> selectPostChains = new Stack<(TabModel, PostClass?)>();
public TabModel CurrentTab
=> this._statuses.SelectedTab;
public DetailsListView CurrentListView
=> (DetailsListView)this.CurrentTabPage.Tag;
- public PostClass CurrentPost
+ public PostClass? CurrentPost
=> this.CurrentTab.SelectedPost;
/// <summary>検索処理タイプ</summary>
/// <summary>画像投稿サービス名</summary>
public string imageService = "";
- public IMediaItem[] mediaItems = null;
+ public IMediaItem[]? mediaItems = null;
public StatusTextHistory()
{
}
}
}
- private Icon LoadIcon(string filePath)
+ private Icon? LoadIcon(string filePath)
{
if (!File.Exists(filePath))
return null;
{
this.InitColumnText();
- ColumnHeader[] columns = null;
+ ColumnHeader[]? columns = null;
try
{
if (this._iconCol)
TimerRefreshIcon.Enabled = false;
_ignoreConfigSave = false;
- this.TweenMain_Resize(null, null);
+ this.TweenMain_Resize(this, EventArgs.Empty);
if (saveRequired) SaveConfigsAll(false);
foreach (var ua in SettingManager.Common.UserAccounts)
tab = new FilterTabModel(tabSetting.TabName);
break;
case MyCommon.TabUsageType.UserTimeline:
- tab = new UserTimelineTabModel(tabSetting.TabName, tabSetting.User);
+ tab = new UserTimelineTabModel(tabSetting.TabName, tabSetting.User!);
break;
case MyCommon.TabUsageType.PublicSearch:
tab = new PublicSearchTabModel(tabSetting.TabName)
};
break;
case MyCommon.TabUsageType.Lists:
- tab = new ListTimelineTabModel(tabSetting.TabName, tabSetting.ListInfo);
+ tab = new ListTimelineTabModel(tabSetting.TabName, tabSetting.ListInfo!);
break;
case MyCommon.TabUsageType.Mute:
tab = new MuteTabModel(tabSetting.TabName);
internal struct ListViewSelection
{
- public long[] SelectedStatusIds { get; set; }
+ public long[]? SelectedStatusIds { get; set; }
public long? SelectionMarkStatusId { get; set; }
public long? FocusedStatusId { get; set; }
}
private void RestoreListViewSelection(DetailsListView listView, TabModel tab, ListViewSelection listSelection)
{
// status_id から ListView 上のインデックスに変換
- int[] selectedIndices = null;
+ int[]? selectedIndices = null;
if (listSelection.SelectedStatusIds != null)
selectedIndices = tab.IndexOf(listSelection.SelectedStatusIds).Where(x => x != -1).ToArray();
this.PushSelectPostChain();
- var post = this.CurrentPost;
+ var post = this.CurrentPost!;
this._statuses.SetReadAllTab(post.StatusId, read: true);
//キャッシュの書き換え
ChangeItemStyleRead(Read, itm, post, (DetailsListView)listCache.TargetList);
}
- private void ChangeItemStyleRead(bool Read, ListViewItem Item, PostClass Post, DetailsListView DList)
+ private void ChangeItemStyleRead(bool Read, ListViewItem Item, PostClass Post, DetailsListView? DList)
{
Font fnt;
string star;
{
//Index:更新対象のListviewItem.Index。Colorを返す。
//-1は全キャッシュ。Colorは返さない(ダミーを戻す)
- PostClass _post;
+ PostClass? _post;
if (_anchorFlag)
_post = _anchorPost;
else
{
//Index:更新対象のListviewItem.Index。Colorを返す。
//-1は全キャッシュ。Colorは返さない(ダミーを戻す)
- PostClass _post;
+ PostClass? _post;
if (_anchorFlag)
_post = _anchorPost;
else
}
var currentPost = this.CurrentPost;
- if (this.ExistCurrentPost && StatusText.Text.Trim() == string.Format("RT @{0}: {1}", currentPost.ScreenName, currentPost.TextFromApi))
+ if (this.ExistCurrentPost && currentPost != null && StatusText.Text.Trim() == string.Format("RT @{0}: {1}", currentPost.ScreenName, currentPost.TextFromApi))
{
var rtResult = MessageBox.Show(string.Format(Properties.Resources.PostButton_Click1, Environment.NewLine),
"Retweet",
return;
}
- IMediaUploadService uploadService = null;
- IMediaItem[] uploadItems = null;
+ IMediaUploadService? uploadService = null;
+ IMediaItem[]? uploadItems = null;
if (ImageSelector.Visible)
{
//画像投稿
.ConfigureAwait(false);
}
catch (TwitterApiException ex)
- when (ex.ErrorResponse.Errors.All(x => x.Code == TwitterErrorCode.AlreadyFavorited))
+ when (ex.Errors.All(x => x.Code == TwitterErrorCode.AlreadyFavorited))
{
// エラーコード 139 のみの場合は成功と見なす
}
this._favTimestamps.Add(DateTimeUtc.Now);
// TLでも取得済みならfav反映
- if (this._statuses.ContainsKey(statusId))
+ if (this._statuses.Posts.TryGetValue(statusId, out var postTl))
{
- var postTl = this._statuses[statusId];
postTl.IsFav = true;
- var favTab = this._statuses.GetTabByType(MyCommon.TabUsageType.Favorites);
+ var favTab = this._statuses.FavoriteTab;
favTab.AddPostQueue(postTl);
}
successIds.Add(statusId);
post.IsFav = false; // リスト再描画必要
- if (this._statuses.ContainsKey(statusId))
- {
- this._statuses[statusId].IsFav = false;
- }
+ if (this._statuses.Posts.TryGetValue(statusId, out var tabinfoPost))
+ tabinfoPost.IsFav = false;
// 検索,リスト,UserTimeline,Relatedの各タブに反映
foreach (var tb in this._statuses.GetTabsInnerStorageType())
if (ct.IsCancellationRequested)
return;
- var favTab = this._statuses.GetTabByType(MyCommon.TabUsageType.Favorites);
+ var favTab = this._statuses.FavoriteTab;
foreach (var statusId in successIds)
{
// ツイートが削除された訳ではないので IsDeleted はセットしない
}
}
- private async Task PostMessageAsync(PostStatusParams postParams, IMediaUploadService uploadService, IMediaItem[] uploadItems)
+ private async Task PostMessageAsync(PostStatusParams postParams, IMediaUploadService? uploadService, IMediaItem[]? uploadItems)
{
await this.workerSemaphore.WaitAsync();
this.RefreshTasktrayIcon();
}
private async Task PostMessageAsyncInternal(IProgress<string> p, CancellationToken ct, PostStatusParams postParams,
- IMediaUploadService uploadService, IMediaItem[] uploadItems)
+ IMediaUploadService? uploadService, IMediaItem[]? uploadItems)
{
if (ct.IsCancellationRequested)
return;
p.Report("Posting...");
- PostClass post = null;
+ PostClass? post = null;
var errMsg = "";
try
await ShowUserTimeline();
break;
case 4:
- ShowRelatedStatusesMenuItem_Click(null, null);
+ ShowRelatedStatusesMenuItem_Click(this.ShowRelatedStatusesMenuItem, EventArgs.Empty);
break;
case 5:
- MoveToHomeToolStripMenuItem_Click(null, null);
+ MoveToHomeToolStripMenuItem_Click(this.MoveToHomeToolStripMenuItem, EventArgs.Empty);
break;
case 6:
- StatusOpenMenuItem_Click(null, null);
+ StatusOpenMenuItem_Click(this.StatusOpenMenuItem, EventArgs.Empty);
break;
case 7:
//動作なし
}
var tab = this.CurrentTab;
var post = this.CurrentPost;
- if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post.IsDm)
+ if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post == null || post.IsDm)
{
FavAddToolStripMenuItem.Enabled = false;
FavRemoveToolStripMenuItem.Enabled = false;
//{
// RefreshMoreStripMenuItem.Enabled = false;
//}
- if (!this.ExistCurrentPost || post.InReplyToStatusId == null)
+ if (!this.ExistCurrentPost || post == null || post.InReplyToStatusId == null)
{
RepliedStatusOpenMenuItem.Enabled = false;
}
{
RepliedStatusOpenMenuItem.Enabled = true;
}
- if (!this.ExistCurrentPost || string.IsNullOrEmpty(post.RetweetedBy))
+ if (!this.ExistCurrentPost || post == null || string.IsNullOrEmpty(post.RetweetedBy))
{
MoveToRTHomeMenuItem.Enabled = false;
}
MoveToRTHomeMenuItem.Enabled = true;
}
- if (this.ExistCurrentPost)
+ if (this.ExistCurrentPost && post != null)
{
this.DeleteStripMenuItem.Enabled = post.CanDeleteBy(this.tw.UserId);
if (post.RetweetedByUserId == this.tw.UserId)
using (ControlTransaction.Cursor(this, Cursors.WaitCursor))
{
- Exception lastException = null;
+ Exception? lastException = null;
foreach (var post in posts)
{
if (!post.CanDeleteBy(this.tw.UserId))
if (SettingManager.Common.IsUseNotifyGrowl) gh.RegisterGrowl();
try
{
- StatusText_TextChanged(null, null);
+ StatusText_TextChanged(this.StatusText, EventArgs.Empty);
}
catch (Exception)
{
cmb.Text = searchWord;
SaveConfigsTabs();
//検索実行
- this.SearchButton_Click(tabPage.Controls["panelSearch"].Controls["comboSearch"], null);
+ this.SearchButton_Click(tabPage.Controls["panelSearch"].Controls["comboSearch"], EventArgs.Empty);
}
private async Task ShowUserTimeline()
{
- if (!this.ExistCurrentPost) return;
- await this.AddNewTabForUserTimeline(this.CurrentPost.ScreenName);
+ var post = this.CurrentPost;
+ if (post == null || !this.ExistCurrentPost) return;
+ await this.AddNewTabForUserTimeline(post.ScreenName);
}
private void SearchComboBox_KeyDown(object sender, KeyEventArgs e)
public bool RemoveSpecifiedTab(string TabName, bool confirm)
{
var tabInfo = _statuses.GetTabByName(TabName);
- if (tabInfo.IsDefaultTabType || tabInfo.Protected) return false;
+ if (tabInfo == null || tabInfo.IsDefaultTabType || tabInfo.Protected)
+ return false;
if (confirm)
{
{
e.Handled = true;
StatusText.Text = "";
- JumpUnreadMenuItem_Click(null, null);
+ JumpUnreadMenuItem_Click(this.JumpUnreadMenuItem, EventArgs.Empty);
}
}
}
- this.StatusText_TextChanged(null, null);
+ this.StatusText_TextChanged(this.StatusText, EventArgs.Empty);
}
private void StatusText_TextChanged(object sender, EventArgs e)
/// <summary>
/// attachment_url に指定可能な URL が含まれていれば除去
/// </summary>
- private string RemoveAttachmentUrl(string statusText, out string attachmentUrl)
+ private string RemoveAttachmentUrl(string statusText, out string? attachmentUrl)
{
attachmentUrl = null;
/// <summary>
/// <see cref="FormatStatusText"/> に加えて、拡張モードで140字にカウントされない文字列の除去を行います
/// </summary>
- private string FormatStatusTextExtended(string statusText, out long[] autoPopulatedUserIds, out string attachmentUrl)
+ private string FormatStatusTextExtended(string statusText, out long[] autoPopulatedUserIds, out string? attachmentUrl)
{
statusText = this.RemoveAutoPopuratedMentions(statusText, out autoPopulatedUserIds);
return remainCount;
}
- private IMediaUploadService GetSelectedImageService()
+ private IMediaUploadService? GetSelectedImageService()
=> this.ImageSelector.Visible ? this.ImageSelector.SelectedService : null;
private void MyList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e)
}
this.TopMost = SettingManager.Common.AlwaysTop;
- var searchOptions = this.SearchDialog.ResultOptions;
+ var searchOptions = this.SearchDialog.ResultOptions!;
if (searchOptions.Type == SearchWordDialog.SearchType.Timeline)
{
if (searchOptions.NewTab)
if (ImageSelector.Enabled)
return;
- TabModel foundTab = null;
+ TabModel? foundTab = null;
var foundIndex = 0;
- DetailsListView lst = null;
-
//現在タブから最終タブまで探索
foreach (var (tab, index) in this._statuses.Tabs.WithIndex().Skip(bgnIdx))
{
ListTab.SelectedIndex = index;
foundTab = tab;
foundIndex = unreadIndex;
- lst = (DetailsListView)this.ListTab.TabPages[index].Tag;
break;
}
}
ListTab.SelectedIndex = index;
foundTab = tab;
foundIndex = unreadIndex;
- lst = (DetailsListView)this.ListTab.TabPages[index].Tag;
break;
}
}
}
+ DetailsListView lst;
+
if (foundTab == null)
{
//全部調べたが未読見つからず→先頭タブの最新発言へ
lst = (DetailsListView)tabPage.Tag;
}
+ else
+ {
+ var foundTabIndex = this._statuses.Tabs.IndexOf(foundTab);
+ lst = (DetailsListView)this.ListTab.TabPages[foundTabIndex].Tag;
+ }
SelectListItem(lst, foundIndex);
public class VersionInfo
{
- public Version Version { get; set; }
- public Uri DownloadUri { get; set; }
- public string ReleaseNote { get; set; }
+ public Version Version { get; }
+ public Uri DownloadUri { get; }
+ public string ReleaseNote { get; }
+
+ public VersionInfo(Version version, Uri downloadUri, string releaseNote)
+ => (this.Version, this.DownloadUri, this.ReleaseNote) = (version, downloadUri, releaseNote);
}
/// <summary>
msgBody = Regex.Replace(msgBody, "(?<!\r)\n", "\r\n"); // LF -> CRLF
- return new VersionInfo
- {
- Version = Version.Parse(msgHeader[0]),
- DownloadUri = new Uri(msgHeader[1]),
- ReleaseNote = msgBody,
- };
+ return new VersionInfo(
+ version: Version.Parse(msgHeader[0]),
+ downloadUri: new Uri(msgHeader[1]),
+ releaseNote: msgBody
+ );
}
private async Task CheckNewVersion(bool startup = false)
/// <summary>
/// サムネイル表示に使用する CancellationToken の生成元
/// </summary>
- private CancellationTokenSource thumbnailTokenSource = null;
+ private CancellationTokenSource? thumbnailTokenSource = null;
private void DispSelectedPost(bool forceupdate)
{
var oldTokenSource = Interlocked.Exchange(ref this.thumbnailTokenSource, new CancellationTokenSource());
oldTokenSource?.Cancel();
- var token = this.thumbnailTokenSource.Token;
+ var token = this.thumbnailTokenSource!.Token;
loadTasks.Add(this.tweetThumbnail1.ShowThumbnailAsync(currentPost, token));
}
.Do(() => this.OpenApplicationWebsite()),
ShortcutCommand.Create(Keys.F3)
- .Do(() => this.MenuItemSearchNext_Click(null, null)),
+ .Do(() => this.MenuItemSearchNext_Click(this.MenuItemSearchNext, EventArgs.Empty)),
ShortcutCommand.Create(Keys.F5)
.Do(() => this.DoRefresh()),
ShortcutCommand.Create(Keys.Space, Keys.ProcessKey)
.NotFocusedOn(FocusedControl.StatusText)
- .Do(() => { this._anchorFlag = false; this.JumpUnreadMenuItem_Click(null, null); }),
+ .Do(() => { this._anchorFlag = false; this.JumpUnreadMenuItem_Click(this.JumpUnreadMenuItem, EventArgs.Empty); }),
ShortcutCommand.Create(Keys.G)
.NotFocusedOn(FocusedControl.StatusText)
- .Do(() => { this._anchorFlag = false; this.ShowRelatedStatusesMenuItem_Click(null, null); }),
+ .Do(() => { this._anchorFlag = false; this.ShowRelatedStatusesMenuItem_Click(this.ShowRelatedStatusesMenuItem, EventArgs.Empty); }),
ShortcutCommand.Create(Keys.Right, Keys.N)
.FocusedOn(FocusedControl.ListTab)
.Do(() => this.doQuoteOfficial()),
ShortcutCommand.Create(Keys.Control | Keys.B)
- .Do(() => this.ReadedStripMenuItem_Click(null, null)),
+ .Do(() => this.ReadedStripMenuItem_Click(this.ReadedStripMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.T)
- .Do(() => this.HashManageMenuItem_Click(null, null)),
+ .Do(() => this.HashManageMenuItem_Click(this.HashManageMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.L)
- .Do(() => this.UrlConvertAutoToolStripMenuItem_Click(null, null)),
+ .Do(() => this.UrlConvertAutoToolStripMenuItem_Click(this.UrlConvertAutoToolStripMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.Y)
.NotFocusedOn(FocusedControl.PostBrowser)
- .Do(() => this.MultiLineMenuItem_Click(null, null)),
+ .Do(() => this.MultiLineMenuItem_Click(this.MultiLineMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.F)
- .Do(() => this.MenuItemSubSearch_Click(null, null)),
+ .Do(() => this.MenuItemSubSearch_Click(this.MenuItemSubSearch, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.U)
.Do(() => this.ShowUserTimeline()),
ShortcutCommand.Create(Keys.Control | Keys.H)
- .Do(() => this.MoveToHomeToolStripMenuItem_Click(null, null)),
+ .Do(() => this.MoveToHomeToolStripMenuItem_Click(this.MoveToHomeToolStripMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.G)
- .Do(() => this.MoveToFavToolStripMenuItem_Click(null, null)),
+ .Do(() => this.MoveToFavToolStripMenuItem_Click(this.MoveToFavToolStripMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.O)
- .Do(() => this.StatusOpenMenuItem_Click(null, null)),
+ .Do(() => this.StatusOpenMenuItem_Click(this.StatusOpenMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.E)
- .Do(() => this.OpenURLMenuItem_Click(null, null)),
+ .Do(() => this.OpenURLMenuItem_Click(this.OpenURLMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.Home, Keys.Control | Keys.End)
.FocusedOn(FocusedControl.ListTab)
}),
ShortcutCommand.Create(Keys.Shift | Keys.F3)
- .Do(() => this.MenuItemSearchPrev_Click(null, null)),
+ .Do(() => this.MenuItemSearchPrev_Click(this.MenuItemSearchPrev, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Shift | Keys.F5)
.Do(() => this.DoRefreshMore()),
ShortcutCommand.Create(Keys.Alt | Keys.P)
.OnlyWhen(() => this.CurrentPost != null)
- .Do(() => this.doShowUserStatus(this.CurrentPost.ScreenName, ShowInputDialog: false)),
+ .Do(() => this.doShowUserStatus(this.CurrentPost!.ScreenName, ShowInputDialog: false)),
ShortcutCommand.Create(Keys.Alt | Keys.Up)
.Do(() => this.tweetDetailsView.ScrollDownPostBrowser(forward: false)),
.Do(() => this.FavoriteChange(FavAdd: false)),
ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.B)
- .Do(() => this.UnreadStripMenuItem_Click(null, null)),
+ .Do(() => this.UnreadStripMenuItem_Click(this.UnreadStripMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.T)
- .Do(() => this.HashToggleMenuItem_Click(null, null)),
+ .Do(() => this.HashToggleMenuItem_Click(this.HashToggleMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.P)
- .Do(() => this.ImageSelectMenuItem_Click(null, null)),
+ .Do(() => this.ImageSelectMenuItem_Click(this.ImageSelectMenuItem, EventArgs.Empty)),
ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.H)
.Do(() => this.doMoveToRTHome()),
};
}
- internal bool CommonKeyDown(Keys keyData, FocusedControl focusedOn, out Task asyncTask)
+ internal bool CommonKeyDown(Keys keyData, FocusedControl focusedOn, out Task? asyncTask)
{
// Task を返す非同期処理があれば asyncTask に代入する
asyncTask = null;
}
string name;
- if (currentPost.RetweetedId == null)
+ if (currentPost.RetweetedBy == null)
{
name = currentPost.ScreenName;
}
if (this.selectPostChains.Count > 1)
{
var idx = -1;
- TabModel foundTab = null;
+ TabModel? foundTab = null;
do
{
private void TrimPostChain()
{
if (this.selectPostChains.Count <= 2000) return;
- var p = new Stack<(TabModel, PostClass)>(2000);
+ var p = new Stack<(TabModel, PostClass?)>(2000);
for (var i = 0; i < 2000; i++)
{
p.Push(this.selectPostChains.Pop());
{
if (statusId == 0) return false;
- var tab = this._statuses.GetTabByType<DirectMessagesTabModel>();
+ var tab = this._statuses.DirectMessageTab;
var index = tab.IndexOf(statusId);
if (index == -1)
e.SuppressKeyPress = true;
}
- this.StatusText_TextChanged(null, null);
+ this.StatusText_TextChanged(this.StatusText, EventArgs.Empty);
if (asyncTask != null)
await asyncTask;
this.TopMost = SettingManager.Common.AlwaysTop;
}
- public bool TabRename(string origTabName, out string newTabName)
+ public bool TabRename(string origTabName, [NotNullWhen(true)] out string? newTabName)
{
//タブ名変更
newTabName = null;
private void TabMenuControl(string tabName)
{
- var tabInfo = _statuses.GetTabByName(tabName);
+ var tabInfo = _statuses.GetTabByName(tabName)!;
this.FilterEditMenuItem.Enabled = true;
this.EditRuleTbMenuItem.Enabled = true;
private void FilterEditMenuItem_Click(object sender, EventArgs e)
{
- if (string.IsNullOrEmpty(_rclickTabName)) _rclickTabName = _statuses.GetTabByType(MyCommon.TabUsageType.Home).TabName;
+ if (string.IsNullOrEmpty(_rclickTabName)) _rclickTabName = _statuses.HomeTab.TabName;
using (var fltDialog = new FilterDialog())
{
private async void AddTabMenuItem_Click(object sender, EventArgs e)
{
- string tabName = null;
+ string? tabName = null;
MyCommon.TabUsageType tabUsage;
using (var inputName = new InputTabName())
{
if (!string.IsNullOrEmpty(tabName))
{
//List対応
- ListElement list = null;
+ ListElement? list = null;
if (tabUsage == MyCommon.TabUsageType.Lists)
{
using var listAvail = new ListAvailable();
tab = new PublicSearchTabModel(tabName);
break;
case MyCommon.TabUsageType.Lists:
- tab = new ListTimelineTabModel(tabName, list);
+ tab = new ListTimelineTabModel(tabName, list!);
break;
default:
return;
fltDialog.SetCurrent(tabName);
- if (post.RetweetedId == null)
+ if (post.RetweetedBy == null)
{
fltDialog.AddNewFilter(post.ScreenName, post.TextFromApi);
}
}
else if (_Post)
{
- PostButton_Click(null, null);
+ PostButton_Click(this.PostButton, EventArgs.Empty);
return true;
}
}
if (tabPage.Controls["panelSearch"].Controls["comboSearch"].Focused ||
tabPage.Controls["panelSearch"].Controls["comboLang"].Focused)
{
- this.SearchButton_Click(tabPage.Controls["panelSearch"].Controls["comboSearch"], null);
+ this.SearchButton_Click(tabPage.Controls["panelSearch"].Controls["comboSearch"], EventArgs.Empty);
return true;
}
}
return;
var screenNameArray = selectedPosts
- .Select(x => x.RetweetedId != null ? x.RetweetedBy : x.ScreenName)
+ .Select(x => x.RetweetedBy ?? x.ScreenName)
.ToArray();
this.AddFilterRuleByScreenName(screenNameArray);
this.SaveConfigsTabs();
}
- private bool SelectTab(out string tabName)
+ private bool SelectTab([NotNullWhen(true)] out string? tabName)
{
do
{
ttl.Append(_history[_history.Count - 2].status.Replace("\r\n", " "));
break;
case MyCommon.DispTitleEnum.UnreadRepCount:
- ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText1, _statuses.GetTabByType(MyCommon.TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).UnreadCount);
+ ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText1, _statuses.MentionTab.UnreadCount + _statuses.DirectMessageTab.UnreadCount);
break;
case MyCommon.DispTitleEnum.UnreadAllCount:
ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText2, ur);
break;
case MyCommon.DispTitleEnum.UnreadAllRepCount:
- ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText3, ur, _statuses.GetTabByType(MyCommon.TabUsageType.Mentions).UnreadCount + _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage).UnreadCount);
+ ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText3, ur, _statuses.MentionTab.UnreadCount + _statuses.DirectMessageTab.UnreadCount);
break;
case MyCommon.DispTitleEnum.UnreadCountAllCount:
ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText4, ur, al);
//ステータス欄にカウント表示
//タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数)
if (_statuses == null) return "";
- var tbRep = _statuses.GetTabByType(MyCommon.TabUsageType.Mentions);
- var tbDm = _statuses.GetTabByType(MyCommon.TabUsageType.DirectMessage);
+ var tbRep = _statuses.MentionTab;
+ var tbDm = _statuses.DirectMessageTab;
if (tbRep == null || tbDm == null) return "";
var urat = tbRep.UnreadCount + tbDm.UnreadCount;
var ur = 0;
UnreadCounter = ur;
UnreadAtCounter = urat;
- var homeTab = this._statuses.GetTabByType<HomeTabModel>();
+ var homeTab = this._statuses.HomeTab;
slbl.AppendFormat(Properties.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, _postTimestamps.Count, _favTimestamps.Count, homeTab.TweetsPerHour);
if (SettingManager.Common.TimelinePeriod == 0)
}
else
{
- var endpointName = (e as TwitterApiStatus.AccessLimitUpdatedEventArgs).EndpointName;
+ var endpointName = ((TwitterApiStatus.AccessLimitUpdatedEventArgs)e).EndpointName;
SetApiStatusLabel(endpointName);
}
}
}
}
- private void SetApiStatusLabel(string endpointName = null)
+ private void SetApiStatusLabel(string? endpointName = null)
{
var tabType = this.CurrentTab.TabType;
private async Task doRepliedStatusOpen()
{
var currentPost = this.CurrentPost;
- if (this.ExistCurrentPost && currentPost.InReplyToUser != null && currentPost.InReplyToStatusId != null)
+ if (this.ExistCurrentPost && currentPost != null && currentPost.InReplyToUser != null && currentPost.InReplyToStatusId != null)
{
if (MyCommon.IsKeyDown(Keys.Shift))
{
await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(currentPost.InReplyToUser, currentPost.InReplyToStatusId.Value));
return;
}
- if (_statuses.ContainsKey(currentPost.InReplyToStatusId.Value))
+ if (this._statuses.Posts.TryGetValue(currentPost.InReplyToStatusId.Value, out var repPost))
{
- var repPost = _statuses[currentPost.InReplyToStatusId.Value];
MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi);
}
else
foreach (var tb in _statuses.GetTabsByType(MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.PublicSearch))
{
if (tb == null || !tb.Contains(currentPost.InReplyToStatusId.Value)) break;
- var repPost = _statuses[currentPost.InReplyToStatusId.Value];
+ repPost = tb.Posts[currentPost.InReplyToStatusId.Value];
MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi);
return;
}
/// </remarks>
/// <exception cref="ArgumentException">不正なフォーマットが入力された場合</exception>
/// <exception cref="NotSupportedException">サポートされていないデータが入力された場合</exception>
- internal static (string Url, string Title) GetUrlFromDataObject(IDataObject data)
+ internal static (string Url, string? Title) GetUrlFromDataObject(IDataObject data)
{
if (data.GetDataPresent("text/x-moz-url"))
{
if (flg) LView.Invalidate(bnd);
}
- private void SelectListItem(DetailsListView LView , int[] Index, int focusedIndex, int selectionMarkIndex)
+ private void SelectListItem(DetailsListView LView , int[]? Index, int focusedIndex, int selectionMarkIndex)
{
//複数
var bnd = new Rectangle();
if (MyCommon.TwitterApiInfo.AccessLevel == TwitterApiAccessLevel.ReadWrite)
{
MessageBox.Show(Properties.Resources.ReAuthorizeText);
- SettingStripMenuItem_Click(null, null);
+ SettingStripMenuItem_Click(this.SettingStripMenuItem, EventArgs.Empty);
}
// 取得失敗の場合は再試行する
private async Task FavoritesRetweetUnofficial()
{
var post = this.CurrentPost;
- if (this.ExistCurrentPost && !post.IsDm)
+ if (this.ExistCurrentPost && post != null && !post.IsDm)
{
_DoFavRetweetFlags = true;
var favoriteTask = this.FavoriteChange(true);
private async void ApiUsageInfoMenuItem_Click(object sender, EventArgs e)
{
- TwitterApiStatus apiStatus;
+ TwitterApiStatus? apiStatus;
using (var dialog = new WaitingDialog(Properties.Resources.ApiInfo6))
{
private void doQuoteOfficial()
{
- if (this.ExistCurrentPost)
+ var post = this.CurrentPost;
+ if (this.ExistCurrentPost && post != null)
{
- var post = this.CurrentPost;
if (post.IsDm || !StatusText.Enabled)
return;
private void doReTweetUnofficial()
{
//RT @id:内容
- if (this.ExistCurrentPost)
+ var post = this.CurrentPost;
+ if (this.ExistCurrentPost && post != null)
{
- var post = this.CurrentPost;
if (post.IsDm || !StatusText.Enabled)
return;
}
else
{
+ DetailsListView? listView;
+
var tb = _statuses.RemovedTab.Pop();
- DetailsListView listView;
if (tb.TabType == MyCommon.TabUsageType.Related)
{
var relatedTab = _statuses.GetTabByType(MyCommon.TabUsageType.Related);
// StatusText.Focus();
//}
this.MarkSettingCommonModified();
- this.StatusText_TextChanged(null, null);
+ this.StatusText_TextChanged(this.StatusText, EventArgs.Empty);
}
private void HashToggleMenuItem_Click(object sender, EventArgs e)
HashTogglePullDownMenuItem.Checked = false;
}
this.MarkSettingCommonModified();
- this.StatusText_TextChanged(null, null);
+ this.StatusText_TextChanged(this.StatusText, EventArgs.Empty);
}
private void HashStripSplitButton_ButtonClick(object sender, EventArgs e)
- => this.HashToggleMenuItem_Click(null, null);
+ => this.HashToggleMenuItem_Click(this.HashToggleMenuItem, EventArgs.Empty);
public void SetPermanentHashtag(string hashtag)
{
var tab = this.CurrentTab;
var post = this.CurrentPost;
- if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post.IsDm)
+ if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post == null || post.IsDm)
{
this.FavOpMenuItem.Enabled = false;
this.UnFavOpMenuItem.Enabled = false;
{
this.RefreshPrevOpMenuItem.Enabled = false;
}
- if (!this.ExistCurrentPost || post.InReplyToStatusId == null)
+ if (!this.ExistCurrentPost || post == null || post.InReplyToStatusId == null)
{
OpenRepSourceOpMenuItem.Enabled = false;
}
{
OpenRepSourceOpMenuItem.Enabled = true;
}
- if (!this.ExistCurrentPost || string.IsNullOrEmpty(post.RetweetedBy))
+ if (!this.ExistCurrentPost || post == null || string.IsNullOrEmpty(post.RetweetedBy))
{
OpenRterHomeMenuItem.Enabled = false;
}
OpenRterHomeMenuItem.Enabled = true;
}
- if (this.ExistCurrentPost)
+ if (this.ExistCurrentPost && post != null)
{
this.DelOpMenuItem.Enabled = post.CanDeleteBy(this.tw.UserId);
}
}
private void MenuItemTab_DropDownOpening(object sender, EventArgs e)
- => this.ContextMenuTabProperty_Opening(sender, null);
+ => this.ContextMenuTabProperty_Opening(sender, null!);
public Twitter TwitterInstance
=> this.tw;
else
PublicSearchQueryMenuItem.Enabled = false;
- if (!this.ExistCurrentPost)
+ var post = this.CurrentPost;
+ if (!this.ExistCurrentPost || post == null)
{
this.CopySTOTMenuItem.Enabled = false;
this.CopyURLMenuItem.Enabled = false;
this.CopyURLMenuItem.Enabled = true;
this.CopyUserIdStripMenuItem.Enabled = true;
- var post = this.CurrentPost;
if (post.IsDm) this.CopyURLMenuItem.Enabled = false;
if (post.IsProtect) this.CopySTOTMenuItem.Enabled = false;
}
private async Task doShowUserStatus(string id, bool ShowInputDialog)
{
- TwitterUser user = null;
+ TwitterUser? user = null;
if (ShowInputDialog)
{
private async void RtCountMenuItem_Click(object sender, EventArgs e)
{
- if (!this.ExistCurrentPost)
+ var post = this.CurrentPost;
+ if (!this.ExistCurrentPost || post == null)
return;
- var post = this.CurrentPost;
var statusId = post.RetweetedId ?? post.StatusId;
TwitterStatus status;
if (ImageSelector.Visible)
{
this.MarkSettingCommonModified();
- this.StatusText_TextChanged(null, null);
+ this.StatusText_TextChanged(this.StatusText, EventArgs.Empty);
}
}
private void ImageSelector_VisibleChanged(object sender, EventArgs e)
- => this.StatusText_TextChanged(null, null);
+ => this.StatusText_TextChanged(this.StatusText, EventArgs.Empty);
/// <summary>
/// StatusTextでCtrl+Vが押下された時の処理
private void MenuItemCommand_DropDownOpening(object sender, EventArgs e)
{
var post = this.CurrentPost;
- if (this.ExistCurrentPost && !post.IsDm)
+ if (this.ExistCurrentPost && post != null && !post.IsDm)
RtCountMenuItem.Enabled = true;
else
RtCountMenuItem.Enabled = false;
private async void ShowRelatedStatusesMenuItem_Click(object sender, EventArgs e)
{
var post = this.CurrentPost;
- if (this.ExistCurrentPost && !post.IsDm)
+ if (this.ExistCurrentPost && post != null && !post.IsDm)
{
try
{
}
if (ev.Event == "unfavorite" && ev.Username.Equals(tw.Username, StringComparison.InvariantCultureIgnoreCase))
{
- var favTab = this._statuses.GetTabByType(MyCommon.TabUsageType.Favorites);
+ var favTab = this._statuses.FavoriteTab;
favTab.EnqueueRemovePost(ev.Id, setIsDeleted: false);
}
}
{
if (e.KeyCode == Keys.Space)
{
- this.JumpUnreadMenuItem_Click(null, null);
+ this.JumpUnreadMenuItem_Click(this.JumpUnreadMenuItem, EventArgs.Empty);
e.SuppressKeyPress = true;
}
// 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.ComponentModel;
// 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.ComponentModel;
{
public partial class TweetDetailsView : UserControl
{
- public TweenMain Owner { get; set; }
+ public TweenMain Owner { get; set; } = null!;
/// <summary>プロフィール画像のキャッシュ</summary>
- public ImageCache IconCache { get; set; }
+ public ImageCache IconCache { get; set; } = null!;
/// <summary><see cref="PostClass"/> のダンプを表示するか</summary>
public bool DumpPostClass { get; set; }
/// <summary>現在表示中の発言</summary>
- public PostClass CurrentPost { get; private set; }
+ public PostClass? CurrentPost { get; private set; }
[DefaultValue(false)]
public new bool TabStop
}
}
- private string GetUserId()
+ private string? GetUserId()
{
var m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$");
if (m.Success && this.Owner.IsTwitterId(m.Result("${ScreenName}")))
{
if (e.Url.AbsoluteUri != "about:blank")
{
- await this.ShowPostDetails(this.CurrentPost); // 現在の発言を表示し直す (Navigated の段階ではキャンセルできない)
+ await this.ShowPostDetails(this.CurrentPost!); // 現在の発言を表示し直す (Navigated の段階ではキャンセルできない)
await this.Owner.OpenUriInBrowserAsync(e.Url.OriginalString);
}
}
if (string.IsNullOrEmpty(imageUrl))
return;
+ var memoryImage = this.IconCache.TryGetFromCache(imageUrl);
+ if (memoryImage == null)
+ return;
+
this.Owner.SaveFileDialog1.FileName = imageUrl.Substring(imageUrl.LastIndexOf('/') + 1);
if (this.Owner.SaveFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
- using var orgBmp = new Bitmap(IconCache.TryGetFromCache(imageUrl).Image);
+ using var orgBmp = new Bitmap(memoryImage.Image);
using var bmp2 = new Bitmap(orgBmp.Size.Width, orgBmp.Size.Height);
using (var g = Graphics.FromImage(bmp2))
{
var menuItem = (ToolStripMenuItem)sender;
- string user;
+ string? user;
if (menuItem.Owner == this.ContextMenuPostBrowser)
{
user = GetUserId();
// 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.Linq;
if (Regex.IsMatch(before, Twitter.url_invalid_without_protocol_preceding_chars))
continue;
- string lasturl = null;
+ string? lasturl = null;
var last_url_invalid_match = false;
var domainMatches = Regex.Matches(domain, Twitter.url_valid_ascii_domain, RegexOptions.IgnoreCase).Cast<Match>();
// 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.Globalization;
/// </summary>
public static class TweetFormatter
{
- public static string AutoLinkHtml(string text, IEnumerable<TwitterEntity> entities, bool keepTco = false)
+ public static string AutoLinkHtml(string text, IEnumerable<TwitterEntity>? entities, bool keepTco = false)
{
if (entities == null)
entities = Enumerable.Empty<TwitterEntity>();
// 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.ComponentModel;
public event EventHandler<ThumbnailImageSearchEventArgs> ThumbnailImageSearchClick;
public ThumbnailInfo Thumbnail
- => this.pictureBox[this.scrollBar.Value].Tag as ThumbnailInfo;
+ => (ThumbnailInfo)this.pictureBox[this.scrollBar.Value].Tag;
public TweetThumbnail()
=> this.InitializeComponent();
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System.Diagnostics;
using System.IO;
using System.Linq;
//プロパティからアクセスされる共通情報
private readonly List<string> _hashList = new List<string>();
- private string nextCursorDirectMessage = null;
+ private string? nextCursorDirectMessage = null;
private long previousStatusId = -1L;
return orgData;
}
- public async Task<PostClass> PostStatus(PostStatusParams param)
+ public async Task<PostClass?> PostStatus(PostStatusParams param)
{
this.CheckAccountState();
return post;
}
- public async Task<long> UploadMedia(IMediaItem item, string mediaCategory = null)
+ public async Task<long> UploadMedia(IMediaItem item, string? mediaCategory = null)
{
this.CheckAccountState();
.ConfigureAwait(false);
}
- public async Task<PostClass> PostRetweet(long id, bool read)
+ public async Task<PostClass?> PostRetweet(long id, bool read)
{
this.CheckAccountState();
this.FollowersCount = self.FollowersCount;
this.FriendsCount = self.FriendsCount;
this.StatusesCount = self.StatusesCount;
- this.Location = self.Location;
- this.Bio = self.Description;
+ this.Location = self.Location ?? "";
+ this.Bio = self.Description ?? "";
}
/// <summary>
else
{
//幻覚fav対策
- var tc = TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites);
+ var tc = TabInformations.GetInstance().FavoriteTab;
post.IsFav = tc.Contains(retweeted.Id);
}
else
{
//幻覚fav対策
- var tc = TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites);
- post.IsFav = tc.Contains(post.StatusId) && TabInformations.GetInstance()[post.StatusId].IsFav;
+ var tc = TabInformations.GetInstance().FavoriteTab;
+ post.IsFav = tc.Posts.TryGetValue(post.StatusId, out var tabinfoPost) && tabinfoPost.IsFav;
}
if (status.Coordinates != null)
/// <summary>
/// ツイートに含まれる引用ツイートのURLからステータスIDを抽出
/// </summary>
- public static IEnumerable<long> GetQuoteTweetStatusIds(IEnumerable<TwitterEntity> entities, TwitterQuotedStatusPermalink quotedStatusLink)
+ public static IEnumerable<long> GetQuoteTweetStatusIds(IEnumerable<TwitterEntity>? entities, TwitterQuotedStatusPermalink? quotedStatusLink)
{
+ entities ??= Enumerable.Empty<TwitterEntity>();
+
var urls = entities.OfType<TwitterEntityUrl>().Select(x => x.ExpandedUrl);
if (quotedStatusLink != null)
}
}
- private long? CreatePostsFromJson(TwitterStatus[] items, MyCommon.WORKERTYPE gType, TabModel tab, bool read)
+ private long? CreatePostsFromJson(TwitterStatus[] items, MyCommon.WORKERTYPE gType, TabModel? tab, bool read)
{
long? minimumId = null;
private long? CreateFavoritePostsFromJson(TwitterStatus[] items, bool read)
{
- var favTab = TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.Favorites);
+ var favTab = TabInformations.GetInstance().FavoriteTab;
long? minimumId = null;
foreach (var status in items)
}
relPosts.Add(targetPost.StatusId, targetPost);
- Exception lastException = null;
+ Exception? lastException = null;
// in_reply_to_status_id を使用してリプライチェインを辿る
var nextPost = FindTopOfReplyChain(relPosts, targetPost.StatusId);
//二重取得回避
lock (LockObj)
{
- if (TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.DirectMessage).Contains(post.StatusId)) continue;
+ if (TabInformations.GetInstance().DirectMessageTab.Contains(post.StatusId)) continue;
}
//sender_id
//recipient_id
.ToArray();
//以下、ユーザー情報
- TwitterUser user;
+ TwitterUser? user;
if (gType == MyCommon.WORKERTYPE.UserStream)
{
- if (this.Api.CurrentUserId == message.Recipient.Id)
+ if (this.Api.CurrentUserId == message.Recipient?.Id)
{
user = message.Sender;
post.IsMe = false;
}
}
- post.UserId = user.Id;
- post.ScreenName = user.ScreenName;
- post.Nickname = user.Name.Trim();
- post.ImageUrl = user.ProfileImageUrlHttps;
- post.IsProtect = user.Protected;
+ if (user != null)
+ {
+ post.UserId = user.Id;
+ post.ScreenName = user.ScreenName;
+ post.Nickname = user.Name.Trim();
+ post.ImageUrl = user.ProfileImageUrlHttps;
+ post.IsProtect = user.Protected;
+ post.IsMe = post.UserId == this.UserId;
+ }
+ else
+ {
+ post.UserId = 0L;
+ post.ScreenName = "?????";
+ post.Nickname = "Unknown User";
+ }
// メモリ使用量削減 (同一のテキストであれば同一の string インスタンスを参照させる)
if (post.Text == post.TextFromApi)
post.IsExcludeReply = false;
post.IsDm = true;
- var dmTab = TabInformations.GetInstance().GetTabByType(MyCommon.TabUsageType.DirectMessage);
+ var dmTab = TabInformations.GetInstance().DirectMessageTab;
dmTab.AddPostQueue(post);
}
}
post.IsExcludeReply = false;
post.IsDm = true;
- var dmTab = TabInformations.GetInstance().GetTabByType<DirectMessagesTabModel>();
+ var dmTab = TabInformations.GetInstance().DirectMessageTab;
dmTab.AddPostQueue(post);
}
}
tab.OldestId = minimumId.Value;
}
- private string ReplaceTextFromApi(string text, TwitterEntities entities, TwitterQuotedStatusPermalink quotedStatusLink)
+ private string ReplaceTextFromApi(string text, TwitterEntities? entities, TwitterQuotedStatusPermalink? quotedStatusLink)
{
if (entities != null)
{
return text;
}
- internal static string CreateAccessibleText(string text, TwitterEntities entities, TwitterStatus quotedStatus, TwitterQuotedStatusPermalink quotedStatusLink)
+ internal static string CreateAccessibleText(string text, TwitterEntities? entities, TwitterStatus? quotedStatus, TwitterQuotedStatusPermalink? quotedStatusLink)
{
if (entities == null)
return text;
}
}
- if (quotedStatusLink != null)
+ if (quotedStatus != null && quotedStatusLink != null)
{
var quoteText = CreateAccessibleText(quotedStatus.FullText, quotedStatus.MergedEntities, quotedStatus: null, quotedStatusLink: null);
text += " " + string.Format(Properties.Resources.QuoteStatus_AccessibleText, quotedStatus.User.ScreenName, quoteText);
return true;
}
catch (TwitterApiException ex)
- when (ex.ErrorResponse.Errors.Any(x => x.Code == TwitterErrorCode.NotFound))
+ when (ex.Errors.Any(x => x.Code == TwitterErrorCode.NotFound))
{
return false;
}
}
- private void ExtractEntities(TwitterEntities entities, List<(long UserId, string ScreenName)> AtList, List<MediaInfo> media)
+ private void ExtractEntities(TwitterEntities? entities, List<(long UserId, string ScreenName)> AtList, List<MediaInfo> media)
{
if (entities != null)
{
}
}
- internal static string CreateHtmlAnchor(string text, TwitterEntities entities, TwitterQuotedStatusPermalink quotedStatusLink)
+ internal static string CreateHtmlAnchor(string text, TwitterEntities? entities, TwitterQuotedStatusPermalink? quotedStatusLink)
{
var mergedEntities = entities.Concat(TweetExtractor.ExtractEmojiEntities(text));
/// <summary>
/// Twitter APIから得たHTML形式のsource文字列を分析し、source名とURLに分離します
/// </summary>
- internal static (string SourceText, Uri SourceUri) ParseSource(string sourceHtml)
+ internal static (string SourceText, Uri? SourceUri) ParseSource(string? sourceHtml)
{
if (string.IsNullOrEmpty(sourceHtml))
return ("", null);
string sourceText;
- Uri sourceUri;
+ Uri? sourceUri;
// sourceHtmlの例: <a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>
return (sourceText, sourceUri);
}
- public async Task<TwitterApiStatus> GetInfoApi()
+ public async Task<TwitterApiStatus?> GetInfoApi()
{
if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return null;
public event EventHandler<PostDeletedEventArgs> PostDeleted;
public event EventHandler<UserStreamEventReceivedEventArgs> UserStreamEventReceived;
private DateTimeUtc _lastUserstreamDataReceived;
- private StreamAutoConnector userStreamConnector;
+ private StreamAutoConnector? userStreamConnector;
public class FormattedEvent
{
public MyCommon.EVENTTYPE Eventtype { get; set; }
public DateTimeUtc CreatedAt { get; set; }
- public string Event { get; set; }
- public string Username { get; set; }
- public string Target { get; set; }
+ public string Event { get; set; } = "";
+ public string Username { get; set; } = "";
+ public string Target { get; set; } = "";
public long Id { get; set; }
public bool IsMe { get; set; }
}
/// </summary>
private FormattedEvent CreateEventFromRetweet(TwitterStatus status)
{
+ if (status.RetweetedStatus == null)
+ throw new InvalidOperationException();
+
return new FormattedEvent
{
Eventtype = MyCommon.EVENTTYPE.Retweet,
if (eventData.Event == "favorite")
{
- var favTab = tabinfo.GetTabByType(MyCommon.TabUsageType.Favorites);
+ var favTab = tabinfo.FavoriteTab;
favTab.AddPostQueue(post);
if (tweetEvent.Source.Id == this.UserId)
public bool IsStreamActive { get; private set; }
public bool IsDisposed { get; private set; }
- public event Action<ITwitterStreamMessage> MessageReceived;
- public event Action Stopped;
- public event Action Started;
+ public event Action<ITwitterStreamMessage>? MessageReceived;
+ public event Action? Stopped;
+ public event Action? Started;
- private Task streamTask;
+ private Task? streamTask;
private CancellationTokenSource streamCts = new CancellationTokenSource();
public StreamAutoConnector(TwitterStreamObservable streamObservable)
// 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.ComponentModel;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
using System.Net;
using OpenTween.Api.DataModel;
{
this.ImageUrl = null;
}
- this.Url = user.Url;
+ this.Url = user.Url ?? "";
this.Protect = user.Protected;
this.FriendsCount = user.FriendsCount;
this.FollowersCount = user.FollowersCount;
public string ScreenName = "";
public string Location = "";
public string Description = "";
- public Uri ImageUrl = null;
+ public Uri? ImageUrl = null;
public string Url = "";
public bool Protect = false;
public int FriendsCount = 0;
// 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.ComponentModel;
{
public partial class UserInfoDialog : OTBaseForm
{
- private TwitterUser _displayUser;
- private CancellationTokenSource cancellationTokenSource = null;
+ private TwitterUser _displayUser = null!;
+ private CancellationTokenSource? cancellationTokenSource = null;
private readonly TweenMain mainForm;
private readonly TwitterApi twitterApi;
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")]
private void CancelLoading()
{
- CancellationTokenSource oldTokenSource = null;
+ CancellationTokenSource? oldTokenSource = null;
try
{
var newTokenSource = new CancellationTokenSource();
this.CancelLoading();
- var cancellationToken = this.cancellationTokenSource.Token;
+ var cancellationToken = this.cancellationTokenSource!.Token;
this._displayUser = user;
await Task.WhenAll(new[]
{
- this.SetDescriptionAsync(user.Description, user.Entities.Description, cancellationToken),
+ this.SetDescriptionAsync(user.Description, user.Entities?.Description, cancellationToken),
this.SetRecentStatusAsync(user.Status, cancellationToken),
- this.SetLinkLabelWebAsync(user.Url, user.Entities.Url, cancellationToken),
+ this.SetLinkLabelWebAsync(user.Url, user.Entities?.Url, cancellationToken),
this.SetUserImageAsync(user.ProfileImageUrlHttps, cancellationToken),
this.LoadFriendshipAsync(user.ScreenName, cancellationToken),
});
}
- private async Task SetDescriptionAsync(string descriptionText, TwitterEntities entities, CancellationToken cancellationToken)
+ private async Task SetDescriptionAsync(string? descriptionText, TwitterEntities? entities, CancellationToken cancellationToken)
{
if (descriptionText != null)
{
- foreach (var entity in entities.Urls)
+ var urlEntities = entities?.Urls ?? Array.Empty<TwitterEntityUrl>();
+
+ foreach (var entity in urlEntities)
entity.ExpandedUrl = await ShortUrl.Instance.ExpandUrlAsync(entity.ExpandedUrl);
// user.entities には urls 以外のエンティティが含まれていないため、テキストをもとに生成する
- var mergedEntities = entities.Urls.AsEnumerable<TwitterEntity>()
+ var mergedEntities = urlEntities.AsEnumerable<TwitterEntity>()
.Concat(TweetExtractor.ExtractHashtagEntities(descriptionText))
.Concat(TweetExtractor.ExtractMentionEntities(descriptionText))
.Concat(TweetExtractor.ExtractEmojiEntities(descriptionText));
});
}
- private async Task SetLinkLabelWebAsync(string uri, TwitterEntities entities, CancellationToken cancellationToken)
+ private async Task SetLinkLabelWebAsync(string? uri, TwitterEntities? entities, CancellationToken cancellationToken)
{
if (uri != null)
{
- var origUrl = entities?.Urls[0].ExpandedUrl ?? uri;
+ var origUrl = entities?.Urls?.FirstOrDefault()?.ExpandedUrl ?? uri;
var expandedUrl = await ShortUrl.Instance.ExpandUrlAsync(origUrl);
if (cancellationToken.IsCancellationRequested)
}
}
- private async Task SetRecentStatusAsync(TwitterStatus status, CancellationToken cancellationToken)
+ private async Task SetRecentStatusAsync(TwitterStatus? status, CancellationToken cancellationToken)
{
if (status != null)
{
var entities = status.MergedEntities;
+ var urlEntities = entities.Urls ?? Array.Empty<TwitterEntityUrl>();
- foreach (var entity in entities.Urls)
+ foreach (var entity in urlEntities)
entity.ExpandedUrl = await ShortUrl.Instance.ExpandUrlAsync(entity.ExpandedUrl);
var mergedEntities = entities.Concat(TweetExtractor.ExtractEmojiEntities(status.FullText));
}
else
{
- Task showUserTask = null;
+ Task? showUserTask = null;
if (TextBoxName.Modified ||
TextBoxLocation.Modified ||
if (disposing)
{
var cts = this.cancellationTokenSource;
- cts.Cancel();
- cts.Dispose();
+ cts?.Cancel();
+ cts?.Dispose();
var oldImage = this.UserPicture.Image;
this.UserPicture.Image = null;
// 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.ComponentModel;
public Task WaitForAsync(Task task)
=> this.WaitForAsync(this.ConvertTaskWithValue(task));
- public Task WaitForAsync(IWin32Window owner, Task task)
+ public Task WaitForAsync(IWin32Window? owner, Task task)
=> this.WaitForAsync(owner, this.ConvertTaskWithValue(task));
public Task<T> WaitForAsync<T>(Task<T> task)
/// </summary>
/// <param name="owner">ダイアログのオーナー</param>
/// <param name="task">待機するタスク</param>
- public Task<T> WaitForAsync<T>(IWin32Window owner, Task<T> task)
+ public Task<T> WaitForAsync<T>(IWin32Window? owner, Task<T> task)
{
return Task.Run(async () =>
{
// 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.Linq;
[Serializable]
public class WebApiException : Exception
{
- public string ResponseText { get; } = null;
+ public string? ResponseText { get; } = null;
public WebApiException() { }
public WebApiException(string message) : base(message) { }
// 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.Linq;
int SetSecuritySite([In] IInternetSecurityMgrSite pSite);
[PreserveSig]
- int GetSecuritySite(out IInternetSecurityMgrSite pSite);
+ int GetSecuritySite(out IInternetSecurityMgrSite? pSite);
[PreserveSig]
int MapUrlToZone([In, MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, out int pdwZone, int dwFlags);
int SetZoneMapping(int dwZone, [In, MarshalAs(UnmanagedType.LPWStr)] string lpszPattern, int dwFlags);
[PreserveSig]
- int GetZoneMappings(int dwZone, ref IEnumString ppenumstring, int dwFlags);
+ int GetZoneMappings(int dwZone, ref IEnumString? ppenumstring, int dwFlags);
}
}
#endregion
private readonly object ocx = new object();
private readonly WebBrowserAPI.IServiceProvider ocxServiceProvider;
private readonly IntPtr profferServicePtr = new IntPtr();
- private readonly WebBrowserAPI.IProfferService profferService;
+ private readonly WebBrowserAPI.IProfferService profferService = null!;
public POLICY SecurityPolicy { get; set; } = 0;
int WebBrowserAPI.IInternetSecurityManager.GetSecurityId(string pwszUrl, byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved)
=> WebBrowserAPI.INET_E_DEFAULT_ACTION;
- int WebBrowserAPI.IInternetSecurityManager.GetSecuritySite(out WebBrowserAPI.IInternetSecurityMgrSite pSite)
+ int WebBrowserAPI.IInternetSecurityManager.GetSecuritySite(out WebBrowserAPI.IInternetSecurityMgrSite? pSite)
{
pSite = null;
return WebBrowserAPI.INET_E_DEFAULT_ACTION;
}
- int WebBrowserAPI.IInternetSecurityManager.GetZoneMappings(int dwZone, ref IEnumString ppenumstring, int dwFlags)
+ int WebBrowserAPI.IInternetSecurityManager.GetZoneMappings(int dwZone, ref IEnumString? ppenumstring, int dwFlags)
{
ppenumstring = null;
return WebBrowserAPI.INET_E_DEFAULT_ACTION;
// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
// Boston, MA 02110-1301, USA.
+#nullable enable
+
using System;
namespace OpenTween