Add immediate startup login and loading states for mini program home
This commit is contained in:
+83
-21
@@ -14,16 +14,22 @@ Page({
|
||||
walkCount: 0,
|
||||
name: "铲屎官",
|
||||
loading: true,
|
||||
ready: false,
|
||||
phase: "auth",
|
||||
error: "",
|
||||
},
|
||||
onShow() {
|
||||
this.load();
|
||||
this.updateEnvironmentLabel();
|
||||
if (!this.environmentAt || Date.now() - this.environmentAt > 15 * 60 * 1000) {
|
||||
this.refreshEnvironment();
|
||||
}
|
||||
this.load();
|
||||
},
|
||||
onUnload() {
|
||||
this.disposed = true;
|
||||
},
|
||||
updateEnvironmentLabel() {
|
||||
this.setData({ headerSubtitle: dateLabel() + " · " + (this.weatherLabel || "轻触获取天气") });
|
||||
this.setData({
|
||||
headerSubtitle:
|
||||
dateLabel() + " · " + (this.weatherLabel || "轻触获取天气"),
|
||||
});
|
||||
},
|
||||
async refreshEnvironment(event) {
|
||||
if (this.environmentBusy) return;
|
||||
@@ -31,44 +37,84 @@ Page({
|
||||
const tapped = !!event;
|
||||
let positioned = false;
|
||||
try {
|
||||
const settings = await new Promise((resolve, reject) => wx.getSetting({ success: resolve, fail: reject }));
|
||||
const settings = await new Promise((resolve, reject) =>
|
||||
wx.getSetting({ success: resolve, fail: reject }),
|
||||
);
|
||||
if (settings.authSetting["scope.userLocation"] === false) {
|
||||
if (!tapped) throw new Error("location-denied");
|
||||
const enabled = await new Promise((resolve, reject) => wx.openSetting({ success: resolve, fail: reject }));
|
||||
if (!enabled.authSetting["scope.userLocation"]) throw new Error("location-denied");
|
||||
const enabled = await new Promise((resolve, reject) =>
|
||||
wx.openSetting({ success: resolve, fail: reject }),
|
||||
);
|
||||
if (!enabled.authSetting["scope.userLocation"])
|
||||
throw new Error("location-denied");
|
||||
}
|
||||
this.weatherLabel = "正在获取天气";
|
||||
this.updateEnvironmentLabel();
|
||||
const point = await new Promise((resolve, reject) => wx.getLocation({
|
||||
type: "gcj02",
|
||||
success: resolve,
|
||||
fail: reject,
|
||||
}));
|
||||
const point = await new Promise((resolve, reject) =>
|
||||
wx.getLocation({
|
||||
type: "gcj02",
|
||||
success: resolve,
|
||||
fail: reject,
|
||||
}),
|
||||
);
|
||||
positioned = true;
|
||||
const result = await secure("/environment", "GET", { latitude: point.latitude, longitude: point.longitude });
|
||||
const result = await secure("/environment", "GET", {
|
||||
latitude: point.latitude,
|
||||
longitude: point.longitude,
|
||||
});
|
||||
this.setData({ locationName: result.location_name });
|
||||
this.weatherLabel = result.weather
|
||||
? `${result.weather.description} ${result.weather.temperature}°C`
|
||||
: "天气暂不可用";
|
||||
this.environmentAt = result.weather ? Date.now() : 0;
|
||||
} catch (error) {
|
||||
const denied = /denied|deny|auth/.test(error.errMsg || error.message || "");
|
||||
this.setData({ locationName: positioned ? "位置暂不可用" : denied ? "开启定位" : "定位暂不可用" });
|
||||
const denied = /denied|deny|auth/.test(
|
||||
error.errMsg || error.message || "",
|
||||
);
|
||||
this.setData({
|
||||
locationName: positioned
|
||||
? "位置暂不可用"
|
||||
: denied
|
||||
? "开启定位"
|
||||
: "定位暂不可用",
|
||||
});
|
||||
this.weatherLabel = denied ? "轻触开启定位" : "轻触重试";
|
||||
if (tapped && !denied) wx.showToast({ title: positioned ? "位置和天气获取失败,请重试" : "定位失败,请重试", icon: "none" });
|
||||
if (tapped && !denied)
|
||||
wx.showToast({
|
||||
title: positioned ? "位置和天气获取失败,请重试" : "定位失败,请重试",
|
||||
icon: "none",
|
||||
});
|
||||
} finally {
|
||||
this.environmentBusy = false;
|
||||
this.updateEnvironmentLabel();
|
||||
}
|
||||
},
|
||||
async load() {
|
||||
if (this.loadPromise) return this.loadPromise;
|
||||
this.loadPromise = this.loadHome().finally(() => {
|
||||
this.loadPromise = null;
|
||||
});
|
||||
return this.loadPromise;
|
||||
},
|
||||
async loadHome() {
|
||||
this.setData({
|
||||
loading: true,
|
||||
error: "",
|
||||
phase: this.data.ready ? "data" : "auth",
|
||||
});
|
||||
let authenticated = false;
|
||||
try {
|
||||
await getApp().login();
|
||||
authenticated = true;
|
||||
if (this.disposed) return;
|
||||
this.setData({ phase: "data" });
|
||||
const [pets, tasks, walks, me] = await Promise.all([
|
||||
secure("/pets"),
|
||||
secure("/tasks"),
|
||||
secure("/walks"),
|
||||
secure("/me"),
|
||||
]);
|
||||
if (this.disposed) return;
|
||||
const chosen = wx.getStorageSync("walk_pet_ids") || [],
|
||||
month = localDate().slice(0, 7);
|
||||
this.setData({
|
||||
@@ -77,14 +123,30 @@ Page({
|
||||
tasks: tasks.items,
|
||||
walkCount: walks.filter((w) => w.started_at.slice(0, 7) === month)
|
||||
.length,
|
||||
name: me.nickname || "铲屎官",
|
||||
name: me.nickname || "毛孩家长",
|
||||
loading: false,
|
||||
ready: true,
|
||||
phase: "ready",
|
||||
});
|
||||
// Location permission and weather never hold up the first usable screen.
|
||||
if (
|
||||
!this.environmentAt ||
|
||||
Date.now() - this.environmentAt > 15 * 60 * 1000
|
||||
) {
|
||||
this.refreshEnvironment();
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.disposed) return;
|
||||
this.setData({
|
||||
loading: false,
|
||||
phase: !authenticated && !this.data.ready ? "auth-error" : "data-error",
|
||||
error: error.message || "暂时没能连接,请稍后重试",
|
||||
});
|
||||
} catch (e) {
|
||||
this.setData({ loading: false });
|
||||
toast(e);
|
||||
}
|
||||
},
|
||||
addPet() {
|
||||
wx.navigateTo({ url: "/pages/pet-edit/pet-edit" });
|
||||
},
|
||||
pick(e) {
|
||||
this.setData({ selected: e.detail.selected });
|
||||
wx.setStorageSync("walk_pet_ids", e.detail.selected);
|
||||
|
||||
Reference in New Issue
Block a user