Skip to content

Instantly share code, notes, and snippets.

@azimidev
Last active August 15, 2019 22:16
Show Gist options
  • Save azimidev/5ca5cc8eaf87a6051ed2443e7422636b to your computer and use it in GitHub Desktop.
Save azimidev/5ca5cc8eaf87a6051ed2443e7422636b to your computer and use it in GitHub Desktop.
<template>
<div class="chat">
<transition-group enter-active-class="fadeIn">
<div v-for="(msg, index) in messages" :key="index" class="messages">
<div :class="index % 2 === 0 ? 'message2' : 'message1'">
<div :class="index % 2 === 0 ? 'msg2' : 'msg1'">{{ msg }}</div>
</div>
</div>
</transition-group>
<textarea v-model.trim="message" @keyup.enter="send" cols="30" rows="3"></textarea>
<button @click="send">Send</button>
</div>
</template>
<script>
export default {
name: "ChatRoom",
data() {
return {
message: "",
messages: []
};
},
methods: {
send() {
this.messages.push(this.message);
this.message = "";
}
}
};
</script>
<style scoped>
.chat {
display: flex;
flex-direction: column;
max-width: 300px;
width: 300px;
}
.message1 {
display: flex;
justify-content: flex-start;
}
.message2 {
display: flex;
justify-content: flex-end;
}
.msg1 {
padding: 5px;
margin: 5px 0 5px 0;
background-color: crimson;
border-radius: 5px;
font-size: smaller;
color: white;
max-width: 80%;
}
.msg2 {
padding: 5px;
margin: 5px 0 5px 0;
background-color: deepskyblue;
border-radius: 5px;
font-size: smaller;
color: white;
max-width: 80%;
}
.fadeIn {
animation-duration: 1s;
animation-fill-mode: both;
animation-name: fadeIn;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
@azimidev
Copy link
Author

<template>
	<div class="chat">
		<transition-group enter-active-class="fadeIn">
			<div v-for="(msg, index) in messages" :key="index" class="messages">
				<div :class="everyOtherMessage(index) ? 'message2' : 'message1'">
					<div class="msg" :class="everyOtherMessage(index) ? 'msg2' : 'msg1'">{{ msg }}</div>
				</div>
			</div>
		</transition-group>
		<input v-model.trim="message" @keyup.enter="sendMessage"/>
		<button @click="sendMessage">Send</button>
	</div>
</template>

<script>
	export default {
		name: 'chatroom',
		data() {
			return {
				message: '',
			};
		},

		methods: {
			sendMessage() {
				if ( ! this.message) return;

				this.$store.dispatch('sendMessage', this.message);
				this.message = '';
			},
			everyOtherMessage(index) {
				return index % 2 === 0;
			},
		},

		computed: {
			messages() {
				return this.$store.getters.messages;
			},
		},
		// computed: mapState([
		// 	'messages'
		// ])

		// computed: mapGetters([
		// 	'messages'
		// ])
	};
</script>

<style scoped>
	.chat {
		display        : flex;
		flex-direction : column;
		max-width      : 300px;
		width          : 300px;
	}

	.message1 {
		display         : flex;
		justify-content : flex-start;
	}

	.message2 {
		display         : flex;
		justify-content : flex-end;
	}
	.msg {
		max-width     : 80%;
		padding       : 5px;
		margin        : 5px 0 5px 0;
		border-radius : 5px;
		font-size     : smaller;
		color         : white;
	}
	.msg1 {
		background-color : tomato;
	}

	.msg2 {
		background-color : dodgerblue;
	}

	.fadeIn {
		animation-duration  : 1s;
		animation-fill-mode : both;
		animation-name      : fadeIn;
	}

	@keyframes fadeIn {
		from {
			opacity : 0;
		}

		to {
			opacity : 1;
		}
	}
</style>

@azimidev
Copy link
Author

azimidev commented Aug 15, 2019

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
	state: {
		messages: [],
	},
	mutations: {
		SEND_MESSAGE(state, message) {
			state.messages.push(message);
		},
	},
	actions: {
		sendMessage({ commit }, message) {
			commit('SEND_MESSAGE', message);
		},
	},
	getters: {
		messages: state => state.messages
	},
});

@azimidev
Copy link
Author

<template>
	<div id="app">
		<div id="nav">
			<router-link to="/">Chat Room</router-link>
		</div>
		<router-view/>
	</div>
</template>

<style lang="scss">
	html, body {
		height : 100%;
	}
	#app {
		height          : 100%;
		display         : flex;
		flex-direction  : column;
		justify-content : center;
		align-items     : center;
	}
</style>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment