Introducing Glitch: A Hackathon Collaboration Tool Powered by Appwrite

Introducing Glitch: A Hackathon Collaboration Tool Powered by Appwrite

Boost team efficiency, manage tasks, and communicate instantly for hackathon triumph. Strengthen your group and spark innovation.

·

15 min read

I sincerely want to express my gratitude to Appwrite and Hashnode, the organizers of this hackathon, for providing us with this remarkable opportunity.

Team Members

  • Aryan Kumar (Hashnode: aryan)

  • Barbra Kokonya (Hashnode: Barbra )


Description: Knowing the 'What' and the 'Why'

Overview

On May 20th, I stumbled upon a tweet about a GitHub project called Vibey which was seeking collaborators. Their backend was handled by Appwrite. To learn more about Appwrite, I visited Appwrite's website. There I got to know about an ongoing hackathon that had started on May 15th. Despite being late by about 5 days, I could not resist participating after going through the hackathon details. I had never used Appwrite before, so I needed to act quickly.

Before starting the project, I dedicated a day to studying Appwrite's documentation and made use of the crisp documentation as my resource and asked questions in the highly responsive Discord community. This helped me grasp concepts such as API keys, JWTs, authentication, events, storage, databases, teams, users, accounts, avatars, permissions and functions.

As my understanding grew, so did my confidence. I realized that Appwrite's SDKs, with their extensive features, were ideal for my envisioned app, particularly the real-time events and teams feature 💛. Excited, I aimed to create something valuable for both myself and the community that would have lasting utility beyond the hackathon.

What is it?

So what is Glitch? It's a tool for managing hackathon teams. After creating a team, invite members and use Glitch to work together. Talk in group chats or private messages, share ideas, and easily send or download files. Keep things organized by handling tasks, setting due dates, filtering tasks using advanced filters, and pinning high-priority tasks. Share notes and use the GPT-3.5 Turbo API to create task descriptions. With instant notifications for chats and tasks, Glitch helps your team communicate well. It's the best online space for your team to work together and succeed.

Why tackle this challenge?

Why did I take on this challenge? Well, having participated in hackathons with teams myself, I've witnessed firsthand the struggles that teams face. The lack of accountability, ineffective communication, and poor task management can often lead to confusion and wasted time. It's frustrating when important tasks get lost in a flood of messages, causing unnecessary delays and redundancy.

That's why I created Glitch—a game-changing solution that tackles these problems head-on. With Glitch, task management becomes a breeze. You can define, organize, and prioritize tasks with absolute clarity. No more losing track of crucial assignments.

But Glitch doesn't stop there. It combines the best features of modern chat apps, allowing teams to collaborate seamlessly. You can reply to messages, edit messages, and receive real-time read status, keeping everyone on the same page. It's the ultimate productivity booster.

Imagine the excitement of streamlined team communication, synchronized efforts, and accelerated achievements. Glitch takes advantage of the powerful capabilities of Appwrite, bringing together chatting and task management in an all-new way.


Tech Stack

Technologies Utilized

  • Frontend: Next.js, Chakra UI

  • Backend: Appwrite, Vercel Serverless

  • Database: Appwrite Storage


https://glitch.zone/


Demo Recording

A demo recording showcasing the features and functionality of Glitch.


Appwrite Usage

Let's discuss how all components of the app function, the Appwrite services we utilize, how security is maintained, and how we cache data in the browser to reduce network requests to Appwrite. I will explain the thought process behind the software architecture. Feel free to skip and just watch the video as well.

1‣ Authentication 🔒

  • a‣ Sign In and Sign Out Workflow

  • b‣ Password Recovery

