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

miya-chat

v1.0.2

Published

Made with create-react-library

Downloads

1

Readme

miya-chat-library

NPM JavaScript Style Guide

Install

npm install --save miya-chat-library

TECHENGINESSRL

Usage 1

import MiYaChat from 'miya-chat-library'
import React from 'react'
import ReactDOM from 'react-dom'
import 'miya-chat-library/dist/index.css'

const div = document.createElement('div')
div.id = 'miya-chat-div'
document.body.appendChild(div)
ReactDOM.render(<MiYaChat text='123123123' />, div)

Usage 2

备注

#chat-component css style id选择器为整个chat的主题颜色

--floating-button-color: #ff550a !important

floating-button 和 notification 背景颜色

.single-select-input-button

.multi-select-input-button

.page-link-submit-button

.page-link-cancel-button

window.chat

  window.chat = {
    appId: "4efb89122",//每个应用(客户)的ID,由平台派发,固定值
    fingerprint: "",//浏览器指纹,可写入自定义 session id用于标记的访问用户
    // topic: "massima-energia/public",//chat对话主题,由平台派发,固定值
    topic: "massima-energia/clients",
    // topic: "demo",
    titleText: "Massimo",//chat对话框标题
    titleLogo: "./images/logo_massima_bianco.png",//chat对话框标题左边图标
    chatLogo: "./images/logo_massima_verde.png",//chat对话框消息部分bot头像
    chatLogoAnimation: "./images/logo_massima_verde.png",//chat对话框消息部分bot动画头像,动画只支持svg文件
    toolTipTitleText: "Ciao, sono Massimo.",//floating button tooltips text 标题
    toolTipMessageText: "L'assistente virtuale di Massima Energia.",//floating button tooltips text 内容
    defaultOpenChat: false,//表示默认chat对话框是否打开,为false时,页面打开显示floating button
    onLoaded: function() {
      // session id init

      // Initialize the agent at application startup.
      // You can also use https://openfpcdn.io/fingerprintjs/v3/esm.min.js
      const fpPromise = import("https://openfpcdn.io/fingerprintjs/v3").then(FingerprintJS => FingerprintJS.load());
      fpPromise.then(fp => fp.get()).then(result => {
        window.chat.fingerprint = result["visitorId"];
        window.chat.init();
      });
      //onLoaded为chat组件加载完成时主动调用,可以在这里初始化fingerprint的值,和其它一些初始化的动作。再需要显示chat的时修调用init()函数即可。
      //window.chat.init();必须在onLoaded中或onLoaded执行完成后调用.
    }
  };
<style type="text/css">
  #chat-component {
    --primary-color: #075C49 !important;
    --primary-color-50: #075C4980 !important;
    --primary-color-60: #075C4999 !important;
    --floating-button-color: #ff550a !important;
  }

  .single-select-input-button {
    background: #ff550a !important;
    border-radius: 20px !important;
  }

  .multi-select-input-button {
    background: #ff550a !important;
    border-radius: 20px !important;
  }

  .page-link-submit-button {
    background: #ff550a !important;
    border-radius: 20px !important;
  }

  .page-link-cancel-button {
    border-radius: 20px !important;
  }
</style>
<script type="text/javascript">
  window.chat = {
    appId: "4efb89122",
    fingerprint: "",
    // topic: "massima-energia/public",
    topic: "massima-energia/clients",
    // topic: "demo",
    titleText: "Massimo",
    titleLogo: "./images/logo_massima_bianco.png",
    chatLogo: "./images/logo_massima_verde.png",
    chatLogoAnimation: "./images/logo_massima_verde.png",
    toolTipTitleText: "Ciao, sono Massimo.",
    toolTipMessageText: "L'assistente virtuale di Massima Energia.",
    defaultOpenChat: false,
    onLoaded: function() {
      // session id init

      // Initialize the agent at application startup.
      // You can also use https://openfpcdn.io/fingerprintjs/v3/esm.min.js
      const fpPromise = import("https://openfpcdn.io/fingerprintjs/v3").then(FingerprintJS => FingerprintJS.load());
      fpPromise.then(fp => fp.get()).then(result => {
        window.chat.fingerprint = result["visitorId"];
        window.chat.init();
      });
    }
  };
</script>
<script defer="defer" src="./static/js/main.c74e21ed_v1.js"></script>
<link href="./static/css/main.3edc8478_v1.css" rel="stylesheet">

rewind按钮说明

如果中间的一个Message没有rewind操作,前面所有rewind操作将在此处截断

用户连续输入说明

只需要message中 title 字段为空即可

