Skip to content

The application allows users to sign up πŸ“, log in πŸ”‘, send πŸ’¬, and receive πŸ“¨ messages in real-time with a decentralized database chat experience 🌐 using the Svelte framework βš™οΈ and Gun.js for real-time πŸš€.

Notifications You must be signed in to change notification settings

yuvrajtiwary-bitmesraece/Chat-Dapp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Decentralized Database Chat Application

Project Overview

This project is a chat application built with the Svelte framework and using Gun.js as a decentralized graph database. The application allows users to sign up, log in, send, and receive messages in real-time With decentralized chat experience using the Svelte framework and Gun.js for real-time.

Important Aspects

Where the Database Stored ? And How this Happen "decentralized chat experience using the Svelte framework and Gun.js for real-time"

Answer :- In this project, the messages are stored in the Gun.js database. Gun.js is a decentralized graph database that allows data to be synchronized in real-time across multiple devices or nodes in a peer-to-peer network.

Specifically, the messages are stored in the Gun.js database within the chativanappostolov node. Each message is encrypted and stored as a separate entry, with a timestamp serving as the key.

The database storage and retrieval logic is implemented in the src/Chat.svelte file, where messages are retrieved from the database and displayed in the chat interface. When a new message is sent, it is encrypted and stored in the database. When the chat component initializes, it fetches messages from the database and decrypts them for display.

Project Structure

`
## Project Structure
β”œβ”€β”€ package-lock.json
β”œβ”€β”€ package.json
β”œβ”€β”€ public
β”‚ β”œβ”€β”€ 404.html
β”‚ β”œβ”€β”€ favicon.png
β”‚ β”œβ”€β”€ global.css
β”‚ └── index.html
β”œβ”€β”€ rollup.config.js
└── src
β”œβ”€β”€ App.svelte
β”œβ”€β”€ Chat.svelte
β”œβ”€β”€ ChatMessage.svelte
β”œβ”€β”€ Header.svelte
β”œβ”€β”€ Login.svelte
β”œβ”€β”€ main.js
└── user.js

----------------------------------


+---------------------+
|  User Interactions  |
+---------------------+
          |
          v
+--------------------+     +--------------------+
|  App Initialization |<---|  main.js           |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  App Component     |<---|  App.svelte         |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  Header Component  |<---|  Header.svelte      |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  Chat Component    |<---|  Chat.svelte        |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  Message Component |<---|  ChatMessage.svelte |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  User Authentication |<--|  user.js           |
+--------------------+     +--------------------+
          |
          v
+--------------------+
|  Database (Gun.js) |
+--------------------+
`

File Explanations

  1. package.json and package-lock.json

    • These files contain metadata about the project and its dependencies, ensuring that the project can be correctly installed and built.
  2. public/

    • Contains static files like 404.html, favicon.png, global.css, and index.html which are served to the client.
  3. rollup.config.js

    • This is the configuration file for Rollup, a module bundler for JavaScript. It sets up the build process for the Svelte application, including plugins for Svelte compilation, CSS handling, and live reloading during development.
  4. src/main.js

    • The entry point for the Svelte application. It initializes the Svelte App component and mounts it to the document.body.
  5. src/user.js

    • Initializes the Gun.js database and handles user authentication. It also sets up a Svelte store to manage the current username.
import GUN from 'gun';
import 'gun/sea';
import 'gun/axe';
import { writable } from 'svelte/store';

export const db = GUN();
export const user = db.user().recall({ sessionStorage: true });
export const username = writable('');

user.get('alias').on(v => username.set(v));

db.on('auth', async (event) => {
    const alias = await user.get('alias');
    username.set(alias);
    console.log(`signed in as ${alias}`);
});
  1. src/App.svelte
    • The root Svelte component. It includes the Header and Chat components.
<script>
  import Chat from './Chat.svelte';
  import Header from './Header.svelte';
</script>

<div class="app">
    <Header />
    <Chat />
</div>
  1. src/Chat.svelte
    • Manages the chat interface. It handles message input, sending messages, and displaying received messages. It also deals with automatic scrolling of the chat view.
<script>
  import Login from './Login.svelte';
  import ChatMessage from './ChatMessage.svelte';
  import { onMount } from 'svelte';
  import { username, user } from './user';
  import debounce from 'lodash.debounce';
  import GUN from 'gun';

  const db = GUN();
  let newMessage;
  let messages = [];
  let scrollBottom;
  let lastScrollTop;
  let canAutoScroll = true;
  let unreadMessages = false;

  function autoScroll() {
    setTimeout(() => scrollBottom?.scrollIntoView({ behavior: 'auto' }), 50);
    unreadMessages = false;
  }

  function watchScroll(e) {
    canAutoScroll = (e.target.scrollTop || Infinity) > lastScrollTop;
    lastScrollTop = e.target.scrollTop;
  }

  $: debouncedWatchScroll = debounce(watchScroll, 1000);

  onMount(() => {
    var match = {
      '.': { '>': new Date(+new Date() - 1 * 1000 * 60 * 60 * 3).toISOString() }, '-': 1,
    };

    db.get('chativanappostolov')
      .map(match)
      .once(async (data, id) => {
        if (data) {
          const key = '#foo';
          var message = {
            who: await db.user(data).get('alias'),
            what: (await SEA.decrypt(data.what, key)) + '',
            when: GUN.state.is(data, 'what'),
          };

          if (message.what) {
            messages = [...messages.slice(-100), message].sort((a, b) => a.when - b.when);
            if (canAutoScroll) {
              autoScroll();
            } else {
              unreadMessages = true;
            }
          }
        }
      });
  });

  async function sendMessage() {
    const secret = await SEA.encrypt(newMessage, '#foo');
    const message = user.get('all').set({ what: secret });
    const index = new Date().toISOString();
    db.get('chativanappostolov').get(index).put(message);
    newMessage = '';
    canAutoScroll = true;
    autoScroll();
  }
