From 8d7f8c6714d3bfbb19442df763095507576d0107 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 7 Feb 2024 10:12:53 +0900 Subject: [PATCH] =?utf8?q?=E3=83=A1=E3=82=A4=E3=83=B3=E4=BB=A5=E5=A4=96?= =?utf8?q?=E3=81=AE=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3=E3=83=88=E3=81=AE?= =?utf8?q?=E3=83=9B=E3=83=BC=E3=83=A0=E3=82=BF=E3=82=A4=E3=83=A0=E3=83=A9?= =?utf8?q?=E3=82=A4=E3=83=B3=E3=82=92=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B?= =?utf8?q?=E6=A9=9F=E8=83=BD=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- CHANGELOG.txt | 4 ++ .../SocialProtocol/AccountCollectionTest.cs | 19 ++++++ OpenTween/ApplicationEvents.cs | 16 +++++ OpenTween/Models/HomeSpecifiedAccountTabModel.cs | 74 ++++++++++++++++++++++ OpenTween/SocialProtocol/AccountCollection.cs | 3 + OpenTween/Tween.cs | 30 ++++++++- 6 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 OpenTween/Models/HomeSpecifiedAccountTabModel.cs diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 3707ae3b..0657dd64 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,10 @@ 更新履歴 ==== Unreleased + * NEW: メインアカウント以外のホームタイムライン表示に対応 + - タブ単位で切り替わるマルチアカウント機能です + - 投稿欄やふぁぼ・RT等の機能も表示中のタブに連動して使用するアカウントが変わります + - 現時点ではメインアカウント以外のタブ設定は次回起動時に保持されません * NEW: Twemoji 15.1.0 に対応しました - Unicode 15.1 で追加された絵文字が表示されるようになります * CHG: 設定画面でのアカウント一覧の表示形式を変更 diff --git a/OpenTween.Tests/SocialProtocol/AccountCollectionTest.cs b/OpenTween.Tests/SocialProtocol/AccountCollectionTest.cs index 7ba90e6c..ae35efc0 100644 --- a/OpenTween.Tests/SocialProtocol/AccountCollectionTest.cs +++ b/OpenTween.Tests/SocialProtocol/AccountCollectionTest.cs @@ -142,6 +142,25 @@ namespace OpenTween.SocialProtocol } [Fact] + public void SecondaryAccounts_Test() + { + using var accounts = new AccountCollection(); + accounts.LoadFromSettings(new() + { + UserAccounts = new() + { + this.CreateAccountSetting("00000000-0000-4000-8000-000000000000"), + this.CreateAccountSetting("00000000-0000-4000-8000-111111111111"), + }, + SelectedAccountKey = new("00000000-0000-4000-8000-000000000000"), + }); + + var secondaryAccounts = accounts.SecondaryAccounts; + Assert.Single(secondaryAccounts); + Assert.Equal(new("00000000-0000-4000-8000-111111111111"), secondaryAccounts[0].UniqueKey); + } + + [Fact] public void GetAccountForTab_DefaultTest() { using var accounts = new AccountCollection(); diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 18f7986e..dd802ac8 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -31,6 +31,7 @@ using System; using System.Linq; using System.Windows.Forms; using OpenTween.Connection; +using OpenTween.Models; using OpenTween.Setting; using OpenTween.SocialProtocol; using OpenTween.SocialProtocol.Twitter; @@ -100,6 +101,7 @@ namespace OpenTween } SetupAccounts(container.AccountCollection, settings); + AddSecondaryAccountTabs(container.AccountCollection, container.TabInfo); Application.Run(container.MainForm); @@ -176,5 +178,19 @@ namespace OpenTween throw new WebApiException(ex.InnerException.Message, ex); } } + + private static void AddSecondaryAccountTabs(AccountCollection accounts, TabInformations tabInfo) + { + foreach (var account in accounts.Items) + { + var accountKey = account.UniqueKey; + if (accountKey == accounts.Primary.UniqueKey) + continue; + + var tabName = tabInfo.MakeTabName($"@{account.UserName}"); + var homeTab = new HomeSpecifiedAccountTabModel(tabName, accountKey); + tabInfo.AddTab(homeTab); + } + } } } diff --git a/OpenTween/Models/HomeSpecifiedAccountTabModel.cs b/OpenTween/Models/HomeSpecifiedAccountTabModel.cs new file mode 100644 index 00000000..cbe10f8f --- /dev/null +++ b/OpenTween/Models/HomeSpecifiedAccountTabModel.cs @@ -0,0 +1,74 @@ +// 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 OpenTween.SocialProtocol; + +namespace OpenTween.Models +{ + public class HomeSpecifiedAccountTabModel : InternalStorageTabModel + { + public override MyCommon.TabUsageType TabType + => MyCommon.TabUsageType.Undefined; + + public override bool IsPermanentTabType + => false; + + public override Guid? SourceAccountId { get; } + + public HomeSpecifiedAccountTabModel(string tabName, Guid accountId) + : base(tabName) + { + this.SourceAccountId = accountId; + } + + public override async Task RefreshAsync(ISocialAccount account, bool backward, IProgress progress) + { + progress.Report("Home refreshing..."); + + var firstLoad = !this.IsFirstLoadCompleted; + var count = Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Timeline, backward, firstLoad); + var cursor = backward ? this.CursorBottom : this.CursorTop; + + var response = await account.Client.GetHomeTimeline(count, cursor, firstLoad) + .ConfigureAwait(false); + + foreach (var post in response.Posts) + this.AddPostQueue(post); + + TabInformations.GetInstance().DistributePosts(); + + if (response.CursorTop != null && !backward) + this.CursorTop = response.CursorTop; + + if (response.CursorBottom != null) + this.CursorBottom = response.CursorBottom; + + if (firstLoad) + this.IsFirstLoadCompleted = true; + + progress.Report("Home refreshed"); + } + } +} diff --git a/OpenTween/SocialProtocol/AccountCollection.cs b/OpenTween/SocialProtocol/AccountCollection.cs index cf713802..afebef2f 100644 --- a/OpenTween/SocialProtocol/AccountCollection.cs +++ b/OpenTween/SocialProtocol/AccountCollection.cs @@ -43,6 +43,9 @@ namespace OpenTween.SocialProtocol public ISocialAccount[] Items => this.accounts.Values.ToArray(); + public ISocialAccount[] SecondaryAccounts + => this.accounts.Values.Where(x => x.UniqueKey != this.primaryId).ToArray(); + public void LoadFromSettings(SettingCommon settingCommon) { var oldAccounts = this.accounts; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 2603383d..a94b0944 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -509,7 +509,11 @@ namespace OpenTween // タイマー設定 - this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Home] = () => this.InvokeAsync(() => this.RefreshTabAsync()); + this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Home] = () => this.InvokeAsync(() => Task.WhenAll(new[] + { + this.RefreshTabAsync(), + this.RefreshTabAsync(), + })); this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Mention] = () => this.InvokeAsync(() => this.RefreshTabAsync()); this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Dm] = () => this.InvokeAsync(() => this.RefreshTabAsync()); this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.PublicSearch] = () => this.InvokeAsync(() => this.RefreshTabAsync()); @@ -2492,6 +2496,7 @@ namespace OpenTween { // 設定画面表示前のユーザー情報 var previousAccountId = this.settings.Common.SelectedAccountKey; + var previousSecondaryAccounts = this.accounts.SecondaryAccounts; var oldIconCol = this.Use2ColumnsMode; if (this.ShowSettingDialog() == DialogResult.OK) @@ -2685,6 +2690,28 @@ namespace OpenTween if (this.PrimaryAccount.UniqueKey != previousAccountId) await this.DoGetFollowersMenu(); + + var currentSecondaryAccounts = this.accounts.SecondaryAccounts; + var newSecondaryAccounts = currentSecondaryAccounts + .Where(x => !previousSecondaryAccounts.Any(y => y.UniqueKey == x.UniqueKey)); + this.AddSecondaryAccountTabs(newSecondaryAccounts); + } + + private void AddSecondaryAccountTabs(IEnumerable accounts) + { + foreach (var account in accounts) + { + var isPrimary = account.UniqueKey == this.accounts.Primary.UniqueKey; + var tabExists = this.statuses.GetTabsByType() + .Any(x => x.SourceAccountId == account.UniqueKey); + if (tabExists) + continue; + + var tabName = this.statuses.MakeTabName($"@{account.UserName}"); + var homeTab = new HomeSpecifiedAccountTabModel(tabName, account.UniqueKey); + this.statuses.AddTab(homeTab); + this.AddNewTab(homeTab, startup: false); + } } /// @@ -7802,6 +7829,7 @@ namespace OpenTween this.RefreshNoRetweetIdsAsync, this.RefreshTwitterConfigurationAsync, this.RefreshTabAsync, + this.RefreshTabAsync, this.RefreshTabAsync, this.RefreshTabAsync, this.RefreshTabAsync, -- 2.11.0