convert_to_actix #2
10
README.md
10
README.md
|
@ -21,12 +21,10 @@ Now open `http://127.0.0.1:8080` in your browser.
|
||||||
- [ ] `EventHandlers.onMessage` should inject successfully decoded message into
|
- [ ] `EventHandlers.onMessage` should inject successfully decoded message into
|
||||||
Msg type directly...
|
Msg type directly...
|
||||||
- [ ] Run `uglify` twice as per [this link](https://github.com/rtfeldman/elm-spa-example/tree/master?tab=readme-ov-file#production-build)
|
- [ ] Run `uglify` twice as per [this link](https://github.com/rtfeldman/elm-spa-example/tree/master?tab=readme-ov-file#production-build)
|
||||||
- [ ] Clicking in upper left should go to landing page.
|
- [ ] JSONify backend code for all send/receive
|
||||||
|
- [ ] Backend should only communicate over websocket
|
||||||
|
- [ ] Close websocket after 15s of no response(from frontend) to websocket pings
|
||||||
|
- [ ] Implement dark mode
|
||||||
- [ ] Add GPLV3 License
|
- [ ] Add GPLV3 License
|
||||||
- [ ] Add `make release` target that is nix ready...
|
- [ ] Add `make release` target that is nix ready...
|
||||||
- [ ] Determine if `src/Body.elm` or pages in `src/Page` should have subscription functions
|
|
||||||
- [ ] use actix backend that maps most root requests to serve `actix_file::Files`
|
|
||||||
- [ ] Submit to slack for feedback...
|
|
||||||
- [ ] Refactor into router page
|
|
||||||
- [ ] Handle back-navigation
|
|
||||||
- [ ] Add `default.nix`
|
- [ ] Add `default.nix`
|
||||||
|
|
7
backend/src/landing.rs
Normal file
7
backend/src/landing.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct Landing {
|
||||||
|
pub time : String
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
|
use actix::prelude::*;
|
||||||
use actix_files::Files;
|
use actix_files::Files;
|
||||||
use actix_web::{web, App, HttpServer, Responder, HttpRequest, HttpResponse, Error};
|
use actix_web::{web, App, Error, HttpRequest, HttpResponse, HttpServer, Responder};
|
||||||
use actix_web_actors::ws;
|
use actix_web_actors::ws;
|
||||||
use log::{info};
|
use log::info;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{fs, time::Duration};
|
use std::{fs, time::Duration};
|
||||||
use actix::prelude::*;
|
|
||||||
|
mod landing;
|
||||||
|
|
||||||
/// Greeting API structures
|
/// Greeting API structures
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -17,6 +19,11 @@ struct GreetingResponse {
|
||||||
message: String,
|
message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
enum ToFrontend {
|
||||||
|
Landing(landing::Landing)
|
||||||
|
}
|
||||||
|
|
||||||
async fn greet(req: web::Json<GreetingRequest>) -> impl Responder {
|
async fn greet(req: web::Json<GreetingRequest>) -> impl Responder {
|
||||||
info!("Received request to /api/greet with name: {}", req.name);
|
info!("Received request to /api/greet with name: {}", req.name);
|
||||||
let message = format!("Hello, {}!", req.name);
|
let message = format!("Hello, {}!", req.name);
|
||||||
|
@ -41,7 +48,11 @@ impl Actor for MyWebSocket {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWebSocket {
|
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWebSocket {
|
||||||
fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut ws::WebsocketContext<Self>) {
|
fn handle(
|
||||||
|
&mut self,
|
||||||
|
msg: Result<ws::Message, ws::ProtocolError>,
|
||||||
|
ctx: &mut ws::WebsocketContext<Self>,
|
||||||
|
) {
|
||||||
if let Ok(ws::Message::Ping(msg)) = msg {
|
if let Ok(ws::Message::Ping(msg)) = msg {
|
||||||
ctx.pong(&msg);
|
ctx.pong(&msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,10 +14,12 @@ import Json.Decode as Decode
|
||||||
type alias Model = {
|
type alias Model = {
|
||||||
time : String
|
time : String
|
||||||
}
|
}
|
||||||
|
type alias Landing = {
|
||||||
|
time : String
|
||||||
|
}
|
||||||
type Msg
|
type Msg
|
||||||
= SocketOpened
|
= ToFrontend Landing
|
||||||
| SocketClosed
|
| Time String
|
||||||
| SocketMessage String
|
|
||||||
| NoOp
|
| NoOp
|
||||||
|
|
||||||
init : () -> Model
|
init : () -> Model
|
||||||
|
@ -34,25 +36,30 @@ decodeMessage message =
|
||||||
Ok decoded -> decoded
|
Ok decoded -> decoded
|
||||||
Err err -> "failed to decode" ++ message
|
Err err -> "failed to decode" ++ message
|
||||||
|
|
||||||
|
decodeMessageOld : String -> String
|
||||||
|
decodeMessageOld message =
|
||||||
|
let
|
||||||
|
decodedMessage = Decode.decodeString (Decode.field "time" Decode.string) message
|
||||||
|
in
|
||||||
|
case decodedMessage of
|
||||||
|
Ok decoded -> decoded
|
||||||
|
Err err -> "failed to decode" ++ message
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
subscriptions model =
|
subscriptions model =
|
||||||
Ports.socketOnEvent
|
Ports.socketOnEvent
|
||||||
(Websockets.EventHandlers
|
(Websockets.EventHandlers
|
||||||
(\_ -> SocketOpened)
|
|
||||||
(\_ -> SocketClosed)
|
|
||||||
(\_ -> NoOp)
|
(\_ -> NoOp)
|
||||||
(\message -> SocketMessage message.data)
|
(\_ -> NoOp)
|
||||||
|
(\_ -> NoOp)
|
||||||
|
(\message -> (message.data |> decodeMessageOld |> Time))
|
||||||
(\_ -> NoOp)
|
(\_ -> NoOp)
|
||||||
)
|
)
|
||||||
|
|
||||||
update : Msg -> Model -> (Model, Cmd Msg)
|
update : Msg -> Model -> (Model, Cmd Msg)
|
||||||
update msg model =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
SocketMessage message ->
|
Time time -> ( {model | time = time}, Cmd.none )
|
||||||
let
|
|
||||||
decoded = decodeMessage message
|
|
||||||
in
|
|
||||||
( {model | time = decoded}, Cmd.none )
|
|
||||||
_ -> (model, Cmd.none)
|
_ -> (model, Cmd.none)
|
||||||
|
|
||||||
view : Model -> Element Msg
|
view : Model -> Element Msg
|
||||||
|
|
Loading…
Reference in a new issue