1<template>
2  <transition name="fade">
3    <b-progress
4      v-if="!isLoadingComplete"
5      :value="loadingIndicatorValue"
6      height="0.4rem"
7    />
8  </transition>
9</template>
10
11<script>
12export default {
13  data() {
14    return {
15      loadingIndicatorValue: 0,
16      isLoadingComplete: false,
17      loadingIntervalId: null,
18      timeoutId: null
19    };
20  },
21  created() {
22    this.$root.$on('loader::start', () => {
23      this.startLoadingInterval();
24    });
25    this.$root.$on('loader::end', () => {
26      this.endLoadingInterval();
27    });
28    this.$root.$on('loader::hide', () => {
29      this.hideLoadingBar();
30    });
31  },
32  methods: {
33    startLoadingInterval() {
34      this.clearLoadingInterval();
35      this.clearTimeout();
36      this.loadingIndicatorValue = 0;
37      this.isLoadingComplete = false;
38      this.loadingIntervalId = setInterval(() => {
39        this.loadingIndicatorValue += 1;
40        if (this.loadingIndicatorValue > 100) this.clearLoadingInterval();
41      }, 100);
42    },
43    endLoadingInterval() {
44      this.clearLoadingInterval();
45      this.clearTimeout();
46      this.loadingIndicatorValue = 100;
47      this.timeoutId = setTimeout(() => {
48        // Let animation complete before hiding
49        // the loading bar
50        this.isLoadingComplete = true;
51      }, 1000);
52    },
53    hideLoadingBar() {
54      this.clearLoadingInterval();
55      this.clearTimeout();
56      this.loadingIndicatorValue = 0;
57      this.isLoadingComplete = true;
58    },
59    clearLoadingInterval() {
60      if (this.loadingIntervalId) clearInterval(this.loadingIntervalId);
61      this.loadingIntervalId = null;
62    },
63    clearTimeout() {
64      if (this.timeoutId) clearTimeout(this.timeoutId);
65      this.timeoutId = null;
66    }
67  }
68};
69</script>
70
71<style lang="scss" scoped>
72.progress {
73  position: absolute;
74  left: 0;
75  right: 0;
76  bottom: -0.4rem;
77  opacity: 1;
78  transition: opacity $duration--moderate-01 $standard-easing--productive;
79
80  &.fade-enter,
81  &.fade-leave-to {
82    opacity: 0;
83  }
84}
85</style>
86