-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
161 lines (141 loc) · 5.16 KB
/
Copy pathscript.js
File metadata and controls
161 lines (141 loc) · 5.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
const screens = Array.from(document.querySelectorAll(".screen"));
const tabs = Array.from(document.querySelectorAll(".tab"));
const scrollArea = document.querySelector(".scroll-area");
const recordState = document.getElementById("recordState");
const rideStatusText = document.getElementById("rideStatusText");
const endRideBtn = document.getElementById("endRideBtn");
const startRideBtn = document.getElementById("startRideBtn");
const generateReviewBtn = document.getElementById("generateReviewBtn");
const saveRecordBtn = document.getElementById("saveRecordBtn");
const aiSuggestions = document.getElementById("aiSuggestions");
const toast = document.getElementById("toast");
const safeBtn = document.getElementById("safeBtn");
const contactBtn = document.getElementById("contactBtn");
const fallCheckText = document.getElementById("fallCheckText");
const docsEntryBtn = document.getElementById("docsEntryBtn");
const docsBackBtn = document.getElementById("docsBackBtn");
let toastTimer = null;
let reviewVersion = 0;
const freshSuggestions = [
{
title: "体能建议",
body: "第 8 趟后休息间隔明显缩短,建议每 4 趟安排一次 6-8 分钟恢复。"
},
{
title: "装备建议",
body: "雪鞋电量充足,当前中档加热适合室内雪场;上雪前 5 分钟预热更稳定。"
},
{
title: "安全建议",
body: "异常停留 1 次发生在速度回落后,可开启同行人提醒并复查护膝固定。"
},
{
title: "训练建议",
body: "速度峰谷差较大,下一次优先练习连续转弯节奏,降低入弯前急减速。"
}
];
const compactSuggestions = [
{
title: "体能建议",
body: "今天强度适中,后半程可把休息点前移,避免疲劳后再做高速滑行。"
},
{
title: "装备建议",
body: "防雾雪镜状态稳定,建议保留当前设置;护具固定仍建议进入雪道前复查。"
},
{
title: "安全建议",
body: "风险等级保持中等,连续滑行超过 45 分钟时请主动休息。"
},
{
title: "训练建议",
body: "本次最高速度 42km/h,建议以稳定半径转弯为目标,而不是继续追求峰值速度。"
}
];
tabs.forEach((tab) => {
tab.addEventListener("click", () => switchScreen(tab.dataset.target));
});
startRideBtn.addEventListener("click", () => {
recordState.textContent = "进行中";
recordState.classList.remove("ended");
recordState.classList.add("running");
rideStatusText.textContent = "本次滑行记录中";
endRideBtn.disabled = false;
switchScreen("records");
showToast("已开始记录本次滑行");
});
endRideBtn.addEventListener("click", () => {
recordState.textContent = "已结束";
recordState.classList.remove("running");
recordState.classList.add("ended");
rideStatusText.textContent = "已结束,已生成 AI 复盘建议";
endRideBtn.disabled = true;
showToast("已生成 AI 复盘建议");
});
generateReviewBtn.addEventListener("click", () => {
const originalText = generateReviewBtn.querySelector("span").textContent;
generateReviewBtn.disabled = true;
generateReviewBtn.querySelector("span").textContent = "生成中...";
aiSuggestions.classList.add("loading");
window.setTimeout(() => {
reviewVersion += 1;
renderSuggestions(reviewVersion % 2 === 1 ? freshSuggestions : compactSuggestions);
aiSuggestions.classList.remove("loading");
generateReviewBtn.disabled = false;
generateReviewBtn.querySelector("span").textContent = originalText;
showToast("AI 复盘建议已更新");
}, 500);
});
saveRecordBtn.addEventListener("click", () => {
showToast("已保存到本周滑雪记录");
});
safeBtn.addEventListener("click", () => {
fallCheckText.textContent = "已记录:用户确认安全,无需进一步处理。";
showToast("已确认安全状态");
});
contactBtn.addEventListener("click", () => {
fallCheckText.textContent = "已模拟通知同行人,请保持当前位置并等待确认。";
showToast("已联系同行人");
});
docsEntryBtn.addEventListener("click", () => {
switchScreen("docs", { keepTab: true });
});
docsBackBtn.addEventListener("click", () => {
switchScreen("equipment");
});
function switchScreen(target, options = {}) {
screens.forEach((screen) => {
screen.classList.toggle("active", screen.dataset.screen === target);
});
if (!options.keepTab) {
tabs.forEach((tab) => {
tab.classList.toggle("active", tab.dataset.target === target);
});
}
scrollArea.scrollTo({ top: 0, behavior: "smooth" });
window.scrollTo({ top: 0, behavior: "smooth" });
}
function renderSuggestions(items) {
aiSuggestions.innerHTML = items.map((item) => `
<article>
<span>${escapeHtml(item.title)}</span>
<p>${escapeHtml(item.body)}</p>
</article>
`).join("");
}
function showToast(message) {
window.clearTimeout(toastTimer);
toast.textContent = message;
toast.classList.add("show");
toastTimer = window.setTimeout(() => {
toast.classList.remove("show");
}, 2200);
}
function escapeHtml(value) {
return String(value)
.replaceAll("&", "&")
.replaceAll("<", "<")
.replaceAll(">", ">")
.replaceAll('"', """)
.replaceAll("'", "'");
}