用户重新输入说明,比如API验证密码输入错误,需要重新输入

只需要date中 error字段写入重新输入的错误信息即可

IntegerNumberInput 整数的输入,可以输入负数

{
  id: 'demo-01',
  title: 'How much is your payment monthly (roughly)?',
  input: 'integer-number',
  attributes: {
    placeholder: 'Please enter number',
    maximum: 100,
    minimum: -20,
    defaultValue: '10',
    errors: {
      maximumError: 'the maximum value is 100',
      minimumError: 'the minimum value is -20'
    }
  },
  additional: [
    'feedback',
    'rewind'
  ],
  var_name: 'monthly',
  value_type: 'integer'
}

FloatNumberInput 带小数浮点的输入,可以输入负数

小数点的长度取maximum或minimum的最大值,如果maximum或minimum都写的整数,则默认取2位长度
{
  id: '0-1-10-1',
  title: '',
  input: 'float-number',
  attributes: {
    placeholder: 'Please enter float number',
    maximum: 100.99,
    minimum: -20.20,
    defaultValue: '10.56',
    errors: {
      maximumError: 'the maximum value is 100.99',
      minimumError: 'the minimum value is -20.20'
    }
  },
  additional: [
    'feedback',
    'rewind'
  ],
  var_name: 'mthinsurance',
  value_type: 'integer'
}

GeneralTextInput 一般文本输入,只有长度限制

{
  id: '0-1-10-222',
  title: '',
  input: 'general-text',
  attributes: {
    placeholder: 'Please enter text',
    maxLength: 20,
    minLength: 1,
    defaultValue: 'hello world',
    errors: {
      maxLengthError: 'the maximum length is 20',
      minLengthError: 'the minimum length is 1',
    },
  },
  additional: ['feedback', 'rewind'],
  var_name: 'name',
  value_type: 'string',
}

PasswordTextInput 密码输入

{
  id: '0-1-10-223',
  title: '',
  input: 'password-text',
  attributes: {
    placeholder: 'Please enter password',
    maxLength: 20,
    minLength: 6,
    defaultValue: '',
    errors: {
      maxLengthError: 'the maximum length is 20',
      minLengthError: 'the minimum length is 6',
    },
  },
  additional: ['feedback', 'rewind'],
  var_name: 'password',
  value_type: 'string',
}

PhoneTextInput 手机号输入 formatMatcher为正则,需要根据不同国家的手机号写匹配正则

formatMatcher为空提交时不验证文本格式,只验证长度。固定长度maxLength和minLength相同即可
{
  id: '0-1-10-223',
  title: '',
  input: 'phone-text',
  attributes: {
    placeholder: 'Please enter phone',
    maxLength: 13,
    minLength: 8,
    defaultValue: '',
    formatMatcher: '^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$',
    errors: {
      maxLengthError: 'the maximum length is 13',
      minLengthError: 'the minimum length is 8',
      formatError: 'the phone format error'
    }
  },
  additional: [
    'feedback',
    'rewind'
  ],
  var_name: 'password',
  value_type: 'string'
}

EmailTextInput email输入 email的输入不区分大小写,统一转小写验证

{
  id: '0-1-10-223',
  title: '',
  input: 'email-text',
  attributes: {
    placeholder: 'Please enter email',
    maxLength: 56,
    defaultValue: '',
    formatMatcher: '^[a-z]([a-z0-9]*[-_]?[a-z0-9]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+[\.][a-z]{2,3}([\.][a-z]{2})?$',
    errors: {
      formatError: 'the email format error'
    }
  },
  additional: [
    'feedback',
    'rewind'
  ],
  var_name: 'email',
  value_type: 'string'
}

DateTextInput date输入,验证格式由正则确定

