Back to projects

Hang On - 감정 공유 플랫폼

Mobile

프로젝트 개요

Hang On은 사용자들이 자신의 감정을 안전하게 표현하고, 다른 사람들과 공감을 나누며, 혼자가 아니라는 것을 느낄 수 있도록 돕는 모바일 애플리케이션입니다. 이 프로젝트는 대학교 Human Computer Interaction(HCI) 수업의 일환으로 시작되었으며, 기획부터 디자인, 개발까지 전 과정을 직접 수행했습니다. 현대 사회에서 많은 사람들이 감정을 표현하는 것에 어려움을 겪고 있으며, 특히 부정적인 감정을 털어놓을 공간이 부족합니다.

프로젝트의 핵심 철학은 "감정에는 옳고 그름이 없다"는 것입니다. 사용자들은 자신의 감정 상태를 날씨 아이콘으로 직관적으로 표현하고, 짧은 글을 통해 마음을 털어놓을 수 있습니다. 다른 사용자들은 공감 버튼이나 따뜻한 메시지를 보내 서로를 격려합니다. 이러한 상호작용을 통해 "나만 힘든 게 아니구나"라는 위안을 얻을 수 있습니다. Hang On은 '혼자 삼키는 감정'을 '함께 나누는 위로'로 바꾸는 것을 목표로 합니다.

React Native CLI를 선택하여 iOS와 Android 모두에서 네이티브에 가까운 성능을 제공하며, Supabase를 백엔드로 활용하여 인증, 데이터베이스, 실시간 기능을 구현했습니다. Claude Code와의 협업을 통해 빠른 프로토타입 개발이 가능했으며, 현재 핵심 기능 개발이 완료된 상태입니다.

문제 인식과 기존 서비스 분석

지은씨의 힘든 밤

밤 11시, 지은씨는 힘든 하루를 보냈습니다. 누군가에게 털어놓고 싶지만 SNS에 올리자니 신원 노출이 걱정됩니다. 친구에게 말하자니 부담을 주는 것 같습니다. 다른 익명 앱을 깔았지만, 공감받는 느낌이 부족합니다. 결국 지은씨는 감정을 혼자 삼키게 됩니다. 이러한 사용자 시나리오 분석을 통해 Hang On의 핵심 가치를 도출했습니다.

기존 서비스의 한계점

기존 서비스들을 분석한 결과, 세 가지 유형의 한계점을 발견했습니다. 첫째, SNS(트위터, 인스타그램)는 익명성이 부재합니다. 유저를 아이디, 닉네임, 프로필로 구분하기 때문에 신원 노출 위험이 있어 감정을 털어놓기 부적합합니다. 둘째, 인증 기반 앱(블라인드, 에브리타임)은 서비스가 제한적입니다. 학교나 회사 인증이 필요하여 특정 집단 내부 사용자만 이용할 수 있고, 완전한 익명이 보장되지 않습니다.

셋째, 기타 익명 앱들은 공감이 부족합니다. 랜덤 피드로 제공되어 상관없는 글만 보이고, 감정 기반 매칭이 없어 공감받는 느낌이 부족합니다. 이러한 분석을 통해 "익명이 보장되며 감정 기반 매칭을 제공하는 앱"이 필요하다는 결론에 도달했고, Hang On의 핵심 차별점으로 완전 익명, 즉각적인 피드백, 감정 기반 매칭을 설정했습니다.

기술 스택

프론트엔드

React Native CLI 0.82.1을 기반으로 개발했습니다. Expo가 아닌 bare workflow를 선택한 이유는 네이티브 모듈에 대한 완전한 제어가 필요했기 때문입니다. 특히 react-native-reanimated를 활용한 고성능 애니메이션과 react-native-gesture-handler를 이용한 자연스러운 제스처 처리가 앱의 핵심 사용자 경험을 구성합니다.

TypeScript 5.8.3을 전면 도입하여 타입 안전성을 확보했습니다. 모든 컴포넌트 Props, API 응답, 상태 관리에 명시적인 타입을 정의했으며, any 타입 사용을 완전히 배제했습니다. 이를 통해 개발 단계에서 많은 잠재적 버그를 사전에 방지할 수 있었고, IDE의 자동 완성 기능을 최대한 활용할 수 있었습니다.

상태 관리에는 Zustand를 선택했습니다. Redux에 비해 보일러플레이트가 적고, 학습 곡선이 낮으면서도 충분한 기능을 제공합니다. 특히 persist 미들웨어를 활용하여 AsyncStorage와 연동한 임시 저장 기능을 쉽게 구현할 수 있었습니다. 네비게이션은 React Navigation 7을 사용하여 스택, 탭, 모달 등 다양한 화면 전환을 구현했습니다.

백엔드

Supabase를 BaaS(Backend as a Service)로 선택했습니다. PostgreSQL 기반의 강력한 데이터베이스, 내장된 인증 시스템, 실시간 구독 기능, Storage, Edge Functions까지 모든 백엔드 요구사항을 단일 플랫폼에서 해결할 수 있었습니다. 특히 Row Level Security(RLS)를 통해 데이터 접근 권한을 세밀하게 제어하여 보안을 강화했습니다.

