A collaborative habit-building app that leverages social accountability to help users establish and maintain positive routines. Users join groups centered around specific habits—such as cleaning, going to the library to study, or exercising—and participate in check-ins that require evidence of their progress in the form of photos (like BeReal). Group members validate each other's check-ins, creating a supportive community that fosters commitment and consistency. If users cumulatively miss the required number of check ins, not only does the streak visibly reset but a beautiful unique plant that was once growing is uprooted and reset (like Forest), adding a gentle layer of peer accountability. To motivate ongoing participation, consistent users earn badges and unlock new plants. By combining habit tracking with peer validation, this idea transforms personal goal-setting into a shared journey, enhancing motivation through collective encouragement and accountability.
Keywords: 005, accountability, habits, social, expo, firebase
This app uses React Native Expo as a frontend mobile framework, Firebase as a backend for storing user data, assets, and group data. It also will likely use Stable Diffusion 3.5 Large to generate assets.
A collaborative habit-building app that leverages social accountability to help users establish and maintain positive routines.
Examples of generating plant assets with Stable Diffusion 3.5 Large.
| Setting | Value |
|---|---|
| Prompt | isolated {plant_name} plant at the {growth_stage}, white background, isometric perspective, 8-bit pixel art style |
| Aspect Ratio | 1:1 |
| CFG | 3.5 |
| Prompt Strength | 0.85 (1.0 might be better) |
| Steps | 40 (35 might be better) |
| Seed | 227468720 |
| Output Format | webp |
| Output Quality | 90 |
The settings to generate the previous examples. Curly brackets indicate arguments to the template prompt. Growth stages indicate the progression of the plant at a certain life cycle.
| State | Description |
|---|---|
| Sprouting | sprouting stage where it germinates and grows its first leaf |
| Seedling | seedling stage where a small green shoot emerges above the soil with tiny leaves starting to spread |
| Vegetating | vegetating stage where the plant grows taller with thickening stems and broadening leaves |
| Budding | budding stage where the plant is transitioning to blooming and small buds appear signaling flower formation |
| Flowering | flowering stage where the plant displays fully opened and prominent flowers |
| Fruiting | fruiting stage where the plant produces fruits as the flowers fade |
| Dying | dying stage where the plant turns brown and wilts |
| Dead | dead plant |
Yucca
Bird of Paradise
Users earn credits in a few ways:
- Each time the user logs a habit for the week (even if the plant dies at the end of the week). User earns extra credits if they log more habits than necessary for the week.
- Each time the team successfully grows a plant for the week.
- Every day each plant in the garden is kept alive users can collect a small amount of credits from each plant.
Users can use their credits to buy things for the garden, like pets, paths, decorations, and food to keep the existing plants and animals in the garden alive.
Here are the items planned so far:
| Item | Description |
|---|---|
| Pets | Animated NPCs that allow plants to live longer without Fertilizer |
| Decorations | Purely cosmetic items that spruce up the users' garden |
| Kibble | Food for Pets that keep them alive and healthy |
| Fertilizer | Food for plants that keep them alive and healthy |
| Gaia | A magic stone that allows users a 50% chance to save a plant that died |
Events that allow users to skip feeding their existing plants for the week.
- It will randomly rain on occasion.
- A rainbow will appear.
- Rare animal visiting.
Provide guidance on how to choose and formulate a good habit.
If users are not meeting goals consistently or are constantly exceeding goals, give nudges for recommendations to adjust.
Users can write an optional reflection that gives them the opportunity to write about their high and low of the week. Pair this with rewarding animations of the plant and pets.
Certain badges are rewarded for unique accomplishments.
Streaks of multiple weeks of successfully growing a plant give users the opportunity to keep growing. Maybe give the opportunity to plant a tree at long term streak?
Make pledges at the beginning of the week to commit to n days that will log a habit. Get extra credit if user logs on those predicted days.
classDiagram
RootLayout *-- Index : composes
RootLayout o-- Header : aggregates
RootLayout o-- Footer : aggregates
RootLayout o-- UserProvider : aggregates
Index *-- Auth : composes
GroupLayout *-- Group : composes
HomeLayout *-- Garden : composes
LogLayout *-- Camera : composes
Auth ..> HomeLayout : navigates
Footer ..> HomeLayout : navigates
Footer ..> LogLayout : navigates
Footer ..> GroupLayout : navigates
UserProvider ..|> UserContextType : implements
Auth --> useUser : uses
Camera --> useUser : uses
Garden --> useUser : uses
Group --> useUser : uses
Footer --> useUser : uses
ProceduralPlatform --> useUser : uses
VotingModal --> useUser : uses
VerificationProgress --> useUser : uses
Group ..> VotingModal : navigates
Garden *-- ProceduralPlatform : composes
Header ..> ProfilePictureUpload : navigates
Garden --> ZoomableView : uses
Group *-- DaysOfTheWeek : composes
Group *-- FrequencyBar : composes
Group *-- PlantWithGlow : composes
Group *-- UserProgress : composes
Group *-- VerificationProgress : composes
class RootLayout {
+usePathname<Pathname> pathname
+boolean isIndexPage
}
class Index
class GroupLayout
class HomeLayout
class LogLayout
class Auth {
+useRouter<Router> router
+useState<Step> step
+useState<string> email
+useState<string> username
+useState<string> displayName
+useState<string> password
+useUser<User> user
+useState<boolean> loading
+useState<string> error
+useState<boolean> emailValid
+handleSignUp()
+handleStep(newStep)
+handleLogin()
+handleLogout()
+handleCheckUsername()
+isValidEmail(email) : boolean
+handleCheckEmail()
+handleLoginPassword()
+handleResetPassword()
}
class Camera {
+useState<CameraType> facing
+useCameraPermissions<CameraPermissions> permission
+useUser<User> user
+useRef<CameraView> cameraRef
+useState<string | null> photoUri
+useState<boolean> isPreviewVisible
+useFonts fontsLoaded
+useState<number> flash
+cycleFlash()
+toggleCameraFacing()
+takePictureAndShowPreview()
+uploadPicture()
+retakePicture()
}
class Footer {
+useRouter<Router> router
+useState<string> selected
+usePathname<Pathname> pathname
+useUser<User> user
+useState<boolean> hasPlant
+handlePress(screen)
+checkForPlant(user)
}
class Garden {
+useRouter<Router> router
+useUser<User> user
+useState<DocumentReference[]> groups
+useState<boolean> hasGroups
+fetchGroups()
}
class Group {
+useState<boolean> isGrown
+useState<Step> step
+useState<boolean> generatingPlant
+useState<number> generatingPlantProgress
+useState<DocumentReference[]> groups
+useState<boolean> hasGroups
+useUser<User> user
+userState<string> groupName
+useState<string> codeInput
+useState<string> habit
+useState<number> frequency
+useState<string> error
+useState<DocumentReference[]> groupMembers
+useState<string> groupCode
+useState<DocumentReference[]> groupLogs
+useState<DocumentReference[] | null> currentPlant
+useState<string | null> currentPlantVector
+useState<string[]> plantVectorChoices
+useState<PlantTextChoice[]> plantTextChoices
+useState<DocumentReference | null> plantChoicesRef
+useState<string> plantName
+useState<string> plantLatinName
+useState<DocumentReference[]> approvedLogs
+useState<boolean> modalVisible
+useState<string | null> response
+useState<boolean> hasShownModal
+useState<DocumentReference | null> currentRefLog
+useState<object[]> userProgress
+useState<JSX.Element[]> userProgressComponents
+useFonts fontsLoaded
+fetchGroups() string
+fetchUserProgress()
+checkPlant()
+grabVotes()
+handleCreateGroup()
+handleJoinGroup()
+handleStep(step)
+handleFrequency(newFrequency)
+handleChoosePlant(plantChoiceIndex)
+handleGeneratePlantTextChoices()
+handleGeneratePlantVectors()
+handleConstructPlantChoices()
+handleModalClose()
+handleChooseNewPlant()
}
class Header {
+useState<string | null> profileImageUrl
+useRouter<Router> router
+handleLogOut()
+handleChangeAvatar()
+uploadImage(uri)
+updateUserProfileImage(downloadURL)
}
class ProceduralPlatform {
+object BLOCK_CATEGORIES
+BlockType[] BLOCK_TYPES
+number tileWidth
+number tileHeight
+useState<number> gridSize
+useState<Grid> grid
+useUser<User> user
+userState<string[]> plantImageUrls
+BlockSVG(blockType) : JSX.Element
+getBlockByCategory(category) : BlockType[]
+getRandomBlockType() BlockType
+generateGrid(size, oldGrid) : Grid
+getNeighbors(grid, row, col) : (Cell | null)[]
+directionFromIndex(index) : Direction
+oppositeDirection(dir) : Direction
+plantPlants(grid, plantsToPlant) : object
+fetchGarden(user) : Promise<void>
}
class ProfilePictureUpload {
+string userId
+(uri: string | null) => void onComplete
+pickImage()
+uploadImage(uri)
}
class UserProvider {
+useState<User | null> user
}
class useUser {
+useContext(UserContext) context
}
class VotingModal {
+boolean visible
+(response: string) => void onClose
+ImageSourcePropType profilePic
+string question
+DocumentReference<DocumentData, DocumentData> | null logRef
+number totalMembers
+getAuth auth
+User currentUser
+useState<string> image
+useUser<User> user
+useFonts fontsLoaded
+getImageFromLogRef()
+handleUpvote()
+handleDownvote()
}
class ZoomableView {
+ReactNode children
+useSharedValue<number> scale
+useSharedValue<number> translateX
+useSharedValue<number> translateY
+useRef pinchRef
+useRef panRef
+Style animatedStyle
+pinchHandler()
+panHandler()
}
class DaysOfTheWeek {
+useState<object> dayLogCounts
+useState<number> totalLogs
+string[] days
+string[] displayDays
+string currentDayIndex
+fetchDays() : number
+getOpacity(percentage) : number
}
class FrequencyBar {
+number frequency
+string code
+object days
}
class PlantWithGlow {
+string | null currentPlantVector
}
class UserProgress {
+number frequency
+number approvedUserLogs
+number totalUserLogs
+number totalCells
}
class VerificationProgress {
+number frequency
+number totalUsers
+number approvedLogs
+number totalLogs
+number totalNeeded
+number stages
+number logsPerStage
+useUser<User> user
+updateGrowState()
}
Use Case: Signing Up from login page
sequenceDiagram
participant User
participant Auth
participant Server
participant Database
User ->> Auth : Enter Email
Auth ->> Server : Store Email
Server --> Database : Check Email Exists
Database -->> Server : Validate Email
Server -->> Auth : Validate Step
User ->> Auth : Enter Username and Display Name
Auth ->> Server : Store Username
Server --> Database : Check Username Exists
Database -->> Server : Validate Username
Server -->> Auth : Validate Step
User ->> Auth : Enter Password
User ->> Auth : Request Sign Up
Auth ->> Server : Handle Sign Up
Server --> Database : Add User
Database -->> Server : Return User
Server -->> Auth : Return User
Auth -->> User : Serve Home Screen
Use Case: Creating Group after successfully login or sign up
sequenceDiagram
participant User
participant Frontend
participant Backend
User->>Frontend: Submit group creation request
Frontend->>Backend: Retrieve user document (getDoc)
Backend->>Backend: Generate join code
Backend->>Backend: Create group document (addDoc)
Backend->>Backend: Update user document with new group (updateDoc)
Backend-->>Frontend: Return new group document
Frontend-->>User: Confirm group creation
Use Case: Logging in
sequenceDiagram
participant User
participant Auth
participant Server
participant Database
User ->> Auth : Enter Email
Auth ->> Server : Store Email
Server -->> Auth : Validate Step
User ->> Auth : Enter Password
Auth ->> Server : Store Password
Server--> Database: Check if Password is correct
Server --> Database : Check Email Exists
alt Password is correct and email Exists
Database -->> Server : Validate Email
Database-->> Server : Validate Password
Server -->> Auth : Handle Sign in
Auth -->> User : Server Home Screen
else Password Incorrect or email DNE
Database -->> Server : Email or Password dne
Server -->> Auth : Handle Incorrect sign in
Auth -->> User : Incorrect Password or email message
end
Use Case: Join Group
sequenceDiagram
participant User
participant Frontend
participant Backend
User->>Frontend: Submit join code
Frontend->>Backend: Query groups collection with join code (where)
Backend-->>Frontend: Return matching group or false
alt Group Found
Frontend->>Backend: Retrieve user document (getDoc)
Backend-->>Backend: Return user data
Backend->>Backend: Update user document with new group (updateDoc)
Backend->>Backend: Update group document with new user (updateDoc)
Backend-->>Frontend: Return updated group data
Frontend-->>User: Group joined successfully
else No Group Found
Frontend-->>User: Display error message: Invalid join code
end
This is the life cycle of a user on this app for a three person group with the goal to workout 3 days a week:
- User creates account.
- Add friends by username.
- Create group.
- Choose a habit. A good example is to go for a run 3 days a week. A bad example is run 1 mile three days a week. It shouldn't need to be quantified, only specific enough that can be verified from a simple photo. qualitative > quantitative.
- Set minimum frequency of check-in (i.e. work out 3 days a week).
- Invite friends to join.
- At the start of every period (i.e. week), given a library of plants to choose from (will auto-pick if not chosen). plants are standard and take minimum frequency (i.e. 3 users * 3 days = 9 total check-ins for the week), while accessories to the garden may take a multiplier of more check-ins (i.e. 3 users * 3 days + 3 extra = 12 total check-ins for the week).
- Users take a picture of their workout (not from camera roll) at their discretion three times on separate days of the week.
- Users must endorse it as valid, can also upvote and comment.
- Every time a user's check-in is endorsed as valid by everyone, the plant or accessory grows or progresses respectively.
- If users do not collectively reach the required number of check-ins, the plant that was growing dies.
- Repeat from step 9.
|
Bash |
Khanh |
Ruben |
Tesfaldet |
Doul |