2‣ Teams 🤝

  • a‣ Listing Teams

    • Upon logging in, users view a list of their teams on the homepage, where team preferences like theme color and team image are displayed.

    • The list of teams is cached in the browser.

    • Users can also search for a team using the team name as their search query.

    • SDK Methods used -

  • b‣ Creating a Team

  • Users create their teams on the homepage. The user who creates the team assumes the role of "owner" as per the API.

  • Permissions are applied to the document created for team preferences, ensuring that only team members are allowed to read and update the preferences in the future.

  • During team creation, a random RGB color is assigned as the theme color for team preferences.

  • SDK Methods used -

  • c‣ Updating Team Preferences

  • Team members can update the team settings like team name, theme color, profile image, and default role for new members.

  • To enable all members to update the team name, we need to use the team's write and teams' read scope for the API key on the server.

  • Other preferences can be updated directly with Web SDK.

  • In case the team profile image is updated, the previous image is deleted from the bucket, and a new image is uploaded and linked to the team.

  • SDK Methods used -

  • d‣ Team Dashboard

  • Overview

    • At the top, the team preferences are displayed, including the name, profile picture, theme color, and default role for new members. The data is cached to reduce server load.
  • Member List

    • A list of team members, featuring their names, profile photos, and roles, is presented below preferences.

    • To reduce server load, all member data, including names and profile pictures, is cached as a crucial step. This data is utilized throughout the app, for instance, in chats and tasks.

  • Inviting/Removing Members ( Web SDK )

  • Users with "owner" roles can invite members via web SDK email invitations or add them directly through Server SDK through the user search page.

  • Users with "owner" roles can remove team members from the team by clicking on "Remove".

  • Team membership statuses are updated in real-time through team events.

  • Assigning Roles To Members

  • e‣ Search Users (Add To Team with Server SDK)

  • Users can search for other users and directly add them to their team. In this scenario, an email invitation is not required.

  • Verification is done on the server using JWT to ensure the user creating the membership has the "owner" role.

  • SDK Methods used -

  • f‣ Draggable Sidebar

    • Implemented a draggable sidebar using the React-Draggable library. Cached dynamic sidebar data to prevent multiple network calls during re-renders while dragging.

    • Sidebar shows the latest team chat message with the sender's name and a list of direct messages.

3‣ Chats 💬

  • a‣ Group Chat

  • Overview

    • Chats are managed through a collection that stores each chat, allowing users to send messages, edit them, delete them, and reply to other chats.

    • File-sharing support, including file preview and download.

    • A notification system allows for a single tick to indicate message delivery and a double tick for read receipts, which include the read time and the names of team members who have read the message.

    • The "Unread Messages" divider in the chat differentiates between unread and read messages, much like the functionality found in Discord.

    • Organize chats by date and display a divider indicating the date, similar to features found in apps such as WhatsApp or Telegram.

    • Scroll to the initial message by clicking on a replied message, like in WhatsApp or Telegram.

    • Support for emojis using the emoji-mart library for React.

  • Security

    • By default, the chat collection prevents the creation of documents by anyone. Therefore, we use API keys with document creation scopes.

    • Since chat documents are associated with a team_id, any malicious party could potentially create a team chat without the proper permissions.

    • Thus, every message creation undergoes a stringent verification process, during which we utilize the JWT from the Account API to confirm that the sender is indeed a member of the team.

    • Only the message creator has the update and delete permissions for the chat, which are achieved through document-based security from Appwrite.

    • Only the team members have read permissions for the team chat.

  • Notifications

    • Appwrite Functions trigger when a chat document is created, generating a separate set of notifications for each team member in a dedicated notification collection.

    • Users receive real-time notifications when a new chat arrives, or when they open the app later, with caching of chats to minimize server calls.

    • Real-time read status is accomplished through the notification system, where messages are marked as read when the intended recipients view them. The sender is then notified in real-time about the read status.

  • Infinite Chat Scroll

    • Query cursorAfter and Query limit from Appwrite were used to load previous messages incrementally. The React Intersection Observer was utilized to initiate this process. UseLayoutEffect and useMemo was used from React to maintain the position of the scrollbar as previous chats are rendered.
  • SDK Methods used

  • Extensive use of the event system and caching is employed to ensure real-time performance and optimal speed.

  • b‣ Direct Messaging ( DM )

  • Most of the functionality is similar to group chats; however, in direct messages, we create a unique channel id for communication between two users to query messages. Architecturally, there isn't a significant difference in how Appwrite is utilized, aside from adjustments to suit the direct messaging scenario. Therefore, I won't be explaining this in depth.

  • The sidebar displays a list of team members available for direct messaging. Additionally, the sidebar is capable of showing notifications for each user who sends you a message within the team.

