Giter Site home page Giter Site logo

vue-quick-chat's Introduction

vue-quick-chat

This vue component is a simple chat that can be easily imported and used in your project.

Features

  • Custom style
  • Handle on type event and on message submit
  • Chat with multiple participants
  • Support for async actions like message uploaded status
  • Send images (released at version 1.1.0)
  • Support for profile pictures (released at version 1.1.1)
  • Uses Luxon in place of moment. Added event functions (released at version 1.2.0)
  • Support for timestamp config (released at version 1.2.1)

Instalation

yarn add vue-quick-chat

or with npm

npm install vue-quick-chat --save

Usage

import { Chat } from 'vue-quick-chat'
import 'vue-quick-chat/dist/vue-quick-chat.css';


export default {
  components: {
    Chat
  },
}
<template>
  <div>
      <Chat v-if="visible"
        :participants="participants"
        :myself="myself"
        :messages="messages"
        :chat-title="chatTitle"
        :placeholder="placeholder"
        :colors="colors"
        :border-style="borderStyle"
        :hide-close-button="hideCloseButton"
        :close-button-icon-size="closeButtonIconSize"
        :submit-icon-size="submitIconSize"
        :submit-image-icon-size="submitImageIconSize"
        :load-more-messages="toLoad.length > 0 ? loadMoreMessages : null"
        :async-mode="asyncMode"
        :scroll-bottom="scrollBottom"
        :display-header="true"
        :send-images="true"
        :profile-picture-config="profilePictureConfig"
        :timestamp-config="timestampConfig"
        :link-options="linkOptions"
        :accept-image-types="'.png, .jpeg'"
        @onImageClicked="onImageClicked"
        @onImageSelected="onImageSelected"
        @onMessageSubmit="onMessageSubmit"
        @onType="onType"
        @onClose="onClose"/>
   </div>
</template>

You can also use a slot to define the header content

<div>
	<Chat 
        :participants="participants"
        :myself="myself"
        :messages="messages"
        :chat-title="chatTitle"
        :placeholder="placeholder"
        :colors="colors"
        :border-style="borderStyle"
        :hide-close-button="hideCloseButton"
        :close-button-icon-size="closeButtonIconSize"
        :submit-icon-size="submitIconSize"
        :submit-image-icon-size="submitImageIconSize"
        :load-more-messages="toLoad.length > 0 ? loadMoreMessages : null"
        :link-options="linkOptions"
        :async-mode="asyncMode"
        :scroll-bottom="scrollBottom"
        :display-header="true"
        :send-images="true"
        :profile-picture-config="profilePictureConfig"
        :timestamp-config="timestampConfig"
        @onImageClicked="onImageClicked"
        @onImageSelected="onImageSelected"
        @onMessageSubmit="onMessageSubmit"
        @onType="onType"
        @onClose="onClose">
        <template v-slot:header>
          <div>
            <p v-for="(participant, index) in participants" :key="index" class="custom-title">{{participant.name}}</p>
          </div>
        </template>
        </Chat>
</div>

Bellow we have an example of the component data structure

import {Chat} from 'vue-quick-chat';
import 'vue-quick-chat/dist/vue-quick-chat.css';

