inputboxFoundation.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { handlePrevent } from "../utils/a11y";
  2. import BaseFoundation, { DefaultAdapter } from "../base/foundation";
  3. import { strings } from './constants';
  4. const { SEND_HOT_KEY } = strings;
  5. export interface InputBoxAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
  6. notifyInputChange: (props: { inputValue: string; attachment: any[]}) => void;
  7. setInputValue: (value: string) => void;
  8. setAttachment: (attachment: any[]) => void;
  9. notifySend: (content: string, attachment: any[]) => void
  10. }
  11. export default class InputBoxFoundation <P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<InputBoxAdapter<P, S>, P, S> {
  12. constructor(adapter: InputBoxAdapter<P, S>) {
  13. super({ ...adapter });
  14. }
  15. onInputAreaChange = (value: string) => {
  16. const attachment = this.getState('attachment');
  17. this._adapter.setInputValue(value);
  18. this._adapter.notifyInputChange({ inputValue: value, attachment });
  19. }
  20. onAttachmentAdd = (props: any) => {
  21. const { fileList } = props;
  22. const { uploadProps } = this.getProps();
  23. const { onChange } = uploadProps;
  24. if (onChange) {
  25. onChange(props);
  26. }
  27. const { content } = this.getStates();
  28. let newFileList = [...fileList];
  29. this._adapter.setAttachment(newFileList);
  30. this._adapter.notifyInputChange({
  31. inputValue: content,
  32. attachment: newFileList
  33. });
  34. }
  35. onAttachmentDelete = (props: any) => {
  36. const { content, attachment } = this.getStates();
  37. const newAttachMent = attachment.filter(item => item.uid !== props.uid);
  38. this._adapter.setAttachment(newAttachMent);
  39. this._adapter.notifyInputChange({
  40. inputValue: content,
  41. attachment: newAttachMent
  42. });
  43. }
  44. onSend = (e: any) => {
  45. if (this.getDisableSend()) {
  46. return;
  47. }
  48. const { content, attachment } = this.getStates();
  49. this._adapter.setInputValue('');
  50. this._adapter.setAttachment([]);
  51. this._adapter.notifySend(content, attachment);
  52. }
  53. getDisableSend = () => {
  54. const { content, attachment } = this.getStates();
  55. const { disableSend: disableSendInProps } = this.getProps();
  56. /** 不能发送的条件:(满足任1)
  57. * 1. props 中禁止发送;2. 没有文本输入,且没有上传文件; 3.上传文件中有状态不为 success 的
  58. * Conditions under which content cannot be sent: (any one of the following conditions must be met)
  59. * 1. Sending is disabled in props; 2. No text input and no file upload; 3. There are files uploaded that do not have a success status.
  60. */
  61. const disabledSend = disableSendInProps ||
  62. (content.length === 0 && attachment.length === 0) ||
  63. attachment.find(item => item.status !== strings.FILE_STATUS.SUCCESS)
  64. ;
  65. return disabledSend;
  66. }
  67. onEnterPress = (e: any) => {
  68. const { sendHotKey } = this.getProps();
  69. if (sendHotKey === SEND_HOT_KEY.SHIFT_PLUS_ENTER && e.shiftKey === false) {
  70. return ;
  71. } else if (sendHotKey === SEND_HOT_KEY.ENTER && e.shiftKey === true) {
  72. return ;
  73. }
  74. handlePrevent(e);
  75. this.onSend(e);
  76. };
  77. onPaste = (e: any) => {
  78. const items = e.clipboardData?.items;
  79. const { manualUpload, pasteUpload } = this.getProps();
  80. let files = [];
  81. if (pasteUpload && items) {
  82. for (const it of items) {
  83. const file = it.getAsFile();
  84. file && files.push(it.getAsFile());
  85. }
  86. if (files.length) {
  87. // 文件上传,则需要阻止默认粘贴行为
  88. // File upload, you need to prevent the default paste behavior
  89. manualUpload(files);
  90. e.preventDefault();
  91. e.stopPropagation();
  92. }
  93. }
  94. }
  95. }