Skip to content

Instantly share code, notes, and snippets.

@keith-kurak
Last active February 27, 2025 03:50
Show Gist options
  • Save keith-kurak/0e7cec28e23eb332b3422d33318cedf2 to your computer and use it in GitHub Desktop.
Save keith-kurak/0e7cec28e23eb332b3422d33318cedf2 to your computer and use it in GitHub Desktop.
introvert chat
Now that we have the Expo NativeWind working via this template, let's turn this into the app I actually want to write.
Write me a mobile app with Expo called "Introvert Chat"
## Purpose
This app is designed to be like an instant messaging or chat app, except you only talk to yourself. Instead of different friends, you'll have different "personas" that you talk with. Each persona is dedicated to a specific topic. When you tap on the persona in the list of personas, you'll be taken into an instant messaging window where you can send messages to each persona.
## Tech stack and platforms
- Expo / Expo Router
- compatible with Android, iOS, and web
- this is a small (phone) screen-only app. The layout needs to be such that items don't get cut off on a phone screen.
- NativeWind for styling
- Zustand for state management, connected to AsyncStorage. All data will be local-only.
- Support both light and dark mode by using NativeWind features
## Screens
### List of personas
The main screen will be a list of personas. When the user opens the app, this is the first thing they'll see. These will look like a vertical list of friends in an instant messenger app. Each list item will have a circle avatar thumbnail to the left and a name on the right. The avatar will be a placeholder until the user sets a photo for the persona. Or, if the user sets a photo in their settings, that photo will appear for any persona that doesn't have a persona set. In the right corner of the avatar will be an emoji if the user has set an emoji for the persona. If the user has set a color on the persona, there should be circle border in that color around the avatar and the title of the persona should use that color.
Personas will be ordered by the most recent message, with favorited personas anchored to the top.
In the bottom right of the screen is a floating plus button, which will take you to a new screen for editing a persona. On the right side of the header bar is a settings button (gear icon).
Tapping and holding on a persona will change the header bar to show a list of icons for interacting with the persona and highlight the persona. These will include Edit (pencil icon), which will take you to the add/edit persona screen, delete (trash can icon), which will prompt a dialog confirming if you would like to delete the persona, and an export button, which will save the persona chat history as a markdown file. On the left side, there will be an X, which will take the persona out of selected state, and
### Add / edit persona screen
The same screen should serve for both adding a new persona and editing an existing persona.
Personas have the following fields:
- Name (required)
- Color (optional) - choose from a dozen different colors that look reasonably good in both light and dark mode.
- Avatar (optional) - this should prompt the user to take a picture or select a photo
- Emoji (optional)
- Favorite (on/off) (star icon)
### Persona Chat screen
This should look like a typical instant messaging / SMS app. There is a list of messages, with the most recent message first. At the bottom is a text input that starts at one line, but expands as you type more, with a send button to the right.
The header has the name of the persona, avatar, and emoji.
When you send a message, it appears at the bottom.
There are four types of messages:
- paragraph
- heading
- question
- answer
- listItem
By default, all messages are of the paragraph type.
When typing a message, the header should change to show a list of icon representing the message type. These icons can be used:
- paragraph (paragraph icon)
- heading (h1 icon)
- question (left word bubble)
- answer (right word bubble)
- listItem (list icon)
Tapping on the icon changes the message type that is used once the message is sent. An X icon should be on the left side of the header, and this will dismiss the keyboard and return the header back to its default state.
After a message is sent, double-tapping on a message should cycle through the message types in this order:
- paragraph
- heading
- question
- answer
- listItem
- checkbox
Long pressing a message will select the message and bring up icons in the header for editing and deleting (confirm with a dialog before deleting). Editing make the message appear in the text input and the message type icons appear. The send button should be replaced with a save icon that confirms the updates when pressed.
Each message type should appear as such in the message feed:
- Paragraph: should appear as plain text in the list of messages, left-justified.
- Heading: larger text, bold, left-justified
- question: gray message bubble or message bubble matching the persona color, anchored to the left. Persona avatar + emoji should appear to the left of the bubble
- answer: blue message bubble, achored to the right
- listItem: left justified, same size as paragraphs, with a bullet in front
- checkbox: left justified, same size as paragraphs, bold. Empty check box in front. Once the message is single-tapped, check the box and cross out the item.
Paragraph type is the default for new messages, but some other rules apply:
- If a listItem is the last message, the next message will default to another listItem
- If a checkbox is the last message, the next message will default to another checkbox
- If a question is the last message, the next message will default to an answer
### Settings screen
The settings screen has the following fields:
- Name (optional)
- Avatar (optional) - prompt to take a picture or choose a photo. Crop this image in a circle.
FontAwesome6 - paragraph
Ionicons - chatbubbles
MaterialCommunityIcons - message-question
MaterialCommunityIcons - chat-alert (reversed)
MaterialCommunityIcons - format-header-1
MaterialCommunityIcons - format-header-2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment