Reimplement compose and add tiling windows
This commit is contained in:
139
core/static/js/compose-panel-core.js
Normal file
139
core/static/js/compose-panel-core.js
Normal file
@@ -0,0 +1,139 @@
|
||||
(function () {
|
||||
if (window.GIAComposePanelCore) {
|
||||
return;
|
||||
}
|
||||
|
||||
const PANEL_SELECTOR = ".compose-shell[data-compose-panel='1']";
|
||||
window.giaComposePanels = window.giaComposePanels || {};
|
||||
|
||||
const collectPanels = function (root) {
|
||||
const panels = [];
|
||||
if (!root) {
|
||||
return panels;
|
||||
}
|
||||
if (root.matches && root.matches(PANEL_SELECTOR)) {
|
||||
panels.push(root);
|
||||
}
|
||||
if (root.querySelectorAll) {
|
||||
root.querySelectorAll(PANEL_SELECTOR).forEach(function (panel) {
|
||||
panels.push(panel);
|
||||
});
|
||||
}
|
||||
return panels;
|
||||
};
|
||||
|
||||
const toInt = function (value) {
|
||||
const parsed = parseInt(value || "0", 10);
|
||||
return Number.isFinite(parsed) ? parsed : 0;
|
||||
};
|
||||
|
||||
const parseJsonSafe = function (value, fallback) {
|
||||
try {
|
||||
return JSON.parse(String(value || ""));
|
||||
} catch (_err) {
|
||||
return fallback;
|
||||
}
|
||||
};
|
||||
|
||||
const createNode = function (tagName, className, text) {
|
||||
const node = document.createElement(tagName);
|
||||
if (className) {
|
||||
node.className = className;
|
||||
}
|
||||
if (text !== undefined && text !== null) {
|
||||
node.textContent = String(text);
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
const normalizeSnippet = function (value) {
|
||||
const compact = String(value || "").replace(/\s+/g, " ").trim();
|
||||
if (!compact) {
|
||||
return "(no text)";
|
||||
}
|
||||
if (compact.length <= 120) {
|
||||
return compact;
|
||||
}
|
||||
return compact.slice(0, 117).trimEnd() + "...";
|
||||
};
|
||||
|
||||
const titleCase = function (value) {
|
||||
const raw = String(value || "").trim().toLowerCase();
|
||||
if (!raw) {
|
||||
return "";
|
||||
}
|
||||
if (raw === "whatsapp") {
|
||||
return "WhatsApp";
|
||||
}
|
||||
if (raw === "xmpp") {
|
||||
return "XMPP";
|
||||
}
|
||||
return raw.charAt(0).toUpperCase() + raw.slice(1);
|
||||
};
|
||||
|
||||
const normalizeIdentifierForService = function (service, identifier) {
|
||||
const serviceKey = String(service || "").trim().toLowerCase();
|
||||
const raw = String(identifier || "").trim();
|
||||
if (serviceKey === "whatsapp" && raw.includes("@")) {
|
||||
return raw.split("@", 1)[0].trim();
|
||||
}
|
||||
return raw;
|
||||
};
|
||||
|
||||
const buildComposeUrl = function (renderMode, service, identifier, personId) {
|
||||
const serviceKey = String(service || "").trim().toLowerCase();
|
||||
const identifierValue = normalizeIdentifierForService(serviceKey, identifier);
|
||||
if (!serviceKey || !identifierValue) {
|
||||
return "";
|
||||
}
|
||||
const params = new URLSearchParams();
|
||||
params.set("service", serviceKey);
|
||||
params.set("identifier", identifierValue);
|
||||
if (personId) {
|
||||
params.set("person", String(personId || "").trim());
|
||||
}
|
||||
return (renderMode === "page" ? "/compose/page/" : "/compose/widget/")
|
||||
+ "?"
|
||||
+ params.toString();
|
||||
};
|
||||
|
||||
const parseServiceMap = function (optionNode) {
|
||||
const fallbackService = String(
|
||||
(optionNode && optionNode.dataset && optionNode.dataset.service) || ""
|
||||
).trim().toLowerCase();
|
||||
const fallbackIdentifier = String((optionNode && optionNode.value) || "").trim();
|
||||
const fallback = {};
|
||||
if (fallbackService && fallbackIdentifier) {
|
||||
fallback[fallbackService] = fallbackIdentifier;
|
||||
}
|
||||
if (!optionNode || !optionNode.dataset) {
|
||||
return fallback;
|
||||
}
|
||||
const parsed = parseJsonSafe(optionNode.dataset.serviceMap || "{}", fallback);
|
||||
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
||||
return fallback;
|
||||
}
|
||||
const normalized = {};
|
||||
Object.keys(parsed).forEach(function (key) {
|
||||
const serviceKey = String(key || "").trim().toLowerCase();
|
||||
const identifierValue = String(parsed[key] || "").trim();
|
||||
if (serviceKey && identifierValue) {
|
||||
normalized[serviceKey] = identifierValue;
|
||||
}
|
||||
});
|
||||
return Object.keys(normalized).length ? normalized : fallback;
|
||||
};
|
||||
|
||||
window.GIAComposePanelCore = {
|
||||
PANEL_SELECTOR: PANEL_SELECTOR,
|
||||
buildComposeUrl: buildComposeUrl,
|
||||
collectPanels: collectPanels,
|
||||
createNode: createNode,
|
||||
normalizeIdentifierForService: normalizeIdentifierForService,
|
||||
normalizeSnippet: normalizeSnippet,
|
||||
parseJsonSafe: parseJsonSafe,
|
||||
parseServiceMap: parseServiceMap,
|
||||
titleCase: titleCase,
|
||||
toInt: toInt,
|
||||
};
|
||||
})();
|
||||
Reference in New Issue
Block a user