diff options
Diffstat (limited to 'core/addon/activity/activity.rb')
-rw-r--r-- | core/addon/activity/activity.rb | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/core/addon/activity/activity.rb b/core/addon/activity/activity.rb new file mode 100644 index 00000000..32e54ab0 --- /dev/null +++ b/core/addon/activity/activity.rb @@ -0,0 +1,245 @@ +# -*- coding: utf-8 -*- +# 通知管理プラグイン + +miquire :mui, 'tree_view_pretty_scroll' +module Plugin::Activity + # アクティビティを更新する。 + # ==== Args + # [kind] Symbol イベントの種類 + # [title] タイトル + # [args] その他オプション。主に以下の値 + # icon :: String|Gdk::Pixbuf アイコン + # date :: Time イベントの発生した時刻 + # service :: Service 関係するServiceオブジェクト + # related :: 自分に関係するかどうかのフラグ + def activity(kind, title, args = {}) + Plugin.call(:modify_activity, + { plugin: self, + kind: kind, + title: title, + date: Time.new, + description: title }.merge(args)) + end +end + +class Plugin + include Plugin::Activity + + def self.activity(kind, title, args = {}) + Plugin.call(:modify_activity, + { plugin: nil, + kind: kind, + title: title, + date: Time.new, + description: title }.merge(args)) + end +end + +Plugin.create(:activity) do + class ActivityView < Gtk::CRUD + include Gtk::TreeViewPrettyScroll + + ICON = 0 + KIND = 1 + TITLE = 2 + DATE = 3 + PLUGIN = 4 + ID = 5 + SERVICE = 6 + EVENT = 7 + + def initialize + super() + @creatable = @updatable = @deletable = false + end + + def column_schemer + [{:kind => :pixbuf, :type => Gdk::Pixbuf, :label => 'icon'}, # ICON + {:kind => :text, :type => String, :label => '種類'}, # KIND + {:kind => :text, :type => String, :label => '説明'}, # TITLE + {:kind => :text, :type => String, :label => '時刻'}, # DATE + {:type => Plugin}, # PLUGIN + {:type => Integer}, # ID + {:type => Service}, # SERVICE + {:type => Hash} ].freeze # EVENT + end + end + + BOOT_TIME = Time.new.freeze + + # そのイベントをミュートするかどうかを返す(trueなら表示しない) + def mute?(params) + mute_kind = UserConfig[:activity_mute_kind] + if mute_kind.is_a? Array + return true if mute_kind.include? params[:kind].to_s end + mute_kind_related = UserConfig[:activity_mute_kind_related] + if mute_kind_related + return true if mute_kind_related.include?(params[:kind].to_s) and !params[:related] end + false end + + activity_view = ActivityView.new + activity_vscrollbar = Gtk::VScrollbar.new(activity_view.vadjustment) + activity_hscrollbar = Gtk::HScrollbar.new(activity_view.hadjustment) + activity_shell = Gtk::Table.new(2, 2) + activity_description = Gtk::IntelligentTextview.new + activity_status = Gtk::Label.new + activity_container = Gtk::VBox.new + + activity_container. + pack_start(activity_shell. + attach(activity_view, 0, 1, 0, 1, Gtk::FILL|Gtk::SHRINK|Gtk::EXPAND, Gtk::FILL|Gtk::SHRINK|Gtk::EXPAND). + attach(activity_vscrollbar, 1, 2, 0, 1, Gtk::FILL, Gtk::SHRINK|Gtk::FILL). + attach(activity_hscrollbar, 0, 1, 1, 2, Gtk::SHRINK|Gtk::FILL, Gtk::FILL)). + closeup(activity_description). + closeup(activity_status.right) + + Delayer.new do + Plugin.call(:mui_tab_regist, activity_container, 'アクティビティ', MUI::Skin.get("underconstruction.png")) + end + + activity_view.ssc("cursor-changed") { |this| + iter = this.selection.selected + if iter + activity_description.rewind(iter[ActivityView::EVENT][:description]) + activity_status.set_text(iter[ActivityView::DATE]) + end + false + } + + # アクティビティ更新を受け取った時の処理 + # plugin, kind, title, icon, date, service + on_modify_activity do |params| + if not mute?(params) + iter = activity_view.model.prepend + if params[:icon].is_a? String + iter[ActivityView::ICON] = Gdk::WebImageLoader.pixbuf(params[:icon], 24, 24){ |loaded_icon| + iter[ActivityView::ICON] = loaded_icon } + else + iter[ActivityView::ICON] = params[:icon] end + iter[ActivityView::KIND] = params[:kind].to_s + iter[ActivityView::TITLE] = params[:title].tr("\n", "") + iter[ActivityView::DATE] = params[:date].strftime('%Y/%m/%d %H:%M:%S') + iter[ActivityView::PLUGIN] = params[:plugin] + iter[ActivityView::ID] = 0 + iter[ActivityView::SERVICE] = params[:service] + iter[ActivityView::EVENT] = params + if (UserConfig[:activity_show_timeline] || []).include?(params[:kind].to_s) + Plugin.call(:update, nil, [Message.new(message: params[:description], system: true, source: params[:plugin].to_s, created: params[:date])]) + end + end + end + + on_favorite do |service, user, message| + activity(:favorite, "#{message.user[:idname]}: #{message.to_s}", + description:("@#{user[:idname]} がふぁぼふぁぼしました\n"+ + "@#{message.user[:idname]}: #{message.to_s}\n"+ + "https://twitter.com/#!/#{message.user[:idname]}/statuses/#{message[:id]}"), + icon: user[:profile_image_url], + related: message.user.is_me? || user.is_me?, + service: service) + end + + on_unfavorite do |service, user, message| + activity(:unfavorite, "#{message.user[:idname]}: #{message.to_s}", + description:("@#{user[:idname]} があんふぁぼしました\n"+ + "@#{message.user[:idname]}: #{message.to_s}\n"+ + "https://twitter.com/#!/#{message.user[:idname]}/statuses/#{message[:id]}"), + icon: user[:profile_image_url], + related: message.user.is_me? || user.is_me?, + service: service) + end + + on_retweet do |retweets| + retweets.each { |retweet| + retweet.retweet_source_d.next{ |source| + activity(:retweet, retweet.to_s, + description:("@#{retweet.user[:idname]} がリツイートしました\n"+ + "@#{source.user[:idname]}: #{source.to_s}\n"+ + "https://twitter.com/#!/#{source.user[:idname]}/statuses/#{source[:id]}"), + icon: retweet.user[:profile_image_url], + date: retweet[:created], + related: (retweet.user.is_me? || source && source.user.is_me?), + service: Service.primary) }.terminate('リツイートソースが取得できませんでした') } + end + + on_list_member_added do |service, user, list, source_user| + activity(:list_member_added, "@#{user[:idname]}が#{list[:full_name]}に追加されました", + description:("@#{user[:idname]} が #{list[:full_name]} に追加されました\n"+ + "#{list[:description]} (by @#{list.user[:idname]})\n"+ + "https://twitter.com/#!/#{list.user[:idname]}/#{list[:slug]}"), + icon: user[:profile_image_url], + related: user.is_me? || source_user.is_me?, + service: service) + end + + on_list_member_removed do |service, user, list, source_user| + activity(:list_member_removed, "@#{user[:idname]}が#{list[:full_name]}から削除されました", + description:("@#{user[:idname]} が #{list[:full_name]} から削除されました\n"+ + "#{list[:description]} (by @#{list.user[:idname]})\n"+ + "https://twitter.com/#!/#{list.user[:idname]}/#{list[:slug]}"), + icon: user[:profile_image_url], + related: user.is_me? || source_user.is_me?, + service: service) + end + + on_follow do |by, to| + activity(:follow, "@#{by[:idname]}が@#{to[:idname]}をフョローしました", + related: by.is_me? || to.is_me?, + icon: (to.is_me? ? by : to)[:profile_image_url]) + end + + on_direct_messages do |service, dms| + dms.each{ |dm| + date = Time.parse(dm[:created_at]) + if date > BOOT_TIME + first_line = dm[:sender].is_me? ? "ダイレクトメッセージを送信しました" : "ダイレクトメッセージを受信しました" + activity(:dm, "D #{dm[:recipient][:idname]} #{dm[:text]}", + description: ("#{first_line}\n" + + "@#{dm[:sender][:idname]}: D #{dm[:recipient][:idname]} #{dm[:text]}"), + icon: dm[:sender][:profile_image_url], + service: service, + date: date) end } + end + + onunload do + Addon.remove_tab 'アクティビティ' + end + + settings "アクティビティ" do + settings "表示しないイベント" do + multiselect("以下の自分に関係ないイベント", :activity_mute_kind_related) do + option "retweet", "リツイート" + option "favorite", "ふぁぼ" + option "follow", "フォロー" + option "list_member_added", "リストに追加" + option "list_member_removed", "リストから削除" + option "dm", "ダイレクトメッセージ" + option "system", "システムメッセージ" + option "error", "エラー" + end + + multiselect("以下の全てのイベント", :activity_mute_kind) do + option "retweet", "リツイート" + option "favorite", "ふぁぼ" + option "follow", "フォロー" + option "list_member_added", "リストに追加" + option "list_member_removed", "リストから削除" + option "dm", "ダイレクトメッセージ" + option "system", "システムメッセージ" + option "error", "エラー" + end + end + + multiselect("タイムラインに表示", :activity_show_timeline) do + option "retweet", "リツイート" + option "favorite", "ふぁぼ" + option "follow", "フォロー" + option "list_member_added", "リストに追加" + option "list_member_removed", "リストから削除" + option "dm", "ダイレクトメッセージ" + option "system", "システムメッセージ" + option "error", "エラー" + end + + end +end |