123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- <template>
- <div class="flow-chat" :class="{active:active}">
- <button class="flow-chat__toggle" @click="active=!active">=</button>
- <div class="flow-chat__area">
- <div class="flow-chat__container">
- <input class="handle" type="text" v-model="handle" @blur="sendChatRename" @keyup.enter="sendChatRename">
- <div ref="messages" class="flow-chat__messages">
- <div v-for="m in events" class="message">
- <div class="handle">
- <div class="name">{{ m.handle }} <span v-if="m.type!='msg'">{{ m.type }}</span></div>
- <div class="time">{{ m.time | time }}</div>
- </div>
- <div class="text">{{ m.message }}</div>
- </div>
- </div>
- <input ref="input" class="message" @keyup.enter="send" type="text" v-model="input">
- </div> <!-- /container -->
- <div class="flow-chat__users">
- <div class="flow-chat__user" v-for="u in userList">
- <img src="../assets/user.svg"><span>{{ u }}</span>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- // init
- let storedHandle = localStorage.getItem('handle')
- if (!storedHandle || storedHandle === '') {
- storedHandle = 'someone'
- }
- // Load handle from storage
- export default {
- filters: {
- time (value) {
- const d = new Date(value)
- const hours = pad(d.getHours(), 2)
- const minutes = pad(d.getMinutes(), 2)
- let msg = `${hours}:${minutes}`
- return msg
- }
- },
- data () {
- return {
- active: false,
- handle: storedHandle,
- events: [],
- userList: [],
- input: ''
- }
- },
- watch: {
- active (val, oldVal) {
- if (val === true && oldVal === false) {
- this.$refs.input.focus()
- }
- },
- events () {
- const height = this.$refs.messages.clientHeight
- if (this.$refs.messages.scrollTop + height >= this.$refs.messages.scrollHeight) {
- this.$nextTick(() => {
- this.$refs.messages.scrollTop = this.$refs.messages.scrollHeight
- })
- }
- if (this.active === false) {
- this.active = true
- }
- }
- },
- mounted () {
- // this.$flowService.on('chatEvent', this.addChatEvent)
- this.$flowService.on('chatEvent', this.recvChatEvent)
- this.$flowService.on('chatUserList', this.recvChatUserList)
- this.$flowService.on('sessionJoin', this.sendChatJoin)
- // we might not be joined in a sess
- // off
- this.$flowService.connected(this.sendChatJoin)
- },
- beforeDestroy () {
- this.$flowService.off('chatEvent', this.recvChatEvent)
- this.$flowService.off('chatUserList', this.recvChatUserList)
- this.$flowService.off('sessionJoin', this.sendChatJoin)
- },
- methods: {
- send () {
- const msg = this.input
- if (msg.trim() === '') { return }
- this.input = ''
- const msgEvent = {type: 'msg', handle: this.handle, message: msg, time: new Date()}
- this.$flowService.chatEvent(msgEvent)
- },
- recvChatUserList (v) {
- this.userList = v.data
- },
- recvChatEvent (v) {
- this.events.push(v.data)
- },
- sendChatJoin () {
- // Clear messages here
- this.events = []
- this.$flowService.chatJoin(this.handle, this.$route.params.sessId)
- },
- sendChatRename () {
- const oldHandle = localStorage.getItem('handle')
- if (this.handle === oldHandle) return
- localStorage.setItem('handle', this.handle)
- this.$flowService.chatRename(this.handle)
- }
- }
- }
- function pad (n, width, z) {
- z = z || '0'
- n = n + ''
- return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n
- }
- </script>
- <style>
- .flow-chat {
- height:100%;
- box-sizing:border-box;
- position:relative;
- width:0px;
- transition: all .3s;
- }
- .flow-chat.active {
- width:530px;
- }
- .flow-chat__toggle {
- user-select:none;
- cursor: pointer;
- position:absolute;
- display:flex;
- justify-content: center;
- align-items: center;
- width:30px;
- height:50px;
- left:-30px;
- top:calc(50% - 25px);
- }
- .flow-chat__area {
- height:100%;
- overflow:hidden;
- display:flex;
- flex-flow:row;
- padding:8px 0px;
- }
- .flow-chat__container {
- height:100%;
- display:flex;
- flex-flow:column;
- flex:1;
- padding:0px 8px;
- }
- .flow-chat__container >*:not(last-child) {
- margin-bottom:10px;
- }
- .flow-chat__users {
- flex-basis:100px;
- padding:20px 8px;
- }
- .flow-chat__user {
- display:flex;
- flex-flow:row;
- justify-content: space-between;
- align-items: center;
- }
- .flow-chat__user img {
- height:10px;
- width:auto;
- }
- .flow-chat__user span {
- text-align:center;
- flex:1;
- width: 100px;
- overflow:hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
- .flow-chat__messages {
- font-size:12px;
- overflow-y:scroll;
- min-width:300px;
- flex:1;
- }
- .flow-chat__messages .message{
- padding:2px 2px 12px 2px;
- }
- .flow-chat__messages .handle {
- display:flex;
- flex-flow:row;
- justify-content: space-between;
- align-items: center;
- padding-top:2px;
- }
- .flow-chat__messages .handle .name {
- padding-bottom:4px;
- }
- .flow-chat__messages .handle .time{
- font-weight:normal;
- font-size:8px;
- }
- .flow-chat__messages .text {
- padding-top:0px;
- padding-left:9px;
- }
- </style>
|