プロジェクト

全般

プロフィール

機能 #1250 » 0001-remain_charcount_spell.patch

Shibafu Midorino, 2018-05-20 23:40

差分を表示:

core/mui/gtk_postbox.rb
6 6

  
7 7
require 'gtk2'
8 8
require 'thread'
9
require 'twitter-text'
10 9
miquire :mui, 'miracle_painter'
11 10
miquire :mui, 'intelligent_textview'
12 11

  
......
95 94
    def widget_remain
96 95
      return @remain if defined?(@remain)
97 96
      @remain = Gtk::Label.new('---')
97
      tag = Plugin[:gtk].handler_tag
98
      @remain.ssc_atonce(:expose_event) {
99
        Plugin[:gtk].on_world_change_current(tags: tag) { |world|
100
          update_remain_charcount
101
        }
102
        false
103
      }
104
      @remain.ssc(:destroy) {
105
        Plugin[:gtk].detach(tag)
106
      }
98 107
      Delayer.new{
99
        if not @remain.destroyed?
100
          @remain.set_text(remain_charcount.to_s) end }
108
        update_remain_charcount
109
      }
101 110
      widget_post.buffer.ssc(:changed){ |textview, event|
102
        @remain.set_text(remain_charcount.to_s) }
111
        update_remain_charcount
112
      }
103 113
      @remain end
104 114

  
105 115
    def widget_send
......
305 315
    def use_blind_footer?
306 316
      @use_blind_footer end
307 317

  
308
    def remain_charcount
309
      if not widget_post.destroyed?
310
        text = trim_hidden_regions(widget_post.buffer.text + UserConfig[:footer])
311
        Twitter::TwitterText::Extractor.extract_urls(text).map{|url|
312
          if url.length < posted_url_length(url)
313
            -(posted_url_length(url) - url.length)
314
          else
315
            url.length - posted_url_length(url) end
316
        }.inject(140 - text.size, &:+)
317
      end end
318

  
319
    def trim_hidden_regions(text)
320
      trim_hidden_header(trim_hidden_footer(text))
321
    end
322

  
323
    # 文字列からhidden headerを除いた文字列を返す。
324
    # hidden headerが含まれていない場合は、 _text_ を返す。
325
    def trim_hidden_header(text)
326
      return text unless UserConfig[:auto_populate_reply_metadata]
327
      mentions = text.match(%r[\A((?:@[a-zA-Z0-9_]+\s+)+)])
328
      forecast_receivers_sn = Set.new
329
      if reply?
330
        @to.first.each_ancestor.each do |m|
331
          forecast_receivers_sn << m.user.idname
332
          forecast_receivers_sn.merge(m.receive_user_screen_names)
333
        end
334
      end
335
      if mentions
336
        specific_screen_names = Set.new(mentions[1].split(/\s+/).map{|s|s[1, s.size]})
337
        [*(specific_screen_names - forecast_receivers_sn).map{|s|"@#{s}"}, text[mentions.end(0),text.size]].join(' '.freeze)
338
      else
339
        text
340
      end
318
    def update_remain_charcount
319
      remain_charcount.next{ |count|
320
        @remain.set_text((count || '---').to_s) if not @remain.destroyed?
321
      }.trap {
322
        @remain.set_text('---') if not @remain.destroyed?
323
      }
341 324
    end
342 325

  
343
    # 文字列からhidden footerを除いた文字列を返す。
344
    # hidden footerが含まれていない場合は、 _text_ を返す。
345
    def trim_hidden_footer(text)
346
      attachment_url = text.match(%r[\A(.*?)\s+(https?://twitter.com/(?:#!/)?(?:[a-zA-Z0-9_]+)/status(?:es)?/(?:\d+)(?:\?.*)?)\Z]m)
347
      if attachment_url
348
        attachment_url[1]
349
      else
350
        text
326
    def remain_charcount
327
      if not widget_post.destroyed?
328
        current_world, = Plugin.filtering(:world_current, nil)
329
        Plugin[:gtk].spell(:remain_charcount, current_world, text: widget_post.buffer.text + UserConfig[:footer])
351 330
      end
352 331
    end
353 332

  
354
    # URL _url_ がTwitterに投稿された時に何文字としてカウントされるかを返す
355
    # ==== Args
356
    # [url] String URL
357
    # ==== Return
358
    # Fixnum URLの長さ
359
    def posted_url_length(url)
360
      Plugin.filtering(:tco_url_length, url, 0).last end
361

  
362 333
    def focus_out_event(widget, event=nil)
363 334
      options = @options
364 335
      Delayer.new{
core/plugin/twitter/twitter.rb
1 1
# -*- coding: utf-8 -*-
2 2
require 'json'
3
require 'twitter-text'
3 4

  
4 5
module Plugin::Twitter; end
5 6

  
......
238 239
    }
239 240
  end
240 241

  
242
  defspell(:remain_charcount, :twitter) do |twitter, text:|
243
    text = trim_hidden_regions(text)
244
    Twitter::TwitterText::Extractor.extract_urls(text).map{|url|
245
      if url.length < posted_url_length(url)
246
        -(posted_url_length(url) - url.length)
247
      else
248
        url.length - posted_url_length(url)
249
      end
250
    }.inject(140 - text.size, &:+)
251
  end
252

  
253
  def trim_hidden_regions(text)
254
    trim_hidden_header(trim_hidden_footer(text))
255
  end
256

  
257
  # 文字列からhidden headerを除いた文字列を返す。
258
  # hidden headerが含まれていない場合は、 _text_ を返す。
259
  def trim_hidden_header(text)
260
    return text unless UserConfig[:auto_populate_reply_metadata]
261
    mentions = text.match(%r[\A((?:@[a-zA-Z0-9_]+\s+)+)])
262
    forecast_receivers_sn = Set.new
263
    if reply?
264
      @to.first.each_ancestor.each do |m|
265
        forecast_receivers_sn << m.user.idname
266
        forecast_receivers_sn.merge(m.receive_user_screen_names)
267
      end
268
    end
269
    if mentions
270
      specific_screen_names = Set.new(mentions[1].split(/\s+/).map{|s|s[1, s.size]})
271
      [*(specific_screen_names - forecast_receivers_sn).map{|s|"@#{s}"}, text[mentions.end(0),text.size]].join(' '.freeze)
272
    else
273
      text
274
    end
275
  end
276

  
277
  # 文字列からhidden footerを除いた文字列を返す。
278
  # hidden footerが含まれていない場合は、 _text_ を返す。
279
  def trim_hidden_footer(text)
280
    attachment_url = text.match(%r[\A(.*?)\s+(https?://twitter.com/(?:#!/)?(?:[a-zA-Z0-9_]+)/status(?:es)?/(?:\d+)(?:\?.*)?)\Z]m)
281
    if attachment_url
282
      attachment_url[1]
283
    else
284
      text
285
    end
286
  end
287

  
288
  # URL _url_ がTwitterに投稿された時に何文字としてカウントされるかを返す
289
  # ==== Args
290
  # [url] String URL
291
  # ==== Return
292
  # Fixnum URLの長さ
293
  def posted_url_length(url)
294
    Plugin.filtering(:tco_url_length, url, 0).last
295
  end
296

  
241 297
  # リツイートを削除した時、ちゃんとリツイートリストからそれを削除する
242 298
  on_destroyed do |messages|
243 299
    messages.each{ |message|
(1-1/3)