最近“死了么”這款 App 因為精準切入獨居人群的安全痛點而爆火。截止到今天已經攀升到蘋果付費App排行榜第一的位置了!

它的核心邏輯非常簡單: “簽到保平安,斷簽發郵件” 。
出於好奇,我去了解了相關信息,看到一個數據,據第七次全國人口普查數據顯示,我國一人戶家庭已超1.25億戶,占全國戶口總數的25%。對於獨居人群來說,發生意外不可怕,可怕的是無人知曉,這款APP也是精準踩中了這部分人的痛點。
於是,我連夜敲代碼,搞出了這款對標產品—— “活著呢”(TO BE LIVE) 。
它的邏輯極其簡單粗暴:
核心功能

在用戶未註冊時,可以先註冊帳號,再登入,核心代碼如下:
const handleSubmit = async (e) => {
e.preventDefault()
setLoading(true)
try {
if (isLogin) {
const { error } = await supabase.auth.signInWithPassword({ email, password })
if (error) throw error
router.push('/')
} else {
const { error } = await supabase.auth.signUp({ email, password })
if (error) throw error
alert('驗證郵件已發送,請查收!')
}
} catch (err) {
alert(err.message)
} finally {
setLoading(false)
}
}

最核心的功能是那個動態倒計時邏輯。我們需要在客戶端即時計算剩餘時間,並根據緊迫程度變換顏色。這裡的安全周期是設定死的48小時,後期可讓用戶自定義。
<motion.button
whileTap={{ scale: 0.94 }}
onClick={handleCheckIn}
className="absolute inset-4 rounded-[4.5rem] bg-app-card border border-app-border flex flex-col items-center justify-center shadow-[0_15px_40px_rgba(0,0,0,0.04)] dark:shadow-none"
>
<div className={`mb-4 transition-colors duration-1000 ${getAlertColorClass()}`}>
{timeLeft.h < 8 ? (
<AlertTriangle size={60} />
) : (
<Shield
size={60}
fill="currentColor"
fillOpacity={0.12}
className="drop-shadow-[0_4px_12px_rgba(0,0,0,0.05)] dark:drop-shadow-none"
/>
)}
</div>
<span className="text-2xl font-black tracking-tight text-app-text">我還活著</span>
<div className="mt-2 font-mono text-[11px] opacity-40 flex items-center gap-1.5 tracking-widest">
<Clock size={12} strokeWidth={2.5} />
{String(timeLeft.h).padStart(2, "0")}:
{String(timeLeft.m).padStart(2, "0")}:
{String(timeLeft.s).padStart(2, "0")}
</div>
</motion.button>
// 動態獲取當前的強調色(預警系統)
const getAlertColorClass = () => {
if (timeLeft.h < 8) return "text-red-500";
if (timeLeft.h < 24) return "text-amber-500";
return "text-app-accent"; // 使用主題定義的強調色
};
const updateCountdown = useCallback(() => {
if (!profile?.last_check_in) return;
const last = new Date(profile.last_check_in).getTime();
const now = new Date().getTime();
const total = 48 * 60 * 60 * 1000;
const remaining = Math.max(0, total - (now - last));
setTimeLeft({
h: Math.floor(remaining / (1000 * 60 * 60)),
m: Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60)),
s: Math.floor((remaining % (1000 * 60)) / 1000),
percent: (remaining / total) * 100
});
}, [profile]);
useEffect(() => {
const timer = setInterval(updateCountdown, 1000);
return () => clearInterval(timer);
}, [updateCountdown]);
const handleCheckIn = async () => {
if (!user) return;
const now = new Date().toISOString();
const { error } = await supabase.from("profiles").update({ last_check_in: now }).eq("id", user.id);
if (!error) {
setProfile((prev) => ({ ...prev, last_check_in: now }));
if ("vibrate" in navigator) navigator.vibrate([50, 30, 50]);
}
};
作為一個守護工具,它必須觸手可及。我為它集成了 PWA 功能,用戶可以“一鍵添加到桌面”。
通過配置 manifest.json,我們的 App 實現了:

“我還活著呢”(TO BE LIVE),在每個平凡的 24 小時裡,溫柔地問一句: “嘿,還在嗎?”
項目已開源/部署,歡迎大家來“續命”!
'to be live' github
welcome to 'to-be-live'
如果你失聯了,你最希望 App 給你的聯絡人發送哪一句話? A. 幫我格式化手機,謝謝。 B. 我在異世界開掛了,莫念。 C. 救命!我還能搶救一下!