card-mod-follow 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +134 -0
- data/lib/card/follow_option.rb +33 -0
- data/lib/card/follower_stash.rb +88 -0
- data/set/abstract/follow_option.rb +56 -0
- data/set/all/follow.rb +33 -0
- data/set/all/follow/follow_link.rb +61 -0
- data/set/all/follow/follow_link_views.rb +29 -0
- data/set/all/follow/followed_by.rb +70 -0
- data/set/all/follow/follower_ids.rb +121 -0
- data/set/all/follow/start_follow_link.rb +11 -0
- data/set/all/follow/stop_follow_link.rb +12 -0
- data/set/all/notify.rb +81 -0
- data/set/all/notify/base_views.rb +127 -0
- data/set/all/notify/html_views.rb +17 -0
- data/set/right/account.rb +15 -0
- data/set/right/follow.rb +118 -0
- data/set/right/follow/follow_status.haml +9 -0
- data/set/right/follow_fields.rb +3 -0
- data/set/right/followers.rb +23 -0
- data/set/right/following.rb +50 -0
- data/set/self/always.rb +13 -0
- data/set/self/created.rb +19 -0
- data/set/self/edited.rb +20 -0
- data/set/self/follow.rb +1 -0
- data/set/self/follow_defaults.rb +88 -0
- data/set/self/follow_fields.rb +1 -0
- data/set/self/never.rb +13 -0
- data/set/type/cardtype.rb +21 -0
- data/set/type/notification_template.rb +33 -0
- data/set/type/set.rb +53 -0
- data/set/type/user.rb +7 -0
- data/set/type_plus_right/user/follow.rb +77 -0
- data/set/type_plus_right/user/follow/follow_editor.haml +8 -0
- data/set/type_plus_right/user/follow/follow_editor_helper.rb +121 -0
- metadata +108 -0
data/set/type/user.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
FOLLOW_TABS = { "Follow" => "follow_tab", "Ignore" => "ignore_tab" }.freeze
|
2
|
+
|
3
|
+
# a virtual pointer to the sets that a user is following.
|
4
|
+
# (data is stored in preferences: `[Set]+[User]+:follow`)
|
5
|
+
|
6
|
+
include_set Abstract::Pointer
|
7
|
+
def virtual?
|
8
|
+
new?
|
9
|
+
end
|
10
|
+
|
11
|
+
# overrides pointer default
|
12
|
+
def item_names _args={}
|
13
|
+
if (user = left)
|
14
|
+
Card::Rule.preference_names user.name, "follow"
|
15
|
+
else
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def suggestions
|
21
|
+
Card[:follow_suggestions]&.item_names || []
|
22
|
+
end
|
23
|
+
|
24
|
+
def current_user?
|
25
|
+
Auth.signed_in? && Auth.current_id == left.id
|
26
|
+
end
|
27
|
+
|
28
|
+
format :html do
|
29
|
+
view :one_line_content do
|
30
|
+
""
|
31
|
+
end
|
32
|
+
|
33
|
+
view :edit do
|
34
|
+
render :open
|
35
|
+
end
|
36
|
+
|
37
|
+
# renders follow tab and ignore tab
|
38
|
+
view :core do
|
39
|
+
tabs FOLLOW_TABS, "follow_tab", load: :lazy do
|
40
|
+
render_follow_tab
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
view :follow_tab, cache: :never do
|
45
|
+
haml :follow_editor, items_method: :following_rules_and_options
|
46
|
+
end
|
47
|
+
|
48
|
+
view :ignore_tab, cache: :never do
|
49
|
+
haml :follow_editor, items_method: :ignoring_rules_and_options
|
50
|
+
end
|
51
|
+
|
52
|
+
def show_button?
|
53
|
+
card.current_user? || Auth.always_ok?
|
54
|
+
end
|
55
|
+
|
56
|
+
def pointer_items args
|
57
|
+
voo.items[:view] ||= :link
|
58
|
+
super(args)
|
59
|
+
end
|
60
|
+
|
61
|
+
# TODO: research and generalize
|
62
|
+
# this does not look specific to following!
|
63
|
+
view :errors, perms: :none do
|
64
|
+
return unless card.errors.any?
|
65
|
+
|
66
|
+
if card.errors.find { |attrib, _msg| attrib == :permission_denied }
|
67
|
+
Env.save_interrupted_action(request.env["REQUEST_URI"])
|
68
|
+
voo.title = "Problems with #{card.name}"
|
69
|
+
class_up "d0-card-frame", "card card-warning card-inverse"
|
70
|
+
frame do
|
71
|
+
"Please #{link_to_card :signin, 'sign in'}" # " #{to_task}"
|
72
|
+
end
|
73
|
+
else
|
74
|
+
super()
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# all the following methods are used to construct the Follow and Ignore tabs
|
2
|
+
|
3
|
+
# TODO: these object representations are complex enough for their own class
|
4
|
+
|
5
|
+
format :html do
|
6
|
+
# constructs hash of rules/options for "Follow" tab
|
7
|
+
def following_rules_and_options &block
|
8
|
+
rule_opt_array = following_rule_options_hash.map do |key, val|
|
9
|
+
[(Card.fetch key, new: {}), val]
|
10
|
+
end
|
11
|
+
rules_and_options_by_set_pattern Hash[rule_opt_array], &block
|
12
|
+
end
|
13
|
+
|
14
|
+
# constructs hash of rules/options for "Ignore" tab
|
15
|
+
def ignoring_rules_and_options &block
|
16
|
+
rule_opts_hash = ignore_rules.each_with_object({}) do |rule, hash|
|
17
|
+
hash[rule] = [:never.cardname]
|
18
|
+
end
|
19
|
+
rules_and_options_by_set_pattern rule_opts_hash, &block
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# all rules with ignore
|
25
|
+
def ignore_rules
|
26
|
+
never = :never.cardname.key
|
27
|
+
card.item_cards.select do |follow_rule|
|
28
|
+
follow_rule.item_names.select { |n| n.key == never }.any?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param rule_opts_hash [Hash] { rule1_card => rule1_follow_options }
|
33
|
+
# for each rule/option variant, yields with rule_card and option params
|
34
|
+
def rules_and_options_by_set_pattern rule_opts_hash
|
35
|
+
pattern_hash = a_set_pattern_hash rule_opts_hash
|
36
|
+
empty = true
|
37
|
+
Card.set_patterns.reverse.map do |pattern|
|
38
|
+
pattern_hash[pattern].each do |rule_card, options|
|
39
|
+
options.each do |option|
|
40
|
+
yield rule_card, option
|
41
|
+
empty = false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
yield nil if empty
|
46
|
+
end
|
47
|
+
|
48
|
+
def a_set_pattern_hash rule_opts_hash
|
49
|
+
pattern_hash = Hash.new { |h, k| h[k] = [] }
|
50
|
+
rule_opts_hash.each do |rule_card, options|
|
51
|
+
pattern_hash[rule_card.rule_set.subclass_for_set] << [rule_card, options]
|
52
|
+
end
|
53
|
+
pattern_hash
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return Hash # { rule1 => rule1_follow_options }
|
57
|
+
def following_rule_options_hash
|
58
|
+
merge_option_hashes current_following_rule_options_hash,
|
59
|
+
suggested_following_rule_options_hash
|
60
|
+
end
|
61
|
+
|
62
|
+
# adds suggested follow options to existing rules where applicable
|
63
|
+
def merge_option_hashes current, suggested
|
64
|
+
current.each do |key, current_opt|
|
65
|
+
if (suggested_opt = suggested.delete(key))
|
66
|
+
current[key] = (current_opt + suggested_opt).uniq
|
67
|
+
end
|
68
|
+
end
|
69
|
+
current.merge suggested
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return Hash # { existing_rule1 => rule1_follow_options } (excluding never)
|
73
|
+
# (*never is excluded because this list is for the Follow tab, and *never is
|
74
|
+
# handled under the Ignore tab)
|
75
|
+
def current_following_rule_options_hash
|
76
|
+
never = :never.cardname
|
77
|
+
card.item_cards.each_with_object({}) do |follow_rule, hash|
|
78
|
+
hash[follow_rule.key] = follow_rule.item_names.reject { |item| item == never }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return Hash # { suggested_rule1 => rule1_follow_options }
|
83
|
+
def suggested_following_rule_options_hash
|
84
|
+
return {} unless card.current_user?
|
85
|
+
|
86
|
+
card.suggestions.each_with_object({}) do |sug, hash|
|
87
|
+
set_card, opt = a_set_and_option_suggestion(sug) || a_set_only_suggestion(sug)
|
88
|
+
hash[set_card.follow_rule_name(card.trunk).key] = [opt]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param sug [String] follow suggestion
|
93
|
+
# @return [Array] set_card and option
|
94
|
+
# suggestion value contains both set and follow option
|
95
|
+
def a_set_and_option_suggestion sug
|
96
|
+
return unless (set_card = valid_set_card(sug.to_name.left))
|
97
|
+
|
98
|
+
[set_card, suggested_follow_option(sug.to_name.right)]
|
99
|
+
end
|
100
|
+
|
101
|
+
def suggested_follow_option name
|
102
|
+
# FIXME: option should be unambiguously name or codename
|
103
|
+
# (if codename use colon or Symbol)
|
104
|
+
option_card = Card.fetch(name) || Card[name.to_sym]
|
105
|
+
option_card&.follow_option? ? option_card.name : :always.cardname
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param sug [String] follow suggestion
|
109
|
+
# @return [Array] set_card and option
|
110
|
+
# suggestion value contains only set (implies *always)
|
111
|
+
def a_set_only_suggestion sug
|
112
|
+
return unless (set_card = valid_set_card(sug))
|
113
|
+
|
114
|
+
yield set_card, :always.cardname
|
115
|
+
end
|
116
|
+
|
117
|
+
def valid_set_card name
|
118
|
+
card = Card.fetch(name)
|
119
|
+
card&.type_code == :set ? card : false
|
120
|
+
end
|
121
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: card-mod-follow
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.11.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ethan McCutchen
|
8
|
+
- Philipp Kühl
|
9
|
+
- Gerry Gleason
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2020-12-24 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: card
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - '='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.101.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - '='
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: 1.101.0
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: card-mod-carrierwave
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - '='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 0.11.0
|
36
|
+
type: :runtime
|
37
|
+
prerelease: false
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - '='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 0.11.0
|
43
|
+
description: ''
|
44
|
+
email:
|
45
|
+
- info@decko.org
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- README.md
|
51
|
+
- lib/card/follow_option.rb
|
52
|
+
- lib/card/follower_stash.rb
|
53
|
+
- set/abstract/follow_option.rb
|
54
|
+
- set/all/follow.rb
|
55
|
+
- set/all/follow/follow_link.rb
|
56
|
+
- set/all/follow/follow_link_views.rb
|
57
|
+
- set/all/follow/followed_by.rb
|
58
|
+
- set/all/follow/follower_ids.rb
|
59
|
+
- set/all/follow/start_follow_link.rb
|
60
|
+
- set/all/follow/stop_follow_link.rb
|
61
|
+
- set/all/notify.rb
|
62
|
+
- set/all/notify/base_views.rb
|
63
|
+
- set/all/notify/html_views.rb
|
64
|
+
- set/right/account.rb
|
65
|
+
- set/right/follow.rb
|
66
|
+
- set/right/follow/follow_status.haml
|
67
|
+
- set/right/follow_fields.rb
|
68
|
+
- set/right/followers.rb
|
69
|
+
- set/right/following.rb
|
70
|
+
- set/self/always.rb
|
71
|
+
- set/self/created.rb
|
72
|
+
- set/self/edited.rb
|
73
|
+
- set/self/follow.rb
|
74
|
+
- set/self/follow_defaults.rb
|
75
|
+
- set/self/follow_fields.rb
|
76
|
+
- set/self/never.rb
|
77
|
+
- set/type/cardtype.rb
|
78
|
+
- set/type/notification_template.rb
|
79
|
+
- set/type/set.rb
|
80
|
+
- set/type/user.rb
|
81
|
+
- set/type_plus_right/user/follow.rb
|
82
|
+
- set/type_plus_right/user/follow/follow_editor.haml
|
83
|
+
- set/type_plus_right/user/follow/follow_editor_helper.rb
|
84
|
+
homepage: http://decko.org
|
85
|
+
licenses:
|
86
|
+
- GPL-3.0
|
87
|
+
metadata:
|
88
|
+
card-mod: follow
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
require_paths:
|
92
|
+
- lib
|
93
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '2.5'
|
98
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
requirements: []
|
104
|
+
rubygems_version: 3.0.3
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: follower notifications
|
108
|
+
test_files: []
|