cubism 0.1.0.pre11 → 0.1.0.pre12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/app/channels/cubism/presence_channel.rb +14 -5
- data/app/channels/cubism/presence_channel.rb~ +14 -5
- data/app/helpers/cubism_helper.rb +3 -3
- data/app/helpers/cubism_helper.rb~ +11 -8
- data/app/models/concerns/cubism/presence.rb +11 -3
- data/lib/cubism/broadcaster.rb +10 -5
- data/lib/cubism/broadcaster.rb~ +13 -6
- data/lib/cubism/cubicle_store.rb +6 -1
- data/lib/cubism/cubicle_store.rb~ +8 -3
- data/lib/cubism/version.rb +1 -1
- data/lib/cubism/version.rb~ +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cd7c7ee681cabc05fd5329e7e6c17fd030d037beb100440faf1ef190a614ddf
|
4
|
+
data.tar.gz: a772708b9dc6a32c5a37766d203ea6a4b119eac57368378121e6b4da9f2b50f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b47525bcc5545b289624615b66215b68467c2a2ba35a7b5335c944bdfacc68d0c6d60c430c93ad1b18470db7e7d3a58313f232b35bc32a34b21847f4a28f086b
|
7
|
+
data.tar.gz: 4595ebf829643d556613ebc5ca03e19f35cc6601a8c435f0dfea3c4e9cc7c08966c94ae69996e87d0e8c572d1d0decc8e6bd1cfa9ee7840a7abad29909f3ab7f
|
data/README.md
CHANGED
@@ -96,9 +96,10 @@ CableReady.initialize({ consumer });
|
|
96
96
|
|
97
97
|
The `cubicle_for` helper accepts the following options as keyword arguments:
|
98
98
|
|
99
|
+
- `scope`: declare a scope in which presence indicators should appear. For example, if you want to divide between index and show views, do `scope: :index` and `scope: :show` respectively (default: `""`).
|
99
100
|
- `exclude_current_user (true|false)`: Whether or not to exclude the current user from the list of present users broadcasted to the view. Useful e.g. for "typing..." indicators (default: `true`).
|
100
|
-
- `appear_trigger`: JavaScript event names (e.g. `["focus", "debounced:input]`) to use. (Can also be a singular string, which will be converted to an array). The default is `:connect`, i.e. register a user as "appeared"/"present" when the element connects to the DOM.
|
101
|
-
- `disappear_trigger`: a JavaScript event name (e.g. `:blur`) to use. (Can also be a singular string, which will be converted to an array). The default is `:disconnect`, i.e. remove a user form the present users list when the element disconnects from the DOM.
|
101
|
+
- `appear_trigger`: JavaScript event names (e.g. `["focus", "debounced:input]`) to use. (Can also be a singular string, which will be converted to an array). The default is `:connect`, i.e. register a user as "appeared"/"present" when the element connects to the DOM. Another special value is `:intersect`, which fires when the `trigger_root` comes into the viewport.
|
102
|
+
- `disappear_trigger`: a JavaScript event name (e.g. `:blur`) to use. (Can also be a singular string, which will be converted to an array). The default is `:disconnect`, i.e. remove a user form the present users list when the element disconnects from the DOM. Analoguous to above, `:intersect` means that `disappear` will fire when the `trigger_root` is scrolled out of the viewport.
|
102
103
|
- `trigger_root`: a CSS selector to attach the appear/disappear events to. Defaults to the `cubicle-element` itself.
|
103
104
|
- `html_options` are passed to the TagBuilder.
|
104
105
|
|
@@ -3,7 +3,7 @@ class Cubism::PresenceChannel < ActionCable::Channel::Base
|
|
3
3
|
|
4
4
|
def subscribed
|
5
5
|
if resource.present?
|
6
|
-
stream_from
|
6
|
+
stream_from element_id
|
7
7
|
resource.cubicle_element_ids << element_id
|
8
8
|
resource.excluded_user_id_for_element_id[element_id] = user.id if exclude_current_user?
|
9
9
|
else
|
@@ -20,11 +20,11 @@ class Cubism::PresenceChannel < ActionCable::Channel::Base
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def appear
|
23
|
-
resource.
|
23
|
+
resource.set_present_users_for_scope(resource.present_users_for_scope(scope).add(user.id), scope) if scope
|
24
24
|
end
|
25
25
|
|
26
26
|
def disappear
|
27
|
-
resource.
|
27
|
+
resource.set_present_users_for_scope(resource.present_users_for_scope(scope).delete(user.id), scope) if scope
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
@@ -35,7 +35,15 @@ class Cubism::PresenceChannel < ActionCable::Channel::Base
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def user
|
38
|
-
|
38
|
+
block_container&.user
|
39
|
+
end
|
40
|
+
|
41
|
+
def scope
|
42
|
+
block_container&.scope
|
43
|
+
end
|
44
|
+
|
45
|
+
def block_container
|
46
|
+
Cubism.block_store[element_id]
|
39
47
|
end
|
40
48
|
|
41
49
|
def exclude_current_user?
|
@@ -43,7 +51,8 @@ class Cubism::PresenceChannel < ActionCable::Channel::Base
|
|
43
51
|
end
|
44
52
|
|
45
53
|
def element_id
|
46
|
-
params[:element_id]
|
54
|
+
/cubicle-(?<element_id>.+)/ =~ params[:element_id]
|
55
|
+
element_id
|
47
56
|
end
|
48
57
|
|
49
58
|
def url
|
@@ -3,7 +3,7 @@ class Cubism::PresenceChannel < ActionCable::Channel::Base
|
|
3
3
|
|
4
4
|
def subscribed
|
5
5
|
if resource.present?
|
6
|
-
stream_from
|
6
|
+
stream_from element_id
|
7
7
|
resource.cubicle_element_ids << element_id
|
8
8
|
resource.excluded_user_id_for_element_id[element_id] = user.id if exclude_current_user?
|
9
9
|
else
|
@@ -20,11 +20,11 @@ class Cubism::PresenceChannel < ActionCable::Channel::Base
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def appear
|
23
|
-
resource.
|
23
|
+
resource.set_present_users_for_scope(resource.present_users_for_scope(scope).add(user.id), scope)
|
24
24
|
end
|
25
25
|
|
26
26
|
def disappear
|
27
|
-
resource.
|
27
|
+
resource.set_present_users_for_scope(resource.present_users_for_scope(scope).delete(user.id), scope)
|
28
28
|
end
|
29
29
|
|
30
30
|
private
|
@@ -35,7 +35,15 @@ class Cubism::PresenceChannel < ActionCable::Channel::Base
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def user
|
38
|
-
|
38
|
+
block_container.user
|
39
|
+
end
|
40
|
+
|
41
|
+
def scope
|
42
|
+
block_container.scope
|
43
|
+
end
|
44
|
+
|
45
|
+
def block_container
|
46
|
+
Cubism.block_store[element_id]
|
39
47
|
end
|
40
48
|
|
41
49
|
def exclude_current_user?
|
@@ -43,7 +51,8 @@ class Cubism::PresenceChannel < ActionCable::Channel::Base
|
|
43
51
|
end
|
44
52
|
|
45
53
|
def element_id
|
46
|
-
params[:element_id]
|
54
|
+
/cubicle-(?<element_id>.+)/ =~ params[:element_id]
|
55
|
+
element_id
|
47
56
|
end
|
48
57
|
|
49
58
|
def url
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module CubismHelper
|
2
2
|
include CableReady::StreamIdentifier
|
3
3
|
|
4
|
-
def cubicle_for(resource, user, html_options: {}, appear_trigger: :connect, disappear_trigger: nil, trigger_root: nil, exclude_current_user: true, &block)
|
4
|
+
def cubicle_for(resource, user, scope: "", html_options: {}, appear_trigger: :connect, disappear_trigger: nil, trigger_root: nil, exclude_current_user: true, &block)
|
5
5
|
block_location = block.source_location.join(":")
|
6
6
|
block_source = Cubism::BlockSource.find_or_create(
|
7
7
|
location: block_location,
|
@@ -14,7 +14,8 @@ module CubismHelper
|
|
14
14
|
block_location: block_location,
|
15
15
|
block_source: block_source,
|
16
16
|
resource_gid: resource_gid,
|
17
|
-
user_gid: user.to_gid.to_s
|
17
|
+
user_gid: user.to_gid.to_s,
|
18
|
+
scope: scope
|
18
19
|
)
|
19
20
|
|
20
21
|
digested_block_key = block_container.digest
|
@@ -23,7 +24,6 @@ module CubismHelper
|
|
23
24
|
|
24
25
|
tag.cubicle_element(
|
25
26
|
identifier: signed_stream_identifier(resource_gid),
|
26
|
-
user: user.to_sgid.to_s,
|
27
27
|
"appear-trigger": Array(appear_trigger).join(","),
|
28
28
|
"disappear-trigger": disappear_trigger,
|
29
29
|
"trigger-root": trigger_root,
|
@@ -1,30 +1,33 @@
|
|
1
1
|
module CubismHelper
|
2
2
|
include CableReady::StreamIdentifier
|
3
3
|
|
4
|
-
def cubicle_for(resource, user, html_options: {}, appear_trigger: :connect, disappear_trigger: nil, trigger_root: nil, exclude_current_user: true, &block)
|
4
|
+
def cubicle_for(resource, user, scope: "", html_options: {}, appear_trigger: :connect, disappear_trigger: nil, trigger_root: nil, exclude_current_user: true, &block)
|
5
5
|
block_location = block.source_location.join(":")
|
6
|
+
block_source = Cubism::BlockSource.find_or_create(
|
7
|
+
location: block_location,
|
8
|
+
view_context: self
|
9
|
+
)
|
6
10
|
|
7
11
|
resource_gid = resource.to_gid.to_s
|
8
12
|
|
9
|
-
|
13
|
+
block_container = Cubism::BlockContainer.new(
|
10
14
|
block_location: block_location,
|
15
|
+
block_source: block_source,
|
11
16
|
resource_gid: resource_gid,
|
12
17
|
user_gid: user.to_gid.to_s,
|
13
|
-
|
18
|
+
scope: scope
|
14
19
|
)
|
15
20
|
|
16
|
-
digested_block_key =
|
17
|
-
|
18
|
-
store_item.parse!
|
21
|
+
digested_block_key = block_container.digest
|
19
22
|
|
20
|
-
Cubism.block_store
|
23
|
+
Cubism.block_store.fetch(digested_block_key, block_container)
|
21
24
|
|
22
25
|
tag.cubicle_element(
|
23
26
|
identifier: signed_stream_identifier(resource_gid),
|
24
|
-
user: user.to_sgid.to_s,
|
25
27
|
"appear-trigger": Array(appear_trigger).join(","),
|
26
28
|
"disappear-trigger": disappear_trigger,
|
27
29
|
"trigger-root": trigger_root,
|
30
|
+
scope: scope,
|
28
31
|
id: "cubicle-#{digested_block_key}",
|
29
32
|
"exclude-current-user": exclude_current_user,
|
30
33
|
**html_options
|
@@ -2,7 +2,7 @@ module Cubism::Presence
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
included do
|
5
|
-
|
5
|
+
kredis_hash :present_users, after_change: :stream_presence
|
6
6
|
kredis_set :cubicle_element_ids
|
7
7
|
kredis_hash :excluded_user_id_for_element_id
|
8
8
|
end
|
@@ -11,8 +11,16 @@ module Cubism::Presence
|
|
11
11
|
Cubism::Broadcaster.new(resource: self).broadcast
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
|
14
|
+
def present_users_for_scope(scope = "")
|
15
|
+
present_users[scope].present? ? Marshal.load(present_users[scope]) : Set.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_present_users_for_scope(user_ids, scope = "")
|
19
|
+
present_users[scope] = Marshal.dump(Set.new(user_ids))
|
20
|
+
end
|
21
|
+
|
22
|
+
def present_users_for_element_id_and_scope(element_id, scope = "")
|
23
|
+
users = Cubism.user_class.find(present_users_for_scope(scope).to_a)
|
16
24
|
users.reject! { |user| user.id == excluded_user_id_for_element_id[element_id].to_i }
|
17
25
|
|
18
26
|
users
|
data/lib/cubism/broadcaster.rb
CHANGED
@@ -13,20 +13,25 @@ module Cubism
|
|
13
13
|
|
14
14
|
def broadcast
|
15
15
|
resource.cubicle_element_ids.to_a.each do |element_id|
|
16
|
-
|
17
|
-
block_container = Cubism.block_store[block_key]
|
16
|
+
block_container = Cubism.block_store[element_id]
|
18
17
|
|
19
18
|
next if block_container.blank?
|
20
19
|
|
20
|
+
present_users = resource.present_users_for_element_id_and_scope(element_id, block_container.scope)
|
21
|
+
|
21
22
|
block_source = block_container.block_source
|
22
23
|
|
23
|
-
html = ApplicationController.render(inline: block_source.source, locals: {"#{block_source.variable_name}":
|
24
|
+
html = ApplicationController.render(inline: block_source.source, locals: {"#{block_source.variable_name}": present_users})
|
25
|
+
|
26
|
+
selector = "cubicle-element#cubicle-#{element_id}[identifier='#{signed_stream_identifier(resource.to_global_id.to_s)}']"
|
24
27
|
|
25
28
|
cable_ready[element_id].inner_html(
|
26
|
-
selector:
|
29
|
+
selector: selector,
|
27
30
|
html: html
|
28
|
-
)
|
31
|
+
)
|
29
32
|
end
|
33
|
+
|
34
|
+
cable_ready.broadcast
|
30
35
|
end
|
31
36
|
end
|
32
37
|
end
|
data/lib/cubism/broadcaster.rb~
CHANGED
@@ -13,18 +13,25 @@ module Cubism
|
|
13
13
|
|
14
14
|
def broadcast
|
15
15
|
resource.cubicle_element_ids.to_a.each do |element_id|
|
16
|
-
|
17
|
-
store_item = Cubism.block_store[block_key]
|
16
|
+
block_container = Cubism.block_store[element_id]
|
18
17
|
|
19
|
-
next if
|
18
|
+
next if block_container.blank?
|
20
19
|
|
21
|
-
|
20
|
+
present_users = resource.present_users_for_element_id_and_scope(element_id, block_container.scope)
|
21
|
+
|
22
|
+
block_source = block_container.block_source
|
23
|
+
|
24
|
+
html = ApplicationController.render(inline: block_source.source, locals: {"#{block_source.variable_name}": present_users})
|
25
|
+
|
26
|
+
selector = "cubicle-element#cubicle-#{element_id}[identifier='#{signed_stream_identifier(resource.to_global_id.to_s)}'][scope='#{block_container.scope}']"
|
22
27
|
|
23
28
|
cable_ready[element_id].inner_html(
|
24
|
-
selector:
|
29
|
+
selector: selector,
|
25
30
|
html: html
|
26
|
-
)
|
31
|
+
)
|
27
32
|
end
|
33
|
+
|
34
|
+
cable_ready.broadcast
|
28
35
|
end
|
29
36
|
end
|
30
37
|
end
|
data/lib/cubism/cubicle_store.rb
CHANGED
@@ -49,6 +49,7 @@ module Cubism
|
|
49
49
|
:block_source,
|
50
50
|
:user_gid,
|
51
51
|
:resource_gid,
|
52
|
+
:scope,
|
52
53
|
keyword_init: true
|
53
54
|
) do
|
54
55
|
def initialize(*args)
|
@@ -65,8 +66,12 @@ module Cubism
|
|
65
66
|
GlobalID::Locator.locate self[:resource_gid]
|
66
67
|
end
|
67
68
|
|
69
|
+
def scope
|
70
|
+
self[:scope] || ""
|
71
|
+
end
|
72
|
+
|
68
73
|
def digest
|
69
|
-
resource_user_key = [resource_gid, user_gid].join(":")
|
74
|
+
resource_user_key = [resource_gid, user_gid, scope].join(":")
|
70
75
|
|
71
76
|
ActiveSupport::Digest.hexdigest("#{block_location}:#{File.read(@filename)}:#{resource_user_key}")
|
72
77
|
end
|
@@ -44,11 +44,12 @@ module Cubism
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# Container for cubicle blocks
|
47
|
-
|
47
|
+
BlockContainer = Struct.new(
|
48
48
|
:block_location,
|
49
49
|
:block_source,
|
50
50
|
:user_gid,
|
51
51
|
:resource_gid,
|
52
|
+
:scope,
|
52
53
|
keyword_init: true
|
53
54
|
) do
|
54
55
|
def initialize(*args)
|
@@ -65,6 +66,10 @@ module Cubism
|
|
65
66
|
GlobalID::Locator.locate self[:resource_gid]
|
66
67
|
end
|
67
68
|
|
69
|
+
def scope
|
70
|
+
self[:scope] || ""
|
71
|
+
end
|
72
|
+
|
68
73
|
def digest
|
69
74
|
resource_user_key = [resource_gid, user_gid].join(":")
|
70
75
|
|
@@ -72,7 +77,7 @@ module Cubism
|
|
72
77
|
end
|
73
78
|
|
74
79
|
def marshal_dump
|
75
|
-
to_h.
|
80
|
+
to_h.merge(block_source: block_source.digest)
|
76
81
|
end
|
77
82
|
|
78
83
|
def marshal_load(serialized_item)
|
@@ -80,7 +85,7 @@ module Cubism
|
|
80
85
|
send("#{arg}=", serialized_item[arg])
|
81
86
|
end
|
82
87
|
|
83
|
-
self.block_source = Cubism.source_store
|
88
|
+
self.block_source = Cubism.source_store[serialized_item[:block_source]]
|
84
89
|
end
|
85
90
|
end
|
86
91
|
|
data/lib/cubism/version.rb
CHANGED
data/lib/cubism/version.rb~
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cubism
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.pre12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Rubisch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|