card-mod-follow 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|