feat(HEL-76): 手机端丝滑度整改②——换页过渡与启动登录反馈
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
+40
-14
@@ -56,6 +56,17 @@
|
||||
let internalNav = 0;
|
||||
let authMode = "login";
|
||||
|
||||
const VIEW_MOTION_CLASSES = ["m-motion-fade-in", "m-motion-push-in", "m-motion-pop-in", "m-motion-boot-in"];
|
||||
|
||||
function applyViewMotion(motion) {
|
||||
const view = document.getElementById("m-view");
|
||||
VIEW_MOTION_CLASSES.forEach(function (cls) {
|
||||
view.classList.remove(cls);
|
||||
});
|
||||
void view.offsetWidth;
|
||||
view.classList.add(motion || "m-motion-fade-in");
|
||||
}
|
||||
|
||||
function currentHash() {
|
||||
let hash = window.location.hash || "";
|
||||
if (!hash || hash === "#" || hash === "#/") return DEFAULT_HASH;
|
||||
@@ -92,14 +103,14 @@
|
||||
function navigate(hash) {
|
||||
stack.push(hash);
|
||||
setHash(hash);
|
||||
render();
|
||||
render("m-motion-push-in");
|
||||
}
|
||||
|
||||
function replace(hash) {
|
||||
function replace(hash, motion) {
|
||||
if (stack.length) stack[stack.length - 1] = hash;
|
||||
else stack.push(hash);
|
||||
setHash(hash);
|
||||
render();
|
||||
render(motion);
|
||||
}
|
||||
|
||||
function resetStack(hash) {
|
||||
@@ -118,11 +129,11 @@
|
||||
if (stack.length > 1) {
|
||||
stack.pop();
|
||||
setHash(stack[stack.length - 1]);
|
||||
render();
|
||||
render("m-motion-pop-in");
|
||||
return;
|
||||
}
|
||||
const parent = parentRoute(currentRoute());
|
||||
if (parent) replace(parent);
|
||||
if (parent) replace(parent, "m-motion-pop-in");
|
||||
}
|
||||
|
||||
function switchEntry(key) {
|
||||
@@ -240,7 +251,7 @@
|
||||
'<label class="m-form-field"><span>密码</span><input id="m-auth-password" type="password" minlength="8" maxlength="128" autocomplete="current-password" required></label>',
|
||||
'<label class="m-form-field" id="m-auth-confirm-field" hidden><span>确认密码</span><input id="m-auth-confirm" type="password" minlength="8" maxlength="128" autocomplete="new-password"></label>',
|
||||
'<p class="m-auth-error" id="m-auth-error" hidden></p>',
|
||||
'<button class="m-btn-primary" id="m-auth-submit" type="submit">登录</button>',
|
||||
'<button class="m-btn-primary" id="m-auth-submit" type="submit"><span class="m-btn-spinner" aria-hidden="true" hidden></span><span class="m-btn-label">登录</span></button>',
|
||||
"</form>",
|
||||
"</div>"
|
||||
].join("");
|
||||
@@ -256,7 +267,8 @@
|
||||
document.getElementById("m-auth-confirm-field").hidden = authMode !== "register";
|
||||
document.getElementById("m-auth-confirm").required = authMode === "register";
|
||||
document.getElementById("m-auth-password").autocomplete = authMode === "register" ? "new-password" : "current-password";
|
||||
document.getElementById("m-auth-submit").textContent = authMode === "register" ? "注册并进入" : "登录";
|
||||
const submitLabel = document.querySelector("#m-auth-submit .m-btn-label");
|
||||
if (submitLabel) submitLabel.textContent = authMode === "register" ? "注册并进入" : "登录";
|
||||
document.getElementById("m-auth-error").hidden = true;
|
||||
}
|
||||
|
||||
@@ -267,18 +279,29 @@
|
||||
document.getElementById("m-auth-form").addEventListener("submit", submitAuth);
|
||||
}
|
||||
|
||||
function showAuthError(element, message) {
|
||||
element.textContent = message;
|
||||
element.classList.remove("m-motion-fade-in");
|
||||
void element.offsetWidth;
|
||||
element.classList.add("m-motion-fade-in");
|
||||
element.hidden = false;
|
||||
}
|
||||
|
||||
async function submitAuth(event) {
|
||||
event.preventDefault();
|
||||
const username = document.getElementById("m-auth-username").value.trim();
|
||||
const password = document.getElementById("m-auth-password").value;
|
||||
const errorElement = document.getElementById("m-auth-error");
|
||||
if (authMode === "register" && password !== document.getElementById("m-auth-confirm").value) {
|
||||
errorElement.textContent = "两次输入的密码不一致。";
|
||||
errorElement.hidden = false;
|
||||
showAuthError(errorElement, "两次输入的密码不一致。");
|
||||
return;
|
||||
}
|
||||
const submit = document.getElementById("m-auth-submit");
|
||||
const spinner = submit.querySelector(".m-btn-spinner");
|
||||
const label = submit.querySelector(".m-btn-label");
|
||||
submit.disabled = true;
|
||||
spinner.hidden = false;
|
||||
label.textContent = authMode === "register" ? "注册中…" : "登录中…";
|
||||
try {
|
||||
if (authMode === "register") {
|
||||
await global.MobileSession.register(username, password);
|
||||
@@ -287,10 +310,11 @@
|
||||
}
|
||||
replace(DEFAULT_HASH);
|
||||
} catch (error) {
|
||||
errorElement.textContent = error.message || "账号操作失败";
|
||||
errorElement.hidden = false;
|
||||
showAuthError(errorElement, error.message || "账号操作失败");
|
||||
} finally {
|
||||
submit.disabled = false;
|
||||
spinner.hidden = true;
|
||||
label.textContent = authMode === "register" ? "注册并进入" : "登录";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +336,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
function render(motion) {
|
||||
const route = currentRoute();
|
||||
if (route.name === "home") {
|
||||
replace(DEFAULT_HASH);
|
||||
@@ -331,6 +355,7 @@
|
||||
else if (route.name === "feature") renderFeature(route.params.join("/"));
|
||||
else if (route.name === "assistant") renderAssistant();
|
||||
else if (route.name === "auth") renderAuth();
|
||||
applyViewMotion(motion);
|
||||
}
|
||||
|
||||
function bindGlobalEvents() {
|
||||
@@ -359,10 +384,11 @@
|
||||
const hash = currentHash();
|
||||
if (stack.length > 1 && hash === stack[stack.length - 2]) {
|
||||
stack.pop();
|
||||
render("m-motion-pop-in");
|
||||
} else if (hash !== stack[stack.length - 1]) {
|
||||
stack.push(hash);
|
||||
render("m-motion-push-in");
|
||||
}
|
||||
render();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -377,7 +403,7 @@
|
||||
} else {
|
||||
stack.push(currentHash());
|
||||
}
|
||||
render();
|
||||
render("m-motion-boot-in");
|
||||
}
|
||||
|
||||
global.MobileRouter = {
|
||||
|
||||
Reference in New Issue
Block a user