0.1.14 β€’ Published 6 months ago

@x-store/vue-comments v0.1.14

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

vue-comments

Description | Install | Usage example | Options | Events | Development

Example Back-End server

Description

The tree comment component for Vue.js 3 Demo. I draw your attention to the fact that this component is not finished yet, its functionality can be changed, removed and supplemented.

  • Add / edit / delete comments.
  • Adding files. If there is more than one file - view in the form of a gallery.
  • Emoji. Unicode characters are used as emoji. The representation of the emoji depend of the system. Will be possible that the system don't have all the representations.
  • Convert http / https to hyperlink.
  • Loading comments.
  • The ability to limit the display of text by the number of lines / characters.
  • Likes / Dislikes.
  • Adaptation for mobile devices.

Install

npm install @x-store/vue-comments --save

or

yarn add @x-store/vue-comments
import Comments from '@x-store/vue-comments'
import '@x-store/vue-comments/dist/vue-comments.css'

Usage example

options - component settings

commentsData - initialization data. The description of the fields can be found at this link: Back-End

options.user.auth - the parameter must be "true" so that the user can leave comments / like.

<Comments :options="options" :commentsData="comments" />

import Comments from '@x-store/vue-comments'
import '@x-store/vue-comments/dist/vue-comments.css'

export default {
  components: {
    Comments
  },
  data() {
    return {
      options: {
        dataApi: {
          vote: {
            url: "/api/comments/vote/",
          },
          commentAdd: {
            url: "/api/comments/",
          },
          commentDelete: {
            url: "/api/comments/",
          },
          commentEdit: {
            url: "/api/comments/",
          },
          commentsListGet: {
            url: "/api/comments/",
          },
        },
        user: {
          auth: true,
          name: "Jhon",
          img: "https://evgeniysaschenko.github.io/vue-comments/user.jpg"
        }
      },
      comments: {
        mapItems: {
          0: { items: [1549], quantity: 1 },
          1549: { items: [1550], quantity: 1 },
          1550: { items: [], quantity: 0 },
        },
        items: {
          1549: {
            dateCreate: 1632329876,
            dateUpdate: 1632329889,
            dislike: 0,
            like: 0,
            voteValue: 0,
            files: [],
            id: 1549,
            isManageDelete: false,
            isManageEdit: false,
            parentId: 0,
            text: "text πŸ˜‡πŸ˜‡πŸ˜‡πŸ˜‡",
            userImg: "https://evgeniysaschenko.github.io/vue-comments/user.jpg",
            userName: "Jhon",
          },
          1550: {
            dateCreate: 1632329876,
            dateUpdate: 1632329889,
            dislike: 0,
            like: 50,
            voteValue: 1,
            files: [
              {
                name: "image 1",
                preview: "https://evgeniysaschenko.github.io/vue-comments/preview.jpg",
                src: "https://evgeniysaschenko.github.io/vue-comments/image.jpg",
              },
            ],
            id: 1550,
            isManageDelete: false,
            isManageEdit: false,
            parentId: 1549,
            text: "text text",
            userImg: "",
            userName: "Ivan",
          },
        },
      }
    }
  },
}

You can change the options after the component has been mounted by using Object.assign():

Object.assign(this.options, { validExtensions: ["jpg"] });

If initialization data needs to be received asynchronously, use v-if to display the component:

  <Comments v-if="isShow" :commentsData="comments" />

  export default {
    components: {
      Comments
    },
    async created() {
      let response = await fetch("/api/comments/?parentId=0&createUser=1");
      let comments = await response.json();
      this.comments = comments;
      this.isShow = true;
    },
    data() {
      return {
        isShow: false,
        comments: {},
        user: {
          auth: true,
          img: "https://vue-comments.ua-ix.biz/images/users/2.jpg"
        }
      }
    },
  }

Options

You can change the behavior of the component using the options

Options description

Current user

ParameterTypeDefaultDescription
nameStringUser NameUser name
imgStringimage userUser avatar
authBooleanfalseThis parameter allows you to add comments if set to "true"

Files

