Przeglądaj źródła

Show new post notification/bubble on thread page

sbkwgh 8 lat temu
rodzic
commit
21aa44a056

+ 90 - 0
src/components/ThreadPostNotification.vue

@@ -0,0 +1,90 @@
+<template>
+	<transition name='slide-fade'>
+		<div class='thread_post_notification' @click='$emit("goToPost")'>
+			<span class='thread_post_notification__close' @click.stop='$emit("close")'></span>
+			<div class='thread_post_notification__header_bar'>
+				<span class='thread_post_notification__username'>{{post.username}}</span>
+				replied &nbsp;&middot;&nbsp; click to view
+			</div>
+			<div class='thread_post_notification__content'>{{post.content | stripTags | truncate(150)}}</div>
+		</div>
+	</transition>
+</template>
+
+<style lang='scss' scoped>
+	@import '../assets/scss/variables.scss';
+
+	.slide-fade-enter-active, .slide-fade-leave-active {
+		transition: all 0.4s cubic-bezier(0.18, 0.89, 0.32, 1.28) !important;
+	}
+	.slide-fade-enter, .slide-fade-leave-to {
+		transform: translateX(25rem);
+		opacity: 0;
+	}
+
+
+	.thread_post_notification {
+		position: fixed;
+		bottom: 2.5rem;
+		cursor: default;
+		overflow: hidden;
+		right: 2.5rem;
+		width: 20rem;
+		height: 5rem;
+		background-color: #fff;
+		z-index: 3;
+		transition: background-color 0.2s;
+		border-radius: 0.25rem;
+		box-shadow: 0 0 0.5rem 1px rgba(175, 175, 175, 0.3), 0 0.2rem 0.3rem 0px rgba(175, 175, 175, 0.15);
+
+		&:hover {
+			background-color: lighten($color__lightgray--primary, 2.75%);
+		}
+
+		@at-root #{&}__header_bar {
+			width: 100%;
+			font-size: 0.9rem;
+			margin-top: 0.5rem;
+			margin-left: 0.75rem;
+			color: $color__text--secondary;
+		}
+		@at-root #{&}__username, #{&}__date {
+			color: $color__text--primary;
+		}
+		@at-root #{&}__content {
+			padding: 0.75rem;
+			padding-top: 0.5rem;
+		}
+		@at-root #{&}__close {
+			    position: absolute;
+				right: 0.5rem;
+				top: 0.5rem;
+				cursor: pointer;
+				border-radius: 100%;
+				background-color: $color__lightgray--primary;
+				transition: background-color 0.2s;
+				width: 1rem;
+				height: 1rem;
+			
+			@include user-select(none);
+
+			&:hover {
+				background-color: $color__lightgray--darker;
+			}
+			&::after {
+				content: '\d7';
+				position: relative;
+				left: 0.2rem;
+				top: -0.15rem;
+			}
+		}
+	}
+
+</style>
+
+<script>
+	export default {
+		name: 'ThreadPostNotification',
+		props: ['post']
+	}
+</script>

+ 29 - 2
src/components/routes/Thread.vue

@@ -1,5 +1,12 @@
 <template>
 	<div class='route_container'>
+		<thread-post-notification
+			v-if='$store.state.thread.postNotification'
+			:post='$store.state.thread.postNotification'
+			@close='$store.commit("thread/setPostNotification", null)'
+			@goToPost='goToPostNotification'
+		></thread-post-notification>
+
 		<div class='thread_side_bar'>
 			<loading-button
 				:class='{ "button--disabled" : !$store.state.thread.selectedPosts.length }'
@@ -107,6 +114,7 @@
 	import InputEditor from '../InputEditor'
 	import ScrollLoad from '../ScrollLoad'
 	import ThreadPost from '../ThreadPost'
+	import ThreadPostNotification from '../ThreadPostNotification'
 	import ThreadPostPlaceholder from '../ThreadPostPlaceholder'
 	import PostScrubber from '../PostScrubber'
 	import MenuButton from '../MenuButton'
@@ -122,6 +130,7 @@
 			InputEditor,
 			ScrollLoad,
 			ThreadPost,
+			ThreadPostNotification,
 			ThreadPostPlaceholder,
 			PostScrubber,
 			MenuButton,
@@ -130,7 +139,8 @@
 		data () {
 			return {
 				headerTitle: false,
-				highlightedPostIndex: null
+				highlightedPostIndex: null,
+				postNotification: null
 			}
 		},
 		computed: {
@@ -263,6 +273,22 @@
 						setTimeout(() => this.highlightedPostIndex = null, 3000)
 					}
 				})
+			},
+			showPostNotification (post) {
+				if(post.username === this.$store.state.username) return;
+
+				this.$store.commit('thread/setPostNotification', null)
+				this.$store.commit('thread/setPostNotification', post)
+
+				setTimeout(_ => {
+					this.$store.commit('thread/setPostNotification', null)
+				}, 5000)
+			},
+			goToPostNotification () {
+				let post = this.$store.state.thread.postNotification
+
+				this.goToPost(post.postNumber)
+				this.$store.commit('thread/setPostNotification', null)
 			}
 		},
 		mounted () {
@@ -304,6 +330,7 @@
 			
 			socket.emit('join', 'thread/' + this.$route.params.id)
 			socket.on('new post', post => {
+				this.showPostNotification(post)
 				this.$store.dispatch('loadNewPostsSinceLoad', post)
 			})
 		},
@@ -314,7 +341,7 @@
 	}
 </script>
 
-<style lang='scss' scoped>
+<style lang='scss' >
 	@import '../../assets/scss/variables.scss';
 
 	.thread_side_bar {

+ 4 - 0
src/store/modules/thread.js

@@ -4,6 +4,7 @@ const state = {
 	thread: '',
 	threadId: undefined,
 	posts: [],
+	postNotification: null,
 	locked: false,
 	reply: {
 		username: '',
@@ -203,6 +204,9 @@ const mutations = {
 		state.reply.username = payload.username;
 		state.reply.id = payload.id;
 	},
+	'thread/setPostNotification': (state, post) => {
+		state.postNotification = post
+	},
 	addPost (state, post) {
 		if(Array.isArray(post)) {
 			state.posts.push(...post)