npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@x-store/vue-comments

v0.1.14

Published

A comments component for Vue.js 3

Downloads

10

Readme

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

| Parameter | Type | Default | Description | | --- | :---: | --- | --- | | name | String | User Name | User name | | img | String | image user | User avatar | | auth | Boolean | false | This parameter allows you to add comments if set to "true" |

Files

| Parameter | Type | Default | Description | | --- | :---: | --- | --- | | filesMaxCount | Number | Infinity | Maximum number of files to upload | | validExtensions | Array | ["jpg", "png", "jpeg", "jpeg", "gif", "svg", "wbpp"] | Allowed file extensions | | isShowBtnUpload | Boolean | true | Show button to download files |

Comments

| Parameter | Type | Default | Description | | --- | :---: | --- | --- | | isScrollToComment | Boolean | true | Scroll to added comment | | text.minLength | Number | 0 | Minimum text length | | text.maxLength | Number | 1000 | Maximum text length | | text.briefMaxLength | Number | 150 | Maximum length of preview text (after which the "More" button is added) | | text.briefMaxLine | Number / String | 4 | Maximum number of lines of preview text (after which the "More" button is added).The values "none" and "number greater than 0" | | list.mainShowStart | Number | 5 | On first boot The number of comments in the main list before "Show more" | | list.secondShowStart | Number | 1 | On first boot The number of comments in the nested list before "Show more" appears | | list.mainShow | Number | 5 | Сlick "Show more" The number of comments that are displayed in the main list when you click on the button "Show more" | | list.secondShow | Number | 3 | Сlick "Show more" The number of comments that are displayed in the second list when you click on the button "Show more" | | deleteCommentBefore | Function | () => <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. | | deleteCommentAfter | Function | () => <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

| Parameter | Type | Default | Description | | --- | :---: | --- | --- | | translation.btnAnswer | String | Answer | Answer button | | translation.btnЕxpand | String | More | Expand text button | | translation.btnCollapse | String | Collapse | Collapse button | | translation.btnFileDownload | String | Download | File download button | | translation.fileDelete | String | Delete | File delete button | | translation.fileRestore | String | Restore | File restore button | | translation.dateToday | String | Today | Text of today's date "Today" | | translation.dateYesterday | String | Yesterday | Yesterday's date text "Yesterday" | | translation.dateEditedText | String | Edited | Text before editing date | | translation.settingsDelete | String | Delete | Delete setting text | | translation.settingsEdit | String | Edit | Edit setting text | | translation.btnMore | String | Show more | Button "Show more" comments | | translation.btnMoreAnswers | String | Show answers | Button "Show answers" comments | | translation.formPlaceholder | String | Add a comment | Placeholder form | | translation.btnСancelEditing | String | Сancel editing | Answer button | | translation.formAnswerTo | String | Answer to | Phrase in the form when replying to a comment | | translation.messageFileParams | String | Maximum file size 2 Mb, supported extentions: jpg, png, jpeg, jpeg, gif, svg, wbpp | Information about the maximum file size and supported extensions | | translation.errorFormSend | String | Error sending form | If 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.errorVoteSend | String | Error sending vote | | | translation.errorUnexpected | String | Unexpected error | | | translation.errorGetComments | String | Error get comments | | | translation.errorFileExtension | String | Error file extension | | | translation.errorFileSize | String | Error file size | | | translation.errorFileMaxCount | String | Error file limit exceeded | | | translation.errorTextLength | String | The length of the text must be between 0 and 1000 characters | |

Data Api

| Parameter | Type | Default | Description | | --- | :---: | --- | --- | | dataApi.vote | Object | send: function url: "/" params.method: "POST" typeData: "form-data" | Like / Dislike | | dataApi.commentsListGet | Object | send: function url: "/" params.method: "GET" typeData: "query" | Get a list of comments | | dataApi.commentAdd | Object | send: function url: "/" params.method: "POST" typeData: "form-data" | Add a comment | | dataApi.commentEdit | Object | send: function url: "/" params.method: "PUT" typeData: "form-data" | Edit a comment | | dataApi.commentDelete | Object | send: 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

| Parameter | Type | Default | Description | | --- | :---: | --- | --- | | parentIdStart | Number / String | 0 | This id is for mapItems, it describes the first level of comments. | | emojiLilst | Array | ["😀", "😃", "😄", "😁", "😆", "😅", "😂", "🤣", "😇", "😉", "😊", "🙂", "🙃", "😋", "😌", "😍", "🥳", "😘", "😗", "😚", "🤪", "😜", "😎", "😓", "👌", "👋", "👍", "👎"] | List emoji | | formAddShowAlways | Boolean | true | Using 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. | | btnAnswerShowAlways | Boolean | true | Use 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. | | imgDefaultUser | String | image user | Default user avatar. | | isShowVote | Boolean | true | If true, like / dislike buttons are displayed | | isShowBtnEmoji | Boolean | true | Show button Emoji | | yourCssClass | String | | You 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

| Type | Description | | --- | --- | | comment-add | Adding a comment| | comment-edit | Editing a comment | | comment-delete | Deleting a comment | | comments-show | By pressing the button "Show more comments" | | vote | Like / Dislike | | user-no-auth | If 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 ./