From 8402c3ebc8e5146b814e4769ed7adcc82c540864 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 20 May 2024 02:37:13 +0900 Subject: [PATCH] =?utf8?q?=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3=E3=83=88?= =?utf8?q?=E8=BF=BD=E5=8A=A0=E6=99=82=E3=81=ABTwitter{Cookie,OAuth}SetupDi?= =?utf8?q?alog=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- CHANGELOG.txt | 1 + OpenTween/AppendSettingDialog.cs | 92 +--------------------- OpenTween/Setting/Panel/BasedPanel.Designer.cs | 9 +++ OpenTween/Setting/Panel/BasedPanel.cs | 54 +++++++++++++ OpenTween/Setting/Panel/BasedPanel.resx | 6 +- OpenTween/SocialProtocol/AccountSetupDispatcher.cs | 65 +++++++++++++++ OpenTween/SocialProtocol/IAccountFactory.cs | 36 +++++++++ .../Twitter/TwitterCookieSetupDialog.cs | 14 +++- .../Twitter/TwitterOAuthSetupDialog.cs | 19 ++++- 9 files changed, 204 insertions(+), 92 deletions(-) create mode 100644 OpenTween/SocialProtocol/AccountSetupDispatcher.cs create mode 100644 OpenTween/SocialProtocol/IAccountFactory.cs diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1df31a34..451e9a19 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,7 @@ * NEW: Twemoji 15.1.0 に対応しました - Unicode 15.1 で追加された絵文字が表示されるようになります * CHG: 設定画面でのアカウント一覧の表示形式を変更 + * CHG: 新規アカウント追加時のダイアログの構成を変更 * CHG: 新規タブの初回に読み込まれた発言を既読状態にする(起動時の初回の読み込みと同じ動作となる) * CHG: ドメインに x.com が使われている引用ツイートの展開・投稿に対応 * FIX: 発言の削除中にタブを切り替えるとエラーが発生する不具合を修正 (thx @Tan90909090!) diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index 9f0939a5..435e7625 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -32,7 +32,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using OpenTween.Api; using OpenTween.Connection; using OpenTween.Models; using OpenTween.Setting.Panel; @@ -47,7 +46,8 @@ namespace OpenTween { this.InitializeComponent(); - this.BasedPanel.AddAccountButton.Click += this.AddAccountButton_Click; + this.BasedPanel.ApplyNetworkSettings = this.ApplyNetworkSettings; + this.BasedPanel.OpenInBrowser = this.OpenInBrowser; this.GetPeriodPanel.CheckPostAndGet.CheckedChanged += this.CheckPostAndGet_CheckedChanged; this.ActionPanel.UReadMng.CheckedChanged += this.UReadMng_CheckedChanged; @@ -166,60 +166,6 @@ namespace OpenTween } } - private async void AddAccountButton_Click(object sender, EventArgs e) - { - using (ControlTransaction.Disabled(this.BasedPanel.AddAccountButton)) - { - try - { - this.ApplyNetworkSettings(); - - var appToken = this.SelectAuthType(); - if (appToken == null) - return; - - UserAccount newAccount; - if (appToken.AuthType == APIAuthType.TwitterComCookie) - { - newAccount = new() - { - TwitterAuthType = appToken.AuthType, - TwitterComCookie = appToken.TwitterComCookie, - }; - - using var twitterApi = new TwitterApi(); - using var apiConnection = new TwitterApiConnection(new TwitterCredentialCookie(appToken), new()); - twitterApi.Initialize(apiConnection); - var twitterUser = await twitterApi.AccountVerifyCredentials(); - newAccount.UserId = twitterUser.IdStr; - newAccount.Username = twitterUser.ScreenName; - } - else - { - var account = await this.PinAuth(appToken); - if (account == null) - return; - newAccount = account; - } - - this.BasedPanel.AddAccount(newAccount); - - MessageBox.Show( - this, - Properties.Resources.AuthorizeButton_Click1, - "Authenticate", - MessageBoxButtons.OK); - } - catch (TwitterApiException ex) - { - var message = Properties.Resources.AuthorizeButton_Click2 + Environment.NewLine + - string.Join(Environment.NewLine, ex.LongMessages); - - MessageBox.Show(this, message, "Authenticate", MessageBoxButtons.OK); - } - } - } - /// /// 現在設定画面に入力されているネットワーク関係の設定を適用します /// @@ -250,40 +196,10 @@ namespace OpenTween TwitterApiConnection.RestApiHost = this.ConnectionPanel.TwitterAPIText.Text.Trim(); } - private TwitterAppToken? SelectAuthType() - { - using var dialog = new AuthTypeSelectDialog(); - - var ret = dialog.ShowDialog(this); - if (ret != DialogResult.OK) - return null; - - return dialog.Result; - } - - private async Task PinAuth(TwitterAppToken appToken) + private async Task OpenInBrowser(IWin32Window? owner, Uri uri) { - var requestToken = await TwitterApiConnection.GetRequestTokenAsync(appToken); - - var pinPageUrl = TwitterApiConnection.GetAuthorizeUri(requestToken); - var browserPath = this.ActionPanel.BrowserPathText.Text; - var pin = AuthDialog.DoAuth(this, pinPageUrl, browserPath); - if (MyCommon.IsNullOrEmpty(pin)) - return null; // キャンセルされた場合 - - var accessTokenResponse = await TwitterApiConnection.GetAccessTokenAsync(requestToken, pin); - - return new UserAccount - { - TwitterAuthType = appToken.AuthType, - TwitterOAuth1ConsumerKey = appToken.OAuth1CustomConsumerKey?.Value ?? "", - TwitterOAuth1ConsumerSecret = appToken.OAuth1CustomConsumerSecret?.Value ?? "", - Username = accessTokenResponse["screen_name"], - UserId = accessTokenResponse["user_id"], - Token = accessTokenResponse["oauth_token"], - TokenSecret = accessTokenResponse["oauth_token_secret"], - }; + await MyCommon.OpenInBrowserAsync(owner, browserPath, uri); } private void CheckPostAndGet_CheckedChanged(object sender, EventArgs e) diff --git a/OpenTween/Setting/Panel/BasedPanel.Designer.cs b/OpenTween/Setting/Panel/BasedPanel.Designer.cs index a111e990..2aa8e5bb 100644 --- a/OpenTween/Setting/Panel/BasedPanel.Designer.cs +++ b/OpenTween/Setting/Panel/BasedPanel.Designer.cs @@ -28,6 +28,7 @@ /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BasedPanel)); this.AccountListLabel = new System.Windows.Forms.Label(); this.AccountsListBox = new System.Windows.Forms.ListBox(); @@ -35,6 +36,7 @@ this.RemoveAccountButton = new System.Windows.Forms.Button(); this.MakePrimaryButton = new System.Windows.Forms.Button(); this.panel1 = new System.Windows.Forms.Panel(); + this.contextMenuAddAccount = new System.Windows.Forms.ContextMenuStrip(this.components); this.panel1.SuspendLayout(); this.SuspendLayout(); // @@ -54,6 +56,7 @@ resources.ApplyResources(this.AddAccountButton, "AddAccountButton"); this.AddAccountButton.Name = "AddAccountButton"; this.AddAccountButton.UseVisualStyleBackColor = true; + this.AddAccountButton.Click += new System.EventHandler(this.AddAccountButton_Click); // // RemoveAccountButton // @@ -79,6 +82,11 @@ resources.ApplyResources(this.panel1, "panel1"); this.panel1.Name = "panel1"; // + // contextMenuAddAccount + // + this.contextMenuAddAccount.Name = "contextMenuAddAccount"; + resources.ApplyResources(this.contextMenuAddAccount, "contextMenuAddAccount"); + // // BasedPanel // resources.ApplyResources(this, "$this"); @@ -98,5 +106,6 @@ internal System.Windows.Forms.Button RemoveAccountButton; internal System.Windows.Forms.Button MakePrimaryButton; private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.ContextMenuStrip contextMenuAddAccount; } } diff --git a/OpenTween/Setting/Panel/BasedPanel.cs b/OpenTween/Setting/Panel/BasedPanel.cs index 7b9370a6..042b27b6 100644 --- a/OpenTween/Setting/Panel/BasedPanel.cs +++ b/OpenTween/Setting/Panel/BasedPanel.cs @@ -30,6 +30,9 @@ using System; using System.ComponentModel; using System.Data; using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; +using OpenTween.SocialProtocol; namespace OpenTween.Setting.Panel { @@ -37,6 +40,12 @@ namespace OpenTween.Setting.Panel { internal BindingList AccountsList { get; } = new(); + internal Action? ApplyNetworkSettings { get; set; } + + internal Func? OpenInBrowser { get; set; } + + private readonly AccountSetupDispatcher setupDispatcher = new(); + internal record AccountListBoxItem(UserAccount AccountSettings, bool IsPrimary) { public string DisplayText @@ -61,6 +70,7 @@ namespace OpenTween.Setting.Panel { this.InitializeComponent(); this.InitializeBinding(); + this.InitializeAddAccountDropdown(); } private void InitializeBinding() @@ -69,6 +79,22 @@ namespace OpenTween.Setting.Panel this.AccountsListBox.DisplayMember = nameof(AccountListBoxItem.DisplayText); } + private void InitializeAddAccountDropdown() + { + foreach (var (id, caption) in this.setupDispatcher.GetCaptions()) + { + var menuItem = new ToolStripMenuItem + { + Text = caption, + Tag = id, + }; + menuItem.Click += this.AddAccountMenuItem_Click; + + this.contextMenuAddAccount.Items.Add(menuItem); + this.components.Add(menuItem); + } + } + public void LoadConfig(SettingCommon settingCommon) { using (ControlTransaction.Update(this.AccountsListBox)) @@ -155,6 +181,34 @@ namespace OpenTween.Setting.Panel this.AccountsList[index] with { IsPrimary = true }; } + private void AddAccountButton_Click(object sender, EventArgs e) + { + this.contextMenuAddAccount.Show( + this.AddAccountButton, + new(x: 0, y: this.AddAccountButton.Height) + ); + } + + private void AddAccountMenuItem_Click(object sender, EventArgs e) + { + var setupId = (Guid)((ToolStripMenuItem)sender).Tag; + + this.ApplyNetworkSettings?.Invoke(); + + var authorizedAccount = this.setupDispatcher.Dispatch(this, setupId, this.OpenInBrowser); + if (authorizedAccount == null) + return; + + this.AddAccount(authorizedAccount); + + MessageBox.Show( + this, + Properties.Resources.AuthorizeButton_Click1, + "Authenticate", + MessageBoxButtons.OK + ); + } + private void RemoveAccountButton_Click(object sender, EventArgs e) { var selectedIndex = this.AccountsListBox.SelectedIndex; diff --git a/OpenTween/Setting/Panel/BasedPanel.resx b/OpenTween/Setting/Panel/BasedPanel.resx index d71e0c3e..277b059e 100644 --- a/OpenTween/Setting/Panel/BasedPanel.resx +++ b/OpenTween/Setting/Panel/BasedPanel.resx @@ -24,6 +24,8 @@ panel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 2 + contextMenuAddAccount + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 MakePrimaryButton panel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -31,7 +33,7 @@ panel1 $this System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 0 + 1 RemoveAccountButton panel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -57,6 +59,8 @@ 100, 25 2 追加 + 181, 26 + 17, 17 Top, Right True NoControl diff --git a/OpenTween/SocialProtocol/AccountSetupDispatcher.cs b/OpenTween/SocialProtocol/AccountSetupDispatcher.cs new file mode 100644 index 00000000..6d69d374 --- /dev/null +++ b/OpenTween/SocialProtocol/AccountSetupDispatcher.cs @@ -0,0 +1,65 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; +using OpenTween.SocialProtocol.Twitter; + +namespace OpenTween.SocialProtocol +{ + public class AccountSetupDispatcher + { + public record AccountSetupItem( + Guid Id, + string Caption, + Func CreateInstance + ); + + private readonly List setupList; + + public AccountSetupDispatcher() + { + this.setupList = new() + { + new(Guid.NewGuid(), "Twitter (OAuth)", () => new TwitterOAuthSetupDialog()), + new(Guid.NewGuid(), "Twitter (Cookie)", () => new TwitterCookieSetupDialog()), + }; + } + + public (Guid Id, string Caption)[] GetCaptions() + => this.setupList.Select(x => (x.Id, x.Caption)).ToArray(); + + public UserAccount? Dispatch(IWin32Window? owner, Guid setupId, Func? openInBrowser) + { + var setupItem = this.setupList.First(x => x.Id == setupId); + + using var setup = setupItem.CreateInstance(); + setup.OpenInBrowser = openInBrowser; + + return setup.ShowAccountSetupDialog(owner); + } + } +} diff --git a/OpenTween/SocialProtocol/IAccountFactory.cs b/OpenTween/SocialProtocol/IAccountFactory.cs new file mode 100644 index 00000000..35a9173c --- /dev/null +++ b/OpenTween/SocialProtocol/IAccountFactory.cs @@ -0,0 +1,36 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2024 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace OpenTween.SocialProtocol +{ + public interface IAccountFactory : IDisposable + { + public Func? OpenInBrowser { get; set; } + + public UserAccount? ShowAccountSetupDialog(IWin32Window? owner); + } +} diff --git a/OpenTween/SocialProtocol/Twitter/TwitterCookieSetupDialog.cs b/OpenTween/SocialProtocol/Twitter/TwitterCookieSetupDialog.cs index 63d7a41d..b4ae2637 100644 --- a/OpenTween/SocialProtocol/Twitter/TwitterCookieSetupDialog.cs +++ b/OpenTween/SocialProtocol/Twitter/TwitterCookieSetupDialog.cs @@ -22,15 +22,18 @@ #nullable enable using System; +using System.Threading.Tasks; using System.Windows.Forms; using OpenTween.Api; namespace OpenTween.SocialProtocol.Twitter { - public partial class TwitterCookieSetupDialog : OTBaseForm + public partial class TwitterCookieSetupDialog : OTBaseForm, IAccountFactory { public TwitterCookieSetup Model { get; } = new(); + public Func? OpenInBrowser { get; set; } + public TwitterCookieSetupDialog() { this.InitializeComponent(); @@ -48,6 +51,15 @@ namespace OpenTween.SocialProtocol.Twitter ); } + public UserAccount? ShowAccountSetupDialog(IWin32Window? owner) + { + var ret = this.ShowDialog(owner); + if (ret != DialogResult.OK) + return null; + + return this.Model.AuthorizedAccount!; + } + private async void ButtonOK_Click(object sender, EventArgs e) { if (MyCommon.IsNullOrEmpty(this.Model.TwitterComCookie)) diff --git a/OpenTween/SocialProtocol/Twitter/TwitterOAuthSetupDialog.cs b/OpenTween/SocialProtocol/Twitter/TwitterOAuthSetupDialog.cs index eafd1d80..3046e1f2 100644 --- a/OpenTween/SocialProtocol/Twitter/TwitterOAuthSetupDialog.cs +++ b/OpenTween/SocialProtocol/Twitter/TwitterOAuthSetupDialog.cs @@ -23,15 +23,18 @@ using System; using System.Runtime.InteropServices; +using System.Threading.Tasks; using System.Windows.Forms; using OpenTween.Api; namespace OpenTween.SocialProtocol.Twitter { - public partial class TwitterOAuthSetupDialog : OTBaseForm + public partial class TwitterOAuthSetupDialog : OTBaseForm, IAccountFactory { public TwitterOAuthSetup Model { get; } = new(); + public Func? OpenInBrowser { get; set; } + public TwitterOAuthSetupDialog() { this.InitializeComponent(); @@ -96,6 +99,15 @@ namespace OpenTween.SocialProtocol.Twitter ); } + public UserAccount? ShowAccountSetupDialog(IWin32Window? owner) + { + var ret = this.ShowDialog(owner); + if (ret != DialogResult.OK) + return null; + + return this.Model.AuthorizedAccount!; + } + private async void ButtonGetAuthorizeUri_Click(object sender, EventArgs e) { using (ControlTransaction.Disabled(this)) @@ -123,7 +135,10 @@ namespace OpenTween.SocialProtocol.Twitter if (e.Button == MouseButtons.Right) return; - await MyCommon.OpenInBrowserAsync(this, this.Model.AuthorizeUri); + if (this.OpenInBrowser == null) + throw new InvalidOperationException($"{nameof(this.OpenInBrowser)} is not set"); + + await this.OpenInBrowser(this, this.Model.AuthorizeUri); } private void MenuItemCopyLink_Click(object sender, EventArgs e) -- 2.11.0