Skip to content

cis3296f24/growe

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

273 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Open in Codespaces

Growe

Firebase Jira Figma

Report Issue on Jira Deploy Docs Documentation Website Link

header

Abstract

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

Requirements

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.

Design

A collaborative habit-building app that leverages social accountability to help users establish and maintain positive routines.

Asset Generation

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

Mechanics

Credits

Users earn credits in a few ways:

  1. 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.
  2. Each time the team successfully grows a plant for the week.
  3. 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

Unique Events

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.

Habit Guidance

Provide guidance on how to choose and formulate a good habit.

Nudges

If users are not meeting goals consistently or are constantly exceeding goals, give nudges for recommendations to adjust.

Reflection

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.

Badges

Certain badges are rewarded for unique accomplishments.

Streaks

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?

Pledges

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.

User Interface

Database Collections

image

Class Diagram

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()
  }
Loading

Sequence Diagram

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
Loading

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
Loading

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
Loading

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
Loading

Background

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:

  1. User creates account.
  2. Add friends by username.
  3. Create group.
  4. 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.
  5. Set minimum frequency of check-in (i.e. work out 3 days a week).
  6. Invite friends to join.
  7. 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).
  8. Users take a picture of their workout (not from camera roll) at their discretion three times on separate days of the week.
  9. Users must endorse it as valid, can also upvote and comment.
  10. Every time a user's check-in is endorsed as valid by everyone, the plant or accessory grows or progresses respectively.
  11. If users do not collectively reach the required number of check-ins, the plant that was growing dies.
  12. Repeat from step 9.

References

Collaborators

gutbash
Bash
khanhquocng2801
Khanh
Ruben-amalgam
Ruben
tus29603
Tesfaldet
Youngdoul
Doul

About

A collaborative habit-building app that leverages social accountability to help users establish and maintain positive routines.

Resources

Stars

Watchers

Forks

Contributors

Languages

  • TypeScript 86.1%
  • JavaScript 13.9%