From e5ca48b03bd8330dec958a89c3aea87a2fbadb07 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Wed, 29 Nov 2023 15:31:23 -0700 Subject: working trongle and rought draft of emacs --- trongleposting-client/src/App.css | 78 +++++++++++++ trongleposting-client/src/App.js | 126 +++++++++++++++++++++ trongleposting-client/src/index.js | 10 ++ .../src/utils/generate_gruvbox.js | 14 +++ 4 files changed, 228 insertions(+) create mode 100644 trongleposting-client/src/App.css create mode 100644 trongleposting-client/src/App.js create mode 100644 trongleposting-client/src/index.js create mode 100644 trongleposting-client/src/utils/generate_gruvbox.js (limited to 'trongleposting-client/src') diff --git a/trongleposting-client/src/App.css b/trongleposting-client/src/App.css new file mode 100644 index 0000000..8e7ba34 --- /dev/null +++ b/trongleposting-client/src/App.css @@ -0,0 +1,78 @@ +body { + font-family: Consolas, monaco, monospace; + color: #fbf1c7; + margin: 0; + background-color: #3c3836; +} + +.container { + max-width: 900px; + width: 80%; + + border: 1px solid #b16286; + border-radius: 8px; + margin: 0; + padding: 24px; + + position: absolute; + top: 50%; + left: 50%; + -moz-transform: translateX(-50%) translateY(-50%); + -webkit-transform: translateX(-50%) translateY(-50%); + transform: translateX(-50%) translateY(-50%); + background-color: #282828; + + box-shadow: rgb( 0, 0, 0, 0.6) 6px 45px 45px -12px; +} + +.chat { + border-bottom: 1px solid #d65d0e; + height: 200px; + overflow-y: scroll; + padding-bottom: 12px; +} + +* { + scrollbar-width: thin; + scrollbar-color: #d5c4a1 rgba(0,0,0,0); +} + +*::-webkit-scrollbar { + width: 4px; +} + +*::-webkit-scrollbar-track { + background: rgba(0,0,0,0); +} + +*::-webkit-scrollbar-thumb { + background-color: #d5c4a1; + border-radius: 12px; +} + +.input { + font-size: 16px; + font-size: max(16px, 1em); + font-family: inherit; + padding: 0.25em 0.5em; + background-color: rgba(0,0,0,0); + border: none; + border-bottom: 1px solid #83a598; + color: #d5c4a1; + margin-top: 12px; + margin-bottom: 12px; + display: block; +} + +.input:focus { + outline: none; +} + +.button { + padding: 12px; + cursor: pointer; + border: 1px solid #8ec07c; + color: #8ec07c; + border-radius: 8px; + display: inline-block; +} \ No newline at end of file diff --git a/trongleposting-client/src/App.js b/trongleposting-client/src/App.js new file mode 100644 index 0000000..37643c5 --- /dev/null +++ b/trongleposting-client/src/App.js @@ -0,0 +1,126 @@ +import { useRef, useState, useEffect } from "react"; +import { generateGruvboxFromString } from "./utils/generate_gruvbox"; +import "./App.css"; + +function App() { + const [socket, setSocket] = useState(null); + const [posts, setPosts] = useState([]); + const postsRef = useRef([]); + const [content, setContent] = useState(""); + const [username, setUsername] = useState(""); + const [error, setError] = useState(""); + const [color, setColor] = useState(""); + + const scrollToBottomOfChat = () => { + const objDiv = document.getElementById("chat"); + objDiv.scrollTop = objDiv.scrollHeight; + }; + + useEffect(() => { + const protocol = document.location.protocol === "https:" ? "wss:" : "ws:"; + let socket; + + fetch("/posts") + .then((r) => r.json()) + .then((msgs) => { + postsRef.current = msgs; + setPosts(postsRef.current); + scrollToBottomOfChat(); + }) + .then(() => { + socket = new WebSocket(`${protocol}//${document.location.host}/`); + socket.addEventListener("open", () => { + socket.send("ping"); + }); + socket.addEventListener("message", (msg) => { + const { data } = msg; + if (data === "pong") return; + + const chat = JSON.parse(msg.data); + if (chat.author) { + postsRef.current = [...postsRef.current, chat]; + setPosts(postsRef.current); + scrollToBottomOfChat(); + } + }); + + setSocket(socket); + }); + + return () => { + socket.close(); + }; + }, []); + + useEffect(() => { + setColor(generateGruvboxFromString(username)); + }, [username]); + + const addPost = () => { + setError(""); + if (socket) { + fetch("/posts", { + method: "POST", + headers: { Content: "application/json" }, + body: JSON.stringify({ author: username, message: content }), + }).then(() => setContent("")); + } + }; + + return ( +
+
+

TronglePosting in ELisp

+
+
+

Welcome!

+ {posts.map((post) => ( +
+
+ + {post.author}:{" "} + + {post.message} +
+
+ [{new Date(post.date).toLocaleString()}] +
+
+ ))} +
+
+ { + setUsername(e.target.value); + }} + value={username} + > + +
+ Post +
+ {error ?

{error}

: null} +
+
+ ); +} + +export default App; diff --git a/trongleposting-client/src/index.js b/trongleposting-client/src/index.js new file mode 100644 index 0000000..7173ce5 --- /dev/null +++ b/trongleposting-client/src/index.js @@ -0,0 +1,10 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +ReactDOM.render( + + + , + document.getElementById('root') +); \ No newline at end of file diff --git a/trongleposting-client/src/utils/generate_gruvbox.js b/trongleposting-client/src/utils/generate_gruvbox.js new file mode 100644 index 0000000..7ff109b --- /dev/null +++ b/trongleposting-client/src/utils/generate_gruvbox.js @@ -0,0 +1,14 @@ +const gruvboxColors = [ + "#b8bb26", + "#fabd2f", + "#83a598", + "#d3869b", + "#8ec07c", + "#458588", + "#cc241d", + "#d65d0e", + "#bdae93", +]; + +export const generateGruvboxFromString = (string) => + gruvboxColors[Array.from(string).map((x) => x.charCodeAt(0)).reduce((a, x) => a+x, 0) % gruvboxColors.length]; \ No newline at end of file -- cgit v1.3