http://momentjs.cn/docs/#/manipulating/add/
today表示今天日期 +d30  今天日期加30天
today表示今天日期 -d30  今天日期减30天
{
  id: '0-1-10-223',
  title: '',
  input: 'date-text',
  attributes: {
    placeholder: 'GG/MM/YYYY',
    maxDate: '31/12/2025',
    minDate: 'today',
    //minDate: '01/01/2012',
    defaultValue: '',
    formatMatcher: 'DD/MM/YYYY',
    errors: {
      formatError: 'the date format error',
      maxDateError: 'the maximum date is {maxDate}',
      minDateError: 'the minimum date is {minDate}',
    },
  additional: [
    'feedback',
    'rewind'
  ],
  var_name: 'date',
  value_type: 'string'
}

SelectInput 列表单选择输入

{
  id: '0-1-10-2',
  title: '',
  input: 'list-select',
  list: [{ key: 'Yes', value: 'Y' }, { key: 'No', value: 'N' }],
  additional: ['feedback'],
  var_name: 'select',
  value_type: 'string'
}

MultiSelectInput 列表多选择输入

{
  id: '0-1-10-2',
  title: '',
  input: 'multi-select',
  list: [
    { key: 'Sposato(a)', value: 'M' },
    { key: 'Single', value: 'S' },
    { key: 'Convivente', value: 'C' },
    { key: 'Separato(a) / Divorziato(a)', value: 'D' },
    { key: 'Vedovo(a)', value: 'W' }
  ],
  additional: ['feedback', 'rewind'],
  var_name: 'select',
  value_type: 'string'
}

SingleSelectInput 列表单选择输入

{
  id: '0-1-10-2',
  title: '',
  input: 'single-select',
  attributes: {
    select: {
      key: `<div>Confermo la presa visione dell'<a href="#">Informativa sulla Privacy</a> (Informativa ai sensi degli
    articoli 13 e 14 del Regolamento Europeo 2016/679 e della normativa italiana di armonizzazione)<br/>
    Inserimento di dati di contatto:</div>`,
      value: 'confermo',
    },
  },
  additional: ['feedback', 'rewind'],
  var_name: 'single-select',
  value_type: 'string'
}

FuzzySearchTextInput 搜索输入,有一个字段defaultList用于存放热门搜索结果集,组件加载时就显示了,用户可以直接选择输入

搜索接口对应POST /fuzzy-search
const { search: { keyword, referenceId } } = req.body
referenceId为当前bot message的id
{
  id: 'demo-01',
  title: 'Come ti chiami (può essere un soprannome)?',
  attributes: {
    placeholder: 'Inserisci 2 lettere e seleziona',
    maxLength: 13,
    minLength: 2,
    errors: {
      maxLengthError: 'the maximum length is 20',
      minLengthError: 'the minimum length is 1',
    },
    defaultList: [
      { key: 'Aiuto giardiniere', value: '21' },
      { key: 'Allenatore cavalli', value: '22' },
      { key: 'Allenatore di cani', value: '23' },
      { key: 'Allenatore professionale', value: '24' },
      { key: 'Allenatore sportivo', value: '25' },
      { key: 'Allennatore non professionale', value: '26' },
      { key: 'Allevatore', value: '27' },
    ],
  },
  input: 'fuzzy-search-text',
  additional: ['feedback', 'rewind'],
  var_name: 'search',
  value_type: 'string'
}

SelectDateTimeInput 时间选择输入

days向后可选天数,skipWeek是否跳过周未,times定义当天可选的工作时间段,没有的取默认值
times要过滤当天已经过时间段,需要再后端API中过滤,组件只做显示,times的日期为空数组时会被忽略
组件暂时不支持取实时的 times
holidays为排除指定日期的时间,当holidays的日期为空时,表示禁用当天日期的选择,不空为时只禁用时间
{
  id: 'demo-01', title: 'Choose a meeting time.', input: 'datetime-select', attributes: {
    selectable: {
      days: 30, skipWeek: true, times: {
        '2022-03-08': ['08:30', '09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '14:00', '14:30', '15:00'], '2022-03-09': ['09:30', '10:00', '10:30', '11:00'],
      },
      holidays: [{ '2022-04-18': ['09:30', '10:00', '10:30', '14:00'] }]
    }, defaultWorkHours: [
      '08:00', '08:30', '09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00', '18:30'],
  }, additional: ['feedback', 'rewind'],
}

Upload 文件或图片上传输入

{
          id: 'demo-01',
          title: 'Choose a  uploads file.',
          input: 'upload',
          attributes: {
            accept: 'accept=image/*',
            imgExtension: ['.jpg', '.gif', '.png'],
            maxFileSize: 5242880,
            fileSizeError: ' file size is too big',
            fileTypeError: ' is not supported file extension',
            singleImage: false,
          },
          additional: ['feedback', 'rewind'],
}

Result 结果返回

result中的title不支持数组,results本身是一个数据,要实现多次输出,只需要在result中加入 {title:"",type:"text"} 即可
*建议title不显示时也写一个不空为的title,可以是下面按钮的描述,方便阅读理解

result中的type button有两个值 为button1和button2

区别 button1中,buttons中每项有一个title值单独显示在button上面,results中的titles不显示
    button2中,buttons中每项没有title,results中的title显示在最上面。

tooltips为链接跳转时的重定向提示文字,默认为空

当display为false时,所有的title不显示

link有字符串值"message","tel:213123123"
     Object值 {url:"http://www.google.com",visible:"false"}
     visible为url是否在跳转提示页面中显示。默认是true.
{
    id: '2-3-2-2',
    input: 'result',
    display:false
    results: [
      {
        title: 'Visualizza la guida alla lettura:',
        type: 'button1',
        buttons: [
          {
            title: 'Vai alla guida', text: 'Vai alla guida', style: { background: '#ff550a', borderRadius: 20, color: '#fff' },
            link: { url: `https://www.massimaenergia.it/bolletta-2-0`, visible: false },
            tooltips: 'Stai per essere reindirizzato alla guida alla lettura della bolletta',
          },
          {
            title: 'Riavvia la chat', text: 'Riavvia la chat', style: { background: 'aliceblue', borderRadius: 20, color: 'rgb(0 0 0)' },
            link: `message`,
          },
        ],
      },
    ],
    additional: ['feedback', 'rewind'],
}

Message 结果返回

当input为Message时间,显示一个独立的bot消息,同时会接着自动请求下一个消息,撤回时,为message question的上一个index
  {
    id: '1-1-3',
    title: [
      `<div><strong>COSA E'</strong><br> </div>`,
      `<div> <strong>MODALITA'</strong><br/></div>`],
    input: 'message',
  },

特殊字段说明

{
  id: '1',
  title: 'Consenso trattativa dati personali',
  input: 'single-select',
  display: false,
  attributes: {
    select: {
      key: `<div>Confermo la presa visione dell'<a href="#" target="_blank">Informativa sulla Privacy</a> (Informativa ai sensi degli
    articoli 13 e 14 del Regolamento Europeo 2016/679 e della normativa italiana di armonizzazione)<br/>
    Inserimento di dati di contatto:</div>`,
      value: 'confermo',
    },
    record: 'none',
  },
  additional: ['feedback', 'rewind'],
}
1. display:false  表示bot边上的message不显示,不写默认为true
   当title为空时 bot边上的message也不显示,使用display为保留title在数据记录中
   根据使用场景决定使用
2. record: 'none' 表示当 action input 输入提交后,bot边上的message和user边上的message不在界面上显示,不写默认为block

命令执行

参数字段放在  attributes>command中
cond为条件字段,目前只做了value的对比。
func为函数名
arg为函数参数

command的目前为同步等待执行,异步状态待开发...
{
  id: '2',
  title: 'Possiamo esserti d\'aiuto con altro? ',
  input: 'list-select',
  list: [
    { key: 'Sì', value: 'si' },
    { key: 'No, grazie', value: 'no' },
  ],
  attributes: {
    command: { cond: 'no', func: 'doClose', arg: [] },
  },
  additional: ['feedback', 'rewind'],
  var_name: 'LIST_RESTART',
  value_type: 'text',
}

i18

react-i18next

chat初始化语言跟随window.chat.language变量变化而变化,默认值为en

  window.chat.language = "en" | "zh" | "ita"
  • How to use
// use hook
export function MyComponent() {
  const { t, i18n } = useTranslation();
  // or const [t, i18n] = useTranslation();

  return (
  <p>{t('my translated text')}</p>
  // or <Component label={t('my translated text')} />
  )
}

// use HOC

import { withTranslation } from 'react-i18next';

function MyComponent({ t, i18n }) {
  return <p>{t('my translated text')}</p>
}

export default withTranslation()(MyComponent);

// render prop
import { Translation } from 'react-i18next';

export function MyComponent() {
  return (
    <Translation>
      {
        (t, { i18n }) => <p>{t('my translated text')}</p>
      }
    </Translation>
  )
}
  • How to add new language
  // add new json file in src/locales/xx/translation.json
  // add new language in src/locales/i18n.js
  const resources = {
    ...
    newLanguage: {
      translation: require('./xx/translation.json')
    }
  }

 // or
  import translationNewLang from './xx/translation.json'
  const resources = {
    ...
    newLanguage: {
      translation: translationNewLang
      }
  }
  • Suppoer multiple Translation Files
  // add new json file in src/locales/xx/xxx.json
  // add new file in src/locales/i18n.js
  const resources = {
    ...
    newLanguage: {
      translation: require('./xx/translation.json'),
      xxx: require('./xx/xxx.json')
    }
  }

  // use
  const { t } = useTranslation(['translation', 'xxx']);

For more usage, see multiple Translation Files

  • todo 由于当前只语言是通过window.chat.language变量来控制的,所以在切换语言时,需要手动刷新页面。 后续若需自动刷新页面,可在chat组件中监听window.chat.language变量的变化,然后调用i18n.changeLanguage方法。