4‣ Notifications 🔔 (Architecture)

  • When a user generates data, such as chat messages or tasks, an Appwrite Function is triggered in response to the event of document creation. The function receives the event data, which contains essential information about the document. It then creates documents in a dedicated notifications collection with read permissions only for the intended user.

  • For chats, a notification is created for each user in the team excluding the message sender. For tasks, members who are assigned the task get notified. In the case of direct messaging, the recipient gets notified.

  • When users perform the intended task, for example reading the messages in case of chats, the notifications are marked as false and no longer pop up on the screen. If the user is already on the chat screen then notifications are marked as false instantly.

  • The notifications are read using Appwrite events in real-time, ensuring a smooth communication flow for notifications.

5‣ Tasks 📌

  • a‣ UI Overview

  • The Tasks page shows a list of team tasks with details like name, description, status, priority, assignee, and creator.

  • Users with "owner" and "admin" roles are permitted to create, edit, delete tasks, and mark tasks as complete. Only the member assigned to the task, along with owners and admins, can mark it as complete, through JWT verification.

  • In addition to filtering, tasks can be searched by their ID or by searching for their name.

  • Security is ensured via document-based JWT verification before task creation. Task creation requires an API key with document write scopes, as it's restricted by default.

  • b‣ Create Tasks

  • Here, users with the "owner" or "admin" roles within the team can create tasks and assign them to other members. The assigned member will receive an instant notification indicating that a task has been assigned to them.

  • Create a task description using the OpenAI GPT-3.5 Turbo API and edit it before creating a task to enhance efficiency.

  • c‣ Edit Task

    • Users with the "owner" or "admin" roles can edit and update tasks, as well as mark them as complete.

  • d‣ Pinning Tasks

  • Members can prioritize tasks by pinning them and accessing them directly in the "Pinned Tasks" section.

  • It is implemented by storing pinned tasks in a document with an array attribute, which enables you to toggle tasks as pinned and unpinned.

  • e‣ Filtering Tasks using Appwrite Queries

  • The Appwrite Query feature is used to create various queries for filtering and sorting tasks effectively.

  • Filter Tasks:

    • Filter completed tasks.

    • Filter pending tasks.

    • Filter tasks assigned to specific team members.

    • View pending or complete tasks for each team member.

  • Sort Tasks:

    • Sort tasks by priority, placing high-priority tasks at the top.

    • Sort tasks by date of creation.

    • Sort tasks by the nearest deadline.

  • f‣ Add Notes to a Task

  • You can create notes for a specific task, such as text, images, or file attachments, to help you work more effectively. For instance, you can save an app's logo as a task note while developing it.

6‣ User Profile 👤

  • a‣ Profile Page

    • Here, other users of the platform can view your profile. Set your name, email, and bio, and link your GitHub profile to display your repositories and stats.

    • All the data is saved as user preferences. An API key with user read scope is required to display information.

    • SDK Methods used -

  • b‣ Edit Profile


Challenges Faced

Designing features such as efficient caching for the chat system with a sidebar displaying the last message, a robust notification system, and real-time read status proved to be quite challenging for me, especially since this was my first attempt at developing a chat application.

Furthermore, I encountered a challenge in designing the architecture for the task pinning feature, as each user had their own set of pinned tasks, and the pin status needed to be displayed dynamically, updating the button to show either "Pin" or "Unpin" based on the task's current pin status.

Another minor obstacle involved figuring out how to utilize team preferences, as they were not supported by the cloud at the time. However, this issue was quickly resolved by making the design decision to use a dedicated collection for the same.

Aside from that, the development experience was remarkably seamless, and I would like to extend my appreciation to the Appwrite team for creating such a fantastic product.


Credits

I would like to express my gratitude to my teammate Barbra for her unwavering presence, whether it was testing the application, proofreading the blog for grammatical errors, or just being there in general.


Code Repository

https://github.com/aryan877/glitch