Versions

  • v15

    11/5/2024
    Open: Version
    Changes from v14 to v15
    +26
    -10
    ⦚ 77 unchanged lines ⦚

    const copyToClipboard = useCallback(() => {
    navigator.clipboard.writeText(window.location.href).then(() => {
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
    });
    }, []);

    ⦚ 19 unchanged lines ⦚
    <p>
    Share this URL with friends:{" "}
    <span className="share-link" onClick={copyToClipboard}>
    {window.location.href}
    </span>
    {copied && <span className="copied-message">Copied!</span>}
    </p>
    ⦚ 201 unchanged lines ⦚
    }
    .share-link {
    color: #0066cc;
    cursor: pointer;
    text-decoration: underline;
    }
    .copied-message {
    ⦚ 5 unchanged lines ⦚
    ⦚ 77 unchanged lines ⦚

    const copyToClipboard = useCallback(() => {
    const el = document.createElement('textarea');
    el.value = window.location.href;
    document.body.appendChild(el);
    el.select();
    document.execCommand('copy');
    document.body.removeChild(el);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
    }, []);

    ⦚ 19 unchanged lines ⦚
    <p>
    Share this URL with friends:{" "}
    <input
    type="text"
    readOnly
    value={window.location.href}
    className="share-link"
    onClick={(e) => e.target.select()}
    />
    <button onClick={copyToClipboard} className="copy-button">
    Copy
    </button>
    {copied && <span className="copied-message">Copied!</span>}
    </p>
    ⦚ 201 unchanged lines ⦚
    }
    .share-link {
    width: 70%;
    padding: 5px;
  • v14

    11/5/2024
    Open: Version
    Changes from v13 to v14
    +26
    -2
    /** @jsxImportSource https://esm.sh/react */
    import React, { useState, useEffect } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";
    import { nanoid } from "https://esm.sh/nanoid";
    ⦚ 14 unchanged lines ⦚
    const [roomId, setRoomId] = useState("");
    const [language, setLanguage] = useState("en");

    useEffect(() => {
    ⦚ 53 unchanged lines ⦚
    };

    if (!username) {
    return (
    <div className="container">
    ⦚ 14 unchanged lines ⦚
    <div className="container">
    <h1>Chat Room</h1>
    <p>Share this URL with friends: {window.location.href}</p>
    <div className="language-selector">
    <label htmlFor="language-select">Select your language: </label>
    ⦚ 197 unchanged lines ⦚
    padding: 5px;
    font-size: 16px;
    }
    `;
    /** @jsxImportSource https://esm.sh/react */
    import React, { useState, useEffect, useCallback } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";
    import { nanoid } from "https://esm.sh/nanoid";
    ⦚ 14 unchanged lines ⦚
    const [roomId, setRoomId] = useState("");
    const [language, setLanguage] = useState("en");
    const [copied, setCopied] = useState(false);

    useEffect(() => {
    ⦚ 53 unchanged lines ⦚
    };

    const copyToClipboard = useCallback(() => {
    navigator.clipboard.writeText(window.location.href).then(() => {
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
    });
    }, []);

    if (!username) {
    return (
    <div className="container">
    ⦚ 14 unchanged lines ⦚
    <div className="container">
    <h1>Chat Room</h1>
    <p>
    Share this URL with friends:{" "}
    <span className="share-link" onClick={copyToClipboard}>
    {window.location.href}
    </span>
    {copied && <span className="copied-message">Copied!</span>}
    </p>
  • v13

    11/5/2024
    Open: Version
    Changes from v12 to v13
    +33
    -87
    /** @jsxImportSource https://esm.sh/react */
    import { nanoid } from "https://esm.sh/nanoid";
    import React, { useEffect, useState, useCallback } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";

    const languages = [
    { code: "en", name: "English" },
    { code: "fr", name: "French" },
    { code: "es", name: "Spanish" },
    { code: "de", name: "German" },
    { code: "it", name: "Italian" },
    ];

    ⦚ 5 unchanged lines ⦚
    const [roomId, setRoomId] = useState("");
    const [language, setLanguage] = useState("en");
    const [linkCopied, setLinkCopied] = useState(false);

    useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const roomFromUrl = urlParams.get("room");
    if (roomFromUrl) {
    setRoomId(roomFromUrl);
    } else {
    const newRoomId = nanoid(10);
    setRoomId(newRoomId);
    window.history.pushState({}, "", `?room=${newRoomId}`);
    }
    }, []);
    ⦚ 23 unchanged lines ⦚
    if (inputMessage && roomId && username) {
    try {
    const response = await fetch("/send-message", {
    method: "POST",
    /** @jsxImportSource https://esm.sh/react */
    import React, { useState, useEffect } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";
    import { nanoid } from "https://esm.sh/nanoid";

    const languages = [
    { code: 'en', name: 'English' },
    { code: 'fr', name: 'French' },
    { code: 'es', name: 'Spanish' },
    { code: 'de', name: 'German' },
    { code: 'it', name: 'Italian' },
    ];

    ⦚ 5 unchanged lines ⦚
    const [roomId, setRoomId] = useState("");
    const [language, setLanguage] = useState("en");

    useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const roomFromUrl = urlParams.get('room');
    if (roomFromUrl) {
    setRoomId(roomFromUrl);
    } else {
    const newRoomId = nanoid(10);
    setRoomId(newRoomId);
    window.history.pushState({}, '', `?room=${newRoomId}`);
    }
    }, []);
    ⦚ 23 unchanged lines ⦚
    if (inputMessage && roomId && username) {
    try {
    const response = await fetch('/send-message', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
  • v12

    11/5/2024
    Open: Version
    Changes from v11 to v12
    +29
    -15
    /** @jsxImportSource https://esm.sh/react */
    import { nanoid } from "https://esm.sh/nanoid";
    import React, { useEffect, useState } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";

    ⦚ 71 unchanged lines ⦚
    };

    const copyRoomLink = () => {
    const roomLink = window.location.href;
    navigator.clipboard.writeText(roomLink).then(() => {
    setLinkCopied(true);
    setTimeout(() => setLinkCopied(false), 3000); // Reset after 3 seconds
    }).catch(err => {
    console.error('Failed to copy: ', err);
    });
    };

    if (!username) {
    ⦚ 16 unchanged lines ⦚
    <div className="container">
    <h1>Multilingual Chat Room</h1>
    <p>
    Share this URL with friends:
    <span className="room-link" onClick={copyRoomLink}>
    {window.location.href}
    </span>
    <span className={`copied-notification ${linkCopied ? 'show' : ''}`}>URL copied!</span>
    </p>
    <div className="language-selector">
    <label htmlFor="language-select">Select your language:</label>
    ⦚ 213 unchanged lines ⦚
    .copied-notification {
    /** @jsxImportSource https://esm.sh/react */
    import { nanoid } from "https://esm.sh/nanoid";
    import React, { useEffect, useState, useCallback } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";

    ⦚ 71 unchanged lines ⦚
    };

    const copyRoomLink = useCallback(() => {
    const roomLink = window.location.href;
    console.log("Copying link:", roomLink); // Debug log
    navigator.clipboard.writeText(roomLink).then(() => {
    console.log("Link copied successfully"); // Debug log
    setLinkCopied(true);
    setTimeout(() => setLinkCopied(false), 3000); // Reset after 3 seconds
    }).catch(err => {
    console.error('Failed to copy: ', err);
    });
    }, []);

    if (!username) {
    ⦚ 16 unchanged lines ⦚
    <div className="container">
    <h1>Multilingual Chat Room</h1>
    <div className="share-section">
    <p>
    Share this URL with friends:
    <span className="room-link" onClick={copyRoomLink}>
    {window.location.href}
    </span>
    </p>
    <button onClick={copyRoomLink} className="copy-button">Copy Link</button>
    {linkCopied && <div className="copied-notification">URL copied!</div>}
    </div>
  • v11

    11/5/2024
    Open: Version
    Changes from v10 to v11
    +6
    -1
    ⦚ 110 unchanged lines ⦚
    {window.location.href}
    </span>
    {linkCopied && <span className="copied-notification">Link copied!</span>}
    </p>
    <div className="language-selector">
    ⦚ 216 unchanged lines ⦚
    margin-left: 10px;
    font-weight: bold;
    }
    `;
    ⦚ 110 unchanged lines ⦚
    {window.location.href}
    </span>
    <span className={`copied-notification ${linkCopied ? 'show' : ''}`}>URL copied!</span>
    </p>
    <div className="language-selector">
    ⦚ 216 unchanged lines ⦚
    margin-left: 10px;
    font-weight: bold;
    opacity: 0;
    transition: opacity 0.3s ease-in-out;
    }
    .copied-notification.show {
    opacity: 1;
    }
    `;
  • v10

    11/5/2024
    Open: Version
    Changes from v9 to v10
    +29
    -1
    ⦚ 18 unchanged lines ⦚
    const [roomId, setRoomId] = useState("");
    const [language, setLanguage] = useState("en");

    useEffect(() => {
    ⦚ 53 unchanged lines ⦚
    };

    if (!username) {
    return (
    <div className="container">
    ⦚ 14 unchanged lines ⦚
    <div className="container">
    <h1>Multilingual Chat Room</h1>
    <p>Share this URL with friends: {window.location.href}</p>
    <div className="language-selector">
    <label htmlFor="language-select">Select your language:</label>
    ⦚ 204 unchanged lines ⦚
    padding: 5px;
    font-size: 16px;
    }
    `;
    ⦚ 18 unchanged lines ⦚
    const [roomId, setRoomId] = useState("");
    const [language, setLanguage] = useState("en");
    const [linkCopied, setLinkCopied] = useState(false);

    useEffect(() => {
    ⦚ 53 unchanged lines ⦚
    };

    const copyRoomLink = () => {
    const roomLink = window.location.href;
    navigator.clipboard.writeText(roomLink).then(() => {
    setLinkCopied(true);
    setTimeout(() => setLinkCopied(false), 3000); // Reset after 3 seconds
    }).catch(err => {
    console.error('Failed to copy: ', err);
    });
    };

    if (!username) {
    return (
    <div className="container">
    ⦚ 14 unchanged lines ⦚
    <div className="container">
    <h1>Multilingual Chat Room</h1>
    <p>
    Share this URL with friends:
    <span className="room-link" onClick={copyRoomLink}>
    {window.location.href}
    </span>
    {linkCopied && <span className="copied-notification">Link copied!</span>}
    </p>
    <div className="language-selector">
  • v9

    11/5/2024
    Open: Version
    Changes from v8 to v9
    +1
    -0
    ⦚ 288 unchanged lines ⦚
    border: none;
    cursor: pointer;
    }
    .message {
    ⦚ 14 unchanged lines ⦚
    ⦚ 288 unchanged lines ⦚
    border: none;
    cursor: pointer;
    margin-left: 10px;
    }
    .message {
    ⦚ 14 unchanged lines ⦚
  • v8

    11/5/2024
    Open: Version
    Changes from v7 to v8
    +38
    -32
    /** @jsxImportSource https://esm.sh/react */
    import React, { useState, useEffect } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";
    import { nanoid } from "https://esm.sh/nanoid";

    const languages = [
    { code: 'en', name: 'English' },
    { code: 'fr', name: 'French' },
    { code: 'es', name: 'Spanish' },
    { code: 'de', name: 'German' },
    { code: 'it', name: 'Italian' },
    ];

    ⦚ 8 unchanged lines ⦚
    useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const roomFromUrl = urlParams.get('room');
    if (roomFromUrl) {
    setRoomId(roomFromUrl);
    } else {
    const newRoomId = nanoid(10);
    setRoomId(newRoomId);
    window.history.pushState({}, '', `?room=${newRoomId}`);
    }
    }, []);
    ⦚ 23 unchanged lines ⦚
    if (inputMessage && roomId && username) {
    try {
    const response = await fetch('/send-message', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ room: roomId, username, content: inputMessage, language }),
    });
    ⦚ 22 unchanged lines ⦚
    /** @jsxImportSource https://esm.sh/react */
    import { nanoid } from "https://esm.sh/nanoid";
    import React, { useEffect, useState } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";

    const languages = [
    { code: "en", name: "English" },
    { code: "fr", name: "French" },
    { code: "es", name: "Spanish" },
    { code: "de", name: "German" },
    { code: "it", name: "Italian" },
    ];

    ⦚ 8 unchanged lines ⦚
    useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const roomFromUrl = urlParams.get("room");
    if (roomFromUrl) {
    setRoomId(roomFromUrl);
    } else {
    const newRoomId = nanoid(10);
    setRoomId(newRoomId);
    window.history.pushState({}, "", `?room=${newRoomId}`);
    }
    }, []);
    ⦚ 23 unchanged lines ⦚
    if (inputMessage && roomId && username) {
    try {
    const response = await fetch("/send-message", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ room: roomId, username, content: inputMessage, language }),
    });
    ⦚ 22 unchanged lines ⦚
  • v7

    11/5/2024
    Open: Version
    +300
    -0

    /** @jsxImportSource https://esm.sh/react */
    import React, { useState, useEffect } from "https://esm.sh/react";
    import { createRoot } from "https://esm.sh/react-dom/client";
    import { nanoid } from "https://esm.sh/nanoid";

    const languages = [
    { code: 'en', name: 'English' },
    { code: 'fr', name: 'French' },
    { code: 'es', name: 'Spanish' },
    { code: 'de', name: 'German' },
    { code: 'it', name: 'Italian' },
    ];

    function App() {
    const [messages, setMessages] = useState([]);
    const [inputMessage, setInputMessage] = useState("");
    const [usernameInput, setUsernameInput] = useState("");
    const [username, setUsername] = useState("");
    const [roomId, setRoomId] = useState("");
    const [language, setLanguage] = useState("en");

    useEffect(() => {
    const urlParams = new URLSearchParams(window.location.search);
    const roomFromUrl = urlParams.get('room');
    if (roomFromUrl) {
    setRoomId(roomFromUrl);
    } else {
    const newRoomId = nanoid(10);
    setRoomId(newRoomId);
    window.history.pushState({}, '', `?room=${newRoomId}`);
    }
    }, []);

    useEffect(() => {
    if (roomId && username) {
    const pollMessages = async () => {
trob-multilingualchatroom.web.val.run
Updated: November 5, 2024