feat: support shared pet care tasks and smooth daily page return
This commit is contained in:
@@ -6,6 +6,10 @@ function dateLabel() {
|
||||
const now = new Date();
|
||||
return `${now.getMonth() + 1}月${now.getDate()}日 周${"日一二三四五六"[now.getDay()]}`;
|
||||
}
|
||||
function accountKey() {
|
||||
const state = getApp().globalData || {};
|
||||
return (state.user && state.user.id) || state.token || "";
|
||||
}
|
||||
Page({
|
||||
data: {
|
||||
locationName: "当前位置",
|
||||
@@ -23,13 +27,32 @@ Page({
|
||||
phase: "auth",
|
||||
error: "",
|
||||
},
|
||||
onLoad() {
|
||||
const cached = getApp().homeSnapshot;
|
||||
if (cached && cached.account === accountKey() && cached.date === localDate()) {
|
||||
this.setData({ ...cached.data, ready: true, phase: "ready", loading: false });
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.applyEnvironment(environment.cached());
|
||||
this.load();
|
||||
},
|
||||
onHide() {
|
||||
this.rememberHome();
|
||||
},
|
||||
onUnload() {
|
||||
this.rememberHome();
|
||||
this.disposed = true;
|
||||
},
|
||||
rememberHome() {
|
||||
if (!this.data.ready || !accountKey()) return;
|
||||
const { pets, selected, tasks, undoneCount, walkCount, name } = this.data;
|
||||
getApp().homeSnapshot = {
|
||||
account: accountKey(),
|
||||
date: localDate(),
|
||||
data: { pets, selected, tasks, undoneCount, walkCount, name },
|
||||
};
|
||||
},
|
||||
updateEnvironmentLabel() {
|
||||
this.setData({
|
||||
headerSubtitle:
|
||||
@@ -112,6 +135,7 @@ Page({
|
||||
ready: true,
|
||||
phase: "ready",
|
||||
});
|
||||
this.rememberHome();
|
||||
// Location permission and weather never hold up the first usable screen.
|
||||
this.refreshEnvironment();
|
||||
} catch (error) {
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"usingComponents": {
|
||||
"tab-bar": "/components/tab-bar/index",
|
||||
"pet-picker": "/components/pet-picker/index",
|
||||
"startup-state": "/components/startup-state/index",
|
||||
"home-skeleton": "/components/home-skeleton/index"
|
||||
"startup-state": "/components/startup-state/index"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<startup-state wx:if="{{phase==='auth' || phase==='auth-error'}}" error="{{error}}" bind:retry="load" />
|
||||
<startup-state wx:if="{{!ready && (!error || phase==='auth-error')}}" error="{{error}}" bind:retry="load" />
|
||||
<page-layout wx:else id="page-layout" title="{{locationName}}" subtitle="{{headerSubtitle}}" location="{{true}}" bind:locationtap="refreshEnvironment">
|
||||
<view class="screen">
|
||||
<home-skeleton wx:if="{{loading && !ready}}" />
|
||||
<view wx:elif="{{!ready && error}}" class="card home-error">
|
||||
<view wx:if="{{!ready && error}}" class="card home-error">
|
||||
<app-icon kind="paw" size="54" />
|
||||
<view class="error-title">暂时没能准备好首页</view>
|
||||
<view class="muted">{{error}}</view>
|
||||
@@ -10,7 +9,6 @@
|
||||
</view>
|
||||
<block wx:else>
|
||||
<view wx:if="{{error}}" class="refresh-error"><text>更新失败,保留上次的日常记录</text><text class="link" bindtap="load">重试</text></view>
|
||||
<view wx:elif="{{loading}}" class="refresh-hint">正在更新今天的小日常…</view>
|
||||
<view class="hero">
|
||||
<view class="hero-copy">
|
||||
<text class="hero-small">今日的主角</text>
|
||||
@@ -91,7 +89,7 @@
|
||||
</view>
|
||||
<view class="task-main">
|
||||
<text class="task-name">{{item.title}}</text>
|
||||
<text class="muted">{{item.time_of_day}} · {{item.completed?'已完成':taskBusyIds[0]===item.id?'正在记录…':'点击完成'}}</text>
|
||||
<text class="muted">{{item.all_pets?'全部宠物 · ':''}}{{item.time_of_day}} · {{item.completed?'已完成':taskBusyIds[0]===item.id?'正在记录…':'点击完成'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{!tasks.length}}" class="empty">
|
||||
|
||||
@@ -189,12 +189,6 @@
|
||||
border-radius: 22rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.refresh-hint {
|
||||
text-align: center;
|
||||
font-size: 22rpx;
|
||||
color: #a48d7e;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.first-pet {
|
||||
padding-top: 30rpx;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ const { localDate, shiftDate } = require("../../utils/date");
|
||||
Page({
|
||||
data: {
|
||||
pets: [],
|
||||
petOptions: [],
|
||||
tasks: [],
|
||||
taskBusyIds: [],
|
||||
completingAll: false,
|
||||
@@ -32,10 +33,11 @@ Page({
|
||||
if (date !== this.data.date) return;
|
||||
const tasks = result.items.map((t) => ({
|
||||
...t,
|
||||
petName: (pets.find((p) => p.id === t.pet_id) || {}).name || "宠物",
|
||||
petName: t.all_pets ? "全部宠物" : (pets.find((p) => p.id === t.pet_id) || {}).name || "宠物",
|
||||
}));
|
||||
this.setData({
|
||||
pets,
|
||||
petOptions: [...pets, { id: "", name: "全部宠物" }],
|
||||
tasks,
|
||||
undoneCount: tasks.filter((t) => !t.completed).length,
|
||||
done: tasks.filter((t) => t.completed).length,
|
||||
@@ -78,7 +80,7 @@ Page({
|
||||
showForm: true,
|
||||
editingId: task.id,
|
||||
title: task.title,
|
||||
petIndex: Math.max(petIndex, 0),
|
||||
petIndex: task.all_pets ? this.data.pets.length : Math.max(petIndex, 0),
|
||||
category: task.category,
|
||||
time_of_day: task.time_of_day,
|
||||
repeat_rule: task.repeat_rule,
|
||||
@@ -125,7 +127,9 @@ Page({
|
||||
this.data.editingId ? "/tasks/" + this.data.editingId : "/tasks",
|
||||
this.data.editingId ? "PUT" : "POST",
|
||||
{
|
||||
pet_id: this.data.pets[this.data.petIndex].id,
|
||||
...(this.data.petIndex === this.data.pets.length
|
||||
? { all_pets: true }
|
||||
: { pet_id: this.data.pets[this.data.petIndex].id }),
|
||||
title: this.data.title.trim(),
|
||||
category: this.data.category,
|
||||
time_of_day: this.data.time_of_day,
|
||||
|
||||
@@ -71,12 +71,12 @@
|
||||
<view class="field">
|
||||
<view class="field-label">照顾谁</view>
|
||||
<picker
|
||||
range="{{pets}}"
|
||||
range="{{petOptions}}"
|
||||
range-key="name"
|
||||
value="{{petIndex}}"
|
||||
bindchange="petChange"
|
||||
>
|
||||
<view class="picker">{{pets[petIndex].name||'请先添加宠物'}}</view>
|
||||
<view class="picker">{{petOptions[petIndex].name||'请先添加宠物'}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="field">
|
||||
|
||||
Reference in New Issue
Block a user