App.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import React, { useState, useEffect, useRef } from 'react';
  2. import styles from './App.module.css';
  3. const UserList = React.memo(({ users }) => (
  4. <div className={styles.userList}>
  5. <span className={styles.title}>TeamSpeak Server Status</span>
  6. {
  7. users.map(user => <span className={styles.user} key={user}>{user}</span>)
  8. }
  9. </div>
  10. ));
  11. let vx = 2;
  12. let vy = 3;
  13. const updateVelocities = (el, bounding) => {
  14. if (el.offsetLeft <= 5 && vx < 0) {
  15. vx = -1 * vx;
  16. }
  17. if ((el.offsetLeft + el.offsetWidth) >= (bounding.offsetWidth - 20)) {
  18. vx = -1 * vx;
  19. }
  20. if (el.offsetTop <= 5 && vy < 0) {
  21. vy = -1 * vy;
  22. }
  23. if ((el.offsetTop + el.offsetHeight) >= (bounding.offsetHeight - 10)) {
  24. vy = -1 * vy;
  25. }
  26. }
  27. export default () => {
  28. const boundRef = useRef(null);
  29. const bounceRef = useRef(null);
  30. const [{x, y}, setPos] = useState({ x: 0, y: 0 });
  31. const [users, setUsers] = useState([]);
  32. useEffect(() => {
  33. const update = async () => {
  34. const res = await fetch("https://hiram.services/teamspeak/api");
  35. const { users } = await res.json();
  36. setUsers(users);
  37. };
  38. const interval = setInterval(update, 30000);
  39. update();
  40. return () => clearInterval(interval);
  41. }, []);
  42. useEffect(() => {
  43. const update = () => {
  44. updateVelocities(bounceRef.current, boundRef.current);
  45. setPos({x: x + vx, y: y + vy})
  46. };
  47. const interval = setTimeout(update, 30);
  48. return () => clearTimeout(interval);
  49. }, [x, y]);
  50. return (
  51. <div className={styles.screen} ref={boundRef}>
  52. <div
  53. style={{
  54. position: "absolute",
  55. top: `${y}px`,
  56. left: `${x}px`,
  57. }}
  58. ref={bounceRef}
  59. >
  60. <UserList users={users} />
  61. </div>
  62. </div>
  63. );
  64. }