Forráskód Böngészése

Create and use ThreadPost component for thread page

sbkwgh 8 éve
szülő
commit
97ae2fddb9
2 módosított fájl, 165 hozzáadás és 135 törlés
  1. 154 0
      src/components/ThreadPost.vue
  2. 11 135
      src/components/routes/Thread.vue

+ 154 - 0
src/components/ThreadPost.vue

@@ -0,0 +1,154 @@
+<template>
+	<div
+		class='post'
+		:class='{"post--highlighted": highlight}'
+		@mouseenter='setPostFooterState(true)'
+		@mouseleave='setPostFooterState(false)'
+	>
+		<div class='post__meta_data'>
+			<avatar-icon :user='post.User' class='post__avatar'></avatar-icon>
+			<div class='post__user'>{{post.User.username}}</div>
+			<replying-to
+				style='margin-right: 0.5rem;'
+				v-if='post.replyingToUsername'
+				:replyId='post.replyId'
+				:username='post.replyingToUsername'
+				@click='$emit("goToPost", post.replyId)'
+			></replying-to>
+			<div class='post__date'>{{post.createdAt | formatDate('time|date', ', ')}}</div>
+		</div>
+		<div class='post__content' v-html='post.content'></div>
+		<div class='post__footer' :class='{ "post__footer--show": hover }'>
+			<div
+				class='post__footer_group'
+				:class='{ "post__footer_group--replies": post.Replies.length }'
+			>
+				<post-reply
+					v-for='reply in post.Replies'
+					:post='reply'
+					:hover='hover'
+					@click='$emit("goToPost", reply.id)'
+				></post-reply>
+			</div>
+			<div
+				class='post__footer_group'>
+				<div class='post__action post__share'>Share</div>
+				<div
+					class='post__action post__reply'
+					v-if='$store.state.username && showReply'
+					@click='$emit("reply", post.id, post.User.username)'
+				>
+					Reply
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script>
+	import PostReply from './PostReply'
+	import ReplyingTo from './ReplyingTo'
+	import AvatarIcon from './AvatarIcon'
+
+	import AjaxErrorHandler from '../assets/js/errorHandler'
+
+	export default {
+		name: 'Post',
+		props: ['post', 'highlight', 'showReply'],
+		components: {
+			PostReply,
+			ReplyingTo,
+			AvatarIcon
+		},
+		data () {
+			return {
+				hover: false
+			}
+		},
+		methods: {
+			setPostFooterState (state) {
+				this.hover = state
+			}
+		}
+	}
+</script>
+
+<style lang='scss' scoped>
+	@import '../assets/scss/variables.scss';
+
+	.post {
+
+		border-top: thin solid $color__gray--primary;
+		transition: background-color 0.5s;
+		margin: 0.5rem 0;
+
+		@at-root #{&}--highlighted {
+			background-color: $color__lightgray--darkest;
+		}
+
+		@at-root #{&}__meta_data {
+			display: flex;
+			padding-top: 0.75rem;
+			position: relative;
+			margin-left: 4rem;
+		}
+		@at-root #{&}__avatar {
+			position: absolute;
+			left: -4rem;
+		}
+		@at-root #{&}__user {
+			@include text($font--role-default, 1rem, 600);
+			margin-right: 0.5rem;
+		}
+		@at-root #{&}__date {
+			color: $color__gray--darkest;
+			margin-right: 0.5rem;
+		}
+		@at-root #{&}__content {
+			padding: 0.5rem 0 0.5rem 4rem;
+		}
+		@at-root #{&}__footer {
+			padding: 0.5rem 0 0.75rem 4rem;
+			display: flex;
+			align-items: baseline;
+			justify-content: space-between;
+			opacity: 0.75;
+			transition: opacity 0.2s;
+
+			@at-root #{&}--show {
+				opacity: 1;
+				transition: opacity 0.2s;
+			}
+
+			@at-root #{&}_group {
+				align-items: baseline;
+				display: inline-flex;
+				position: relative;
+
+
+				@at-root #{&}--replies {
+					&::before {
+						content: 'Replies:';
+						bottom: 0.25rem;
+						left: -3.75rem;
+						font-size: 0.9rem;
+						position: absolute;	
+						color: $color__darkgray--primary;
+						transition: opacity 0.2s, bottom 0.2s;
+					}
+				}
+			}
+		}
+		@at-root #{&}__action {
+			color: $color__darkgray--primary;
+			cursor: pointer;
+			margin-right: 0.75rem;
+
+			transition: all 0.2s;
+
+			&:hover {
+				color: $color__darkgray--darkest;
+			}
+		}
+	}
+</style>

+ 11 - 135
src/components/routes/Thread.vue

@@ -24,61 +24,22 @@
 		>
 		</input-editor>
 		<div class='posts'>
-			<div
+			<thread-post
 				v-for='(post, index) in posts'
-				class='post'
-				:class='{"post--highlighted": highlightedPostIndex == index}'
+				@reply='replyUser'
+				@goToPost='goToPost'
+				:post='post'
+				:show-reply='true'
+				:highlight='highlightedPostIndex === index'
 				ref='posts'