ParameterTypeDefaultDescription
filesMaxCountNumberInfinityMaximum number of files to upload
validExtensionsArray"jpg", "png", "jpeg", "jpeg", "gif", "svg", "wbpp"Allowed file extensions
isShowBtnUploadBooleantrueShow button to download files

Comments

ParameterTypeDefaultDescription
isScrollToCommentBooleantrueScroll to added comment
text.minLengthNumber0Minimum text length
text.maxLengthNumber1000Maximum text length
text.briefMaxLengthNumber150Maximum length of preview text (after which the "More" button is added)
text.briefMaxLineNumber / String4Maximum number of lines of preview text (after which the "More" button is added).The values "none" and "number greater than 0"
list.mainShowStartNumber5On first boot The number of comments in the main list before "Show more"
list.secondShowStartNumber1On first boot The number of comments in the nested list before "Show more" appears
list.mainShowNumber5Π‘lick "Show more" The number of comments that are displayed in the main list when you click on the button "Show more"
list.secondShowNumber3Π‘lick "Show more" The number of comments that are displayed in the second list when you click on the button "Show more"
deleteCommentBeforeFunction() => <br>{ return new Promise((resolve, reject) => { resolve }You can describe here the action that must be performed before deleting a comment. If resolve() is called, the comment will be removed, unless reject() the comment is removed.
deleteCommentAfterFunction() => <br>{ return new Promise((resolve, reject) => { resolve }You can describe here the action that must be performed after deleting a comment. If resolve() is called, the action will be committed, If reject() is called, the action will not be performed.

Translation

ParameterTypeDefaultDescription
translation.btnAnswerStringAnswerAnswer button
translation.btnΠ•xpandStringMoreExpand text button
translation.btnCollapseStringCollapseCollapse button
translation.btnFileDownloadStringDownloadFile download button
translation.fileDeleteStringDeleteFile delete button
translation.fileRestoreStringRestoreFile restore button
translation.dateTodayStringTodayText of today's date "Today"
translation.dateYesterdayStringYesterdayYesterday's date text "Yesterday"
translation.dateEditedTextStringEditedText before editing date
translation.settingsDeleteStringDeleteDelete setting text
translation.settingsEditStringEditEdit setting text
translation.btnMoreStringShow moreButton "Show more" comments
translation.btnMoreAnswersStringShow answersButton "Show answers" comments
translation.formPlaceholderStringAdd a commentPlaceholder form
translation.btnΠ‘ancelEditingStringΠ‘ancel editingAnswer button
translation.formAnswerToStringAnswer toPhrase in the form when replying to a comment
translation.messageFileParamsStringMaximum file size 2 Mb, supported extentions: jpg, png, jpeg, jpeg, gif, svg, wbppInformation about the maximum file size and supported extensions
translation.errorFormSendStringError sending formIf this field is replaced with an empty string, the response from the server can be used as an error message (the response must be a string)
translation.errorVoteSendStringError sending vote
translation.errorUnexpectedStringUnexpected error
translation.errorGetCommentsStringError get comments
translation.errorFileExtensionStringError file extension
translation.errorFileSizeStringError file size
translation.errorFileMaxCountStringError file limit exceeded
translation.errorTextLengthStringThe length of the text must be between 0 and 1000 characters

Data Api

ParameterTypeDefaultDescription
dataApi.voteObjectsend: function url: "/" params.method: "POST" typeData: "form-data"Like / Dislike
dataApi.commentsListGetObjectsend: function url: "/" params.method: "GET" typeData: "query"Get a list of comments
dataApi.commentAddObjectsend: function url: "/" params.method: "POST" typeData: "form-data"Add a comment
dataApi.commentEditObjectsend: function url: "/" params.method: "PUT" typeData: "form-data"Edit a comment
dataApi.commentDeleteObjectsend: function url: "/" params.method: "DELETE" typeData: "form-data"Delete a comment
Note

url - url of the server that processes the request

typeData - Indicates how to prepare data for sending to the server. The options could be like this json, query, form-data

params - the method of sending is specified here, you can also add additional headers

send: function - this function is used to send data to the server, it uses the "fetch" method, if you need to use another method, the "send" function can be replaced with your own, but it must accept and return data as the code below does:

send: ({ url, params }) => {
  return fetch(url, params).then((response) => {
    if (!response.ok) {
      return response.json().then((error)=> {
        throw error?.error;
      });
    }
    return response.json();
  });
}

Other

ParameterTypeDefaultDescription
parentIdStartNumber / String0This id is for mapItems, it describes the first level of comments.
emojiLilstArray"πŸ˜€", "πŸ˜ƒ", "πŸ˜„", "😁", "πŸ˜†", "πŸ˜…", "πŸ˜‚", "🀣", "πŸ˜‡", "πŸ˜‰", "😊", "πŸ™‚", "πŸ™ƒ", "πŸ˜‹", "😌", "😍", "πŸ₯³", "😘", "πŸ˜—", "😚", "πŸ€ͺ", "😜", "😎", "πŸ˜“", "πŸ‘Œ", "πŸ‘‹", "πŸ‘", "πŸ‘Ž"List emoji
formAddShowAlwaysBooleantrueUsing this parameter, you can show or hide the form for adding a comment. This may be needed if you do not want to show the form when the user is not logged in.
btnAnswerShowAlwaysBooleantrueUse this option to show or hide the Reply to Comment button. This may be needed if you do not want to show the button when the user is not logged in.
imgDefaultUserStringimage userDefault user avatar.
isShowVoteBooleantrueIf true, like / dislike buttons are displayed
isShowBtnEmojiBooleantrueShow button Emoji
yourCssClassStringYou can add your css class to the parent tag

Options example

      {
        parentIdStart: 0,
        isShowVote: true,
        yourCssClass: "",
        filesMaxCount: Infinity,
        fileMaxSize: 2097152,
        validExtensions: ["jpg", "png", "jpeg", "jpeg", "gif", "svg", "wbpp"],
        emojiLilst: ["πŸ˜€", "πŸ˜ƒ", "πŸ˜„", "😁", "πŸ˜†", "πŸ˜…", "πŸ˜‚", "🀣", "πŸ˜‡", "πŸ˜‰", "😊", "πŸ™‚", "πŸ™ƒ", "πŸ˜‹", "😌", "😍", "πŸ₯³", "😘", "πŸ˜—", "😚", "πŸ€ͺ", "😜", "😎", "πŸ˜“", "πŸ‘Œ", "πŸ‘‹", "πŸ‘", "πŸ‘Ž"],
        isScrollToComment: true,
        isShowBtnUpload: true,
        isShowBtnEmoji: true,
        text: {
          minLength: 0,
          maxLength: 1000,
          briefMaxLength: 150,
          briefMaxLine: 4,
        },
        list: {
          mainShowStart: 5,
          secondShowStart: 1,
          mainShow: 5,
          secondShow: 3,
        },
        translation: {
          btnAnswer: "Answer",
          btnΠ•xpand: "More",
          btnCollapse: "Collapse",
          btnFileDownload: "Download",
          formPlaceholder: "Add a comment",
          fileDelete: "Delete",
          fileRestore: "Restore",
          dateToday: "Today",
          dateYesterday: "Yesterday",
          settingsDelete: "Delete",
          settingsEdit: "Edit",
          dateEditedText: "Edited:",
          btnΠ‘ancelEditing: "Π‘ancel editing",
          btnMore: "Show more",
          btnMoreAnswers: "Show answers",
          formAnswerTo: "Answer to",
          messageFileParams:
            "Maximum file size 2 Mb, supported extentions: jpg, png, jpeg, jpeg, gif, svg, wbpp",
          errorFormSend: "Error sending form",
          errorVoteSend: "Error sending vote",
          errorUnexpected: "Unexpected error",
          errorGetComments: "Error get comments",
          errorFileExtension: "Error file extension",
          errorFileSize: "Error file size",
          errorFileMaxCount: "Error file limit exceeded",
          errorTextLength: "The length of the text must be between 0 and 1000 characters",
        },

        dataApi: {
          vote: {
            send: ({ url, params }) => {
              return fetch(url, params).then((response) => {
                if (!response.ok) {
                  return response.json().then((error)=> {
                    throw error?.error;
                  });
                }
                return response.json();
              });
            },
            url: "/",
            params: {
              method: "POST",
            },
            typeData: "",
          },
          commentsListGet: {
            send: ({ url, params }) => {
              return fetch(url, params).then((response) => {
                if (!response.ok) {
                  return response.json().then((error)=> {
                    throw error?.error;
                  });
                }
                return response.json();
              });
            },
            url: "/",
            params: {
              method: "GET",
            },
            typeData: "query",
          },
          commentAdd: {
            send: ({ url, params }) => {
              return fetch(url, params).then((response) => {
                if (!response.ok) {
                  return response.json().then((error)=> {
                    throw error?.error;
                  });
                }
                return response.json();
              });
            },
            url: "/",
            params: {
              method: "POST",
            },
            typeData: "",
          },
          commentEdit: {
            send: ({ url, params }) => {
              return fetch(url, params).then((response) => {
                if (!response.ok) {
                  return response.json().then((error)=> {
                    throw error?.error;
                  });
                }
                return response.json();
              });
            },
            url: "/",
            params: {
              method: "PUT",
            },
            typeData: "",
          },
          commentDelete: {
            send: ({ url, params }) => {
              return fetch(url, params).then((response) => {
                if (!response.ok) {
                  return response.json().then((error)=> {
                    throw error?.error;
                  });
                }
                return response.json();
              });
            },
            url: "/",
            params: {
              method: "DELETE",
            },
            typeData: "",
          },
        },
        user: {
          name: "User Name",
          img: "/img/default-user.png",
          auth: false,
        },
        formAddShowAlways: true,
        btnAnswerShowAlways: true,
        imgDefaultUser: "/img/default-user.png",
        deleteCommentBefore: () => {
          return new Promise((resolve, reject) => {
            resolve();
          });
        },
        deleteCommentAfter: () => {
          return new Promise((resolve, reject) => {
            resolve();
          });
        },
      }

Events

You can get information about what action the user has taken (for example, the user has put a like), for this you need to add a message-comment listener to the component

Events example

<Comments @message-comment="messageComment($event)" />

export default {
  methods: {
    messageComment(data) {
      console.log(data);
    }
  }
}

Events description

TypeDescription
comment-addAdding a comment
comment-editEditing a comment
comment-deleteDeleting a comment
comments-showBy pressing the button "Show more comments"
voteLike / Dislike
user-no-authIf the user is not logged in

Development wich Docker

  1. Install docker
  2. In order for user to get "root" rights in "Docker", you must run the command: *This is not required, but if this is not done in some situations it may be inconvenient to work
  • For current user
sudo usermod -aG docker ${USER}
  • For other user
sudo usermod -aG docker username123

After that, you need to restart your computer.

  1. To start developing. Run the following commands in the project folder:
  • Create container
docker compose build
  • Run container
docker compose up

Dev-server started in address http://localhost:8080/, api-sever started in address http://localhost:8888/

  1. Preparation for publication in "NPM" / "GitHub":
  • Create "build files" in Docker (npm run build) and copy the files from Docker to a local computer
docker compose --file docker-compose-npm.yml up && docker cp -a vue-comments--front-end:/usr/src/app/vue-comments/dist-demo ./  && docker cp -a vue-comments--front-end:/usr/src/app/vue-comments/dist  ./
  1. The created folder "dist-demo" must be replaced with "https://github.com/EvgeniySaschenko/comments-api-server", in the folder "public"

  2. Upload all changes to https://github.com/. "vue-comments" publish to "npm". "comments-api-server" upload to https://vue-comments.ua-ix.biz/.

Useful Commands

  • Copy file from local computer to Docker container
docker cp -a ./package.json vue-comments--front-end:/usr/src/app/vue-comments
  • Copy a file from a Docker container to a local computer
docker cp -a vue-comments--front-end:/usr/src/app/vue-comments/dist ./
0.1.13

10 months ago

0.1.14

6 months ago

0.1.12

12 months ago

0.1.10

1 year ago

0.1.11

1 year ago

0.1.9

1 year ago

0.1.8

1 year ago

0.1.7

1 year ago

0.1.6

3 years ago

0.1.5

3 years ago

0.1.4

3 years ago

0.1.3

3 years ago

0.1.2

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago