OSDN Git Service

ツイート文字数の280文字への上限緩和 (weightedLength) に対応
[opentween/open-tween.git] / OpenTween / Twitter.cs
index 8cd9875..340b270 100644 (file)
@@ -149,6 +149,7 @@ namespace OpenTween
 
         public TwitterApi Api { get; }
         public TwitterConfiguration Configuration { get; private set; }
+        public TwitterTextConfiguration TextConfiguration { get; private set; }
 
         delegate void GetIconImageDelegate(PostClass post);
         private readonly object LockObj = new object();
@@ -181,6 +182,7 @@ namespace OpenTween
         {
             this.Api = api;
             this.Configuration = TwitterConfiguration.DefaultConfiguration();
+            this.TextConfiguration = TwitterTextConfiguration.DefaultConfiguration();
         }
 
         public TwitterApiAccessLevel AccessLevel
@@ -280,8 +282,7 @@ namespace OpenTween
         {
             this.CheckAccountState();
 
-            if (mediaIds == null &&
-                Twitter.DMSendTextRegex.IsMatch(postStr))
+            if (Twitter.DMSendTextRegex.IsMatch(postStr))
             {
                 await this.SendDirectMessage(postStr)
                     .ConfigureAwait(false);
@@ -602,8 +603,7 @@ namespace OpenTween
             }
 
             var minimumId = this.CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.Timeline, tab, read);
-
-            if (minimumId != null && minimumId.Value < tab.OldestId)
+            if (minimumId != null)
                 tab.OldestId = minimumId.Value;
         }
 
@@ -626,8 +626,7 @@ namespace OpenTween
             }
 
             var minimumId = this.CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.Reply, tab, read);
-
-            if (minimumId != null && minimumId.Value < tab.OldestId)
+            if (minimumId != null)
                 tab.OldestId = minimumId.Value;
         }
 
@@ -662,7 +661,7 @@ namespace OpenTween
 
             var minimumId = CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.UserTimeline, tab, read);
 
-            if (minimumId != null && minimumId.Value < tab.OldestId)
+            if (minimumId != null)
                 tab.OldestId = minimumId.Value;
         }
 
@@ -845,7 +844,7 @@ namespace OpenTween
             post.Source = string.Intern(sourceText);
             post.SourceUri = sourceUri;
 
-            post.IsReply = post.ReplyToList.Contains(_uname);
+            post.IsReply = post.RetweetedId == null && post.ReplyToList.Contains(_uname);
             post.IsExcludeReply = false;
 
             if (post.IsMe)
@@ -995,7 +994,7 @@ namespace OpenTween
 
             var minimumId = CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.List, tab, read);
 
-            if (minimumId != null && minimumId.Value < tab.OldestId)
+            if (minimumId != null)
                 tab.OldestId = minimumId.Value;
         }
 
@@ -1137,7 +1136,7 @@ namespace OpenTween
 
             var minimumId = this.CreatePostsFromSearchJson(searchResult, tab, read, more);
 
-            if (minimumId != null && minimumId.Value < tab.OldestId)
+            if (minimumId != null)
                 tab.OldestId = minimumId.Value;
         }
 
@@ -1313,7 +1312,7 @@ namespace OpenTween
 
             var minimumId = this.CreateFavoritePostsFromJson(statuses, read);
 
-            if (minimumId != null && minimumId.Value < tab.OldestId)
+            if (minimumId != null)
                 tab.OldestId = minimumId.Value;
         }
 
@@ -1711,12 +1710,12 @@ namespace OpenTween
         {
             var matchDm = Twitter.DMSendTextRegex.Match(postText);
             if (matchDm.Success)
-                return this.GetTextLengthRemainInternal(matchDm.Groups["body"].Value, isDm: true);
+                return this.GetTextLengthRemainDM(matchDm.Groups["body"].Value);
 
-            return this.GetTextLengthRemainInternal(postText, isDm: false);
+            return this.GetTextLengthRemainWeighted(postText);
         }
 
-        private int GetTextLengthRemainInternal(string postText, bool isDm)
+        private int GetTextLengthRemainDM(string postText)
         {
             var textLength = 0;
 
@@ -1741,10 +1740,54 @@ namespace OpenTween
                 textLength += shortUrlLength - url.Length;
             }
 
-            if (isDm)
-                return this.Configuration.DmTextCharacterLimit - textLength;
-            else
-                return 140 - textLength;
+            return this.Configuration.DmTextCharacterLimit - textLength;
+        }
+
+        private int GetTextLengthRemainWeighted(string postText)
+        {
+            var config = this.TextConfiguration;
+            var totalWeight = 0;
+
+            var urls = TweetExtractor.ExtractUrlEntities(postText).ToArray();
+
+            var pos = 0;
+            while (pos < postText.Length)
+            {
+                var urlEntity = urls.FirstOrDefault(x => x.Indices[0] == pos);
+                if (urlEntity != null)
+                {
+                    totalWeight += config.TransformedURLLength * config.Scale;
+
+                    var urlLength = urlEntity.Indices[1] - urlEntity.Indices[0];
+                    pos += urlLength;
+
+                    continue;
+                }
+
+                var codepoint = char.ConvertToUtf32(postText, pos);
+                var weight = config.DefaultWeight;
+
+                foreach (var weightRange in config.Ranges)
+                {
+                    if (codepoint >= weightRange.Start && codepoint <= weightRange.End)
+                    {
+                        weight = weightRange.Weight;
+                        break;
+                    }
+                }
+
+                totalWeight += weight;
+
+                var isSurrogatePair = codepoint > 0xffff;
+                if (isSurrogatePair)
+                    pos += 2; // サロゲートペアの場合は2文字分進める
+                else
+                    pos++;
+            }
+
+            var remainWeight = config.MaxWeightedTweetLength * config.Scale - totalWeight;
+
+            return remainWeight / config.Scale;
         }