Skip to content

Instantly share code, notes, and snippets.

@faustinoaq
Last active December 6, 2017 03:15
Show Gist options
  • Save faustinoaq/2fd199a0cd92c824ee2f7d62635e73ab to your computer and use it in GitHub Desktop.
Save faustinoaq/2fd199a0cd92c824ee2f7d62635e73ab to your computer and use it in GitHub Desktop.
Guide to reload client on public file changes.

Amber Reload

Reloading public files on Amber.

Requisites

You need Crystal and Amber::CMD installed

Steps

  1. Create a new Amber project
>>> amber new my_project
Rendering App my_project in ./my_project
new       src/my_project.cr
new       src/views/layouts/application.slang
new       src/views/layouts/_nav.slang
new       src/views/home/index.slang
new       src/models/.gitkeep
new       src/mailers/.gitkeep
new       src/controllers/static_controller.cr
new       src/controllers/home_controller.cr
new       src/controllers/application_controller.cr
new       spec/spec_helper.cr
new       shard.yml
new       public/stylesheets/main.css
new       public/robots.txt
new       public/javascripts/main.js
new       public/crossdomain.xml
new       docker-compose.yml
new       config/routes.cr
new       config/deploy/Dockerfile
new       config/database.yml
new       config/application.cr
new       README.md
new       LICENSE
new       Dockerfile
new       .travis.yml
new       .gitignore
new       .amber.yml
  1. Create a socket
>>> cd my_project
>>> amber g socket reload reload
Rendering Socket reload
new       src/channels/reload_channel.cr
new       src/sockets/reload_socket.cr
new       public/javascripts/amber.js
  1. Add watcher shard on shard.yml
  watcher:
    github: faustinoaq/watcher
    version: ~> 0.2.0
  1. Add watcher on src/channels/reload_channel.cr
require "watcher"

class ReloadChannel < Amber::WebSockets::Channel
  def initialize(topic_path)
    super(topic_path)
    spawn do
      reload_msg = {
        "event":   "message",
        "topic":   "reload_room:reload",
        "subject": "msg:new",
        "payload": {"message": "reload"},
      }
      puts "๐Ÿ”ƒ  Your WatcherBot is vigilant. beep-boop..."
      watch("public/**/*") do |event|
        event.on_change do
          puts "๐Ÿ”ƒ  watching public files"
          rebroadcast!(reload_msg)
        end
      end
    end
  end

  def handle_joined
  end

  def handle_message(msg)
  end
end
  1. Add path for socket on config/routes.cr pipeline
websocket "/reload", ReloadSocket
  1. Add client script on public/javascripts/main.js
let socket = new Amber.Socket("/reload")
socket.connect().then(() => {
  this.channel = socket.channel(`reload_room:reload`)
  this.channel.join()
  this.channel.on('msg:new', data => {
    if (data.message == "reload") {
      console.log("reloading...")
      window.location.reload()
    }
  })
})
  1. Call client script on src/views/layouts/application.ecr
<script src="/javascripts/amber.js"></script>
<script src="/javascripts/main.js"></script>
  1. Execute Amber on watch mode
>>> amber watch

Results

๐Ÿ”ƒ  Your WatcherBot is vigilant. beep-boop...
๐Ÿ”ƒ  watching public files
I, [2017-07-22 11:18:08 -0500 #24600]  INFO -- : socket listening at /reload

Amber client reloading

It support multiples browsers at same time.

Also you can execute other tasks inside Watcher, by example:

event.on_change do |files|
  files.each do |file, time|
    case file
    when .ends_with?(".scss")
      system("scss #{file} -o public/stylesheets/")
    when .ends_with?(".ts")
      system("tsc #{file} -o public/javascripts/")
    end
  end
  puts "๐Ÿ”ƒ  watching public files"
  rebroadcast!(reload_msg)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment