Skip to content

Commit

Permalink
rewrite rontend in htmx
Browse files Browse the repository at this point in the history
  • Loading branch information
Klaven committed Jul 6, 2024
1 parent 31992c5 commit 492b53c
Show file tree
Hide file tree
Showing 17 changed files with 332 additions and 37 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[workspace]


members = [
"ai_manager_service",
"twitch_listener_service",
Expand All @@ -21,7 +20,7 @@ exclude = [

[workspace.dependencies]
anyhow = "1.0"
sqlx = { version = "0.7.4", features = ["sqlite"] }
sqlx = { version = "0.7.4", features = ["sqlite", "runtime-tokio"] }
structopt = "0.3"
twitch_api = { git = "https://github.com/twitch-rs/twitch_api.git", features = [
"reqwest",
Expand Down
39 changes: 33 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,39 @@
FROM cgr.dev/chainguard/rust:latest-dev as build
USER root
RUN mkdir -p /usr/src/app
ARG UBUNTU_RELEASE=22.04

FROM rust:1.79 AS builder

WORKDIR /usr/src/app

COPY . .
RUN cargo build --bin monolith --release

FROM cgr.dev/chainguard/cc-dynamic:latest


# Build the chiselled filesystem based on the desired slices.
FROM ubuntu:$UBUNTU_RELEASE AS chiselled
ARG UBUNTU_RELEASE
ARG TARGETARCH

# Get chisel binary
ADD https://github.com/canonical/chisel/releases/download/v0.9.1/chisel_v0.9.1_linux_$TARGETARCH.tar.gz chisel.tar.gz
RUN tar -xvf chisel.tar.gz -C /usr/bin/
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates

WORKDIR /rootfs


RUN chisel cut --release ubuntu-$UBUNTU_RELEASE --root /rootfs \
base-files_base \
base-files_release-info \
ca-certificates_data \
libgcc-s1_libs \
libc6_libs \
libssl3_libs

FROM scratch
COPY ./ai_manager_service/migrations /var/lib/db/migrations
EXPOSE 9000
COPY --from=build --chown=nonroot:nonroot /usr/src/app/target/release/monolith /usr/local/bin/twitch-alerts
CMD ["/usr/local/bin/monolith"]
COPY --from=chiselled /rootfs /
COPY --from=builder /usr/src/app/target/release/monolith /usr/local/bin/twitch-alerts
CMD ["/usr/local/bin/twitch-alerts"]
Binary file added alerts.db-shm
Binary file not shown.
Binary file added alerts.db-wal
Binary file not shown.
2 changes: 1 addition & 1 deletion deployment/twitch-alerts-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ spec:
# Start your application & Litestream to share a PVC data directory.
containers:
- name: twitch-alerts
image: nullchannel/twitch-alerts:0.1.21
image: nullchannel/twitch-alerts:0.1.22
ports:
- name: websocket
containerPort: 9000
Expand Down
100 changes: 100 additions & 0 deletions frontend_api/assets/css/alert.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
:root {
--font-size: 1.5vw;
}

div.wrapper {
border-radius: 1vw;
background-color: #2d3140;
align-items: center;
display: flex;
flex-direction: column;
background-image: url('../img/background.png');
background-size: cover;
width: 30vw;
height: 30vw;
}

p {
color: #e8e8e8;
font-size: var(--font-size);
padding: 1.5vw;
width: 95%;
height: 90%;
text-align: center;
margin: 0;
}

p.message {
width: 47%;
height: 93%;
text-align: center;
margin: 0;
font-size: var(--font-size);
padding: 1vw;
}

p.event {
text-align: center;
margin-bottom: 0vw;
margin-top: .7vw;
font-size: var(--font-size);
height: fit-content;
padding: 1vw;
font-weight: bold;
}

p.follow {
color: black;
}

p.subscribe {
color: #de4b35;
}

p.raid {
color: #9147ff;
}

p.resubscribe {
color: rgb(32, 117, 42);

}


h2.message {
margin-bottom: .4vw;
padding: 0vw;
text-align: center;
font-size: var(--font-size);
}

div#message {
width: 100%;
height: 100%;
display: flex;
padding: 1.5vw;
flex-direction: row;
justify-content: space-around;
align-items: center;
}

div#footer {
width: 100%;
height: 100%;
display: flex;
padding: 1.5vw;
flex-direction: row;
justify-content: space-around;
align-items: center;
}

span#sub {
color: #9e2b25;
font-size: 2vw;
padding: 1.5vw;
width: 95%;
height: 90%;
text-align: center;
margin: 0;
}

26 changes: 25 additions & 1 deletion frontend_api/assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
div {
display: grid;
grid-template-columns: repeat(2, 1fr);
width: 75%;
width: 100%;
}

.queue {
Expand All @@ -13,6 +13,30 @@ div {
flex-direction: column;
justify-content: space-between;
align-items: center;
width: 100%;
}

#latest {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
width: 100%;
}

.paused {
border: 10px solid red;
align-items: center;
padding: 10px;
border-radius: 15px;
color: #ccc;
width: 100%;
}

.running {
color: #000;
width: 100%;
align-items: center;
}

ul {
Expand Down
Binary file added frontend_api/assets/img/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend_api/assets/sounds/dial-up.wav
Binary file not shown.
110 changes: 110 additions & 0 deletions frontend_api/src/htmx.rs
Original file line number Diff line number Diff line change
@@ -1 +1,111 @@
use maud::{html, Markup};
use messages::{DisplayMessage, TwitchEvent};

pub fn get_display_html(message: DisplayMessage) -> Markup {
html! {
@match &message.payload {
TwitchEvent::ChannelFollow(follow) => {
p class="event follow" { "Followed" }
p class="message" { (message.message) }
(get_html_name_follow(follow))
}
TwitchEvent::ChannelSubscribe(sub) => {
p class="event subscribe" { "Subscribed" }
p class="message" { (message.message) }
(get_html_name_channel_subscribe(sub))
}
TwitchEvent::ChannelRaid(raid) => {
p class="event raid" { "Raided" }
p class="message" { (message.message) }
(get_html_name_raid(raid))
}
TwitchEvent::ChannelSubGift(gift) => {
p class="event subgift" { "Gifted Sub!" }
p class="message" { (message.message) }
(get_html_name_sub_gift(gift))
}
TwitchEvent::ChannelCheer(cheer) => {
p class="event cheer" { "Cheered!" }
p class="message" { (message.message) }
(get_html_name_cheer(cheer))
}
TwitchEvent::ChannelResubscribe(sub) => {
p class="event resubscribe" { "Resubscribed" }
p class="message" { (message.message) }
(get_html_name_channel_subscribe(sub))
}
}
}
}

fn get_html_name_cheer(cheer: &messages::CheerEvent) -> Markup {
html! {
h2 class="message" { (format!("{}", cheer.user_name )) }
}
}

fn get_html_name_raid(raid: &messages::RaidEvent) -> Markup {
html! {
h2 class="message" { (format!("{}", raid.from_broadcaster_user_name)) }
}
}

fn get_html_name_sub_gift(gift: &messages::ChannelGiftMessage) -> Markup {
if let Some(gifter) = gift.clone().user_name {
html! {
h2 class="message" { (format!("{}", gifter)) }
}
} else {
html! {
h2 class="message" { "Anonymous" }
}
}
}

fn get_html_name_follow(follow: &messages::FollowEvent) -> Markup {
html! {
h2 class="message" { (format!("{}", follow.user_name)) }
}
}

fn get_html_name_channel_subscribe(sub: &messages::SubscribeEvent) -> Markup {
html! {
h2 class="message" { (format!("{}", sub.user_name)) }
}
}

fn get_html_cheer(cheer: &messages::CheerEvent) -> Markup {
html! {
p { (format!("Thank you {} for cheering with {} bits", cheer.user_name, cheer.bits)) }
}
}

fn get_html_raid(raid: &messages::RaidEvent) -> Markup {
html! {
p { (format!("Thank you {} for raiding with {} viewers", raid.from_broadcaster_user_name, raid.viewers)) }
}
}

fn get_html_sub_gift(gift: &messages::ChannelGiftMessage) -> Markup {
if let Some(gifter) = gift.clone().user_name {
html! {
p { (format!("Thank you {} for gifting a sub to {}", gifter, gift.broadcaster_user_name)) }
}
} else {
html! {
p { (format!("Thank you for gifting a sub to {}", gift.broadcaster_user_name)) }
}
}
}

fn get_html_follow(follow: &messages::FollowEvent) -> Markup {
html! {
p { (format!("Thank you {} for following", follow.user_name)) }
}
}

fn get_html_channel_subscribe(sub: &messages::SubscribeEvent) -> Markup {
html! {
p { (format!("Thank you {} for subscribing", sub.user_name)) }
}
}
18 changes: 12 additions & 6 deletions frontend_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use tokio_tungstenite::{
tungstenite::{Error, Message, Result},
};

mod htmx;
mod routes;
mod types;
use routes::{admin, index};
Expand All @@ -29,14 +30,16 @@ pub struct FrontendApi {
ws_address: String,
http_address: String,
connection_state: ConnectionMap,
asset_path: String,
}

impl FrontendApi {
pub fn new(ws_address: String, http_address: String) -> FrontendApi {
pub fn new(ws_address: String, http_address: String, asset_path: String) -> FrontendApi {
FrontendApi {
ws_address,
http_address,
connection_state: ConnectionMap::new(Mutex::new(HashMap::new())),
asset_path,
}
}

Expand Down Expand Up @@ -88,9 +91,10 @@ impl FrontendApi {
//Make html message to send to frontend
//<div id="alerts" hx-swap-oob="true">
let html_message = html! {
div id="notifications" hx-swap="afterend" hx-target="notifications" {
h1 { (message.message) }
img src=(message.image_url) {}
div id="notifications" class="alert" hx-swap="afterend" hx-target="notifications" {
div class="wrapper" {
(htmx::get_display_html(message.clone()))
}
}
};

Expand All @@ -111,7 +115,7 @@ impl FrontendApi {
}

//Pause for a bit to allow the message to be displayed
tokio::time::sleep(tokio::time::Duration::from_millis(5000)).await;
tokio::time::sleep(tokio::time::Duration::from_millis(10000)).await;

let html_message = html! {
div id="notifications" hx-swap="delete" hx-target="notifications" {
Expand All @@ -136,7 +140,9 @@ impl FrontendApi {
});

let https_address = self.http_address.clone();
print!("Frontend HTTP is Listening on: {}", https_address);
let event_queues = message_queue_arc.clone();
let asset_path = self.asset_path.clone();
tokio::spawn(async move {
let listener = TcpListener::bind(&https_address)
.await
Expand All @@ -153,7 +159,7 @@ impl FrontendApi {
.route("/events/start", get(routes::resume_events))
//TODO: understand where to put our assets
// Remember that these need served by nginx in production
.nest_service("/assets", ServeDir::new("assets"))
.nest_service("/assets", ServeDir::new(asset_path.clone()))
.with_state(event_queues.clone());

// run it
Expand Down
Loading

0 comments on commit 492b53c

Please sign in to comment.