add truncate to websockets example app

This commit is contained in:
vincanger 2024-07-16 12:38:07 +02:00
parent c2aa2b1c4a
commit e0b09c4212
2 changed files with 36 additions and 29 deletions

View File

@ -19,7 +19,8 @@
}
},
".wasp/out/sdk/wasp": {
"version": "0.0.1",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@lucia-auth/adapter-prisma": "^4.0.0",
"@prisma/client": "4.16.2",
@ -28,7 +29,6 @@
"@tanstack/react-query": "^4.29.0",
"@testing-library/jest-dom": "^6.3.0",
"@testing-library/react": "^14.1.2",
"@tsconfig/node18": "*",
"@types/express-serve-static-core": "^4.17.13",
"@types/react-router-dom": "^5.3.3",
"@vitest/ui": "^1.2.1",
@ -51,6 +51,9 @@
"superjson": "^1.12.2",
"tailwindcss": "^3.2.7",
"vitest": "^1.2.1"
},
"devDependencies": {
"@tsconfig/node18": "latest"
}
},
".wasp/out/sdk/wasp/node_modules/@node-rs/argon2": {
@ -2198,7 +2201,8 @@
"node_modules/@tsconfig/node18": {
"version": "18.2.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.2.tgz",
"integrity": "sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw=="
"integrity": "sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw==",
"dev": true
},
"node_modules/@tybys/wasm-util": {
"version": "0.8.1",
@ -9810,7 +9814,8 @@
"@tsconfig/node18": {
"version": "18.2.2",
"resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.2.tgz",
"integrity": "sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw=="
"integrity": "sha512-d6McJeGsuoRlwWZmVIeE8CUA27lu6jLjvv1JzqmpsytOYYbVi1tHZEnwCNVOXnj4pyLvneZlFlpXUK+X9wBWyw==",
"dev": true
},
"@tybys/wasm-util": {
"version": "0.8.1",
@ -13959,7 +13964,7 @@
"@tanstack/react-query": "^4.29.0",
"@testing-library/jest-dom": "^6.3.0",
"@testing-library/react": "^14.1.2",
"@tsconfig/node18": "*",
"@tsconfig/node18": "latest",
"@types/express-serve-static-core": "^4.17.13",
"@types/react-router-dom": "^5.3.3",
"@vitest/ui": "^1.2.1",

View File

@ -2,23 +2,21 @@ import { type ServerToClientPayload, useSocket, useSocketListener } from "wasp/c
import { useAuth } from "wasp/client/auth";
import { useState, useMemo, useEffect } from "react";
import { Button, Card } from "flowbite-react";
import { getUsername } from 'wasp/auth'
import { getUsername } from "wasp/auth";
const MainPage = () => {
const { data: user } = useAuth();
const [poll, setPoll] = useState<ServerToClientPayload<"updateState"> | null>(
null
);
const [poll, setPoll] = useState<ServerToClientPayload<"updateState"> | null>(null);
const totalVotes = useMemo(() => {
return (
poll?.options.reduce((acc, option) => acc + option.votes.length, 0) ?? 0
);
return poll?.options.reduce((acc, option) => acc + option.votes.length, 0) ?? 0;
}, [poll]);
const { socket } = useSocket();
const username = user ? getUsername(user) : null;
const TRUNCATE_SIZE = 7;
useSocketListener("updateState", (newState) => {
setPoll(newState);
});
@ -34,11 +32,7 @@ const MainPage = () => {
return (
<div className="w-full max-w-2xl mx-auto p-8">
<h1 className="text-2xl font-bold">{poll?.question ?? "Loading..."}</h1>
{poll && (
<p className="leading-relaxed text-gray-500">
Cast your vote for one of the options.
</p>
)}
{poll && <p className="leading-relaxed text-gray-500">Cast your vote for one of the options.</p>}
{poll && (
<div className="mt-4 flex flex-col gap-4">
{poll.options.map((option) => (
@ -58,15 +52,27 @@ const MainPage = () => {
</div>
{option.votes.length > 0 && (
<div className="mt-2 flex gap-2 flex-wrap max-w-[75%]">
{option.votes.map((vote) => (
<div
key={vote}
className="py-1 px-3 bg-gray-100 rounded-lg flex items-center justify-center shadow text-sm"
>
{option.votes.map((username, idx) => {
if (idx > TRUNCATE_SIZE) {
return undefined;
}
return (
<div
key={username}
className="py-1 px-3 bg-gray-100 rounded-lg flex items-center justify-center shadow text-sm"
>
<div className="w-2 h-2 bg-green-500 rounded-full mr-2"></div>
<div className="text-gray-700">{username}</div>
</div>
);
})}
{option.votes.length > TRUNCATE_SIZE + 2 && <div className="text-gray-700">{`...`}</div>}
{option.votes.length > TRUNCATE_SIZE + 1 && (
<div className="py-1 px-3 bg-gray-100 rounded-lg flex items-center justify-center shadow text-sm">
<div className="w-2 h-2 bg-green-500 rounded-full mr-2"></div>
<div className="text-gray-700">{vote}</div>
<div className="text-gray-700">{option.votes[option.votes.length - 1]}</div>
</div>
))}
)}
</div>
)}
</div>
@ -76,11 +82,7 @@ const MainPage = () => {
<div
className="absolute inset-0 bg-gradient-to-r from-yellow-400 to-orange-500 opacity-75 rounded-lg transition-all duration-300"
style={{
width: `${
totalVotes > 0
? (option.votes.length / totalVotes) * 100
: 0
}%`,
width: `${totalVotes > 0 ? (option.votes.length / totalVotes) * 100 : 0}%`,
}}
></div>
</Card>