OSDN Git Service

PostClass.CreatedAtの型をDateTimeUtcに変更
[opentween/open-tween.git] / OpenTween / Models / HomeTabModel.cs
index fe44419..627fa9c 100644 (file)
 // Boston, MA 02110-1301, USA.
 
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
+using OpenTween.Setting;
 
 namespace OpenTween.Models
 {
@@ -38,6 +41,12 @@ namespace OpenTween.Models
         public override MyCommon.TabUsageType TabType
             => MyCommon.TabUsageType.Home;
 
+        public int TweetsPerHour => this.tweetsPerHour;
+
+        // 流速計測用
+        private int tweetsPerHour = 0;
+        private ConcurrentDictionary<DateTimeUtc, int> tweetsTimestamps = new ConcurrentDictionary<DateTimeUtc, int>();
+
         public HomeTabModel() : this(MyCommon.DEFAULTTAB.RECENT)
         {
         }
@@ -45,5 +54,62 @@ namespace OpenTween.Models
         public HomeTabModel(string tabName) : base(tabName)
         {
         }
+
+        public override void AddPostQueue(PostClass post)
+        {
+            base.AddPostQueue(post);
+            this.UpdateTimelineSpeed(post.CreatedAt);
+        }
+
+        public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress<string> progress)
+        {
+            bool read;
+            if (!SettingManager.Common.UnreadManage)
+                read = true;
+            else
+                read = startup && SettingManager.Common.Read;
+
+            progress.Report(string.Format(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText5, backward ? -1 : 1));
+
+            await tw.GetHomeTimelineApi(read, this, backward, startup)
+                .ConfigureAwait(false);
+
+            // 新着時未読クリア
+            if (SettingManager.Common.ReadOldPosts)
+                TabInformations.GetInstance().SetReadHomeTab();
+
+            TabInformations.GetInstance().DistributePosts();
+
+            progress.Report(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText1);
+        }
+
+        /// <summary>
+        /// タイムラインに追加された発言件数を反映し、タイムラインの流速を更新します
+        /// </summary>
+        private void UpdateTimelineSpeed(DateTimeUtc postCreatedAt)
+        {
+            var now = DateTimeUtc.Now;
+
+            // 1 時間以上前の時刻は追加しない
+            var oneHour = TimeSpan.FromHours(1);
+            if (now - postCreatedAt > oneHour)
+                return;
+
+            this.tweetsTimestamps.AddOrUpdate(postCreatedAt, 1, (k, v) => v + 1);
+
+            var removeKeys = new List<DateTimeUtc>();
+            var tweetsInWindow = 0;
+            foreach (var (timestamp, count) in this.tweetsTimestamps)
+            {
+                if (now - timestamp > oneHour)
+                    removeKeys.Add(timestamp);
+                else
+                    tweetsInWindow += count;
+            }
+            Interlocked.Exchange(ref this.tweetsPerHour, tweetsInWindow);
+
+            foreach (var key in removeKeys)
+                this.tweetsTimestamps.TryRemove(key, out var _);
+        }
     }
 }