-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
111 lines (92 loc) · 3.31 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
const qs = (selector, parent = document) => parent.querySelector(selector);
const adviceElm = qs("[data-advice]");
const adviceIdElm = qs("[data-advice-id]");
const adviceBtnElm = qs("[data-advice-generate-btn]");
const loaderElm = qs("[data-loader]");
const loaderMsgElm = qs("[data-loader-msg]");
const errorSnackbarElm = qs("[data-error-snackbar]");
const errorSnackbarMsgElm = qs("[data-error-snackbar-msg]");
const errorRetryBtnElm = qs("[data-error-retry-btn]");
const disableBtn = (disable = true, btn = adviceBtnElm) => {
btn.disabled = disable;
}
disableBtn(false);
const getRandomAdvice = async () => {
const res = await fetch("https://api.adviceslip.com/advice", { cache: "no-cache" });
const randomAdvice = await res.json();
return randomAdvice;
};
const showLoader = () => {
loaderElm.style.display = "block";
loaderMsgElm.innerText = "Loading advice..."; // for `aria-live` to work
adviceElm.classList.add("sr-only"); // not using `display: none`, cuz,
adviceIdElm.classList.add("sr-only"); // aria-live won't work (ie. screen reader won't read changing text)
};
const hideLoader = () => {
loaderElm.style.display = "none";
loaderMsgElm.innerText = "";
adviceElm.classList.remove("sr-only");
adviceIdElm.classList.remove("sr-only");
};
const hideSnackbar = () => {
errorSnackbarElm.style.transition = "opacity 0s";
errorSnackbarElm.style.opacity = "0";
errorRetryBtnElm.style.display = "none";
errorSnackbarMsgElm.innerText = "";
};
const showSnackbar = (errMsg = "An error occurred. Please try again.") => {
errorSnackbarElm.style.transition = "opacity 0.2s";
errorSnackbarElm.style.opacity = "1";
errorSnackbarMsgElm.innerText = errMsg;
errorRetryBtnElm.style.display = "inline-block";
errorRetryBtnElm.focus();
};
const setNewAdviceAnimation = (enable) => {
const root = document.documentElement;
adviceElm.classList.toggle("card-advice-anim", enable);
adviceIdElm.classList.toggle("card-advice-id-anim", enable);
adviceIdElm.style.setProperty("--txt-animation-order", 0); // to prevent delay
adviceElm.style.setProperty("--txt-animation-order", 1);
root.style.setProperty("--txt-anim-interval", "0.28s");
};
const showRandomAdvice = (initialCb, successCb, errorCb) => { // cb = callback
initialCb();
getRandomAdvice()
.then((data) => { // data validation is omitted for now
adviceElm.innerText = `“${data.slip.advice}”`;
adviceIdElm.innerText = `Advice #${data.slip.id}`;
successCb();
})
.catch((err) => {
console.error(err);
errorCb();
});
};
let runAnimation = false; // to prevent setNewAdviceAnimation from running when page is loaded
const runNewAdviceAnim = (set = true) => {
if (runAnimation === true) setNewAdviceAnimation(set);
};
const showRandomAdviceWrapper = () =>
showRandomAdvice(
() => {
showLoader();
hideSnackbar();
disableBtn();
runNewAdviceAnim(false);
},
() => {
hideLoader();
hideSnackbar();
runNewAdviceAnim();
disableBtn(false);
runAnimation = true; // `true` only after fetching the first advice
},
() => {
hideLoader();
showSnackbar();
disableBtn(false);
}
);
showRandomAdviceWrapper();
adviceBtnElm.addEventListener("click", showRandomAdviceWrapper);
errorRetryBtnElm.addEventListener("click", showRandomAdviceWrapper);