diff --git a/front/src/components/ServiceMessages.vue b/front/src/components/ServiceMessages.vue index 4e53be241b04c244d977aac29157e37969801f07..a7fad93a57fb25ecb60e366b9c5c998b970ef374 100644 --- a/front/src/components/ServiceMessages.vue +++ b/front/src/components/ServiceMessages.vue @@ -1,83 +1,11 @@ <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 class="ui toast-container"> + <message v-for="message in $store.state.ui.messages" :message="message" :key="message.key"></message> <slot></slot> </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 - }) - return toDisplay.slice(0, 3) - } - }, - 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) { - return message.level || 'info' - } - }, - watch: { - messages: { - handler (v) { - if (v.length > 0 && !this.interval) { - this.setupInterval() - } - }, - deep: true - } - } -} +export default {} </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> diff --git a/front/src/components/common/Message.vue b/front/src/components/common/Message.vue index bbde16a1250fdf7d8b4c8c53128580ed8595d2b4..e837faa4e3417438fe766fba69f6bf1c37e323c1 100644 --- a/front/src/components/common/Message.vue +++ b/front/src/components/common/Message.vue @@ -1,33 +1,25 @@ <template> - <div class="ui message"> - <div class="content"> - <slot></slot> - </div> - <i class="close icon"></i> - </div> + <div></div> </template> <script> import $ from 'jquery' export default { + props: ['message'], mounted () { let self = this - $(this.$el).on('click', function () { - $(self.$el).transition('fade', 125) - }) + let params = { + context: "#app", + message: this.message.content, + showProgress: 'top', + position: "bottom right", + progressUp: true, + onRemove () { + self.$store.commit("ui/removeMessage", self.message.key) + }, + ...this.message, + } + $("body").toast(params) } } </script> -<style scoped> -.ui.message .content { - padding-right: 0.5em; - cursor: pointer; -} -.ui.message .content :first-child { - margin-top: 0; -} - -.ui.message .content :last-child { - margin-bottom: 0; -} -</style> diff --git a/front/src/main.js b/front/src/main.js index 917e105b2e6c00bfffeada17e9dca312763d6069..cea2d095ff2d1748612eed87753fce73d6aaa99f 100644 --- a/front/src/main.js +++ b/front/src/main.js @@ -117,7 +117,7 @@ axios.interceptors.response.use(function (response) { store.commit("ui/addMessage", { content: message, date: new Date(), - level: 'error', + class: 'error', }) logger.default.error('This client is rate-limited!', rateLimitStatus) } else if (error.response.status === 500) { diff --git a/front/src/semantic.js b/front/src/semantic.js index 206b59149fcc099e3c2f012b14149fe06f5ece00..279997f3d4886fd72f652996b6eb554c816eb020 100644 --- a/front/src/semantic.js +++ b/front/src/semantic.js @@ -18,6 +18,7 @@ require('fomantic-ui-css/components/site.min.js') require('fomantic-ui-css/components/state.min.js') require('fomantic-ui-css/components/sticky.min.js') // require('fomantic-ui-css/components/tab.min.js') +require('fomantic-ui-css/components/toast.min.js') require('fomantic-ui-css/components/transition.min.js') // require('fomantic-ui-css/components/video.min.js') require('fomantic-ui-css/components/visibility.min.js') diff --git a/front/src/store/ui.js b/front/src/store/ui.js index 1146e5201a3fc9d24af5cfde3d8642d6f2ca4023..195458d2fe74ad692413890d22e40fce972c6b4f 100644 --- a/front/src/store/ui.js +++ b/front/src/store/ui.js @@ -153,11 +153,21 @@ export default { state.theme = value }, addMessage (state, message) { - state.messages.push(message) + let finalMessage = { + displayTime: state.messageDisplayDuration, + key: String(new Date()), + ...message, + } + state.messages.push(finalMessage) if (state.messages.length > state.maxMessages) { state.messages.shift() } }, + removeMessage (state, key) { + state.messages = state.messages.filter((m) => { + return m.key != key + }) + }, notifications (state, {type, count}) { state.notifications[type] = count }, diff --git a/front/src/style/_main.scss b/front/src/style/_main.scss index 3ffea35286c322ba6916310fc2ee2b44358ef23c..365e1da22a5d229a143a05faf4db639b82f9825c 100644 --- a/front/src/style/_main.scss +++ b/front/src/style/_main.scss @@ -70,6 +70,7 @@ @import "~fomantic-ui-css/components/sticky.css"; @import "~fomantic-ui-css/components/tab.css"; @import "~fomantic-ui-css/components/text.css"; +@import "~fomantic-ui-css/components/toast.css"; @import "~fomantic-ui-css/components/transition.css"; @@ -108,7 +109,7 @@ html { flex-direction: column; &.has-bottom-player { padding-bottom: $bottom-player-height; - .service-messages { + .toast-container { bottom: $bottom-player-height + 1rem; } @@ -173,14 +174,6 @@ html { } } -.service-messages { - position: fixed; - bottom: 1em; - right: 1em; - > .ui.message { - box-shadow: 0px 0px 7px rgba(0, 0, 0, 0.7); - } -} .main-pusher { padding: 1.5rem 0; } diff --git a/front/tests/unit/specs/store/ui.spec.js b/front/tests/unit/specs/store/ui.spec.js deleted file mode 100644 index 2f810e064346355f7df8b2fbaec8ac9d1df1ff0e..0000000000000000000000000000000000000000 --- a/front/tests/unit/specs/store/ui.spec.js +++ /dev/null @@ -1,17 +0,0 @@ -import {expect} from 'chai' -import store from '@/store/ui' - -describe('store/ui', () => { - describe('mutations', () => { - it('addMessage', () => { - const state = {maxMessages: 100, messages: []} - store.mutations.addMessage(state, 'hello') - expect(state.messages).to.deep.equal(['hello']) - }) - it('addMessage', () => { - const state = {maxMessages: 1, messages: ['hello']} - store.mutations.addMessage(state, 'world') - expect(state.messages).to.deep.equal(['world']) - }) - }) -})