PageSourceSearch

https://auto-therapy.web.app/js/Utils.js

js auto-therapy.web.app collected 2026-10-03 12:17:21 UTC 10,855 bytes, 409 lines download raw bytes

1// Firebase
2const firebaseConfig = {
3  apiKey: "AIzaSyDbwiKT2tKrAGgH9RI6l57Uq982HgJGG38",
4  authDomain: "auto-therapy.firebaseapp.com",
5  databaseURL: "https://auto-therapy.firebaseio.com",
6  projectId: "auto-therapy",
7  storageBucket: "auto-therapy.appspot.com",
8  messagingSenderId: "708209119869",
9  appId: "1:708209119869:web:d035c0c9e9b2c61f8d5714",
10  measurementId: "G-LZM03NR12Y",
11};
12
13firebase.initializeApp(firebaseConfig);
14
15// analytics
16firebase.analytics();
17
18// Utiliser le cache
19firebase
20  .firestore()
21  .enablePersistence()
22  .catch((err) => {});
23
24// Cloud messaging
25// async function requestPermission() {
26//   const permission = await Notification.requestPermission();
27//   if (permission === "granted") {
28//   } else {
29//   }
30// }
31
32// try {
33//   firebase.auth().onAuthStateChanged((user) => {
34//     if (user) {
35//       const messaging = firebase.messaging();
36//       messaging.usePublicVapidKey(
37//         "BOpU1z4m0xhNcVTBI_pV8ibkFnEHAMEMeYe4gBeTw_475IyJhYV2X3A_O1_Vo-rtR2xP1xWEZveirHqgi_hbJ1k"
38//       );
39
40//       messaging
41//         .getToken()
42//         .then((currentToken) => {
43//           if (currentToken) {
44//             // sendTokenToServer(currentToken);
45//             // updateUIForPushEnabled(currentToken);
46//             console.log("currentToken", currentToken);
47//           } else {
48//             // Show permission request.
49//             console.log("No Instance ID token available. Request permission to generate one.");
50//             // Show permission UI.
51//             // updateUIForPushPermissionRequired();
52//             // setTokenSentToServer(false);
53//             requestPermission();
54//           }
55//         })
56//         .catch((err) => {
57//           console.log("An error occurred while retrieving token. ", err);
58//           // showToken("Error retrieving Instance ID token. ", err);
59//           // setTokenSentToServer(false);
60//         });
61
62//       messaging.onTokenRefresh(() => {
63//         messaging
64//           .getToken()
65//           .then((refreshedToken) => {
66//             console.log("Token refreshed.");
67//             // Indicate that the new Instance ID token has not yet been sent to the
68//             // app server.
69//             // setTokenSentToServer(false);
70//             // Send Instance ID token to app server.
71//             // sendTokenToServer(refreshedToken);
72//             console.log("refreshedToken", refreshedToken);
73//           })
74//           .catch((err) => {
75//             console.log("Unable to retrieve refreshed token ", err);
76//             // showToken("Unable to retrieve refreshed token ", err);
77//           });
78//       });
79//     }
80//   });
81// } catch (e) {}
82
83/**
84 * Check if serviceWorker
85 */
86if ("serviceWorker" in navigator) {
87  navigator.serviceWorker.register("service-worker.js").then((reg) => {});
88}
89
90document.addEventListener("DOMContentLoaded", () => {
91  loadInstallPromotion();
92
93  document.querySelector(".menu-button").addEventListener("click", (e) => toggleMenu());
94
95  toggleHeader();
96});
97
98/**
99 * PWA install
100 */
101function loadInstallPromotion() {
102  window.addEventListener("appinstalled", (event) => {});
103
104  let deferredPrompt;
105  window.addEventListener("beforeinstallprompt", (e) => {
106    e.preventDefault();
107    deferredPrompt = e;
108    showInstallPromotion();
109  });
110
111  try {
112    document.getElementById("install-button").addEventListener("click", () => {
113      const promptEvent = deferredPrompt;
114
115      if (!promptEvent) {
116        return;
117      }
118      promptEvent.prompt();
119
120      promptEvent.userChoice.then((result) => {
121        window.deferredPrompt = null;
122        hideInstallPromotion();
123      });
124    });
125  } catch (e) {}
126}
127
128export function showInstallPromotion() {
129  try {
130    document.querySelector(".install-app").classList.toggle("hidden", false);
131  } catch (e) {}
132}
133
134export function hideInstallPromotion() {
135  try {
136    document.querySelector(".install-app").classList.toggle("hidden", true);
137  } catch (e) {}
138}
139
140/**
141 * Check if the user is connected
142 */
143export function checkUserConnected() {
144  greeting();
145
146  firebase.auth().onAuthStateChanged((user) => {
147    if (!user) {
148      showNotification(
149        "<p class='center'>Vous n'êtes pas connecté</p>",
150        "Connexion",
151        () => (window.location.href = "#!login")
152      );
153    } else {
154      let userName = document.getElementById("username");
155      if (userName) {
156        userName.innerHTML = user.displayName;
157      }
158    }
159  });
160}
161
162/**
163 * Sign out user
164 */
165export function signOut() {
166  firebase
167    .auth()
168    .signOut()
169    .then(function () {
170      window.location.href = "./fr/";
171      showNotification(
172        `<p class="center">Vous êtes maintenant déconnecté</p>`,
173        "Ok",
174        () => (window.location.href = "./fr/")
175      );
176    })
177    .catch(function (error) {
178      // An error happened.
179    });
180}
181
182/**
183 * Personalise la formule de salutation
184 */
185export function greeting() {
186  let greeting = document.getElementById("greeting");
187
188  if (greeting) {
189    let heures = new Date().getHours();
190    let formule = "Bonjour";
191
192    if (heures < 18) {
193      formule = "Bonjour";
194    } else {
195      formule = "Bonsoir";
196    }
197
198    greeting.innerHTML = formule;
199  }
200}
201
202/**
203 * Notification
204 * @param {HTMLElement} message
205 * @param {String} buttonLabel
206 * @param {CallableFunction} callback
207 */
208export function showNotification(message, buttonLabel = "Fermer", callback) {
209  let bg = document.querySelector(".modal-bg");
210  let modal = document.querySelector(".modal-notification");
211  let btn = modal.querySelector(".btn-modal");
212
213  [bg, modal].map((element) => element.classList.remove("hidden"));
214
215  modal.querySelector(".modal-content").innerHTML = message;
216
217  btn.innerHTML = buttonLabel;
218
219  document.body.classList.add("noscroll");
220
221  btn.addEventListener("click", (e) => {
222    [bg, modal].map((element) => element.classList.add("hidden"));
223
224    document.body.classList.remove("noscroll");
225
226    callback();
227  });
228}
229
230/**
231 * Import le modèle
232 * @param {String} id
233 */
234export function page(id) {
235  const file = "templates/" + id + ".html";
236  const req = new XMLHttpRequest();
237  req.open("GET", file, false);
238  req.send();
239
240  document.getElementById("page").innerHTML = req.responseText;
241}
242
243/**
244 * Affiche/cache le menu
245 */
246export function toggleMenu() {
247  const menu = document.getElementById("menu");
248  menu.classList.toggle("show");
249  document.body.classList.toggle("noscroll");
250
251  menu.querySelectorAll("li a").forEach((element) => element.addEventListener("click", (e) => toggleMenu()));
252
253  menu.addEventListener("swiped-left", (e) => toggleMenu());
254
255  return false;
256}
257
258/**
259 * Help modal
260 * @param {URL} URL
261 */
262export function showHelp(URL) {
263  let bg = document.querySelector(".modal-bg");
264  let modal = document.querySelector(".modal-help");
265
266  document.querySelectorAll("[data-help]").forEach((element) => {
267    element.addEventListener("click", (e) => {
268      modal.querySelector("#help-frame").src = URL + "#" + element.dataset.help;
269
270      [bg, modal].map((element) => element.classList.remove("hidden"));
271
272      document.body.classList.add("noscroll");
273    });
274  });
275
276  modal.querySelector(".btn-modal").addEventListener("click", (e) => {
277    [bg, modal].map((element) => element.classList.add("hidden"));
278    document.body.classList.remove("noscroll");
279  });
280}
281
282/**
283 * Libère le focus
284 */
285export function blurTextarea() {
286  document.querySelectorAll("textarea, input").forEach((element) => element.blur());
287}
288
289/**
290 * Autoreize textarea with data-autoresize
291 */
292export function autoResizeTextarea() {
293  document.querySelectorAll("[data-autoresize]").forEach((element) => {
294    element.style.boxSizing = "border-box";
295    let offset = element.offsetHeight - element.clientHeight;
296    element.addEventListener("input", (event) => {
297      event.target.style.height = "auto";
298      event.target.style.height = event.target.scrollHeight + offset + "px";
299    });
300
301    element.addEventListener("focus", (event) => {
302      event.target.style.height = "auto";
303      event.target.style.height = event.target.scrollHeight + offset + "px";
304    });
305
306    element.removeAttribute("data-autoresize");
307  });
308}
309
310/**
311 * Masque/affiche le menu
312 */
313export function toggleHeader() {
314  // console.log("toggleHeader");
315  const hash = window.location.hash;
316
317  try {
318    const header = document.querySelector(".header");
319    const install = document.querySelector(".install-app");
320    const body = document.body;
321
322    header.style.visibility = "hidden";
323    install.style.visibility = "hidden";
324    body.classList.add("no-background");
325
326    if (hash !== "#!login" && hash !== "#!login/retrieve" && hash !== "#!register" && hash !== "#!coherence/create") {
327      header.style.visibility = "visible";
328      install.style.visibility = "visible";
329      body.classList.remove("no-background");
330    }
331  } catch (e) {}
332
333  window.addEventListener("hashchange", () => toggleHeader(), { once: true });
334}
335
336/**
337 * Trace le graphique
338 *
339 * @param {Array} arrLabels
340 * @param {Array} arrScores
341 */
342export function drawChart(arrLabels, arrScores) {
343  try {
344    const ctx = document.getElementById("progression").getContext("2d");
345
346    // Chart.defaults.scale.gridLines.display = false;
347
348    const chart = new Chart(ctx, {
349      type: "line",
350
351      // The data for our dataset
352      data: {
353        labels: arrLabels,
354        datasets: [
355          {
356            label: "Score",
357            backgroundColor: "rgba(255, 99, 132, .5)", // "rgb(243, 156, 203)"
358            borderColor: "rgb(255, 99, 132)",
359            data: arrScores,
360          },
361        ],
362      },
363
364      options: {
365        responsive: true,
366        maintainAspectRatio: true,
367        legend: {
368          display: false,
369        },
370        scales: {
371          xAxes: [
372            {
373              display: false,
374            },
375          ],
376          yAxes: [
377            {
378              display: false,
379              ticks: {
380                beginAtZero: true,
381                max: 70,
382              },
383            },
384          ],
385        },
386      },
387    });
388  } catch (e) {}
389}
390
391/**
392 * Number days in current month
393 */
394export function daysInThisMonth() {
395  var now = new Date();
396  return new Date(now.getFullYear(), now.getMonth() + 1, 0).getDate();
397}
398
399/**
400 * Shuffle array
401 * @param {Array} a
402 */
403export function shuffle(a) {
404  for (let i = a.length - 1; i > 0; i--) {
405    const j = Math.floor(Math.random() * (i + 1));
406    [a[i], a[j]] = [a[j], a[i]];
407  }
408  return a;
409}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.