export default {
    components: {
        Chat
    },
    data() {
        return {
            visible: true,
            participants: [
                {
                    name: 'Arnaldo',
                    id: 1,
                    profilePicture: 'https://upload.wikimedia.org/wikipedia/en/thumb/a/a1/NafSadh_Profile.jpg/768px-NafSadh_Profile.jpg'
                },
                {
                    name: 'José',
                    id: 2,
                    profilePicture: 'https://lh3.googleusercontent.com/-G1d4-a7d_TY/AAAAAAAAAAI/AAAAAAAAAAA/AAKWJJPez_wX5UCJztzEUeCxOd7HBK7-jA.CMID/s83-c/photo.jpg'
                }
            ],
            myself: {
                name: 'Matheus S.',
                id: 3,
                profilePicture: 'https://lh3.googleusercontent.com/-G1d4-a7d_TY/AAAAAAAAAAI/AAAAAAAAAAA/AAKWJJPez_wX5UCJztzEUeCxOd7HBK7-jA.CMID/s83-c/photo.jpg'
            },
            messages: [
                {
                    content: 'received messages',
                    myself: false,
                    participantId: 1,
                    timestamp: {year: 2019, month: 3, day: 5, hour: 20, minute: 10, second: 3, millisecond: 123},
                    type: 'text'
                },
                {
                    content: 'sent messages',
                    myself: true,
                    participantId: 3,
                    timestamp: {year: 2019, month: 4, day: 5, hour: 19, minute: 10, second: 3, millisecond: 123},
                    type: 'text'
                },
                {
                    content: 'other received messages',
                    myself: false,
                    participantId: 2,
                    timestamp: {year: 2019, month: 5, day: 5, hour: 10, minute: 10, second: 3, millisecond: 123},
                    type: 'text'
                }
            ],
            chatTitle: 'My chat title',
            placeholder: 'send your message',
            colors: {
                header: {
                    bg: '#d30303',
                    text: '#fff'
                },
                message: {
                    myself: {
                        bg: '#fff',
                        text: '#bdb8b8'
                    },
                    others: {
                        bg: '#fb4141',
                        text: '#fff'
                    },
                    messagesDisplay: {
                        bg: '#f7f3f3'
                    }
                },
                submitIcon: '#b91010',
                submitImageIcon: '#b91010',
            },
            borderStyle: {
                topLeft: "10px",
                topRight: "10px",
                bottomLeft: "10px",
                bottomRight: "10px",
            },
            hideCloseButton: false,
            submitIconSize: 25,
            closeButtonIconSize: "20px",
            asyncMode: false,
            toLoad: [
                {
                    content: 'Hey, John Doe! How are you today?',
                    myself: false,
                    participantId: 2,
                    timestamp: {year: 2011, month: 3, day: 5, hour: 10, minute: 10, second: 3, millisecond: 123},
                    uploaded: true,
                    viewed: true,
                    type: 'text'
                },
                {
                    content: "Hey, Adam! I'm feeling really fine this evening.",
                    myself: true,
                    participantId: 3,
                    timestamp: {year: 2010, month: 0, day: 5, hour: 19, minute: 10, second: 3, millisecond: 123},
                    uploaded: true,
                    viewed: true,
                    type: 'text'
                },
            ],
            scrollBottom: {
                messageSent: true,
                messageReceived: false
            },
            displayHeader:true,
            profilePictureConfig: {
                others: true,
                myself: true,
                styles: {
                    width: '30px',
                    height: '30px',
                    borderRadius: '50%'
                }
            },
            timestampConfig: {   
                format: 'HH:mm',
                relative: false
            },
            // there are other options, you can check them here
            // https://soapbox.github.io/linkifyjs/docs/options.html
            linkOptions: {
                myself: {
                    className: 'myLinkClass',
                    events: {
                        click: function (e) {
                            alert('Link clicked!');
                        },
                        mouseover: function (e) {
                            alert('Link hovered!');
                        }
                    },
                    format: function (value, type) {
                        if (type === 'url' && value.length > 50) {
                            value = value.slice(0, 50) + '…';
                        }
                        return value;
                    }
                },
                others: {
                    className: 'othersLinkClass',
                    events: {
                        click: function (e) {
                            alert('Link clicked!');
                        },
                        mouseover: function (e) {
                            alert('Link hovered!');
                        }
                    },
                    format: function (value, type) {
                        if (type === 'url' && value.length > 50) {
                            value = value.slice(0, 50) + '…';
                        }
                        return value;
                    }
                }
            }
        }
    },
    methods: {
        onType: function (event) {
            //here you can set any behavior
        },
        loadMoreMessages(resolve) {
            setTimeout(() => {
                resolve(this.toLoad); //We end the loading state and add the messages
                //Make sure the loaded messages are also added to our local messages copy or they will be lost
                this.messages.unshift(...this.toLoad);
                this.toLoad = [];
            }, 1000);
        },
        onMessageSubmit: function (message) {
            /*
            * example simulating an upload callback. 
            * It's important to notice that even when your message wasn't send 
            * yet to the server you have to add the message into the array
            */
            this.messages.push(message);

            /*
            * you can update message state after the server response
            */
            // timeout simulating the request
            setTimeout(() => {
                message.uploaded = true
            }, 2000)
        },
        onClose() {
            this.visible = false;
        },
        onImageSelected(files, message){
            let src = 'https://149364066.v2.pressablecdn.com/wp-content/uploads/2017/03/vue.jpg'
            this.messages.push(message);
            /**
             * This timeout simulates a requisition that uploads the image file to the server.
             * It's up to you implement the request and deal with the response in order to
             * update the message status and the message URL
             */
            setTimeout((res) => {
                message.uploaded = true
                message.src = res.src
            }, 3000, {src});
        },
        onImageClicked(message){
            /**
             * This is the callback function that is going to be executed when some image is clicked.
             * You can add your code here to do whatever you need with the image clicked. A common situation is to display the image clicked in full screen.
             */
            console.log('Image clicked', message.src)
        }
    }
}

