Created
March 27, 2022 21:16
-
-
Save Beyarz/5c54e361a021e94ef91cbbfe314880e2 to your computer and use it in GitHub Desktop.
Live updates from sinatra server via hotwired stimulus
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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