機能 #1250 » 0001-remain_charcount_spell.patch
core/mui/gtk_postbox.rb | ||
---|---|---|
require 'gtk2'
|
||
require 'thread'
|
||
require 'twitter-text'
|
||
miquire :mui, 'miracle_painter'
|
||
miquire :mui, 'intelligent_textview'
|
||
... | ... | |
def widget_remain
|
||
return @remain if defined?(@remain)
|
||
@remain = Gtk::Label.new('---')
|
||
tag = Plugin[:gtk].handler_tag
|
||
@remain.ssc_atonce(:expose_event) {
|
||
Plugin[:gtk].on_world_change_current(tags: tag) { |world|
|
||
update_remain_charcount
|
||
}
|
||
false
|
||
}
|
||
@remain.ssc(:destroy) {
|
||
Plugin[:gtk].detach(tag)
|
||
}
|
||
Delayer.new{
|
||
if not @remain.destroyed?
|
||
@remain.set_text(remain_charcount.to_s) end }
|
||
update_remain_charcount
|
||
}
|
||
widget_post.buffer.ssc(:changed){ |textview, event|
|
||
@remain.set_text(remain_charcount.to_s) }
|
||
update_remain_charcount
|
||
}
|
||
@remain end
|
||
def widget_send
|
||
... | ... | |
def use_blind_footer?
|
||
@use_blind_footer end
|
||
def remain_charcount
|
||
if not widget_post.destroyed?
|
||
text = trim_hidden_regions(widget_post.buffer.text + UserConfig[:footer])
|
||
Twitter::TwitterText::Extractor.extract_urls(text).map{|url|
|
||
if url.length < posted_url_length(url)
|
||
-(posted_url_length(url) - url.length)
|
||
else
|
||
url.length - posted_url_length(url) end
|
||
}.inject(140 - text.size, &:+)
|
||
end end
|
||
def trim_hidden_regions(text)
|
||
trim_hidden_header(trim_hidden_footer(text))
|
||
end
|
||
# 文字列からhidden headerを除いた文字列を返す。
|
||
# hidden headerが含まれていない場合は、 _text_ を返す。
|
||
def trim_hidden_header(text)
|
||
return text unless UserConfig[:auto_populate_reply_metadata]
|
||
mentions = text.match(%r[\A((?:@[a-zA-Z0-9_]+\s+)+)])
|
||
forecast_receivers_sn = Set.new
|
||
if reply?
|
||
@to.first.each_ancestor.each do |m|
|
||
forecast_receivers_sn << m.user.idname
|
||
forecast_receivers_sn.merge(m.receive_user_screen_names)
|
||
end
|
||
end
|
||
if mentions
|
||
specific_screen_names = Set.new(mentions[1].split(/\s+/).map{|s|s[1, s.size]})
|
||
[*(specific_screen_names - forecast_receivers_sn).map{|s|"@#{s}"}, text[mentions.end(0),text.size]].join(' '.freeze)
|
||
else
|
||
text
|
||
end
|
||
def update_remain_charcount
|
||
remain_charcount.next{ |count|
|
||
@remain.set_text((count || '---').to_s) if not @remain.destroyed?
|
||
}.trap {
|
||
@remain.set_text('---') if not @remain.destroyed?
|
||
}
|
||
end
|
||
# 文字列からhidden footerを除いた文字列を返す。
|
||
# hidden footerが含まれていない場合は、 _text_ を返す。
|
||
def trim_hidden_footer(text)
|
||
attachment_url = text.match(%r[\A(.*?)\s+(https?://twitter.com/(?:#!/)?(?:[a-zA-Z0-9_]+)/status(?:es)?/(?:\d+)(?:\?.*)?)\Z]m)
|
||
if attachment_url
|
||
attachment_url[1]
|
||
else
|
||
text
|
||
def remain_charcount
|
||
if not widget_post.destroyed?
|
||
current_world, = Plugin.filtering(:world_current, nil)
|
||
Plugin[:gtk].spell(:remain_charcount, current_world, text: widget_post.buffer.text + UserConfig[:footer])
|
||
end
|
||
end
|
||
# URL _url_ がTwitterに投稿された時に何文字としてカウントされるかを返す
|
||
# ==== Args
|
||
# [url] String URL
|
||
# ==== Return
|
||
# Fixnum URLの長さ
|
||
def posted_url_length(url)
|
||
Plugin.filtering(:tco_url_length, url, 0).last end
|
||
def focus_out_event(widget, event=nil)
|
||
options = @options
|
||
Delayer.new{
|
core/plugin/twitter/twitter.rb | ||
---|---|---|
# -*- coding: utf-8 -*-
|
||
require 'json'
|
||
require 'twitter-text'
|
||
module Plugin::Twitter; end
|
||
... | ... | |
}
|
||
end
|
||
defspell(:remain_charcount, :twitter) do |twitter, text:|
|
||
text = trim_hidden_regions(text)
|
||
Twitter::TwitterText::Extractor.extract_urls(text).map{|url|
|
||
if url.length < posted_url_length(url)
|
||
-(posted_url_length(url) - url.length)
|
||
else
|
||
url.length - posted_url_length(url)
|
||
end
|
||
}.inject(140 - text.size, &:+)
|
||
end
|
||
def trim_hidden_regions(text)
|
||
trim_hidden_header(trim_hidden_footer(text))
|
||
end
|
||
# 文字列からhidden headerを除いた文字列を返す。
|
||
# hidden headerが含まれていない場合は、 _text_ を返す。
|
||
def trim_hidden_header(text)
|
||
return text unless UserConfig[:auto_populate_reply_metadata]
|
||
mentions = text.match(%r[\A((?:@[a-zA-Z0-9_]+\s+)+)])
|
||
forecast_receivers_sn = Set.new
|
||
if reply?
|
||
@to.first.each_ancestor.each do |m|
|
||
forecast_receivers_sn << m.user.idname
|
||
forecast_receivers_sn.merge(m.receive_user_screen_names)
|
||
end
|
||
end
|
||
if mentions
|
||
specific_screen_names = Set.new(mentions[1].split(/\s+/).map{|s|s[1, s.size]})
|
||
[*(specific_screen_names - forecast_receivers_sn).map{|s|"@#{s}"}, text[mentions.end(0),text.size]].join(' '.freeze)
|
||
else
|
||
text
|
||
end
|
||
end
|
||
# 文字列からhidden footerを除いた文字列を返す。
|
||
# hidden footerが含まれていない場合は、 _text_ を返す。
|
||
def trim_hidden_footer(text)
|
||
attachment_url = text.match(%r[\A(.*?)\s+(https?://twitter.com/(?:#!/)?(?:[a-zA-Z0-9_]+)/status(?:es)?/(?:\d+)(?:\?.*)?)\Z]m)
|
||
if attachment_url
|
||
attachment_url[1]
|
||
else
|
||
text
|
||
end
|
||
end
|
||
# URL _url_ がTwitterに投稿された時に何文字としてカウントされるかを返す
|
||
# ==== Args
|
||
# [url] String URL
|
||
# ==== Return
|
||
# Fixnum URLの長さ
|
||
def posted_url_length(url)
|
||
Plugin.filtering(:tco_url_length, url, 0).last
|
||
end
|
||
# リツイートを削除した時、ちゃんとリツイートリストからそれを削除する
|
||
on_destroyed do |messages|
|
||
messages.each{ |message|
|