diff --git a/src/renderer/App.js b/src/renderer/App.js index 4930836f..f7d45d8f 100644 --- a/src/renderer/App.js +++ b/src/renderer/App.js @@ -1,6 +1,7 @@ import Vue from 'vue' import TopNav from './components/top-nav/top-nav.vue' import SideNav from './components/side-nav/side-nav.vue' +import FtToast from './components/ft-toast/ft-toast.vue' import $ from 'jquery' let useElectron @@ -18,7 +19,8 @@ export default Vue.extend({ name: 'App', components: { TopNav, - SideNav + SideNav, + FtToast, }, computed: { isOpen: function () { diff --git a/src/renderer/App.vue b/src/renderer/App.vue index 187e4b0d..2bb16c04 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -14,6 +14,7 @@ /> + diff --git a/src/renderer/components/ft-share-button/ft-share-button.js b/src/renderer/components/ft-share-button/ft-share-button.js index ac9799c0..8da6f680 100644 --- a/src/renderer/components/ft-share-button/ft-share-button.js +++ b/src/renderer/components/ft-share-button/ft-share-button.js @@ -2,6 +2,7 @@ import Vue from 'vue' import FtIconButton from '../ft-icon-button/ft-icon-button.vue' import FtButton from '../ft-button/ft-button.vue' +import { mapActions } from 'vuex' export default Vue.extend({ name: 'FtShareButton', @@ -59,6 +60,7 @@ export default Vue.extend({ }, copyInvidious() { + this.showToast('Invidious URL copied to clipboard') this.copy(this.invidiousURL) this.$refs.iconButton.toggleDropdown() }, @@ -69,6 +71,7 @@ export default Vue.extend({ }, copyYoutube() { + this.showToast('YouTube URL copied to clipboard') this.copy(this.youtubeURL) this.$refs.iconButton.toggleDropdown() }, @@ -79,6 +82,7 @@ export default Vue.extend({ }, copyYoutubeEmbed() { + this.showToast('YouTube Embed URL copied to clipboard') this.copy(this.youtubeEmbedURL) this.$refs.iconButton.toggleDropdown() }, @@ -89,8 +93,13 @@ export default Vue.extend({ }, copyInvidiousEmbed() { + this.showToast('Invidious Embed URL copied to clipboard') this.copy(this.invidiousEmbedURL) this.$refs.iconButton.toggleDropdown() }, + + ...mapActions([ + 'showToast' + ]) } }) diff --git a/src/renderer/components/ft-toast/ft-toast-events.js b/src/renderer/components/ft-toast/ft-toast-events.js new file mode 100644 index 00000000..c32b0e13 --- /dev/null +++ b/src/renderer/components/ft-toast/ft-toast-events.js @@ -0,0 +1,4 @@ +import Vue from 'vue' + +const events = new Vue() +export default events diff --git a/src/renderer/components/ft-toast/ft-toast.css b/src/renderer/components/ft-toast/ft-toast.css new file mode 100644 index 00000000..79ce9f80 --- /dev/null +++ b/src/renderer/components/ft-toast/ft-toast.css @@ -0,0 +1,37 @@ +.toast-holder { + position: fixed; + left: 50vw; + transform: translate(-50%, 0); + bottom: 50px; + z-index: 1; + display: flex; + flex-direction: column; + align-items: center; +} + +.toast { + padding: 10px; + margin: 5px; + overflow-y: auto; + background-color: rgba(0, 0, 0, 0.7); + color: white; + opacity: 0; + border-radius: 20px; + cursor: pointer; +} + +.message { + margin: auto; +} + +.open { + visibility: visible; + opacity: 1; + transition: visibility 0s linear 0s, opacity 300ms; +} + +.closed { + visibility: hidden; + opacity: 0; + transition: visibility 0s linear 300ms, opacity 300ms; +} diff --git a/src/renderer/components/ft-toast/ft-toast.js b/src/renderer/components/ft-toast/ft-toast.js new file mode 100644 index 00000000..79a49c50 --- /dev/null +++ b/src/renderer/components/ft-toast/ft-toast.js @@ -0,0 +1,42 @@ +import Vue from 'vue' +import FtToastEvents from './ft-toast-events.js' + +export default Vue.extend({ + name: 'FtToast', + data: function () { + return { + toasts: [], + } + }, + mounted: function () { + FtToastEvents.$on('toast.open', this.open) + }, + beforeDestroy: function () { + FtToastEvents.$off('toast.open', this.open) + }, + methods: { + performAction: function (index) { + this.toasts[index].action() + this.remove(index) + }, + close: function (toast) { + // Wait for fade-out to finish + setTimeout(this.remove, 300, 0) + + toast.isOpen = false + }, + open: function (message, action, time) { + const toast = { message: message, action: action || (() => { }), isOpen: false, timeout: null } + toast.timeout = setTimeout(this.close, time || 3000, toast) + setImmediate(() => { toast.isOpen = true }) + if (this.toasts.length > 4) { + this.remove(0) + } + this.toasts.push(toast) + }, + remove: function(index) { + const removed = this.toasts.splice(index, 1) + clearTimeout(removed[0].timeout) + } + }, +}) diff --git a/src/renderer/components/ft-toast/ft-toast.vue b/src/renderer/components/ft-toast/ft-toast.vue new file mode 100644 index 00000000..efcd91a8 --- /dev/null +++ b/src/renderer/components/ft-toast/ft-toast.vue @@ -0,0 +1,18 @@ + + +