UNPKG

@acrsolutions/chat-components

Version:

Un set di componenti per la creazione di un'applicazione di messaggistica

197 lines (196 loc) 8 kB
import { always, filter, map, pipe } from 'lodash/fp'; import { getTypedObjectKeys, includesIgnoreCase } from './utils'; /** * * @param templateSegments : array di stringhe, dove gli elementi sono i segnaposto delle variabili {{1}}, {{2}} e le stringhe di testo * @param templateInsertedValues : oggetto con le chiavi dei segnaposto e i valori delle variabili {1: 'ciao'} * @returns una stringa con il testo del template, con i segnaposto sostituiti dai valori delle variabili */ export function reconstructTemplateText(templateSegments, templateInsertedValues) { const text = templateSegments.map((segment) => { //isola le stringhe con i segnaposto {{1}}, {{2}} const match = segment.match(/{{(\d+)}}/); //recupera l'id del segnaposto (esempio {{1}} --> 1) e lo usa per recuperare il valore delle variabili const placeholderId = match ? match[1] : 0; const text = templateInsertedValues[placeholderId] ? templateInsertedValues[placeholderId] : segment; return text; }); //ricompone il testo del template con i segnaposto sostituiti dai valori delle variabili return text.join(''); } /** * * @param text : il testo del template base, con i segnaposto {{1}}, {{2}} dove l'utente inserisce le variabili * @returns lo stesso testo diviso in un array di stringhe, dove gli elementi sono i segnaposto e le stringhe di testo */ export function toSplittedTemplatePlaceholders(text) { return text.split(/(\{\{\d+\}\})/g); } /** * * @param variablesFromUser : array di oggetti con le chiavi key e value, dove key è il nome della variabile e value è il valore della variabile * @returns oggetto con le chiavi 1, 2, 3... e i valori delle variabili * Rende compatibile il template e le variabili inserite dall'utente */ export function getTemplateInsertedValues(variablesFromUser) { const acc = {}; variablesFromUser.forEach((variable, i) => { acc[i + 1] = variable.value; }); return acc; } /** * @param templateText il testo del template base, con i segnaposto {{1}}, {{2}} dove l'utente inserisce le variabili * @param templateSectionKey la chiave della sezione del template, ad esempio BUTTONS, TEXT, ecc. * E' la chiave con cui vengono salvati i valori delle variabili. * @param variablesFromMessage array di oggetti con le chiavi key e value. * Se valorizzato: ci si trova in un messaggio di tipo template * @param values oggetto con le chiavi sectionkey_1, sectionkey_2... e i valori delle variabili. * Se valorizzato: si sta creando un template nuovo. * @description Questa funzione costruisce il testo del template con le variabili inserite dall'utente. * Può prendere i valori delle variabili in forma di oggetto oppure in forma di array di oggetti. * Questo perchè la preview in un invio di nuovo messaggio template riceve le variabili in forma differente * dalla preview di un messaggio template nella conversazione. * @returns il testo completo del template con le variabili inserite dall'utente */ export function buildTemplateTextWithInsertedValues({ templateText, templateSectionKey, variablesFromMessage, values, }) { // Se non ci sono valori e non ci sono variabili dal messaggio, restituisci una stringa vuota if (!values && !variablesFromMessage) return ''; const segments = toSplittedTemplatePlaceholders(templateText); const filteredValues = pipe( //sempre: un array di chiavi tipizzate, composte da templateType_1, templateType_2, ecc. always(getTypedObjectKeys(values ?? {})), //ignora tutte quelle che non hanno la chiave sezione template corretta filter((key) => includesIgnoreCase(templateSectionKey, key.toString())), map((key) => { const value = values?.[key] ?? ''; //se la chiave è BUTTONS, l'ultima parte della chiave è il numero del segnaposto const lastKeyPart = templateSectionKey === 'BUTTONS' ? key.toString().split('_').pop() : null; const index = lastKeyPart ?? key.toString().split('_')[1]; return { [index]: value }; }))(); const obj = Object.assign({}, ...filteredValues); //se non ci sono variabili dal messaggio, usa i valori filtrati const filteredVariables = variablesFromMessage?.filter((v) => v.key.includes(templateSectionKey)); const insertedValues = filteredVariables ? getTemplateInsertedValues(filteredVariables) : obj ?? {}; return reconstructTemplateText(segments, insertedValues); } export const extractFileDataFromFile = async (file) => { const readFileAsBase64 = (file) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { if (e.target?.result) { const base64String = e.target.result; resolve(base64String); // resolve(e.target.result as ArrayBuffer); } else { resolve(null); return; } }; reader.onerror = reject; reader.readAsDataURL(file); }); }; const base64 = await readFileAsBase64(file); // Legge il file e lo converte in Base64 const base64String = base64?.split(',')[1] ?? null; if (!base64String) return null; return { fileBytes: base64String, fileName: file.name, }; }; export function getUserInitials(userFullName) { if (!userFullName.includes(' ')) return userFullName[0]; const user = userFullName.split(' '); const userName = user?.[0] ?? ''; const userSurname = user?.[1] ?? ''; const initials = userName[0] + userSurname[0]; return initials; } /** * * @param sentDate data di invio del messaggio in formato ISOstring: YYYY-MM-DDTHH:mm:ss.sssZ * @returns La data in formato "ieri", "giorno della settimana" o "giorno mese anno" */ export function buildPreviewDate(sentDate) { const now = Date.now(); const sendDate = new Date(sentDate).getTime(); const oneDay = 24 * 60 * 60 * 1000; const twoDays = 2 * oneDay; const oneWeek = 7 * oneDay; // Tra 24 e 48 ore fa → "ieri" if (now - oneDay > sendDate && now - twoDays < sendDate) { return 'ieri'; } // Tra 48 ore fa e 1 settimana fa → Giorno della settimana if (now - twoDays > sendDate && now - oneWeek < sendDate) { const days = [ 'domenica', 'lunedì', 'martedì', 'mercoledì', 'giovedì', 'venerdì', 'sabato', ]; return days[new Date(sendDate).getDay()]; } // Più di una settimana fa → "giorno + mese" (es. 21 Feb) if (now - oneWeek > sendDate) { const dateObj = new Date(sendDate); const day = dateObj.getDate(); const months = [ 'Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic', ]; const month = months[dateObj.getMonth()]; const year = dateObj.getFullYear(); return `${day} ${month} ${year}`; } // Meno di 24 ore fa → Ora in formato HH:mm return sentDate.split('T')[1].slice(0, 5); } export function buildSentDate(sentDate) { const months = [ 'Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic', ]; const sentDateAsDate = new Date(sentDate); // Estrarre giorno, mese e anno const day = sentDateAsDate.getDate(); const month = months[sentDateAsDate.getMonth()]; // Converti il mese in formato abbreviato const year = sentDateAsDate.getFullYear(); // Costruire il formato desiderato return `${day} ${month} ${year}`; }