Files
habit-tracker/app/templates/base.html
T
shinalokandClaude Sonnet 5 ac98cf4f99 replace EasyMDE journal editor with plain textarea to fix iOS Korean IME jamo split
Forcing inputStyle to contenteditable (previous commit) didn't fix it on
iPhone, confirming this is CodeMirror 5's own long-standing weakness with
CJK IME composition on iOS WebKit, not just the iPad desktop-UA detection
issue. There's no reliable fix short of dropping CodeMirror for the journal
content field, so EasyMDE is removed entirely and the textarea goes back to
a native, uncontrolled <textarea> — nothing intercepts/re-renders it during
composition, so iOS's IME just works.

The markdown toolbar buttons (bold/italic/heading/quote/lists/code/link)
now manipulate the textarea's selection directly via a small JournalEditor
JS API instead of calling EasyMDE/CodeMirror commands, and image paste
tracks its upload placeholder by a unique text marker instead of a
CodeMirror bookmark. Also drops the vendored easymde.min.js/css (no longer
referenced) and bumps the service worker CACHE_NAME so stale cached copies
of the old vendor files get evicted.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 20:23:09 +09:00

82 lines
4.7 KiB
HTML

<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>{% block title %}해빗랩{% endblock %}</title>
{# 구글 OAuth 브랜딩 심사는 홈페이지에서 앱 이름과 목적을 확인한다 — 설명 메타 태그가 없으면 "앱의 목적에 관한 설명이 없다"로 반려된다. #}
<meta name="description" content="{% block meta_description %}HabitLab (해빗랩) is a habit tracking web app. 해빗랩은 만들고 싶은 습관과 끊고 싶은 습관을 요일 단위로 관리하는 습관 기록 앱입니다.{% endblock %}" />
<link rel="manifest" href="/static/manifest.json" />
<meta name="theme-color" content="#d97757" media="(prefers-color-scheme: light)" />
<meta name="theme-color" content="#e08962" media="(prefers-color-scheme: dark)" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="해빗랩" />
<link rel="apple-touch-icon" sizes="180x180" href="/static/icons/icon-apple-180.png" />
<link rel="apple-touch-icon" href="/static/icons/icon-192.png" />
<link rel="icon" href="/static/icons/icon-192.png" />
<link rel="stylesheet" href="/static/css/style.css" />
<script src="/static/js/vendor/htmx.min.js" defer></script>
<script src="/static/js/push-register.js" defer></script>
<script src="/static/js/vendor/sortable.min.js" defer></script>
<script src="/static/js/habit-reorder.js" defer></script>
<script src="/static/js/journal-category-reorder.js" defer></script>
<script src="/static/js/journal-editor.js" defer></script>
<script src="/static/js/vendor/alpine.min.js" defer></script>
<script src="/static/js/app.js" defer></script>
</head>
<body>
<div class="app-shell{% block shell_class %}{% endblock %}">
{% if logged_in %}
<div id="ios-install-banner" class="ios-install-banner">
<span>홈 화면에 추가하면 알림도 받을 수 있어요. 공유 버튼 → &lsquo;홈 화면에 추가&rsquo;를 눌러보세요.</span>
<button type="button" onclick="dismissIosInstallBanner()" aria-label="닫기">&times;</button>
</div>
<nav class="top-nav">
<span class="brand">해빗랩</span>
<div class="nav-links">
<a href="/today" class="{% block nav_today %}{% endblock %}">오늘</a>
<a href="/habits" class="{% block nav_habits %}{% endblock %}">습관 관리</a>
<a href="/history" class="{% block nav_history %}{% endblock %}">기록</a>
<a href="/journal" class="{% block nav_journal %}{% endblock %}">일기</a>
</div>
{% if current_user %}
<div class="nav-user">
{% if account_level %}<span class="nav-level-pill">Lv.{{ account_level.level }}</span>{% endif %}
<a href="/account">{{ current_user.name or current_user.email }}</a>
<form method="post" action="/auth/logout">
<button type="submit" class="btn-link">로그아웃</button>
</form>
</div>
{% endif %}
</nav>
<nav class="bottom-tab-bar">
<a href="/today" class="tab-item {{ self.nav_today() }}">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9" /><path d="M8 12l3 3 5-6" /></svg>
<span>오늘</span>
</a>
<a href="/habits" class="tab-item {{ self.nav_habits() }}">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" y1="6" x2="20" y2="6" /><line x1="4" y1="12" x2="20" y2="12" /><line x1="4" y1="18" x2="20" y2="18" /></svg>
<span>습관 관리</span>
</a>
<a href="/history" class="tab-item {{ self.nav_history() }}">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="5" width="18" height="16" rx="2" /><line x1="3" y1="10" x2="21" y2="10" /><line x1="8" y1="3" x2="8" y2="7" /><line x1="16" y1="3" x2="16" y2="7" /></svg>
<span>기록</span>
</a>
<a href="/journal" class="tab-item {{ self.nav_journal() }}">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20" /><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z" /></svg>
<span>일기</span>
</a>
</nav>
{% endif %}
{% block content %}{% endblock %}
<footer class="app-footer">
<a href="/privacy">개인정보처리방침</a>
<a href="/terms">서비스 약관</a>
</footer>
</div>
</body>
</html>