Component Props

name type required default description
participants Array true An array of participants. Each participant should be an Object with name and id
myself Object true Object of my participant. "myself" should be an Object with name and id
messages Array true An array of messages. Each message should be an Object with content, myself, participantId and timestamp
chatTitle String false Empty String The title on chat header
placeholder String false 'type your message here' The placeholder of message text input
colors Object true Object with the color's description of style properties
borderStyle Object false { topLeft: "10px", topRight: "10px", bottomLeft: "10px", bottomRight: "10px"} Object with the description of border style properties
hideCloseButton Boolean false false If true, the 'Close' button will be hidden
submitIconSize int false 24 The submit icon size in pixels.
submitImageIconSize int false 24 The image submit icon size in pixels.
closeButtonIconSize String false "15px" The close button icon size in pixels.
asyncMode Boolean false false If the value is true the component begins to watch message upload status and displays a visual feedback for each message. If the value is false the visual feedback is disabled
loadMoreMessages Function false () => false If this function is passed and you reach the top of the messages, it will be called and a loading state will be displayed until you resolve it by calling the only parameter passed to it
scrollBottom Object false { messageSent: true, messageReceived: false} This object describes the chat scroll behavior. The two options represent the moment when the chat should scroll to the bottom. If 'messageSent' is true, the chat will scroll to bottom aways you send a new message. If 'messageReceived' is true, the chat will scroll to bottom always you receive a new message.
displayHeader Boolean false true This prop describes whether the header should be displayed or not
profilePictureConfig Object false { others: true, myself: false, styles: { width: '25px', height: '25px', borderRadius: '50%'} } This prop is a js Object that decribes the style and the behavoir of the chat regards to the users profile picture.
timestampConfig Object false { format: 'HH:mm', relative: false } This prop is a js Object that decribes the timestamp format / relativeness.
linkOptions Object false { myself: {}, others: {} } This prop is an Object that configures the links that may appear on the messages' content. myself defines the config for links in sent messages. others defines the config for links in received messages. This functionality relies on linkifyjs. You can find the full doc of this prop here.
acceptImageTypes String false image/* This prop defines the image types that are accepted to be uploaded. The image types should be separated by a comma (e.g. '.png, .jpeg, .jpg')

Events

name type required default description
onType Function false () => false Event called when the user is typing
onMessageSubmit Function false () => false Event called when the user sends a new message
onClose Function false () => false Event called when the user presses the close icon
onImageClicked Function false () => false This prop is a callback function that is called after the user clicks on an image. This function may receive the message that represents the image clicked. You have many possibilities of implementations, one of them, is to display the clicked image on full-screen mode.
onImageSelected Function false () => false This prop is a callback function that is called after the user selects an image from the computer. This is the function that should upload the image to the server and update the message status to uploaded and the src to the uploaded image URL.

participant

name type description
id int The user id should be an unique value
name String The user name that will be displayed
profilePicture String The user profule picture url

Example

{
  name:  'Username',
  id: 1,
  profilePicture: 'profile_url'
},

message

name type description
content String The message text content
myself boolean (REMOVED) Whether the message was sent by myself or by other participants. Since version 1.0.8 this property is automatically set by the chat
participantId int The participant's id who sent the message
timestamp Object Object describing the year, month, day, hour, minute, second and millisecond that the message was sent
uploaded Boolean If asyncMode is true and uploaded is true, a visual feedback is displayed bollow the message. If asyncMode is true and uploaded is false, a visual loading feedback is displayed bollow the message. If asyncMode is false, this property is ignored.
viewed Boolean If asyncMode is true and viewed is true, a visual feedback is displayed bollow the message.
preview String (ONLY FOR IMAGES) This prop is automatically set by the chat. It represents the preview image URL while the image is being uploaded to the server.
src String (ONLY FOR IMAGES) This prop should be set by you after the image is uploaded. You should do it in the callback function onImageSelected. The prop represents the image URL of the uploaded image.
type String This prop should be set by you in case a new message is received, otherwise, the chat will automatically set this prop.

Example

{
  content: 'received messages', 
  //myself: false,
  participantId: 1,
  timestamp: { 
    year: 2019, 
    month: 3, 
    day: 5, 
    hour: 20, 
    minute: 10, 
    second: 3, 
    millisecond: 123 
  },
  uploaded: true,
  viewed: true,
  type: 'text' // or 'image'
  // generated by URL.createObjectURL(file)
  // (ONLY NEEDED FOR IMAGES)
  preview: 'blob:http://mydomain/11999c0j-4abc-4e56-acc7-fb0bbd616ea7',
  src: 'myurl.com/images/image.png',
}

color

name type description
header Object Object containing the header background and text color
message Object Object containing the message background and text color. The Object should contains the style for 'myself' and 'others'
messagesDisplay Object Object containing the background color of mesages container.
submitIcon String The color applied to the send message button icon
submitImageIcon String The color applied to the send image button icon

Example

{
  header:{
    bg: '#d30303',
    text: '#fff'
  },
  message:{
    myself: {
      bg: '#fff',
      text: '#bdb8b8'
    },
    others: {
      bg: '#fb4141',
      text: '#fff'
    }
  },
  messagesDisplay: {
    bg: '#f7f3f3'
  },
  submitIcon: '#b91010',
  submitImageIcon: '#b91010'
}

profilePictureConfig

name type description
others Boolean Whether the profile picture of the other participant should be displayed on the screen
myself Boolean Whether the profile picture of the current participant (myself) should be displayed on the screen
styles Object Object containing the description of the size and the shape of the profile images picture

Example

profilePictureConfig: {
    others: true,
    myself: true,
    styles: {
        width: '30px',
        height: '30px',
        borderRadius: '50%'
    }
}

timestampConfig

name type description
format String Timestamp format
relative Boolean Whether the timestamp should be relative to current time

Example

timestampConfig: {   
    format: 'HH:mm',
    relative: false
}

Project setup

npm install

Compiles and hot-reloads for development

npm run serve

Compiles and minifies for production

npm run build

Run your tests

npm run test

Lints and fixes files

npm run lint

Customize configuration

See Configuration Reference.

vue-quick-chat's People

Contributors

matheusrdsantos avatar qanah avatar tofandel avatar trkyshorty avatar vonec avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

vue-quick-chat's Issues

[Bug] IOS - Keyboard "Done/Submit" button

IOS only.
Works fine in Safari, Chrome etc.

I'm not going to use so much time on this one...

Description:

  • Clicking Done does nothing.
  • Clicking the Red Triangle works.

Possible solutions:

- Inspecting the DOM, it looks like there is not used a <input type="text"> and a <input type="submit" value="Submit">. I'm not sure if that will fix it.. 
- Having a <form onsubmit="myFunction()">...</form> around the text field is maybe a solution.. 

Anyway, its a smaller thing, now documented :-)

iOGYK3y4wY

Proposal: Replace moment.js with date-fns or Luxon.js

This thread purpose, is to discuss if it should be done.

Why? -> Bundle size, thats why :-)

When looking at the package size of moment.js, its "medium-huge"...
https://bundlephobia.com/[email protected]

Luxon is supposed to replace moment.js, with better webpack support (include what you need). Also made by the team of moment. They created Luxon, because it support new techologies, and they did not want to break moment.js

date-fns, same as luxon..

https://moment.github.io/luxon/
https://date-fns.org/

This is maybe a "nice" to have and not a "need" to have. But would be best practice.

Now.. it all comes down to browser compatibility and opinions. What is the general opinion on this?

:-)

On Clicking on Send Getting the Error: Cannot read property zone on Null

I am just using the example provided on the readme page in my nuxtjs project

TypeError: Cannot read property 'zone' of null
    at Function.fromObject (vue-quick-chat.common.js:7236)
    at vue-quick-chat.common.js:17232
    at Array.map (<anonymous>)
    at Store.setMessages (vue-quick-chat.common.js:17230)
    at wrappedMutationHandler (vue-quick-chat.common.js:10860)
    at commitIterator (vue-quick-chat.common.js:10553)
    at Array.forEach (<anonymous>)
    at vue-quick-chat.common.js:10552
    at Store._withCommit (vue-quick-chat.common.js:10662)
    at Store.commit (vue-quick-chat.common.js:10551)

Real time chat

Hello,

Is it possible to make this chat in real time by updating "toLoad"?

Thank you.

README incorrect docs the starting data block

What a shame this took me an hour to debug. My software skills are not what they used to be.

You have 'messagesDisplay' in the wrong code block

INCORRECT

        message:{
          myself: {
            bg: '#fff',
            text: '#bdb8b8'
          },
          others: {
            bg: '#fb4141',
            text: '#fff'
          }
        },
        messagesDisplay: {
            bg: '#f7f3f3'
        },

CORRECT

        message:{
          myself: {
            bg: '#fff',
            text: '#bdb8b8'
          },
          others: {
            bg: '#fb4141',
            text: '#fff'
          },
          messagesDisplay: {
              bg: '#f7f3f3'
          },
        },

Add message date

Hello,

Currently it is possible to see the time when the message was sent, instead the sending date cannot be displayed.
I think it is, in case it is not currently possible, an interesting improvement.

Thank you.

on close props is function

onClose props is function so if i need to pass param to this function this method
will fire when component mounted so the chat will be close again
so i suggesting to be event
and we catch this event outside component

current :on-close="onClose(pram)"
suggest @onClose="onClose(param)"

send image in chat

i am using your template it awsome but sir can i use image in chat kinldy guide how to achieve this. thanks
regards
Tahseen ullah

[new Feature] Image upload -> customize file types :-)

It would be nice to be able to customize what files types, the user can upload.
Since the server maybe only support jpg/png or something else :D

Docs:

https://www.w3schools.com/tags/att_input_accept.asp

Code:

<input ref="inputImage" accept="image/*" type="file" style="display: none;" @input="handleImageChange">

All the file formats that the browser (chrome) suggest on windows:

image

And again, thanks for a awesome component ;-) ;-) ;-)

ZONE error on push message

Hi, please help if you can
I got the message object from onMessageSubmit.
When I push a message in messages, I catch an error with ZONE

image
image
what am I doing wrong?

Vue2 to Vue3

Your application is Currently using Vue2. I can convert it to Vue3. Just check out my git-hub profile and contact me on Whatsapp.

Feature: Send Image/Attachments... Custom slots?

In my project I have to send pictures in the chat. I do not want to create a fork, but rather improve this project.

Thought it would probably be best to discuss how it can be implemented here first.

My first thought is that we can have two custom slots. One for pictures and one for attachments.


Suggested solution:

step 1 - Register that the user clicked the image button:
image

step 2 - the programmer does whatever he wants with the callback.

step 3 - Now it needs to be displayed in the chat..

Here is some possible suggestions/solutions:

- There are custom slots for different file types
- or no slots, but the json define how the "chat buble" will look like.
- Raw HTML components, with a <custom :rawHtml="<i>hi</i>">
- 10 different <custom1>,  <custom2>, <custom3>... slots..
  • Can you think of more options?

What are your thoughts on that? :-)

A message adds after cliking on enter even if its empty

I tried

async onMessageSubmit (message) {
  message.content = message.content.trim().replace(/\r\n/g, '')
  if (message.content === '') {
    return
  }
  ...

but empty message still adds
it seems newMessage mutation should have some condition

can you fix it? Or is there a way how can i avoid it?

slot to customize the layout of the message content

Is there any way to customize the layout of the message content, perhaps using a slot like the header's?

    <template v-slot:header>
      <div>
        <p v-for="(participant, index) in participants" :key="index" class="custom-title">{{participant.name}}</p>
      </div>
    </template>          

[question/propocal] Delete previous messages

How delete all previous messages? All or probably better for particular participant.
I need on click event clean pallet and change participants.
Change participants looks like not complicated. But how delete previous messages :( ?

Error while building in a Vue project

My package.json is as follows.

{
  "dependencies": {
    "vue-quick-chat": "^1.2.0",
  },
}

With npm install, I have 1.2.3 installed. However, when running npm run build, error occurred.'

Starting type checking service...
Using 1 worker with 2048MB memory limit
 ERROR  Failed to compile with 2 errors6:26:07 AM

These dependencies were not found:

* vue-quick-chat in ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Interview.vue?vue&type=script&lang=ts&
 ERROR  Build failed with errors.
* vue-quick-chat/dist/vue-quick-chat.css in ./node_modules/cache-loader/dist/cjs.js??ref--14-0!./node_modules/thread-loader/dist/cjs.js!./node_modules/babel-loader/lib!./node_modules/ts-loader??ref--14-3!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/views/Interview.vue?vue&type=script&lang=ts&

To install them, you can run: npm install --save vue-quick-chat vue-quick-chat/dist/vue-quick-chat.css
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] build: `vue-cli-service build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/runner/.npm/_logs/2020-07-29T06_26_07_880Z-debug.log
##[error]Process completed with exit code 1.

I modify my package.json so that the version of vue-quick-chat is locked to 1.2.0, then it can build successfully.

{
  "dependencies": {
    "vue-quick-chat": "1.2.0",
  },
}

Vue2 to Vue3

Your application is Currently using Vue2. I can convert it to Vue3. Just check out my git-hub profile and contact me on Whatsapp.

Text color

I've tried to change the text color. But I think this one is overriding the text color?

Here is my colors:


colors:{
        header:{
          bg: '#0099ff',
          text: '#fff'
        },
        message:{
          myself: {
            bg: '#0099ff',
            text: '#fff'
          },
          others: {
            bg: '#f1f0f0',
            text: '#3e3e3e'
          },
          messagesDisplay: {
            bg: '#fff'
          }
        },

text colors, should be: other=black, and myself=white

s

Typing

How can I implement typing effect with the component?

Quote message

Answer to specified message. For example, button with arrow on side of message text. After click append quoted message before answer message.

Problems with Vuex Timetravel because of MomentJs

I had some problems in my App when i tried to use Vuex Timetravel. The Problems are the Moment objects in the Vuex Store.
I have solved it by saving the ISO 8601 String of the timestamp in the Vuex Store instead of the Moment object.
Then I also added a getter method which converts the String to a moment Object.
The changes for this are quite simple:
Here are the new mutatiuons:

newMessage: (state, message) => {
            message.timestamp = message.timestamp.toISOString();
            state.messages = [...state.messages, message];
        },
setMessages: (state, messages) => {
            messages.map(message => {
                message.timestamp = moment(message.timestamp).toISOString();
            })
            state.messages = messages;
        }

and here is the new getter:

  messages: (state) => {
            let messages = [];
            state.messages.forEach(message => {
                let newMessage = { ...message };
                newMessage.timestamp = moment(newMessage.timestamp);
                messages.push(newMessage);
            })
            return messages;
        }

There are some other ways to solve this problem. Here is a very good article:
https://medium.com/dailyjs/dates-in-vuex-primitives-or-complex-objects-6e6b29ebb880
At the bottom there is even an paragraph about momentjs.

Greetings

timestampConfig change locale

Hello,

I want to setLocale to "tr" but not able to do that. I searched on the google but could not found any solution.

Thanks,
Abullah.

header participants text. and maximum height.

Thanks for the greate project,. Is their an option to maximize the hight of messages display (in "quick-chat-container" class),? and to hide the participants header text (in "header-paticipants-text" class)?.

Getting the scrollbar appear at the bottom initially

Currently when the component loads for the first time the scrollbar shows up at the very top by default instead of at the bottom
to display the latest message.

Is there any way to make the scrollbar appear at the bottom position?

[Bug? + possible solution] IOS Safari

This bug is only on IOS (i used Apples Xcode iphone simulator, i believe the browser version is safari 12.1).
This is not a bug in Chrome, Firefix, Opera, Edge.
I'm not sure if this is a bug. But I'll report anyway.

Trying to fit the chat on mobile.

When there is MORE than 10 ish messages on the phone, then the "message-text-box", is longer down and outside the screen, the user then need to scroll down to find the "message-text-box". The default behavior is that the scroll is at the top, and not down at the textbox.

Setting a fixed calculated height of "container-message-display":
To fix this, I want to Calculate the max-height of the "container-message-display".
Here is a hardcoded example:

.container-message-display{
    max-height: 400px !important;
    height: 400px !important;
    /* background-color: red !important; */
    overflow-y: scroll !important;
}

The above code results in the screenshot, with overlapping messages. Inspecting the Safari developer tools, it looks like the flexbox needs some work. It behaves like in the illustration.

Possible Solution (Worked for me):

/************** Safari 10.1+ ********************/
@media not all and (min-resolution:.001dpcm)
{ @supports (-webkit-appearance:none) {

    .message-container{
        display:-webkit-box !important;
    }
    
}}

Screenshots is from safari / ios(simulator):

image

Screenshot 2019-11-16 at 17 40 08

Screenshot 2019-11-16 at 17 59 13

Proposal: Make scrolling work and keep chatbox fixed irrespective of scroll position

Hello,
Currently when we use this component the inner scroll does not work, when we scroll, the scrollbar of main windows is the one that is getting scrolled, so it would be nice if innerscroll could made to work or remove it from ui altogether, also scrollBottom:{messageSent:true} only makes sense if we could type in message irrespective of scroll position

Capture

Incorrect rendering in Firefox

Firefox: 69.0.2
vue-quick-chat: 1.0.1

Screenshot:
image

The component is rendered correctly if I toggle off the height: 100% style from .message-text > p[data-v-0e9711a6]:
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.