{"id":13878658,"url":"https://github.com/julianrubisch/cubism","last_synced_at":"2025-09-07T07:08:51.528Z","repository":{"id":43454629,"uuid":"384897483","full_name":"julianrubisch/cubism","owner":"julianrubisch","description":"Lightweight Resource-Based Presence Solution with CableReady","archived":false,"fork":false,"pushed_at":"2024-03-28T17:31:18.000Z","size":213,"stargazers_count":61,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-29T12:19:10.152Z","etag":null,"topics":["actioncable","cableready","presence","rails","ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/julianrubisch.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"julianrubisch"}},"created_at":"2021-07-11T08:35:05.000Z","updated_at":"2025-01-22T23:18:21.000Z","dependencies_parsed_at":"2022-09-17T11:12:28.454Z","dependency_job_id":"868e03bb-8373-4a51-b7eb-d9613a8e2349","html_url":"https://github.com/julianrubisch/cubism","commit_stats":{"total_commits":132,"total_committers":4,"mean_commits":33.0,"dds":"0.11363636363636365","last_synced_commit":"dfa776a6d37a17d7aad7eea8236b5bfccb2040dd"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julianrubisch%2Fcubism","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julianrubisch%2Fcubism/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julianrubisch%2Fcubism/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julianrubisch%2Fcubism/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/julianrubisch","download_url":"https://codeload.github.com/julianrubisch/cubism/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252624493,"owners_count":21778288,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actioncable","cableready","presence","rails","ruby"],"created_at":"2024-08-06T08:01:55.891Z","updated_at":"2025-05-08T00:27:35.020Z","avatar_url":"https://github.com/julianrubisch.png","language":"Ruby","funding_links":["https://github.com/sponsors/julianrubisch"],"categories":["Ruby"],"sub_categories":[],"readme":"# Cubism\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-1-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n[![Twitter follow](https://img.shields.io/twitter/follow/julian_rubisch?style=social)](https://twitter.com/julian_rubisch)\n\nLightweight Resource-Based Presence Solution with CableReady.\n\n`Cubism` provides real-time updates of who is viewing or interacting with whatever resources you need. Whether you want Slack's \"X is typing...\" indicator or an e-commerce \"5 other customers are viewing this item\" notice, `Cubism` gives you everything you need \"under the hood\" so that you can focus on what really matters—end-user functionality.\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Usage](#usage)\n- [Installation](#installation)\n- [API](#api)\n- [Limitations](#limitations)\n- [Gotchas](#gotchas)\n- [Contributing](#contributing)\n- [License](#license)\n- [Contributors](#contributors)\n\n## Usage\n\n### Prepare your User Model\nIn your app's `User` model, include `Cubism::User`:\n\n```rb\nclass User \u003c ApplicationRecord\n  include Cubism::User\n\n  # ...\nend\n```\n\n### Track Present Users in your Models\nIn the models you'd like to track presence for, include the `Cubism::Presence` concern:\n\n```rb\nclass Project \u003c ApplicationRecord\n  include Cubism::Presence\n\n  # ...\nend\n```\n\n### Set Up the Cubicle Template\n\nUsing the `cubicle_for` helper, you can set up a presence indicator. It will\n\n1. subscribe to the respective resource, and\n2. render a block which is passed the list of present `users`:\n\n```erb\n\u003c%= cubicle_for @project, current_user do |users| %\u003e\n  \u003c%= users.map(\u0026:username).join(\", \")\n\u003c% end %\u003e\n```\n\n**Important!** due to technical limitations the cubism block does _not_ act as a closure, i.e. it has _only_ access to the `users` variable passed to it - think of it more as a self-contained component.\n\n## Installation\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'cubism'\n```\n\nAnd then execute:\n```bash\n$ bundle\n```\n\nThere are a few ways to install the Cubism JavaScript client, depending on your application setup.\n\n#### ESBuild / Webpacker\n\n```sh\nyarn add @minthesize/cubism\n```\n\n#### Import maps:\n\n```ruby\n# config/importmap.rb\n# ...\npin '@minthesize/cubism', to: 'cubism.min.js', preload: true\n```\n\n#### Rails Asset pipeline (Sprockets):\n\n```html+erb\n\u003c!-- app/views/layouts/application.html.erb --\u003e\n\u003c%= javascript_include_tag \"cubism.umd.min.js\", \"data-turbo-track\": \"reload\" %\u003e\n```\n\n### Kredis\n\nThis gem uses [kredis](https://github.com/rails/kredis) under the hood, so be sure to follow their [installation instructions](https://github.com/rails/kredis#installation). In other words, provide a Redis instance and configure it in `config/redis/shared.yml`.\n\n### Javascript\n\nIn your app's Javascript entrypoint (e.g. `app/javascript/packs/application.js`) import and initialize `CableReady` (cubism will make use of the injected ActionCable consumer):\n\n```js\nimport CableReady from \"cable_ready\";\nimport \"@minthesize/cubism\";\n\nCableReady.initialize({ consumer });\n```\n\n## API\n\nThe `cubicle_for` helper accepts the following options as keyword arguments:\n\n- `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: `\"\"`).\n- `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`).\n- `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.\n- `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.\n- `trigger_root`: a CSS selector to attach the appear/disappear events to. Defaults to the `cubicle-element` itself.\n- `html_options` are passed to the TagBuilder.\n\n## Limitations\n\n### Supported Template Handlers\n- ERB\n\n## Testing\nIn Rails system tests there is a chance that tests will hang in some cases. To overcome this, add the flag\n\n```ruby\nCubism.skip_in_test = true\n```\n\nto an initializer, for example `config/initializers/cubism.rb`.\n\n## Gotchas\n\n### Usage with ViewComponent\n\nCurrently there's a bug in VC resulting in the `capture` helper not working correctly (https://github.com/github/view_component/pull/974). The current workaround is to assign a slot in your component and render the presence list from outside:\n\n```rb\nclass MyComponent \u003c ViewComponent::Base\n  renders_one :presence_list\n\n  # ...\nend\n```\n\n```erb\n\u003c%= render MyComponent.new do |c| %\u003e\n  \u003c% c.presence_list do %\u003e\n    \u003c%= cubicle_for @project, current_user do |users| %\u003e\n      ...\n    \u003c% end %\u003e\n  \u003c% end %\u003e\n\u003c% end %\u003e\n```\n\n## Contributing\n\n### Get local environment setup\n\nBelow are a set of instructions that may help you get a local development environment working\n\n```sh\n# Get the gem/npm package source locally\ngit clone https://github.com/julianrubisch/cubism\nyarn install # install all of the npm package's dependencies\nyarn link # set the local machine's cubism npm package's lookup to this local path\n\n# Setup a sample project and edit Gemfile to point to local gem\n# (e.g. `gem \"cubism\", path: \"../cubism\"`)\n# yarn link @minthesize/cubism\n\n\n# Do your work, Submit PR, Profit!\n\n\n# To stop using your local version of cubism\n# change your Gemfile back to the published (e.g. `gem \"cubism\"`)\ncd path/to/cubism/javascript\n# Stop using the local npm package\nyarn unlink\n\n# Instruct your project to reinstall the published version of the npm package\ncd path/to/project\nyarn install --force\n```\n\n### 📦 Releasing\n\n1. Make sure that you run `yarn` and `bundle` to pick up the latest.\n2. Bump version number at `lib/cubism/version.rb`. Pre-release versions use `.preN`\n3. Run `rake build` and `yarn build`\n4. Commit and push changes to github `git commit -m \"Bump version to x.x.x\"`\n5. Run `rake release`\n6. Run `yarn publish --no-git-tag-version`\n7. Yarn will prompt you for the new version. Pre-release versions use `-preN`\n8. Commit and push changes to GitHub\n9. Create a new release on GitHub ([here](https://github.com/julianrubisch/cubism/releases)) and generate the changelog for the stable release for it\n## License\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n\n## Contributors\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://www.minthesize.com\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/4352208?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJulian Rubisch\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/julianrubisch/cubism/commits?author=julianrubisch\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjulianrubisch%2Fcubism","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjulianrubisch%2Fcubism","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjulianrubisch%2Fcubism/lists"}