@opentiny/tiny-robot 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/extensions.json +3 -0
- package/README.md +1 -0
- package/dist/_virtual/_plugin-vue_export-helper.js +9 -0
- package/dist/bubble-item/components/actions/copy.vue.d.ts +10 -0
- package/dist/bubble-item/components/actions/index.d.ts +2 -0
- package/dist/bubble-item/components/actions/refresh.vue.d.ts +2 -0
- package/dist/bubble-item/components/icons/ai.vue.d.ts +2 -0
- package/dist/bubble-item/components/icons/index.d.ts +2 -0
- package/dist/bubble-item/components/icons/user.vue.d.ts +2 -0
- package/dist/bubble-item/index.d.ts +7 -0
- package/dist/bubble-list/bubble-list.vue.d.ts +5 -0
- package/dist/bubble-list/index.d.ts +8 -0
- package/dist/bubble-list/index.type.d.ts +55 -0
- package/dist/conversations/index.d.ts +7 -0
- package/dist/conversations/index.vue.d.ts +2 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +29 -0
- package/dist/node_modules/.pnpm/@opentiny_utils@3.22.0/node_modules/@opentiny/utils/dist/index.es.js +2202 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-button@3.22.0/node_modules/@opentiny/vue-button/lib/index.js +113 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-button@3.22.0/node_modules/@opentiny/vue-button/lib/pc.js +93 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-common@3.22.0/node_modules/@opentiny/vue-common/lib/index.js +725 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-dialog-box@3.22.0/node_modules/@opentiny/vue-dialog-box/lib/index.js +198 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-dialog-box@3.22.0/node_modules/@opentiny/vue-dialog-box/lib/pc.js +204 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-directive@3.22.0/node_modules/@opentiny/vue-directive/index.js +57 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/useEventListener.js +10 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/useInstanceSlots.js +14 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/useRelation.js +54 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/vue-popper.js +85 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-hooks@3.22.0/node_modules/@opentiny/vue-hooks/dist/src/vue-popup.js +69 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/close.js +29 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/eyeclose.js +42 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/eyeopen.js +43 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/finish.js +34 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/fullscreen.js +30 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/loading-shadow.js +78 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/minscreen.js +30 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-add-column-after.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-add-column-before.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-add-row-after.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-add-row-before.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-align-center.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-align-left.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-align-right.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-bold.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-code-block.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-code-view.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-color.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-delete-column.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-delete-row.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-delete-table.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-font-size.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-format-clear.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h1.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h2.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h3.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h4.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h5.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-h6.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-heading.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-high-light.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-image.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-italic.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-line-height.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-link-unlink.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-link.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-list-ordered.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-list-unordered.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-merge-cells-vertical.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-merge-cells.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-node-delete.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-paragraph.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-quote-text.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-redo.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-split-cells-horizontal.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-split-cells-vertical.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-strike-through.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-subscript.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-superscript.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-table.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-task-list.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-underline.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/rich-text-undo.js +24 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/sub-script.js +29 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-icon@3.22.0/node_modules/@opentiny/vue-icon/lib/warn.js +26 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-input@3.22.0/node_modules/@opentiny/vue-input/lib/index.js +196 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-input@3.22.0/node_modules/@opentiny/vue-input/lib/pc.js +568 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-locale@3.22.0/node_modules/@opentiny/vue-locale/lib/index.js +1783 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/button/index.js +13 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/button/vue.js +34 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/chunk-G2ADBYYC.js +12 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/dialog-box/index.js +135 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/dialog-box/vue.js +149 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/input/index.js +228 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/input/vue.js +263 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tall-storage/index.js +63 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tall-storage/vue-storage-box.js +16 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tall-storage/vue.js +23 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tooltip/index.js +77 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-renderless@3.22.0/node_modules/@opentiny/vue-renderless/tooltip/vue.js +90 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-tooltip@3.22.0/node_modules/@opentiny/vue-tooltip/lib/index.js +176 -0
- package/dist/node_modules/.pnpm/@opentiny_vue-tooltip@3.22.0/node_modules/@opentiny/vue-tooltip/lib/pc.js +248 -0
- package/dist/node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/decode.js +277 -0
- package/dist/node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/decode_codepoint.js +46 -0
- package/dist/node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/generated/decode-data-html.js +7 -0
- package/dist/node_modules/.pnpm/entities@4.5.0/node_modules/entities/lib/esm/generated/decode-data-xml.js +7 -0
- package/dist/node_modules/.pnpm/linkify-it@5.0.0/node_modules/linkify-it/index.js +187 -0
- package/dist/node_modules/.pnpm/linkify-it@5.0.0/node_modules/linkify-it/lib/re.js +19 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_Symbol.js +5 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseGetTag.js +10 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_baseTrim.js +8 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_freeGlobal.js +4 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_getRawTag.js +15 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_objectToString.js +7 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_root.js +5 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/_trimmedEndIndex.js +9 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/debounce.js +54 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isObject.js +7 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isObjectLike.js +6 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/isSymbol.js +9 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/now.js +7 -0
- package/dist/node_modules/.pnpm/lodash-es@4.17.21/node_modules/lodash-es/toNumber.js +22 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/html_blocks.js +67 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/html_re.js +5 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/common/utils.js +164 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/index.js +8 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_destination.js +44 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_label.js +21 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/helpers/parse_link_title.js +37 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/index.js +112 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_block.js +63 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_core.js +34 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/parser_inline.js +96 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/commonmark.js +78 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/default.js +40 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/presets/zero.js +59 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/renderer.js +127 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/ruler.js +95 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/blockquote.js +59 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/code.js +23 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/fence.js +30 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/heading.js +28 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/hr.js +27 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/html_block.js +37 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/lheading.js +43 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/list.js +110 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/paragraph.js +25 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/reference.js +95 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/state_block.js +84 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_block/table.js +99 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/block.js +7 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/inline.js +10 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/linkify.js +57 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/normalize.js +9 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/replacements.js +31 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/smartquotes.js +80 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/state_core.js +8 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_core/text_join.js +16 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/autolink.js +46 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/backticks.js +31 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/balance_pairs.js +34 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/emphasis.js +57 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/entity.js +33 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/escape.js +32 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/fragments_join.js +10 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/html_inline.js +32 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/image.js +48 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/link.js +40 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/linkify.js +28 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/newline.js +23 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/state_inline.js +27 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/strikethrough.js +54 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/rules_inline/text.js +39 -0
- package/dist/node_modules/.pnpm/markdown-it@14.1.0/node_modules/markdown-it/lib/token.js +31 -0
- package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/index.js +10 -0
- package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/decode.js +61 -0
- package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/encode.js +48 -0
- package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/format.js +7 -0
- package/dist/node_modules/.pnpm/mdurl@2.0.0/node_modules/mdurl/lib/parse.js +74 -0
- package/dist/node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.es6.js +139 -0
- package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Cc/regex.js +4 -0
- package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Cf/regex.js +4 -0
- package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/P/regex.js +4 -0
- package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/S/regex.js +4 -0
- package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/categories/Z/regex.js +4 -0
- package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/index.js +14 -0
- package/dist/node_modules/.pnpm/uc.micro@2.1.0/node_modules/uc.micro/properties/Any/regex.js +4 -0
- package/dist/packages/components/src/assets/icons/accessory.svg.js +4 -0
- package/dist/packages/components/src/assets/icons/loading-speech.svg.js +4 -0
- package/dist/packages/components/src/assets/icons/loading.svg.js +4 -0
- package/dist/packages/components/src/assets/icons/send.svg.js +4 -0
- package/dist/packages/components/src/assets/icons/voice.svg.js +4 -0
- package/dist/packages/components/src/bubble-item/bubble-item.vue.js +7 -0
- package/dist/packages/components/src/bubble-item/bubble-item.vue2.js +111 -0
- package/dist/packages/components/src/bubble-item/components/actions/copy.vue.js +46 -0
- package/dist/packages/components/src/bubble-item/components/actions/copy.vue2.js +4 -0
- package/dist/packages/components/src/bubble-item/components/actions/refresh.vue.js +12 -0
- package/dist/packages/components/src/bubble-item/components/icons/ai.vue.js +45 -0
- package/dist/packages/components/src/bubble-item/components/icons/user.vue.js +63 -0
- package/dist/packages/components/src/bubble-item/index.js +9 -0
- package/dist/packages/components/src/bubble-list/bubble-list.vue.js +7 -0
- package/dist/packages/components/src/bubble-list/bubble-list.vue2.js +52 -0
- package/dist/packages/components/src/bubble-list/index.js +9 -0
- package/dist/packages/components/src/conversations/index.js +9 -0
- package/dist/packages/components/src/conversations/index.vue.js +9 -0
- package/dist/packages/components/src/sender/components/ActionButtons.vue.js +161 -0
- package/dist/packages/components/src/sender/components/ActionButtons.vue2.js +4 -0
- package/dist/packages/components/src/sender/composables/useInputHandler.js +34 -0
- package/dist/packages/components/src/sender/composables/useKeyboardHandler.js +31 -0
- package/dist/packages/components/src/sender/composables/useSpeechHandler.js +67 -0
- package/dist/packages/components/src/sender/index.js +9 -0
- package/dist/packages/components/src/sender/index.vue.js +233 -0
- package/dist/packages/components/src/sender/index.vue2.js +4 -0
- package/dist/packages/components/src/welcome/index.js +9 -0
- package/dist/packages/components/src/welcome/index.vue.js +9 -0
- package/dist/sender/components/ActionButtons.vue.d.ts +23 -0
- package/dist/sender/composables/useInputHandler.d.ts +17 -0
- package/dist/sender/composables/useKeyboardHandler.d.ts +18 -0
- package/dist/sender/composables/useSpeechHandler.d.ts +14 -0
- package/dist/sender/index.d.ts +7 -0
- package/dist/sender/index.type.d.ts +90 -0
- package/dist/sender/index.vue.d.ts +948 -0
- package/dist/style.css +1 -0
- package/dist/welcome/index.d.ts +7 -0
- package/dist/welcome/index.vue.d.ts +2 -0
- package/package.json +42 -0
- package/src/assets/icons/accessory.svg +12 -0
- package/src/assets/icons/loading-speech.svg +16 -0
- package/src/assets/icons/loading.svg +17 -0
- package/src/assets/icons/send.svg +21 -0
- package/src/assets/icons/voice.svg +22 -0
- package/src/bubble-item/bubble-item.vue +264 -0
- package/src/bubble-item/components/actions/copy.vue +47 -0
- package/src/bubble-item/components/actions/index.ts +2 -0
- package/src/bubble-item/components/actions/refresh.vue +27 -0
- package/src/bubble-item/components/icons/ai.vue +30 -0
- package/src/bubble-item/components/icons/index.ts +2 -0
- package/src/bubble-item/components/icons/user.vue +78 -0
- package/src/bubble-item/index.ts +12 -0
- package/src/bubble-list/bubble-list.vue +53 -0
- package/src/bubble-list/index.ts +14 -0
- package/src/bubble-list/index.type.ts +65 -0
- package/src/conversations/index.ts +12 -0
- package/src/conversations/index.vue +3 -0
- package/src/index.ts +30 -0
- package/src/sender/components/ActionButtons.vue +165 -0
- package/src/sender/composables/useInputHandler.ts +69 -0
- package/src/sender/composables/useKeyboardHandler.ts +99 -0
- package/src/sender/composables/useSpeechHandler.ts +128 -0
- package/src/sender/global.d.ts +44 -0
- package/src/sender/index.less +344 -0
- package/src/sender/index.ts +12 -0
- package/src/sender/index.type.ts +111 -0
- package/src/sender/index.vue +289 -0
- package/src/sender/vars.less +84 -0
- package/src/vite-env.d.ts +1 -0
- package/src/welcome/index.ts +12 -0
- package/src/welcome/index.vue +3 -0
- package/tsconfig.json +37 -0
- package/tsconfig.node.json +10 -0
- package/vite.config.ts +53 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Options as MarkdownItOptions } from 'markdown-it'
|
|
2
|
+
import { Component, CSSProperties, VNode } from 'vue'
|
|
3
|
+
|
|
4
|
+
export type BubbleRole = 'ai' | 'user'
|
|
5
|
+
|
|
6
|
+
export interface BubbleRoleConfig {
|
|
7
|
+
avatar?: VNode
|
|
8
|
+
align: 'left' | 'right'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type BubbleStatus = 'loading' | 'generating' | 'aborted' | 'complete' | 'error'
|
|
12
|
+
|
|
13
|
+
export interface BubbleActionOptions {
|
|
14
|
+
name: string
|
|
15
|
+
vnode: VNode | Component
|
|
16
|
+
show?: boolean | ((props: BubbleItemProps) => boolean)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type BubbleAction = 'copy' | 'regenerate' | 'like' | 'dislike' | 'continue' | 'edit' | BubbleActionOptions
|
|
20
|
+
|
|
21
|
+
export interface BubbleItemProps {
|
|
22
|
+
/**
|
|
23
|
+
* 角色,`ai` 或 `user`
|
|
24
|
+
*/
|
|
25
|
+
role: BubbleRole
|
|
26
|
+
/**
|
|
27
|
+
* 内容
|
|
28
|
+
*/
|
|
29
|
+
content?: string
|
|
30
|
+
/**
|
|
31
|
+
* 内容类型
|
|
32
|
+
*/
|
|
33
|
+
type?: 'text' | 'markdown'
|
|
34
|
+
/**
|
|
35
|
+
* 气泡状态
|
|
36
|
+
*/
|
|
37
|
+
status?: BubbleStatus
|
|
38
|
+
/**
|
|
39
|
+
* 角色配置项
|
|
40
|
+
*/
|
|
41
|
+
roleConfig?: BubbleRoleConfig
|
|
42
|
+
/**
|
|
43
|
+
* type 为 'markdown' 时,markdown 的配置项
|
|
44
|
+
*/
|
|
45
|
+
mdConfig?: MarkdownItOptions
|
|
46
|
+
showActions?: boolean
|
|
47
|
+
actions?: BubbleAction[]
|
|
48
|
+
// 样式相关
|
|
49
|
+
maxWidth?: CSSProperties['maxWidth']
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface BubbleActionConfig {
|
|
53
|
+
show?: boolean
|
|
54
|
+
actions?: BubbleAction[]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface BubbleListProps {
|
|
58
|
+
items: BubbleItemProps[]
|
|
59
|
+
roleConfigs?: Partial<Record<BubbleRole, BubbleRoleConfig>>
|
|
60
|
+
mdConfig?: MarkdownItOptions
|
|
61
|
+
actionConfigs?: Partial<Record<BubbleRole, BubbleActionConfig>>
|
|
62
|
+
autoScroll?: boolean
|
|
63
|
+
// 样式相关
|
|
64
|
+
maxWidth?: CSSProperties['maxWidth']
|
|
65
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { App } from 'vue'
|
|
2
|
+
import Conversations from './index.vue'
|
|
3
|
+
|
|
4
|
+
Conversations.name = 'TrConversations'
|
|
5
|
+
|
|
6
|
+
const install = function <T>(app: App<T>) {
|
|
7
|
+
app.component(Conversations.name!, Conversations)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Conversations.install = install
|
|
11
|
+
|
|
12
|
+
export default Conversations as typeof Conversations & { install: typeof install }
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { App } from 'vue'
|
|
2
|
+
import Welcome from './welcome'
|
|
3
|
+
import Conversations from './conversations'
|
|
4
|
+
import BubbleItem from './bubble-item'
|
|
5
|
+
import BubbleList from './bubble-list'
|
|
6
|
+
import Sender from './sender'
|
|
7
|
+
|
|
8
|
+
export * from './bubble-list/index.type'
|
|
9
|
+
|
|
10
|
+
const components = [Welcome, Conversations, BubbleItem, BubbleList, Sender]
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
install<T>(app: App<T>) {
|
|
14
|
+
components.forEach((component) => {
|
|
15
|
+
const name = component.name?.replace(/^Tiny/, '').replace(/^Tr/, '')
|
|
16
|
+
app.component(`Tr${name}`, component)
|
|
17
|
+
app.component(`Tiny${name}`, component)
|
|
18
|
+
})
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
Welcome as TrWelcome,
|
|
24
|
+
Conversations as TrConversations,
|
|
25
|
+
BubbleItem as TrBubbleItem,
|
|
26
|
+
BubbleItem as TinyBubbleItem,
|
|
27
|
+
BubbleList as TrBubbleList,
|
|
28
|
+
BubbleList as TinyBubbleList,
|
|
29
|
+
Sender as TrSender,
|
|
30
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { TinyButton, TinyTooltip } from '@opentiny/vue'
|
|
4
|
+
import { IconClose } from '@opentiny/vue-icon'
|
|
5
|
+
import { ActionButtonsProps } from '../index.type'
|
|
6
|
+
|
|
7
|
+
const TinyIconCloseSquare = IconClose()
|
|
8
|
+
|
|
9
|
+
const props = withDefaults(defineProps<ActionButtonsProps>(), {
|
|
10
|
+
/**
|
|
11
|
+
* 是否显示加载状态
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
loading: false,
|
|
15
|
+
/**
|
|
16
|
+
* 是否禁用所有操作
|
|
17
|
+
* @default false
|
|
18
|
+
*/
|
|
19
|
+
disabled: false,
|
|
20
|
+
/**
|
|
21
|
+
* 是否显示清除按钮
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
showClear: true,
|
|
25
|
+
/**
|
|
26
|
+
* 输入框是否有内容
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
hasContent: false,
|
|
30
|
+
/**
|
|
31
|
+
* 是否允许语音功能
|
|
32
|
+
*/
|
|
33
|
+
allowSpeech: false,
|
|
34
|
+
speechStatus: () => ({
|
|
35
|
+
isRecording: false,
|
|
36
|
+
isSupported: false,
|
|
37
|
+
}),
|
|
38
|
+
/**
|
|
39
|
+
* 是否允许附件功能
|
|
40
|
+
*/
|
|
41
|
+
allowFiles: false,
|
|
42
|
+
/**
|
|
43
|
+
* 提交快捷方式
|
|
44
|
+
* @default 'enter'
|
|
45
|
+
*/
|
|
46
|
+
submitType: 'enter',
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const emit = defineEmits({
|
|
50
|
+
/**
|
|
51
|
+
* 清除内容事件
|
|
52
|
+
*/
|
|
53
|
+
clear: () => true,
|
|
54
|
+
/**
|
|
55
|
+
* 切换语音识别状态事件
|
|
56
|
+
* @param {boolean} state - 新的语音识别状态
|
|
57
|
+
*/
|
|
58
|
+
'toggle-speech': (state: boolean) => Boolean(state),
|
|
59
|
+
/**
|
|
60
|
+
* 提交内容事件
|
|
61
|
+
*/
|
|
62
|
+
submit: () => true,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 是否启用语音功能
|
|
67
|
+
*/
|
|
68
|
+
const speechEnabled = computed(() => props.allowSpeech)
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 语音按钮提示文本
|
|
72
|
+
*/
|
|
73
|
+
const speechButtonText = computed(() => (props.speechStatus.isRecording ? '停止录音' : '开始语音输入'))
|
|
74
|
+
|
|
75
|
+
const isSpeechRecording = computed(() => props.speechStatus.isRecording)
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* 提交按钮tooltip
|
|
79
|
+
*/
|
|
80
|
+
const submitTooltip = computed(() => {
|
|
81
|
+
return props.loading ? `发送中...` : '发送消息'
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 整体禁用状态
|
|
86
|
+
*/
|
|
87
|
+
const isDisabled = computed(() => props.disabled)
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 处理清除操作
|
|
91
|
+
*/
|
|
92
|
+
const handleClear = () => {
|
|
93
|
+
if (!isDisabled.value) {
|
|
94
|
+
emit('clear')
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 切换语音识别状态
|
|
100
|
+
*/
|
|
101
|
+
const handleToggleSpeech = () => {
|
|
102
|
+
if (!isDisabled.value) {
|
|
103
|
+
const newState = !props.speechStatus.isRecording
|
|
104
|
+
emit('toggle-speech', newState)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 处理提交操作
|
|
110
|
+
*/
|
|
111
|
+
const handleSubmit = () => {
|
|
112
|
+
if (!isDisabled.value) {
|
|
113
|
+
emit('submit')
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<template>
|
|
119
|
+
<div class="action-buttons">
|
|
120
|
+
<!-- 文件上传按钮 -->
|
|
121
|
+
<template v-if="allowFiles && !loading">
|
|
122
|
+
<tiny-tooltip content="上传文件" placement="top">
|
|
123
|
+
<tiny-button type="text" :disabled="isDisabled">
|
|
124
|
+
<img src="../../assets/icons/accessory.svg" class="button-icon" alt="上传文件" />
|
|
125
|
+
</tiny-button>
|
|
126
|
+
</tiny-tooltip>
|
|
127
|
+
</template>
|
|
128
|
+
|
|
129
|
+
<!-- 语音按钮:仅在启用语音功能时显示 -->
|
|
130
|
+
<template v-if="speechEnabled && !loading">
|
|
131
|
+
<tiny-tooltip :content="speechButtonText" placement="top">
|
|
132
|
+
<tiny-button
|
|
133
|
+
type="text"
|
|
134
|
+
:disabled="isDisabled"
|
|
135
|
+
@click="handleToggleSpeech"
|
|
136
|
+
class="speech-button"
|
|
137
|
+
:class="{ 'is-recording': isSpeechRecording }"
|
|
138
|
+
>
|
|
139
|
+
<img v-if="!isSpeechRecording" src="../../assets/icons/voice.svg" class="button-icon" alt="录音" />
|
|
140
|
+
<img v-else src="../../assets/icons/loading-speech.svg" class="button-icon recording-icon" alt="语音中" />
|
|
141
|
+
</tiny-button>
|
|
142
|
+
</tiny-tooltip>
|
|
143
|
+
</template>
|
|
144
|
+
|
|
145
|
+
<template v-if="showClear">
|
|
146
|
+
<tiny-tooltip content="清空内容" placement="top">
|
|
147
|
+
<tiny-button type="text" :disabled="isDisabled || !hasContent" @click="handleClear" style="margin-left: 0">
|
|
148
|
+
<component :is="TinyIconCloseSquare" class="button-icon" />
|
|
149
|
+
</tiny-button>
|
|
150
|
+
</tiny-tooltip>
|
|
151
|
+
</template>
|
|
152
|
+
|
|
153
|
+
<!-- 提交按钮:主操作按钮 -->
|
|
154
|
+
<template v-if="hasContent || loading">
|
|
155
|
+
<tiny-tooltip :content="submitTooltip" placement="top">
|
|
156
|
+
<tiny-button type="text" @click="handleSubmit" class="submit-button" :disabled="isDisabled">
|
|
157
|
+
<div class="button-content">
|
|
158
|
+
<img v-if="!loading" src="../../assets/icons/send.svg" alt="发送" />
|
|
159
|
+
<img v-else src="../../assets/icons/loading.svg" alt="加载中" class="loading" />
|
|
160
|
+
</div>
|
|
161
|
+
</tiny-button>
|
|
162
|
+
</tiny-tooltip>
|
|
163
|
+
</template>
|
|
164
|
+
</div>
|
|
165
|
+
</template>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ref, watch } from 'vue'
|
|
2
|
+
import { debounce } from 'lodash-es'
|
|
3
|
+
import type { SenderProps, SenderEmits } from '../index.type'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 输入框值处理 Hook
|
|
7
|
+
* 对输入框的值进行集中处理
|
|
8
|
+
*
|
|
9
|
+
* @param props 组件属性
|
|
10
|
+
* @param emit 组件方法
|
|
11
|
+
*/
|
|
12
|
+
export function useInputHandler(props: SenderProps, emit: SenderEmits) {
|
|
13
|
+
const inputValue = ref(props.defaultValue || '')
|
|
14
|
+
const inputWrapper = ref<HTMLElement | null>(null)
|
|
15
|
+
|
|
16
|
+
// 同步外部值变化
|
|
17
|
+
watch(
|
|
18
|
+
() => props.modelValue,
|
|
19
|
+
(val) => {
|
|
20
|
+
if (val !== undefined && val !== inputValue.value) {
|
|
21
|
+
inputValue.value = val
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
// 双向绑定处理
|
|
27
|
+
const handleChange = (value: string) => {
|
|
28
|
+
inputValue.value = value
|
|
29
|
+
emit('update:modelValue', value)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 防抖提交
|
|
33
|
+
const debouncedSubmit = debounce((value: string) => {
|
|
34
|
+
if (!props.disabled && !props.loading && value.trim()) {
|
|
35
|
+
emit('submit', value)
|
|
36
|
+
}
|
|
37
|
+
}, props.debounceSubmit)
|
|
38
|
+
|
|
39
|
+
// 提交处理
|
|
40
|
+
const handleSubmit = (event?: Event) => {
|
|
41
|
+
event?.preventDefault()
|
|
42
|
+
debouncedSubmit(inputValue.value)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 清空输入
|
|
46
|
+
const handleClear = () => {
|
|
47
|
+
inputValue.value = ''
|
|
48
|
+
emit('update:modelValue', '')
|
|
49
|
+
emit('clear')
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 输入法状态
|
|
53
|
+
const isComposing = ref(false)
|
|
54
|
+
|
|
55
|
+
// 清除输入
|
|
56
|
+
const clearInput = () => {
|
|
57
|
+
handleClear()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
inputValue,
|
|
62
|
+
inputWrapper,
|
|
63
|
+
isComposing,
|
|
64
|
+
handleChange,
|
|
65
|
+
handleSubmit,
|
|
66
|
+
handleClear,
|
|
67
|
+
clearInput,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Ref } from 'vue'
|
|
2
|
+
import type { SenderProps, SenderEmits, SpeechState, SubmitTrigger } from '../index.type'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 键盘处理Hook
|
|
6
|
+
* 集中管理组件的键盘相关操作
|
|
7
|
+
*
|
|
8
|
+
* @param props - 组件属性
|
|
9
|
+
* @param emit - 组件方法
|
|
10
|
+
* @param inputValue - 输入值
|
|
11
|
+
* @param isComposing - 是否处于输入法组合状态(即编辑态)
|
|
12
|
+
* @param speechState - 语音识别状态
|
|
13
|
+
* @param showSuggestions - 是否显示建议列表
|
|
14
|
+
* @param toggleSpeech - 切换语音识别函数
|
|
15
|
+
*/
|
|
16
|
+
export function useKeyboardHandler(
|
|
17
|
+
props: SenderProps,
|
|
18
|
+
emit: SenderEmits,
|
|
19
|
+
inputValue: Ref<string>,
|
|
20
|
+
isComposing: Ref<boolean>,
|
|
21
|
+
speechState: SpeechState,
|
|
22
|
+
showSuggestions: Ref<boolean>,
|
|
23
|
+
toggleSpeech: () => void,
|
|
24
|
+
) {
|
|
25
|
+
/**
|
|
26
|
+
* 验证提交条件
|
|
27
|
+
*/
|
|
28
|
+
const validateSubmission = (value: string) => {
|
|
29
|
+
return !props.disabled && !props.loading && value.trim().length > 0
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 触发提交
|
|
34
|
+
*/
|
|
35
|
+
const triggerSubmit = () => {
|
|
36
|
+
if (!validateSubmission(inputValue.value)) return
|
|
37
|
+
alert('提交成功')
|
|
38
|
+
emit('submit', inputValue.value.trim())
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 检查是否为指定的提交快捷键
|
|
43
|
+
* @param event 键盘事件
|
|
44
|
+
* @param submitType 提交类型
|
|
45
|
+
*/
|
|
46
|
+
const checkSubmitShortcut = (event: KeyboardEvent, submitType: SubmitTrigger): boolean => {
|
|
47
|
+
const isEnter = event.key === 'Enter'
|
|
48
|
+
if (!isEnter) return false
|
|
49
|
+
|
|
50
|
+
switch (submitType) {
|
|
51
|
+
case 'enter':
|
|
52
|
+
console.log('enter')
|
|
53
|
+
return !event.shiftKey && !event.ctrlKey && !event.metaKey
|
|
54
|
+
case 'ctrlEnter':
|
|
55
|
+
console.log('ctrlEnter')
|
|
56
|
+
return (event.ctrlKey || event.metaKey) && !event.shiftKey
|
|
57
|
+
case 'shiftEnter':
|
|
58
|
+
console.log('shiftEnter')
|
|
59
|
+
return event.shiftKey && !event.ctrlKey && !event.metaKey
|
|
60
|
+
default:
|
|
61
|
+
return false
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 处理键盘按下事件
|
|
67
|
+
*/
|
|
68
|
+
const handleKeyPress = (event: KeyboardEvent) => {
|
|
69
|
+
if (isComposing.value) return // 阻止输入法状态下的提交
|
|
70
|
+
|
|
71
|
+
// 处理Esc键 - 关闭建议列表或停止语音录制
|
|
72
|
+
if (event.key === 'Escape') {
|
|
73
|
+
if (showSuggestions.value) {
|
|
74
|
+
showSuggestions.value = false
|
|
75
|
+
event.preventDefault()
|
|
76
|
+
} else if (speechState.isRecording) {
|
|
77
|
+
toggleSpeech()
|
|
78
|
+
event.preventDefault()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
emit('escape-press')
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 检查是否匹配当前的提交快捷键
|
|
86
|
+
const shouldSubmit = checkSubmitShortcut(event, props.submitType as SubmitTrigger)
|
|
87
|
+
|
|
88
|
+
// 只有当满足提交条件且输入框有内容时才提交
|
|
89
|
+
if (shouldSubmit && validateSubmission(inputValue.value)) {
|
|
90
|
+
event.preventDefault()
|
|
91
|
+
triggerSubmit()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
handleKeyPress,
|
|
97
|
+
triggerSubmit,
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { reactive } from 'vue'
|
|
2
|
+
import type { SpeechHookOptions, SpeechHandler, SpeechState } from '../index.type'
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
webkitSpeechRecognition: typeof SpeechRecognition
|
|
7
|
+
SpeechRecognition: typeof SpeechRecognition
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 语音识别处理 Hook
|
|
13
|
+
* 集中管理语音识别相关逻辑
|
|
14
|
+
*
|
|
15
|
+
* @param options 语音识别配置
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export function useSpeechHandler(options: SpeechHookOptions): SpeechHandler {
|
|
19
|
+
// 语音识别状态
|
|
20
|
+
const speechState = reactive<SpeechState>({
|
|
21
|
+
isRecording: false,
|
|
22
|
+
isSupported: 'webkitSpeechRecognition' in window || 'SpeechRecognition' in window,
|
|
23
|
+
error: undefined,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// 创建语音识别实例
|
|
27
|
+
const recognition = speechState.isSupported
|
|
28
|
+
? new (window.webkitSpeechRecognition || window.SpeechRecognition)()
|
|
29
|
+
: null
|
|
30
|
+
|
|
31
|
+
// 初始化语音识别配置
|
|
32
|
+
if (recognition) {
|
|
33
|
+
recognition.continuous = options.continuous ?? false
|
|
34
|
+
recognition.interimResults = options.interimResults ?? true
|
|
35
|
+
recognition.lang = options.lang ?? navigator.language
|
|
36
|
+
|
|
37
|
+
// 开始识别事件
|
|
38
|
+
recognition.onstart = () => {
|
|
39
|
+
speechState.isRecording = true
|
|
40
|
+
speechState.error = undefined
|
|
41
|
+
options.onStart?.()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 结束识别事件
|
|
45
|
+
recognition.onend = () => {
|
|
46
|
+
speechState.isRecording = false
|
|
47
|
+
options.onEnd?.()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 中间结果事件
|
|
51
|
+
recognition.onresult = (event: SpeechRecognitionEvent) => {
|
|
52
|
+
const transcript = Array.from(event.results)
|
|
53
|
+
.map((result) => result[0].transcript)
|
|
54
|
+
.join('')
|
|
55
|
+
|
|
56
|
+
if (event.results[0].isFinal) {
|
|
57
|
+
options.onFinal?.(transcript)
|
|
58
|
+
} else {
|
|
59
|
+
options.onInterim?.(transcript)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 错误处理
|
|
64
|
+
recognition.onerror = (event: SpeechRecognitionErrorEvent) => {
|
|
65
|
+
speechState.error = new Error(event.error)
|
|
66
|
+
speechState.isRecording = false
|
|
67
|
+
options.onError?.(speechState.error)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 开始录音
|
|
72
|
+
const start = () => {
|
|
73
|
+
if (!recognition) {
|
|
74
|
+
const error = new Error('浏览器不支持语音识别')
|
|
75
|
+
speechState.error = error
|
|
76
|
+
options.onError?.(error)
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 已经在录音中则先停止当前会话
|
|
81
|
+
if (speechState.isRecording) {
|
|
82
|
+
try {
|
|
83
|
+
recognition.stop()
|
|
84
|
+
// 短暂延迟后再开始新的录音会话
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
try {
|
|
87
|
+
recognition.start()
|
|
88
|
+
} catch (err) {
|
|
89
|
+
handleError(err)
|
|
90
|
+
}
|
|
91
|
+
}, 100)
|
|
92
|
+
} catch (err) {
|
|
93
|
+
handleError(err)
|
|
94
|
+
}
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
recognition.start()
|
|
100
|
+
} catch (error) {
|
|
101
|
+
handleError(error)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 停止录音
|
|
106
|
+
const stop = () => {
|
|
107
|
+
if (recognition && speechState.isRecording) {
|
|
108
|
+
try {
|
|
109
|
+
recognition.stop()
|
|
110
|
+
} catch (error) {
|
|
111
|
+
handleError(error)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 处理错误
|
|
117
|
+
const handleError = (error: unknown) => {
|
|
118
|
+
speechState.error = error instanceof Error ? error : new Error('语音识别操作失败')
|
|
119
|
+
speechState.isRecording = false
|
|
120
|
+
options.onError?.(speechState.error)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
speechState,
|
|
125
|
+
start,
|
|
126
|
+
stop,
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
interface SpeechRecognitionEvent extends Event {
|
|
2
|
+
results: SpeechRecognitionResultList
|
|
3
|
+
resultIndex: number
|
|
4
|
+
emma?: Document
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface SpeechRecognitionErrorEvent extends Event {
|
|
8
|
+
error:
|
|
9
|
+
| 'no-speech'
|
|
10
|
+
| 'aborted'
|
|
11
|
+
| 'audio-capture'
|
|
12
|
+
| 'network'
|
|
13
|
+
| 'not-allowed'
|
|
14
|
+
| 'service-not-allowed'
|
|
15
|
+
| 'bad-grammar'
|
|
16
|
+
| 'language-not-supported'
|
|
17
|
+
message: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface SpeechRecognition extends EventTarget {
|
|
21
|
+
// 属性
|
|
22
|
+
lang: string
|
|
23
|
+
continuous: boolean
|
|
24
|
+
interimResults: boolean
|
|
25
|
+
maxAlternatives: number
|
|
26
|
+
serviceURI: string
|
|
27
|
+
|
|
28
|
+
// 事件处理器
|
|
29
|
+
onend: (this: SpeechRecognition, ev: Event) => void
|
|
30
|
+
onerror: (ev: SpeechRecognitionErrorEvent) => void
|
|
31
|
+
onresult: (this: SpeechRecognition, ev: SpeechRecognitionEvent) => void
|
|
32
|
+
onstart: (this: SpeechRecognition, ev: Event) => void
|
|
33
|
+
|
|
34
|
+
// 方法
|
|
35
|
+
start(): void
|
|
36
|
+
stop(): void
|
|
37
|
+
abort(): void
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 声明全局变量
|
|
41
|
+
declare let SpeechRecognition: {
|
|
42
|
+
new (): SpeechRecognition
|
|
43
|
+
prototype: SpeechRecognition
|
|
44
|
+
}
|