No updates detected yet. GitHub releases will appear here.
Loading the full README. The saved excerpt is shown below.
jellyjelly.vercel.app · 설명서 독서기록 앱 북적북적이 읽은 책을 쌓아 올리듯, 먹은 젤리를 쌓아 올린다. 달마다 유리병이 하나씩 생기고, 하나 먹을 때마다 알맹이가 병 안으로 떨어진다. 달이 끝나면 그 병은 선반에 남는다. 기록과 사진은 전부 기기 안(IndexedDB)에 있다. 서버는 선택이다. 젤리 선반 — 첫 화면. 지금까지의 병이 최신 순으로 놓인다. 아무것도 안 먹은 달도 빈 병으로 남아서 쉰 달이 보인다. 달 보관함 — 그 달의 병 하나를 크게. 병을 톡 치면 젤리가 실제로 섞이고 소리가 난다. 알맹이를 누르면 그때의 기록이 뜬다. 달력 — 먹은 날에 젤리 색 점이 찍힌다. 위에는 이번 달 개수와 칼로리 합계, 날짜를 누르면 그날 목록. 젤리 고르기 — 가운데 + 버튼. 초성으로 찾는다(ㅁㄱㅁ → 마이구미). 목록에 없으면 그 자리에서 새로 추가. 다 먹었어요 — 오늘 찍은 사진, 별점, 식감 슬라이더 셋, 한 줄. 전부 건너뛰어도 담긴다. 담으면 알맹이가 병으로 떨어진다. 젤리 상세 — 먹은 횟수, 내 평균 별점, 칼로리, 내가 기억하는 맛, 기록 타임라인. 하트를 누르면 최애, 책갈피를 누르면 찜.Read the full README ↗
독서기록 앱 북적북적이 읽은 책을 쌓아 올리듯, 먹은 젤리를 쌓아 올린다. 달마다 유리병이 하나씩 생기고, 하나 먹을 때마다 알맹이가 병 안으로 떨어진다. 달이 끝나면 그 병은 선반에 남는다.
기록과 사진은 전부 기기 안(IndexedDB)에 있다. 서버는 선택이다.
브라우저 탭으로도 되지만, 홈 화면에 추가해야 주소창 없이 앱처럼 열리고 한동안 안 열어도 저장소가 안 지워진다.
아이폰에는 앱 안에 추가 버튼을 만들 수 없다. 웹에 그 API가 없다 - 공유 시트를 열 방법도, 홈 화면에 무언가를 꽂을 방법도 애플이 안 열어줬다. 그래서 설정 화면은 버튼 대신 어디를 눌러야 하는지 그 자리의 그림으로 짚어준다.
아이폰 (사파리) — 아래 가운데 공유 버튼 → 홈 화면에 추가 → 추가
아이폰 (크롬·엣지·파이어폭스) — iOS 16.4부터는 여기서도 된다. 주소창 옆 공유 (또는 ⋮ 안의 공유) → 홈 화면에 추가. 사파리로 옮길 필요 없다. 카카오톡·인스타그램 안에서 열린 창만 안 되고, 그때는 Safari로 열기를 한 번 거친다.
안드로이드 (크롬) — 오른쪽 위 ⋮ → 앱 설치 또는 홈 화면에 추가
브라우저마다, 그리고 홈 화면 앱과 브라우저 탭 사이에도 기록이 따로 쌓인다. 사파리 탭에서 모으다가 홈 화면 앱으로 옮기면 빈 병으로 시작한다. 옮기기 전에 설정 → 백업 파일 내려받기로 챙긴다.
| 화면 | 하는 일 |
|---|---|
| 젤리 선반 (홈) | 지난 병들을 한 화면에. 빈 달도 빈 병으로 남는다 |
| 달 보관함 | 달 단위 유리병, 젤리를 누르면 그 기록, 병 흔들기(소리 포함), 폰을 기울이면 쏠림, 먹는 중 목록 |
| 기록하기 | 초성 검색으로 찾아 한 번 탭 |
| 젤리 추가/수정 | 이름만 필수. 사진·모양·색 |
| 다 먹었어요 | 그날 찍은 사진 + 별점 + 식감 슬라이더 3종 + 한 줄, 그리고 병에 떨어지는 연출 |
| 젤리 상세 | 최애 표시, 먹은 횟수, 평균 별점, 식감 평균, 기록 타임라인 |
| 달력 | 날짜별 젤리 색 점, 이번 달 칼로리 합계, 날짜를 누르면 그날 기록 |
| 도감 | 최애 / 모은 것 / 전체 / 브랜드별 수집률, 카드 그리드, 검색, 찜 표시 |
| 추천 | 내 기록만으로 - 찜해둔 것, 취향 프로필, 다시 만날 때, 취향에 가까운, 안 가본 길 |
| 젤리 뽑기 | 못 고르겠을 때. 레버를 돌리면 캡슐이 투출구로 |
| PLAY GROUND | 장난감 아홉의 입구. 만지작거리기와 머리 쓰기로 나누고 최고 기록을 한 줄로 모은다 |
| 젤리 왁뿌볼 | 왁스를 파삭 깨서 벗기면 안에서 젤리 말랑이가 나온다. 깨는 동안에도 누르고 당길 수 있다 |
| 마법약 만들기 | 섞은 색만 보고 약병 여섯의 색을 거꾸로 알아낸다. 기회는 넷에서 둘로 줄어든다 |
| 돌려 맞추기 | 돌리고 뒤집어 변경 후 모양으로. 결과는 안 보여주고 최소 횟수여야 정답 |
| 도형 회전하기 | 돌린 것만 정답, 뒤집은 건 오답. 넷 중 하나는 반드시 거울상 함정 |
| 길 만들기 | 같은 젤리끼리 잇되 길이 겹치면 안 되고 빈 칸도 남으면 안 된다 |
| 개수 비교 | 젤리가 많은 쪽 빠르게 고르기. 알 크기가 매번 달라서 넓이로는 못 맞힌다 |
| 순서 외우기 | 반짝인 젤리를 그 순서대로. 젤리마다 음이 달라서 가락으로도 외워진다 |
| 도토리 받기 | 가을 놀이. 다람쥐가 바구니를 들고 받는다. 아가리 안에 떨어져야 받은 것. 밤송이는 피한다 |
| 코끼리 배 | 두드리면 북처럼 운다. 코를 당겨 한 바퀴 돌리거나 머리를 쓰다듬으면 뿌우 하고 울고, 바닥 젤리를 누르면 코로 주워 먹고 야르 한다 |
| 설정 | 닉네임, 테마 5색, 소리, 기울이기, 설명서, 홈 화면에 추가, 백업 내보내기·복원, 전체 삭제 |
탭은 넷까지다. 다섯을 넘으면 손가락이 헤매서, 자주 갈 일 없는 설정은 보관함 오른쪽 위 톱니로 뺐다.
칼로리는 젤리마다 직접 넣는다. 국내 젤리 칼로리를 제품 단위로 주는 무료 API는 식약처 식품영양성분DB뿐인데 키 발급이 필요해서, 지금은 봉지 뒷면을 보고 적는다.
아직 안 한 것: 월간 리포트 카드, 바코드 스캔, 자동 누끼.
npm install
npm run dev
npm run dev의 Network 주소는 구경용이다. 브라우저는 저장소를 주소(origin)
단위로 나누는데, 그 주소는 공유기가 빌려준 IP라 언제든 바뀌고 포트도 밀린다.
주소가 바뀌면 브라우저 입장에서는 완전히 다른 앱이라 빈 병이 뜬다.
npm run build # 타입체크 + 빌드
npm run lint # oxlint
Vercel에 올린 고정 https 주소에서 쓴다. 그래야 주소가 안 바뀌어서 기록이 남고, 서비스 워커가 등록돼 오프라인에서도 열리고, 홈 화면에 추가했을 때 제대로 앱처럼 동작한다. 올라가는 건 HTML/JS 껍데기뿐이고 기록과 사진은 폰 안에만 있다.
이후로는 git push만 하면 자동으로 다시 배포된다.
기본은 기기 안에만 저장한다. Supabase 를 연결하면 로그인과 기기 간 동기화가 켜지고, 연결하지 않으면 지금 그대로 돈다.
supabase/schema.sql 을 통째로 붙여넣고 실행.env 에 넣는다 (.env.example 참고)anon 키는 브라우저에 노출되는 게 정상이다. 데이터는 RLS 가 막는다.
service_role 키는 절대 넣지 않는다.
도감은 계정마다 따로다. 가입하면 편의점 젤리 73종이 각자에게 깔린다. 친구가 추가한 젤리가 내 도감에 끼어들지 않는다.
지운 것은 묘비로 남긴다. 줄에 '지움' 표시를 달아두면 화면마다 걸러내야 하고 한 군데만 빠뜨려도 지운 젤리가 튀어나온다. 그래서 줄은 진짜로 지우고 지웠다는 사실만 따로 모은다. 다른 기기가 "얘가 없네" 하고 되살리는 것도 이걸로 막는다.
씨앗을 깔 때 읽기와 쓰기는 한 트랜잭션이어야 한다. "없는 것만 넣는다"는 판단을 트랜잭션 밖에서 하고 넣기만 안에서 했더니, 탭이 둘이면 둘 다 "아직 없네"를 보고 각자 넣었다. 씨앗 버전을 올린 날 새 젤리 다섯 종이 네 벌씩 깔린 걸 배포판에서 봤다. 읽기를 안으로 들여 고쳤고, 이미 겹쳐 받은 사람을 위해 한 번 쓸어내는 것도 같이 넣었다. 다만 손댄 흔적이 있는 벌(기록이 달렸거나 사진·최애·찜·메모·칼로리를 넣어둔 것)은 남긴다 - 겹친 걸 치우다 남의 기록을 지우면 고친 것보다 나쁘다.
묘비에는 줄 id 말고 무엇이었는지도 적는다. id 는 기기마다 새로 뽑은 난수라, 씨앗 목록을 다시 깔 때 "이건 지웠던 젤리다"를 알아볼 수가 없었다. 도감 젤리를 지워둔 사람은 씨앗이 한 번 업데이트되는 순간 지운 게 통째로 되살아났을 것이다. 씨앗 버전을 올리기 전까지 아무도 밟지 않았을 뿐이다.
React 19 · TypeScript · Vite · Tailwind v4 · Motion · Dexie(IndexedDB) · React Router · es-hangul(초성 검색) · date-fns · vite-plugin-pwa
의도적으로 안 쓰는 것: Next.js, 상태관리 라이브러리(useLiveQuery가 대신한다),
UI 컴포넌트 라이브러리(이 앱의 전부가 커스텀 귀여움이라), ORM.
소리는 전부 Web Audio 로 그때그때 합성한다. 음원 파일이 하나도 없다. 왁뿌볼과 코끼리는 캔버스에 직접 그린다.
src/
styles/tokens.css 디자인 토큰 - 젤리 8색, 액센트, 폰트
styles/app.css Tailwind + 유리병 + 식감 슬라이더 CSS
data/types.ts Jelly(카탈로그) / Entry(먹은 기록)
data/db.ts Dexie 스키마와 쓰기 함수
data/seed.ts 편의점 젤리 도감 73종
lib/pile.ts 병에 젤리가 쌓이는 배치와 알 굵기
lib/search.ts 초성 검색
lib/photo.ts 사진 압축(WebP)과 URL 수명 관리
lib/backup.ts 내보내기 / 되살리기
lib/taste.ts 취향 프로필과 추천 (순수 함수)
lib/sound.ts 병 흔드는 소리 (Web Audio 합성, 음원 파일 없음)
lib/storage.ts 폰 저장소 - 지우지 말아 달라 부탁하고, 얼마나 찼는지 본다
lib/theme.ts 테마 5색
lib/updates.ts 새로 배포한 판을 알아서 갈아끼우기
lib/tilt.ts 폰 기울기 읽기 (아이폰은 허락을 받아야 한다)
lib/draw.ts 오늘 먹을 젤리 뽑기 (순수 함수)
lib/waxball.ts 왁뿌볼 모양 계산 (순수 함수)
lib/squish.ts 왁스 깨짐과 말랑이 소리
lib/audio.ts AudioContext 와 잡음 버퍼 - 소리 내는 파일들이 나눠 쓴다
lib/autumn.ts 다람쥐·바구니·도토리·은행잎·밤송이 그리기와 소리
lib/chime.ts 순서 외우기의 음 (5음 음계 마림바)
lib/maze.ts 길 만들기 퍼즐 만들기 (해밀턴 경로를 토막 내서)
lib/rotate.ts 도형 회전 문제 만들기 (돌린 것과 뒤집은 것 가리기)
lib/fold.ts 돌려 맞추기 - 열여섯 모양과 최소 횟수 (너비 우선 탐색)
lib/potion.ts 마법약 - 색 섞기와 문제 만들기, 점수 (순수 함수)
lib/drum.ts 북 소리 (5음 음계 · 북면 울림) 와 뿌우 울음
lib/elephant.ts 코와 바닥 젤리 그리기
components/Jelly.tsx 알맹이 6종(곰·벌레·링·큐브·하트·콜라병) + 봉지
components/Jar.tsx 유리병
screens/ 화면 스물셋 (시작 화면과 놀이터 포함)
docs/
logo/ 로고 원본(SVG)과 내보낸 PNG
screens/ 이 문서의 화면 캡처
manual.html 사용자용 설명서 (public/manual/ 로 같이 배포된다)
Jelly와 Entry는 분리한다. 같은 젤리를 열 번 먹어도 카탈로그는 하나고, 먹은 사건이 열 개 쌓인다.
This is the beginning of the README. Read the rest at the original. Read the full README ↗