Первая версия мобильного приложения

This commit is contained in:
mi
2026-08-21 17:37:12 +03:00
parent d2415fcfeb
commit c1e49fb15d
60 changed files with 14106 additions and 6 deletions
@@ -17,6 +17,8 @@ otpResendCountdown=Отправить повторно через
otpResend=Отправить код снова
authBack=Назад
verifyOtp=Подтвердить
otpVerifying=Проверяем...
otpSubmitUnavailable=Не удалось отправить код. Проверьте соединение и попробуйте ещё раз.
mockMode=Тестовый режим отправки кода
phoneInvalid=Проверьте формат номера телефона.
otpInvalid=Код неверен, истёк или уже использован.
@@ -61,12 +61,18 @@
</button>
</div>
<button id="han-otp-submit" class="han-primary-button" type="submit" disabled>
<div id="han-otp-submit-error" class="han-error han-otp-error" role="alert" hidden>
<span class="han-error-icon">!</span>
<span>${msg("otpSubmitUnavailable")}</span>
</div>
<button id="han-otp-submit" class="han-primary-button" type="submit"
data-submitting-label="${msg("otpVerifying")}" disabled>
${msg("verifyOtp")}
</button>
</form>
</div>
<script src="${url.resourcesPath}/js/han-login.js?v=5"></script>
<script src="${url.resourcesPath}/js/han-login.js?v=7"></script>
<#if captchaEnabled!false>
<script src="https://smartcaptcha.cloud.yandex.ru/captcha.js?render=onload&amp;onload=hanCaptchaOnload"
async defer></script>
@@ -56,16 +56,28 @@
function initOtpForm() {
var fields = Array.prototype.slice.call(document.querySelectorAll(".han-otp-digit"));
var form = document.getElementById("kc-otp-form");
var hidden = document.getElementById("otp");
var submit = document.getElementById("han-otp-submit");
if (!fields.length || !hidden || !submit) return;
var submitError = document.getElementById("han-otp-submit-error");
if (!fields.length || !form || !hidden || !submit) return;
var submitLabel = submit.textContent;
var submitting = false;
function submitForm() {
if (typeof form.requestSubmit === "function") {
form.requestSubmit();
return;
}
HTMLFormElement.prototype.submit.call(form);
}
function syncOtp() {
fields.forEach(function (field) {
field.classList.toggle("han-filled", Boolean(field.value));
});
hidden.value = fields.map(function (field) { return field.value; }).join("");
submit.disabled = hidden.value.length !== fields.length;
submit.disabled = submitting || hidden.value.length !== fields.length;
}
fields.forEach(function (field, index) {
@@ -106,6 +118,22 @@
});
syncOtp();
submit.addEventListener("click", function (event) {
event.preventDefault();
syncOtp();
if (submit.disabled || submitting) return;
submitting = true;
submit.disabled = true;
submit.textContent = submit.getAttribute("data-submitting-label") || submitLabel;
if (submitError) submitError.hidden = true;
submitForm();
window.setTimeout(function () {
submitting = false;
submit.textContent = submitLabel;
syncOtp();
if (submitError) submitError.hidden = false;
}, 12000);
});
var countdown = document.getElementById("han-resend-countdown");
var countdownValue = countdown && countdown.querySelector("strong");
@@ -126,9 +154,17 @@
}
updateCountdown();
if (expiresAt > Date.now()) timer = window.setInterval(updateCountdown, 1000);
resend.addEventListener("click", function () {
resend.addEventListener("click", function (event) {
if (document.getElementById("han-captcha-container")) return;
window.setTimeout(function () { resend.disabled = true; }, 0);
event.preventDefault();
resend.disabled = true;
var action = document.createElement("input");
action.type = "hidden";
action.name = "otp_action";
action.value = "resend";
form.appendChild(action);
submitForm();
window.setTimeout(function () { resend.disabled = false; }, 12000);
});
}
@@ -142,8 +178,11 @@
var widgetId = null;
var executing = false;
var pendingSubmitter = null;
var executionTimeout = null;
function showError() {
if (executionTimeout) window.clearTimeout(executionTimeout);
executionTimeout = null;
executing = false;
if (pendingSubmitter) pendingSubmitter.disabled = false;
pendingSubmitter = null;
@@ -162,6 +201,8 @@
invisible: true,
hl: "ru",
callback: function (token) {
if (executionTimeout) window.clearTimeout(executionTimeout);
executionTimeout = null;
if (!token || !pendingSubmitter) {
showError();
return;
@@ -209,6 +250,7 @@
if (pendingSubmitter) pendingSubmitter.disabled = true;
tokenInput.value = "";
try {
executionTimeout = window.setTimeout(showError, 12000);
window.smartCaptcha.execute(widgetId);
} catch (_error) {
showError();