-				@mouseenter='setPostFooterState(index, true)'
-				@mouseleave='setPostFooterState(index, false)'
-			>
-				<div class='post__meta_data'>
-					<avatar-icon :user='post.User' class='post__avatar'></avatar-icon>
-					<div class='post__user'>{{post.User.username}}</div>
-					<replying-to
-						style='margin-right: 0.5rem;'
-						v-if='post.replyingToUsername'
-						:replyId='post.replyId'
-						:username='post.replyingToUsername'
-						@click='goToPost(post.replyId)'
-					></replying-to>
-					<div class='post__date'>{{post.createdAt | formatDate('time|date', ', ')}}</div>
-				</div>
-				<div class='post__content' v-html='post.content'></div>
-				<div class='post__footer' :class='{ "post__footer--show": postIndexHover === index }'>
-					<div
-						class='post__footer_group'
-						:class='{ "post__footer_group--replies": post.Replies.length }'
-					>
-						<post-reply
-							v-for='reply in post.Replies'
-							:post='reply'
-							:hover='postIndexHover === index'
-							@click='goToPost(reply.id)'
-						></post-reply>
-					</div>
-					<div
-						class='post__footer_group'>
-						<div class='post__action post__share'>Share</div>
-						<div
-							class='post__action post__reply'
-							v-if='$store.state.username'
-							@click='replyUser(post.id, post.User.username)'
-						>
-							Reply
-						</div>
-					</div>
-				</div>
-			</div>
+			></thread-post>
 		</div>
 	</div>
 </template>
 
 <script>
 	import InputEditor from '../InputEditor'
-	import PostReply from '../PostReply'
-	import ReplyingTo from '../ReplyingTo'
-	import AvatarIcon from '../AvatarIcon'
+	import ThreadPost from '../ThreadPost'
 
 	import throttle from 'lodash.throttle'
 	import AjaxErrorHandler from '../../assets/js/errorHandler'
@@ -87,14 +48,11 @@
 		name: 'Thread',
 		components: {
 			InputEditor,
-			PostReply,
-			ReplyingTo,
-			AvatarIcon
+			ThreadPost
 		},
 		data () {
 			return {
 				headerTitle: false,
-				postIndexHover: null,
 				highlightedPostIndex: null
 			}
 		},
@@ -146,19 +104,12 @@
 			addPost () {
 				this.$store.dispatch('addPostAsync', this);
 			},
-			setPostFooterState (index, state) {
-				if(state) {
-					this.postIndexHover = index
-				} else {
-					this.postIndexHover = null
-				}
-			},
 			goToPost (postId) {
 				for(var i = 0; i < this.posts.length; i++) {
 					let post = this.posts[i]
 
-					if(post.id === postId) {				
-						let postTop = this.$refs.posts[i].getBoundingClientRect().top
+					if(post.id === postId) {
+						let postTop = this.$refs.posts[i].$el.getBoundingClientRect().top
 						let header = this.$refs.title.getBoundingClientRect().height
 						window.scrollTo(0, postTop - header - 32)
 
@@ -243,79 +194,4 @@
 			border-bottom: thin solid $color__gray--primary;
 		}
 	}
-
-	.post {
-		border-top: thin solid $color__gray--primary;
-		transition: background-color 0.5s;
-		margin: 0.5rem 0;
-
-		@at-root #{&}--highlighted {
-			background-color: $color__lightgray--darkest;
-		}
-
-		@at-root #{&}__meta_data {
-			display: flex;
-			padding-top: 0.75rem;
-			position: relative;
-			margin-left: 4rem;
-		}
-		@at-root #{&}__avatar {
-			position: absolute;
-			left: -4rem;
-		}
-		@at-root #{&}__user {
-			@include text($font--role-default, 1rem, 600);
-			margin-right: 0.5rem;
-		}
-		@at-root #{&}__date {
-			color: $color__gray--darkest;
-			margin-right: 0.5rem;
-		}
-		@at-root #{&}__content {
-			padding: 0.5rem 0 0.5rem 4rem;
-		}
-		@at-root #{&}__footer {
-			padding: 0.5rem 0 0.75rem 4rem;
-			display: flex;
-			align-items: baseline;
-			justify-content: space-between;
-			opacity: 0.75;
-			transition: opacity 0.2s;
-
-			@at-root #{&}--show {
-				opacity: 1;
-				transition: opacity 0.2s;
-			}
-
-			@at-root #{&}_group {
-				align-items: baseline;
-				display: inline-flex;
-				position: relative;
-
-
-				@at-root #{&}--replies {
-					&::before {
-						content: 'Replies:';
-						bottom: 0.25rem;
-						left: -3.75rem;
-						font-size: 0.9rem;
-						position: absolute;	
-						color: $color__darkgray--primary;
-						transition: opacity 0.2s, bottom 0.2s;
-					}
-				}
-			}
-		}
-		@at-root #{&}__action {
-			color: $color__darkgray--primary;
-			cursor: pointer;
-			margin-right: 0.75rem;
-
-			transition: all 0.2s;
-
-			&:hover {
-				color: $color__darkgray--darkest;
-			}
-		}
-	}
 </style>