</script>

<div class="container">
  {#if $username}
    <main on:scroll={debouncedWatchScroll}>
      {#each messages as message (message.when)}
        <ChatMessage {message} sender={$username} />
      {/each}
      <div class="dummy" bind:this={scrollBottom} />
    </main>

    <form on:submit|preventDefault={sendMessage}>
      <input type="text" placeholder="Type a message..." bind:value={newMessage} maxlength="100" />
      <button type="submit" disabled={!newMessage}>Send</button>
    </form>
  {:else}
    <main>
      <Login />
    </main>
  {/if}
</div>
  1. src/ChatMessage.svelte
    • Displays individual chat messages.
<script>
  export let message;
  export let sender;

  const messageClass = message.who === sender ? 'sent' : 'received';
  const avatar = `https://avatars.dicebear.com/api/initials/${message.who}.svg`;
  const ts = new Date(message.when);
</script>

<div class={`message ${messageClass}`}>
  <img src={avatar} alt="avatar" />
  <div class="message-text">
    <p>{message.what}</p>
    <time>{ts.toLocaleTimeString()}</time>
  </div>
</div>
  1. src/Header.svelte
    • Displays the header with the username and a sign-out button.
<script>
  import { username, user } from './user';

  function signout() {
    user.leave();
    username.set('');
  }
</script>

<header>
  <h1>MychatApp</h1>
  {#if $username}
    <div class="user-bio">
      <span><strong>{$username}</strong></span>
      <img src={`https://avatars.dicebear.com/api/initials/${$username}.svg`} alt="avatar" />
    </div>
    <button class="signout-button" on:click={signout}>Sign Out</button>
  {/if}
</header>
  1. src/Login.svelte
  • Manages user login and signup.
<script>
  import { user } from './user';

  let username;
  let password;

  function login() {
    user.auth(username, password, ({ err }) => err && alert(err));
  }

  function signup() {
    user.create(username, password, ({ err }) => {
      if (err) {
        alert(err);
      } else {
        login();
      }
    });
  }
</script>

<label for="username">Username</label>
<input name="username" bind:value={username} minlength="3" maxlength="16" />
<label for="password">Password</label>
<input name="password" bind:value={password} type="password" />
<button class="login" on:click={login}>Login</button>
<button class="login"  on:click={signup}>Sign Up</button>
+---------------------+
|  User Interactions  |
+---------------------+
          |
          v
+--------------------+     +--------------------+
|  App Initialization |<---|  main.js           |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  App Component     |<---|  App.svelte         |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  Header Component  |<---|  Header.svelte      |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  Chat Component    |<---|  Chat.svelte        |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  Message Component |<---|  ChatMessage.svelte |
+--------------------+     +--------------------+
          |
          v
+--------------------+     +--------------------+
|  User Authentication |<--|  user.js           |
+--------------------+     +--------------------+
          |
          v
+--------------------+
|  Database (Gun.js) |
+--------------------+

Project Overview:

Initialization (main.js):

  • The application initializes by creating a new instance of the App component and mounting it to the DOM.

Root Component (App.svelte):

  • The root component (App.svelte) includes the Header and Chat components, which are rendered inside a div.

Header Component (Header.svelte):

  • Displays the current username and a sign-out button.
  • Shows the user's avatar and name if signed in; otherwise, omits the sign-out button.

Chat Component (Chat.svelte):

  • Responsible for handling the chat interface.
  • Loads existing messages from the Gun.js database, displays them, and handles new message input and sending.
  • Utilizes the onMount lifecycle function to load messages from the database and set up listeners for new messages.
  • Handles user input for new messages and sends them to the database upon form submission.

Message Component (ChatMessage.svelte):

  • Renders individual messages, formatting the message text and metadata (sender and timestamp).

User Authentication (user.js):

  • Initializes Gun.js and manages user authentication.
  • Sets up a writable store for the username and handles login and signup processes.
  • Configures the Gun.js database instance (db) to recall the user session and update the username store upon authentication.

Login Component (Login.svelte):

  • Manages the login and signup forms.
  • Handles user input for username and password.
  • Performs login or signup actions when the respective buttons are clicked.

The application offers a decentralized chat experience using the Svelte framework and Gun.js for real-time data synchronization. Each component fulfills a specific role, ensuring smooth functionality from user authentication to message handling and rendering. The flow chart provides a clear overview of the application's data flow and interactions.

About

The application allows users to sign up πŸ“, log in πŸ”‘, send πŸ’¬, and receive πŸ“¨ messages in real-time with a decentralized database chat experience 🌐 using the Svelte framework βš™οΈ and Gun.js for real-time πŸš€.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy