ServiceMessages.vue 1.62 KB
Newer Older
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
<template>
  <div class="service-messages">
    <message v-for="message in displayedMessages" :key="String(message.date)" :class="['large', getLevel(message)]">
      <p>{{ message.content }}</p>
    </message>
  </div>
</template>

<script>
import {mapState} from 'vuex'

export default {
  data () {
    return {
      date: new Date(),
      interval: null
    }
  },
  created () {
    this.setupInterval()
  },
  destroyed () {
    if (this.interval) {
      clearInterval(this.interval)
    }
  },
  computed: {
    ...mapState({
      messages: state => state.ui.messages,
      displayDuration: state => state.ui.messageDisplayDuration
    }),
    displayedMessages () {
      let now = this.date
      let interval = this.displayDuration
      let toDisplay = this.messages.filter(m => {
        return now - m.date <= interval
      })
38
      return toDisplay.slice(0, 3)
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
    }
  },
  methods: {
    setupInterval () {
      if (this.interval) {
        return
      }
      let self = this
      this.interval = setInterval(() => {
        if (self.displayedMessages.length === 0) {
          clearInterval(self.interval)
          this.interval = null
        }
        self.date = new Date()
      }, 1000)
    },
    getLevel (message) {
56
      return message.level || 'info'
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
    }
  },
  watch: {
    messages: {
      handler (v) {
        if (v.length > 0 && !this.interval) {
          this.setupInterval()
        }
      },
      deep: true
    }
  }
}
</script>

<style>
.service-messages {
  z-index: 9999;
  margin-left: 1em;
  min-width: 20em;
  max-width: 40em;
}
.service-messages .message:last-child {
  margin-bottom: 0;
}
</style>