repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
db5c0a4
parent
6e77947
author
Eric Bower
date
2024-10-08 02:47:22 +0000 UTC
style(pubsub): make it pop
12 files changed,  +88, -13
M pubsub/api.go
+1, -8
 1@@ -40,14 +40,7 @@ func createStaticRoutes() []shared.Route {
 2 		shared.NewRoute("GET", "/apple-touch-icon.png", serveFile("apple-touch-icon.png", "image/png")),
 3 		shared.NewRoute("GET", "/favicon.ico", serveFile("favicon.ico", "image/x-icon")),
 4 		shared.NewRoute("GET", "/robots.txt", serveFile("robots.txt", "text/plain")),
 5-		shared.NewRoute("GET", "/send-output.gif", serveFile("send-output.gif", "image/gif")),
 6-		shared.NewRoute("GET", "/send-file.gif", serveFile("send-file.gif", "image/gif")),
 7-		shared.NewRoute("GET", "/multi-sub.gif", serveFile("multi-sub.gif", "image/gif")),
 8-		shared.NewRoute("GET", "/multi-pub.gif", serveFile("multi-pub.gif", "image/gif")),
 9-		shared.NewRoute("GET", "/multi-pub-sub.gif", serveFile("multi-pub-sub.gif", "image/gif")),
10-		shared.NewRoute("GET", "/pipe-chat.gif", serveFile("pipe-chat.gif", "image/gif")),
11-		shared.NewRoute("GET", "/pipe-cmd-output.gif", serveFile("pipe-cmd-output.gif", "image/gif")),
12-		shared.NewRoute("GET", "/pipe-reverse-shell.gif", serveFile("pipe-reverse-shell.gif", "image/gif")),
13+		shared.NewRoute("GET", "/anim.js", serveFile("anim.js", "text/javascript")),
14 	}
15 }
16 
M pubsub/html/base.layout.tmpl
+1, -0
1@@ -12,6 +12,7 @@
2         {{template "meta" .}}
3 
4         <link rel="stylesheet" href="https://pico.sh/smol.css" />
5+        <script src="/anim.js"></script>
6     </head>
7     <body {{template "attrs" .}}>{{template "body" .}}</body>
8 </html>
M pubsub/html/marketing.page.tmpl
+7, -5
 1@@ -15,13 +15,15 @@
 2 {{define "attrs"}}class="container-sm"{{end}}
 3 
 4 {{define "body"}}
 5-<header class="flex flex-col items-center gap">
 6-  <img src="https://pico.sh/logo.svg" alt="pico logo" width="50" height="50" />
 7+<header class="flex flex-col items-center gap-2">
 8+  <div class="flex flex-col">
 9+    <img src="https://pico.sh/logo.svg" alt="pico logo" width="50" height="50" />
10+    <canvas id="canvas" width="50" height="50"></canvas>
11+    <hr width="100%" class="m-0" />
12+  </div>
13   <h1 class="text-2xl font-bold text-center">Authenticated *nix pipes over ssh</h1>
14 </header>
15 
16-<hr />
17-
18 <article class="flex flex-col gap-2">
19   <div>
20     <p>
21@@ -271,7 +273,7 @@
22     <h2 class="text-xl">Latest posts</h2>
23     <div class="flex items-center">
24       <div class="mr font-italic">2024-10-06</div>
25-      <div><a href="https://blog.pico.sh/pubsub">announcing pubsub service</a></div>
26+      <div><a href="https://blog.pico.sh/pubsub">pipe: our pubsub ssh service</a></div>
27     </div>
28   </div>
29 
A pubsub/public/anim.js
+79, -0
 1@@ -0,0 +1,79 @@
 2+document.addEventListener("DOMContentLoaded", init);
 3+const raf = window.requestAnimationFrame;
 4+
 5+function init() {
 6+  const canvas = document.getElementById("canvas");
 7+  const ctx = canvas.getContext("2d");
 8+  const data = {
 9+    ctx,
10+    // speed of movement (higher = faster)
11+    speed: 200,
12+    frame: 1,
13+    prev: 0,
14+    cur: 0,
15+    // boundary balls can traverse inside canvas
16+    minY: -20,
17+    maxY: canvas.height + 20,
18+    // balls
19+    entities: [
20+      { x: 20, y: 0, mod: 1 },
21+      // { x: 25, y: canvas.height / 2, mod: 1 },
22+      { x: 35, y: canvas.height, mod: -1 },
23+    ],
24+  };
25+
26+  raf(tick(data));
27+}
28+
29+function tick(data) {
30+  return (ms) => {
31+    const prev = data.cur;
32+    const cur = ms * 0.001;
33+    const next = {
34+      ...data,
35+      prev,
36+      cur,
37+      frame: data.frame + 1,
38+      delta: cur - prev,
39+    };
40+    return loop(next);
41+  };
42+}
43+
44+function loop(data) {
45+  const { ctx, entities, speed, delta, minY, maxY } = data;
46+  const width = ctx.canvas.width;
47+  const height = ctx.canvas.height;
48+  ctx.clearRect(0, 0, width, height);
49+
50+  for (let i = 0; i < entities.length; i += 1) {
51+    const entity = entities[i];
52+    const x = entity.x;
53+    const y = entity.y + (speed * delta * entity.mod);
54+    const nextMod = () => {
55+      if (y < minY) return 1;
56+      if (y > maxY) return -1;
57+      return entity.mod;
58+    };
59+
60+    // grace for entire ball to leave scene
61+    // const buffer = 25
62+    // dont bother drawing circle if outside canvas
63+    // if (y + buffer >= 0 && y - buffer <= height) {
64+    ball(ctx, x, y);
65+    // }
66+
67+    entities[i].x = x;
68+    entities[i].y = y;
69+    entities[i].mod = nextMod();
70+  }
71+
72+  raf(tick(data));
73+}
74+
75+function ball(ctx, x, y) {
76+  ctx.fillStyle = "#f2f2f2";
77+  ctx.beginPath();
78+  ctx.arc(x, y, 5, 0, 2 * Math.PI);
79+  ctx.fill();
80+}
D pubsub/public/multi-pub-sub.gif
+0, -0
D pubsub/public/multi-pub.gif
+0, -0
D pubsub/public/multi-sub.gif
+0, -0
D pubsub/public/pipe-chat.gif
+0, -0
D pubsub/public/pipe-cmd-output.gif
+0, -0
D pubsub/public/pipe-reverse-shell.gif
+0, -0
D pubsub/public/send-file.gif
+0, -0
D pubsub/public/send-output.gif
+0, -0