機能 #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|
|
||