인증은 Supabase Auth의 이메일/비밀번호 방식을 사용합니다. JWT 토큰 기반으로 동작하며, 클라이언트에서는 AsyncStorage에 세션을 안전하게 저장합니다. 실시간 기능은 Supabase Realtime을 활용하여 새로운 공감이나 메시지가 도착하면 즉시 UI가 업데이트됩니다.

개발 도구 및 품질 관리

코드 품질 관리를 위해 ESLint와 Prettier를 설정했습니다. 테스트는 Jest와 React Native Testing Library를 사용하여 약 80%의 코드 커버리지를 유지하고 있습니다. CI/CD는 GitHub Actions를 통해 구성했으며, PR마다 자동으로 테스트와 빌드가 실행됩니다. Claude Code와의 협업을 통해 효율적인 프로토타입 개발이 가능했습니다.

핵심 기능

감정 털어놓기

앱의 핵심 인터페이스인 감정 날씨 시스템은 5단계의 감정 상태를 날씨 아이콘으로 표현합니다. 맑음은 기쁨과 행복을, 구름은 그저 그런 상태를, 흐림은 무기력과 답답함을, 비는 슬픔과 우울을, 폭풍은 불안과 화남을 나타냅니다. 텍스트보다 직관적인 시각적 표현을 통해 감정을 쉽게 선택하고 공유할 수 있습니다.

접근성을 고려하여 색맹 유저도 피드백을 받을 수 있도록 선택 시 크기와 색상이 동시에 변경됩니다. Reanimated의 withSpring을 활용하여 자연스러운 바운스 효과를 구현했습니다. 글로 털어놓으며 본인의 감정을 돌아보고 해소되는 카타르시스 효과를 경험할 수 있습니다. 작성 중인 내용은 5초 간격으로 자동 임시 저장되어, 뒤로 돌아가서 다시 돌아와도 내용이 유실되지 않습니다.

누군가와 함께

피드 화면에서는 비슷한 감정 사용자와 자동 매칭되어 다른 사용자들의 익명 감정 기록을 볼 수 있습니다. 인스타그램/틱톡의 스와이프 구조를 채택하여 사용자 친화적인 디자인을 제공합니다. 하루에 최대 20개의 기록만 볼 수 있도록 제한하여, 무분별한 스크롤링을 방지하고 각 기록에 더 집중할 수 있게 했습니다.

공감 버튼은 하트 아이콘으로 구현되어 있으며, 탭 시 펄스 애니메이션이 재생됩니다. 익명성을 유지한 채 따뜻한 메시지를 전달할 수 있으며, "힘내세요", "저도 그래요", "괜찮을 거예요", "함께해요" 등의 프리셋 메시지를 선택할 수 있습니다. 이를 통해 사회적 연결감을 강화하고, 공감으로 상대방의 감정을 표현할 수 있습니다.

내 기록 관리

내 기록 탭에서는 작성한 모든 감정 기록을 시간순으로 확인할 수 있습니다. Pull-to-refresh로 최신 데이터를 불러올 수 있으며, 각 기록 카드에는 감정 아이콘, 내용 미리보기, 작성 시간, 받은 공감/메시지 수가 표시됩니다. 카드를 탭하면 상세 화면으로 이동하여 전체 내용과 받은 메시지 목록을 확인할 수 있습니다.

기록 수정과 삭제 기능도 제공됩니다. 더보기 메뉴를 통해 수정, 삭제, 공유 설정 변경이 가능합니다. 삭제 시에는 ConfirmDialog를 통해 한 번 더 확인을 받아 실수로 인한 데이터 손실을 방지합니다.

UX 설계 원칙

즉각적인 피드백

설정 변경, 코멘트 전송, 로그인 등의 동작 시 토스트 메시지를 통해 즉각적인 피드백을 제공합니다. Toast 컴포넌트는 success, error, warning, info 4가지 타입을 지원하며, Context API를 통해 앱 어디서든 호출할 수 있습니다. 사용자가 자신의 행동에 대한 결과를 즉시 확인할 수 있어 불확실성을 줄이고 신뢰감을 높입니다.

익숙한 구조로 학습 최소화

사용자가 이미 익숙한 구조를 채택하여 자연스러운 사용자 흐름을 제공합니다. 하단 탭 네비게이션, 스와이프 제스처, 플로팅 액션 버튼 등 일반적인 모바일 앱에서 사용되는 패턴을 그대로 적용했습니다. 새로운 사용자도 별도의 튜토리얼 없이 앱을 사용할 수 있도록 직관적인 인터페이스를 설계했습니다.

현재 상태 알려주기

