Skip to content

Instantly share code, notes, and snippets.

@Beyarz
Created March 27, 2022 21:16
Show Gist options
  • Select an option

  • Save Beyarz/5c54e361a021e94ef91cbbfe314880e2 to your computer and use it in GitHub Desktop.

Select an option

Save Beyarz/5c54e361a021e94ef91cbbfe314880e2 to your computer and use it in GitHub Desktop.
Live updates from sinatra server via hotwired stimulus
# frozen_string_literal: true
# rubocop:disable Metrics/BlockLength
require 'date'
require 'sinatra'
require 'sinatra/reloader' if development?
set :port, 3020
set :bind, '0.0.0.0'
status = 'Inactive'
get '/cmd/:command' do |command|
case command.downcase
when 'hello'
response = 'Hello, world!'
when 'time'
response = Time.now
when 'help'
response = 'Commands: hello, time, status'
when 'status'
response = status
end
erb response.to_s, format: :plain
end
get '/status' do
case rand(1..3)
when 1
erb Time.now.to_s, format: :plain
when 2
erb Date.today.to_s, format: :plain
when 3
erb rand.to_s, format: :plain
end
end
get '/' do
html = %(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Stimulus</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/milligram/1.4.1/milligram.css">
<script type="module">
import { Application, Controller } from "https://cdn.skypack.dev/@hotwired/stimulus";
window.Stimulus = Application.start();
Stimulus.register("command",
class extends Controller {
static targets = ["inbound", "outbound", "status"]
connect() {
setInterval(() => {
this.ping()
}, 2500)
}
ping() {
fetch(`/status`)
.then( response => response.body )
.then( body => body.getReader().read() )
.then( content => content.value )
.then( buffer => new TextDecoder().decode(buffer) )
.then( string => {
if (string == 'null' || string == '') {
return false
}
this.statusTarget.insertAdjacentHTML('afterend', `<blockquote><p>${string}</p></blockquote>`)
})
}
sendCommand() {
let command = this.inboundTarget.value
this.inboundTarget.value = null
if (command == 'null' || command == '') {
return false
}
fetch(`/cmd/${command}`)
.then( response => response.body )
.then( body => body.getReader().read() )
.then( content => content.value )
.then( buffer => new TextDecoder().decode(buffer) )
.then( string => {
if (string == '') {
return false
}
this.outboundTarget.insertAdjacentHTML('afterend', `<blockquote><p>${string}</p></blockquote>`)
})
}
}
)
</script>
</head>
<body>
<div data-controller="command" class="container" style="padding-top: 3rem">
<div class="row">
<div class="column column-10">
<h4>Input: </h4>
</div>
<div class="column">
<input
data-command-target="inbound"
placeholder="Enter something..."
value=""
type="text"
/>
</div>
<div class="column">
<button class="button" data-action="click->command#sendCommand">Submit</button>
</div>
</div>
<div class="row">
<div class="column">
<h4>Logs:</h4>
<div data-command-target="outbound"></div>
</div>
<div class="column">
<h4>Status:</h4>
<div style="height: 75vh; overflow-y: scroll;">
<div data-command-target="status"></div>
</div>
</div>
</div>
</div>
</body>
</html>
)
erb html, format: :html5
end
# rubocop:enable Metrics/BlockLength
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment