ソースを参照

Add overlay with LoadingIcon to InputEditor shown when editor.loading is set to true in vuex

sbkwgh 8 年 前
コミット
b50cc2f80c

+ 29 - 1
src/components/InputEditor.vue

@@ -6,6 +6,10 @@
 			"input_editor--focus-input": focusInput
 		}'
 	>
+		<div class='input_editor__overlay' :class='{ "input_editor__overlay--show" : loading }'>
+			<loading-icon></loading-icon>
+		</div>
+
 		<div class='input_editor__reply_username' v-if='replyUsername'>Replying to <strong>{{replyUsername}}</strong></div>
 		<div class='input_editor__close input_editor__format_button' @click='closeEditor'>&times;</div>
 		
@@ -36,15 +40,17 @@
 <script>
 	import InputEditorCore from './InputEditorCore'
 	import InputEditorPreview from './InputEditorPreview'
+	import LoadingIcon from './LoadingIcon'
 	import TabView from './TabView'
 
 
 	export default {
 		name: 'InputEditor',
-		props: ['value', 'error', 'replyUsername', 'show'],
+		props: ['value', 'error', 'replyUsername', 'show', 'loading'],
 		components: {
 			InputEditorCore,
 			InputEditorPreview,
+			LoadingIcon,
 			TabView
 		},
 		data () {
@@ -118,6 +124,28 @@
 			transition:  margin-bottom 0.2s, opacity 0.2s;
 		}
 
+		@at-root #{&}__overlay {
+			position: absolute;
+			left: 0;
+			top: 0;
+			height: 100%;
+			width: 100%;
+			z-index: 5;
+			background-color: rgba(0, 0, 0, 0.15);
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			pointer-events: none;
+			opacity: 0;
+
+			transition: all 0.2s;
+
+			@at-root #{&}--show {
+				pointer-events: all;
+				opacity: 1;
+			}
+		}
+
 
 		@at-root #{&}__close {
 			position: absolute;

+ 1 - 0
src/components/routes/Thread.vue

@@ -24,6 +24,7 @@
 
 			:show='editorState'
 			:replyUsername='replyUsername'
+			:loading='$store.state.thread.editor.loading'
 			
 			v-on:mentions='setMentions'
 			v-on:close='hideEditor'

+ 11 - 1
src/store/modules/thread.js

@@ -10,6 +10,7 @@ const state = {
 	},
 	editor: {
 		show: false,
+		loading: false,
 		value: ''
 	},
 	mentions: [],
@@ -47,9 +48,12 @@ const actions = {
 			post.replyingToId = state.reply.id;
 		}
 
+		commit('setThreadEditorLoading', true)
+
 		vue.axios
 			.post('/api/v1/post', post)
 			.then(res => {
+				commit('setThreadEditorLoading', false)
 				commit('addPost', res.data);
 				commit('addReplyBubble', res.data)
 				commit('setThreadEditorValue', '');
@@ -61,7 +65,10 @@ const actions = {
 					id: ''
 				});
 			})
-			.catch(AjaxErrorHandler(vue.$store))
+			.catch(e => {
+				commit('setThreadEditorLoading', false)
+				AjaxErrorHandler(vue.$store)(e)
+			})
 	},
 	loadInitialPostsAsync ({ state, commit, rootState }, vue) {
 		let postNumber = vue.$route.params.post_number
@@ -182,6 +189,9 @@ const mutations = {
 	setThreadEditorValue (state, value) {
 		state.editor.value = value
 	},
+	setThreadEditorLoading (state, value) {
+		state.editor.loading = value
+	},
 	setThreadEditorState (state, value) {
 		state.editor.show = value
 	},