화면이 로딩 중일 때 스켈레톤 UI를 통해 로딩 상태를 시각적으로 보여주어 사용자 경험을 개선합니다. SkeletonLoader 컴포넌트는 shimmer 애니메이션을 제공하며, RecordCardSkeleton과 FeedCardSkeleton으로 각 화면에 맞는 로딩 UI를 표시합니다. 털어놓기 플로우에서는 StepIndicator를 통해 현재 진행 단계(감정 선택 → 글쓰기 → 공유 설정)를 명확히 보여줍니다.

디자인 시스템

일관된 디자인을 위해 중앙화된 테마 시스템을 구축했습니다. colors.ts에서 Primary, Semantic, Neutral 색상 팔레트를 정의하고, typography.ts에서 7개의 텍스트 스케일을 관리합니다. spacing.ts에는 8pt Grid System 기반의 간격 값이, shadows.ts에는 4단계(sm, md, lg, xl) 그림자 스타일이 정의되어 있습니다.

접근성을 위해 WCAG AA 기준을 충족하는 색상 대비율(5.2:1 이상)을 적용했습니다. 재사용 가능한 UI 컴포넌트들을 직접 설계하고 구현했으며, Button, Input, EmotionButton, RecordCard, BottomSheet 등의 핵심 컴포넌트가 포함됩니다. BottomSheet 컴포넌트는 Gesture Handler를 활용하여 스와이프 제스처로 닫을 수 있으며, 부드러운 스프링 애니메이션을 제공합니다.

개발 과정

초기 설계 및 기획

프로젝트 시작 전 충분한 시간을 들여 요구사항을 정의하고 문서화했습니다. REQUIREMENTS.md에 기능 요구사항과 우선순위를 정리하고, USER_SCENARIOS.md에 5개의 핵심 사용자 여정을 작성했습니다. SCREEN_FLOW.md에는 Mermaid 다이어그램으로 화면 구조를 시각화하고, LAYOUT_SKETCHES.md에 8개 주요 화면의 상세 레이아웃을 설계했습니다.

디자인 시스템은 개발 초기에 먼저 구축했습니다. 색상, 타이포그래피, 간격, 그림자 등의 기초 요소를 정의하고, 이를 기반으로 컴포넌트를 만들어나갔습니다. 이 선제적 투자 덕분에 이후 화면 개발 속도가 크게 향상되었고, 일관된 룩앤필을 유지할 수 있었습니다.

구현 단계

개발은 10개의 Phase로 나누어 진행했습니다. Phase 1-2에서 프로젝트 초기화와 개발 환경을 구축하고, Phase 3에서 테마, 컴포넌트, 유틸리티 등 공통 리소스를 제작했습니다. Phase 4-5에서 Supabase 연동과 인증 플로우를 구현하고, Phase 6-8에서 탭 네비게이션, 털어놓기 플로우, 피드, 상세/수정 화면 등 핵심 기능을 완성했습니다.

Phase 9에서는 애니메이션 라이브러리를 Animated API에서 Reanimated로 마이그레이션했습니다. 이를 통해 UI 스레드에서 60fps 애니메이션을 실행할 수 있게 되었고, 복잡한 제스처 처리도 부드러워졌습니다. Phase 10에서는 Toast, Skeleton, StepIndicator, 자동 임시 저장 등 HCI 관점의 개선을 진행했습니다.

도전과 해결

WSL2 환경에서 Windows Android 에뮬레이터를 연결하는 것이 초기에 큰 도전이었습니다. NAT 모드에서는 네트워크 격리로 인해 Metro 서버에 연결할 수 없었고, 여러 가지 workaround를 시도했습니다. 최종적으로 Windows 11의 Mirrored Mode 네트워킹을 활용하여 문제를 해결했으며, 이 과정에서 얻은 지식을 WSL2_ANDROID_COMPLETE_GUIDE.md로 정리하여 다른 개발자들도 참고할 수 있게 했습니다.

결과 및 성과

핵심 기능 개발을 완료하고 37개의 유닛 테스트가 통과하는 안정적인 상태에 도달했습니다. 애니메이션은 모두 60fps로 동작하며, 스크린 리더 호환성을 위한 접근성 레이블도 추가했습니다. FlatList 최적화와 React.memo 적용을 통해 긴 목록에서도 부드러운 스크롤 성능을 확보했습니다.

이 프로젝트를 통해 React Native 생태계에 대한 깊은 이해를 얻었습니다. 특히 Reanimated의 worklet 개념, Gesture Handler의 이벤트 시스템, Zustand의 미들웨어 패턴 등을 실전에서 활용하며 숙달할 수 있었습니다. HCI 수업에서 배운 사용자 중심 설계, 피드백 원칙, 접근성 고려 등을 실제 앱 개발에 적용하며 이론과 실무를 연결하는 귀중한 경험을 얻었습니다.

사용자 가치

지은씨는 이제 Hang On을 통해 익명으로 감정을 털어놓습니다. "누군가 당신의 마음에 공감했어요"라는 알림과 함께 5명이 공감했다는 소식을 받습니다. "저도 그래요"라는 메시지를 받고, 혼자가 아니라는 걸 느낍니다. Hang On은 '혼자 삼키는 감정'을 '함께 나누는 위로'로 바꿉니다.