feat: Enhance FaceAI functionality with storage management and update deployment instructions
All checks were successful
Publish FaceAI Container / publish (push) Successful in 5m45s
All checks were successful
Publish FaceAI Container / publish (push) Successful in 5m45s
This commit is contained in:
parent
c0d072c6ea
commit
23f811e465
14 changed files with 500 additions and 22 deletions
|
|
@ -228,6 +228,197 @@ function clearFaceAiErrorState() {
|
|||
window.history.replaceState({}, document.title, cleanUrl.pathname + cleanUrl.search + cleanUrl.hash);
|
||||
}
|
||||
|
||||
function getFaceAiMatchStorageEntryKey(storageKey) {
|
||||
return "faceai-match-state:" + String(storageKey || "").trim();
|
||||
}
|
||||
|
||||
function getFaceAiPendingMatchEntryKey() {
|
||||
return "faceai-pending-match-state";
|
||||
}
|
||||
|
||||
function getFaceAiPathForComparison(value) {
|
||||
if (!value) {
|
||||
return "";
|
||||
}
|
||||
|
||||
try {
|
||||
return decodeURIComponent(String(value));
|
||||
} catch (error) {
|
||||
return String(value);
|
||||
}
|
||||
}
|
||||
|
||||
function getFaceAiCurrentRaceId() {
|
||||
return String($("#id_gara").val() || "").trim();
|
||||
}
|
||||
|
||||
function isFaceAiStoredPayloadFresh(storedAt, maxAgeMs) {
|
||||
var timestamp = Date.parse(String(storedAt || ""));
|
||||
|
||||
if (!timestamp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (Date.now() - timestamp) <= maxAgeMs;
|
||||
}
|
||||
|
||||
function canUseFaceAiWebStorage(storage) {
|
||||
var testKey = "__faceai_storage_test__";
|
||||
|
||||
if (!storage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
storage.setItem(testKey, "1");
|
||||
storage.removeItem(testKey);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function readFaceAiStoredMatchPayload(storageKey) {
|
||||
var entryKey = getFaceAiMatchStorageEntryKey(storageKey);
|
||||
var rawPayload = "";
|
||||
var windowNamePayload;
|
||||
|
||||
if (!storageKey) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (canUseFaceAiWebStorage(window.sessionStorage)) {
|
||||
rawPayload = window.sessionStorage.getItem(entryKey) || "";
|
||||
}
|
||||
|
||||
if (!rawPayload && canUseFaceAiWebStorage(window.localStorage)) {
|
||||
rawPayload = window.localStorage.getItem(entryKey) || "";
|
||||
}
|
||||
|
||||
if (!rawPayload && window.name) {
|
||||
try {
|
||||
windowNamePayload = JSON.parse(window.name);
|
||||
if (windowNamePayload && windowNamePayload.faceAiStorageKey === storageKey && windowNamePayload.faceAiMatchState) {
|
||||
rawPayload = JSON.stringify(windowNamePayload.faceAiMatchState);
|
||||
}
|
||||
} catch (error) {
|
||||
rawPayload = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (!rawPayload) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.parse(rawPayload);
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function readFaceAiPendingMatchPayload() {
|
||||
var entryKey = getFaceAiPendingMatchEntryKey();
|
||||
var rawPayload = "";
|
||||
var parsedPayload = null;
|
||||
var windowNamePayload;
|
||||
var currentPath = getFaceAiPathForComparison(window.location.pathname || "");
|
||||
var currentRaceId = getFaceAiCurrentRaceId();
|
||||
|
||||
if (canUseFaceAiWebStorage(window.sessionStorage)) {
|
||||
rawPayload = window.sessionStorage.getItem(entryKey) || "";
|
||||
}
|
||||
|
||||
if (!rawPayload && canUseFaceAiWebStorage(window.localStorage)) {
|
||||
rawPayload = window.localStorage.getItem(entryKey) || "";
|
||||
}
|
||||
|
||||
if (!rawPayload && window.name) {
|
||||
try {
|
||||
windowNamePayload = JSON.parse(window.name);
|
||||
if (windowNamePayload && windowNamePayload.faceAiPendingMatchState) {
|
||||
rawPayload = JSON.stringify(windowNamePayload.faceAiPendingMatchState);
|
||||
}
|
||||
} catch (error) {
|
||||
rawPayload = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (!rawPayload) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
parsedPayload = JSON.parse(rawPayload);
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!parsedPayload || !parsedPayload.payload || !parsedPayload.payload.photoIds || !parsedPayload.payload.photoIds.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isFaceAiStoredPayloadFresh(parsedPayload.payload.storedAt, 15 * 60 * 1000)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (String(parsedPayload.raceId || "").trim() && currentRaceId && String(parsedPayload.raceId || "").trim() !== currentRaceId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!String(parsedPayload.raceId || "").trim() && getFaceAiPathForComparison(parsedPayload.targetPath || "") !== currentPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parsedPayload;
|
||||
}
|
||||
|
||||
function clearFaceAiStoredMatchPayload(storageKey) {
|
||||
var entryKey = getFaceAiMatchStorageEntryKey(storageKey);
|
||||
var pendingEntryKey = getFaceAiPendingMatchEntryKey();
|
||||
var windowNamePayload;
|
||||
var pendingPayload = readFaceAiPendingMatchPayload();
|
||||
|
||||
if (!storageKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (canUseFaceAiWebStorage(window.sessionStorage)) {
|
||||
window.sessionStorage.removeItem(entryKey);
|
||||
}
|
||||
|
||||
if (canUseFaceAiWebStorage(window.localStorage)) {
|
||||
window.localStorage.removeItem(entryKey);
|
||||
if (pendingPayload && pendingPayload.storageKey === storageKey) {
|
||||
window.localStorage.removeItem(pendingEntryKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (canUseFaceAiWebStorage(window.sessionStorage) && pendingPayload && pendingPayload.storageKey === storageKey) {
|
||||
window.sessionStorage.removeItem(pendingEntryKey);
|
||||
}
|
||||
|
||||
if (!window.name) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
windowNamePayload = JSON.parse(window.name);
|
||||
if (windowNamePayload && windowNamePayload.faceAiStorageKey === storageKey) {
|
||||
delete windowNamePayload.faceAiStorageKey;
|
||||
delete windowNamePayload.faceAiMatchState;
|
||||
}
|
||||
if (windowNamePayload && windowNamePayload.faceAiPendingMatchState && windowNamePayload.faceAiPendingMatchState.storageKey === storageKey) {
|
||||
delete windowNamePayload.faceAiPendingMatchState;
|
||||
}
|
||||
if (!windowNamePayload || !Object.keys(windowNamePayload).length) {
|
||||
window.name = "";
|
||||
} else {
|
||||
window.name = JSON.stringify(windowNamePayload);
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
function showFaceAiErrorModal(title, message) {
|
||||
var modal = $("#faceAiErrorModal");
|
||||
|
||||
|
|
@ -266,6 +457,7 @@ function stripFaceAiStateFromUrl(url) {
|
|||
cleanUrl.searchParams.delete("faceaiMatchSource");
|
||||
cleanUrl.searchParams.delete("faceaiMatchCount");
|
||||
cleanUrl.searchParams.delete("faceaiPhotoIds");
|
||||
cleanUrl.searchParams.delete("faceaiMatchStorageKey");
|
||||
return cleanUrl.toString();
|
||||
} catch (error) {
|
||||
return url || fallbackUrl;
|
||||
|
|
@ -279,6 +471,26 @@ function getFaceAiMatchState() {
|
|||
|
||||
var params = new URLSearchParams(window.location.search || "");
|
||||
var rawIds = params.get("faceaiPhotoIds") || "";
|
||||
var storageKey = String(params.get("faceaiMatchStorageKey") || "").trim();
|
||||
var storedPayload = null;
|
||||
var pendingPayload = null;
|
||||
|
||||
if (!rawIds && storageKey) {
|
||||
storedPayload = readFaceAiStoredMatchPayload(storageKey);
|
||||
if (storedPayload && storedPayload.photoIds && storedPayload.photoIds.length) {
|
||||
rawIds = storedPayload.photoIds.join(",");
|
||||
}
|
||||
}
|
||||
|
||||
if (!rawIds) {
|
||||
pendingPayload = readFaceAiPendingMatchPayload();
|
||||
if (pendingPayload && pendingPayload.payload && pendingPayload.payload.photoIds && pendingPayload.payload.photoIds.length) {
|
||||
rawIds = pendingPayload.payload.photoIds.join(",");
|
||||
storageKey = storageKey || String(pendingPayload.storageKey || "").trim();
|
||||
storedPayload = storedPayload || pendingPayload.payload;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rawIds) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -303,7 +515,8 @@ function getFaceAiMatchState() {
|
|||
return {
|
||||
photoIds: photoIds,
|
||||
photoIdSet: photoIdSet,
|
||||
matchCount: isNaN(parsedCount) ? photoIds.length : parsedCount,
|
||||
matchCount: isNaN(parsedCount) ? ((storedPayload && storedPayload.matchCount) ? storedPayload.matchCount : photoIds.length) : parsedCount,
|
||||
storageKey: storageKey,
|
||||
clearUrl: stripFaceAiStateFromUrl(window.location.href)
|
||||
};
|
||||
}
|
||||
|
|
@ -499,12 +712,17 @@ function renderFaceAiLegacyBanner(state) {
|
|||
}
|
||||
|
||||
banner = $("#faceAiFilterBanner");
|
||||
$(document).off("click.faceAiClearFilter", "#faceAiClearFilterButton");
|
||||
$(document).on("click.faceAiClearFilter", "#faceAiClearFilterButton", function() {
|
||||
window.location.href = state.clearUrl;
|
||||
});
|
||||
}
|
||||
|
||||
$(document).off("click.faceAiClearFilter", "#faceAiClearFilterButton");
|
||||
$(document).on("click.faceAiClearFilter", "#faceAiClearFilterButton", function() {
|
||||
var activeState = window.faceAiMatchState || state;
|
||||
if (activeState && activeState.storageKey) {
|
||||
clearFaceAiStoredMatchPayload(activeState.storageKey);
|
||||
}
|
||||
window.location.href = activeState && activeState.clearUrl ? activeState.clearUrl : state.clearUrl;
|
||||
});
|
||||
|
||||
$("#faceAiFilterBannerTitle").text(copy.bannerTitle);
|
||||
$("#faceAiFilterBannerText").html(message);
|
||||
$("#faceAiClearFilterButton").text(copy.clearText);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue