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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf5d9eed6d97039688a2f51dd5ddab248619879ad47d50abbf37bab73d7f7d56
4
- data.tar.gz: 8120474f22abf5ee4b9bc2497e91ef2e68f41aea79f59fde4ae1c9e577a75dd7
3
+ metadata.gz: 8cd7c7ee681cabc05fd5329e7e6c17fd030d037beb100440faf1ef190a614ddf
4
+ data.tar.gz: a772708b9dc6a32c5a37766d203ea6a4b119eac57368378121e6b4da9f2b50f6
5
5
  SHA512:
6
- metadata.gz: fe7a0bca6d22807e0eb6b81e612ee8d435f67380a5aec20df253a86a92606642f907a67341b845159b2ae498dfcc0d7c56c1f49fb3425e1470789140adf4939e
7
- data.tar.gz: dd6925f36a82fcfab2de5a888b1d974b151fb9a14a7c4cf76cab9f3ffde28b865790c09dd4b97b19a8284192cef644847a3c944b06e53dd2d690ef8da2a7245e
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 params[:element_id]
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.present_users.add(user.id)
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.present_users.remove(user.id)
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
- GlobalID::Locator.locate_signed(params[:user])
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 params[:element_id]
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.present_users.add(user.id)
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.present_users.remove(user.id)
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
- GlobalID::Locator.locate_signed(params[:user])
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
- store_item = Cubism::BlockStoreItem.new(
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
- view_context: self
18
+ scope: scope
14
19
  )
15
20
 
16
- digested_block_key = store_item.digest
17
-
18
- store_item.parse!
21
+ digested_block_key = block_container.digest
19
22
 
20
- Cubism.block_store[digested_block_key] = store_item
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
- kredis_set :present_users, after_change: :stream_presence
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 present_users_for_element_id(element_id)
15
- users = Cubism.user_class.find(present_users.members)
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
@@ -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
- /cubicle-(?<block_key>.+)/ =~ element_id
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}": resource.present_users_for_element_id(element_id)})
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: "cubicle-element##{element_id}[identifier='#{signed_stream_identifier(resource.to_global_id.to_s)}']",
29
+ selector: selector,
27
30
  html: html
28
- ).broadcast
31
+ )
29
32
  end
33
+
34
+ cable_ready.broadcast
30
35
  end
31
36
  end
32
37
  end
@@ -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
- /cubicle-(?<block_key>.+)/ =~ element_id
17
- store_item = Cubism.block_store[block_key]
16
+ block_container = Cubism.block_store[element_id]
18
17
 
19
- next if store_item.blank?
18
+ next if block_container.blank?
20
19
 
21
- html = ApplicationController.render(inline: store_item.block_source, locals: {"#{store_item.block_variable_name}": resource.present_users_for_element_id(element_id)})
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: "cubicle-element##{element_id}[identifier='#{signed_stream_identifier(resource.to_global_id.to_s)}']",
29
+ selector: selector,
25
30
  html: html
26
- ).broadcast
31
+ )
27
32
  end
33
+
34
+ cable_ready.broadcast
28
35
  end
29
36
  end
30
37
  end
@@ -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
- BlockStoreItem = Struct.new(
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.reverse_merge(block_source: block_source.digest)
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(serialized_item[:block_source])
88
+ self.block_source = Cubism.source_store[serialized_item[:block_source]]
84
89
  end
85
90
  end
86
91
 
@@ -1,3 +1,3 @@
1
1
  module Cubism
2
- VERSION = "0.1.0.pre11"
2
+ VERSION = "0.1.0.pre12"
3
3
  end
@@ -1,3 +1,3 @@
1
1
  module Cubism
2
- VERSION = "0.1.0.pre9"
2
+ VERSION = "0.1.0.pre11"
3
3
  end
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.pre11
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-02-16 00:00:00.000000000 Z
11
+ date: 2022-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails