akveo / nebular

:boom: Customizable Angular UI Library based on Eva Design System :new_moon_with_face::sparkles:Dark Mode
https://akveo.github.io/nebular
MIT License
8.06k stars 1.51k forks source link

Chat UI - textarea instead of input / disable send on enter #2184

Open KyleCser opened 4 years ago

KyleCser commented 4 years ago

Issue type

I'm submitting a ... (check one with "x")

Issue description

Current behavior:

Expected behavior:

Steps to reproduce: Include any basic ChatUI element

Other information:

npm, node, OS, Browser

Angular, Nebular

Angular CLI: 8.3.20
Nebular: 4.5.0
Destreyf commented 4 years ago

@KyleCser I ran into a similar thing, and while i believe that nebular should implement this in a way that either allows us to choose the type of input, or default to a textarea for simplicity, the fact is that they intend for the enter key to send, so a textarea isn't immediately usable.

However, my workaround, would be to extend the nebular form component with something like this:

(this has not been tested and is only a reference/concept)

@Component({
  selector: 'custom-chat-form',
  template: `
    <div class="dropped-files" *ngIf="droppedFiles?.length">
      <ng-container *ngFor="let file of droppedFiles">
        <div *ngIf="file.urlStyle" [style.background-image]="file.urlStyle">
          <span class="remove" (click)="removeFile(file)">&times;</span>
        </div>
        <div>
          <nb-icon *ngIf="!file.urlStyle" icon="file-text-outline" pack="nebular-essentials"></nb-icon>
          <span class="remove" (click)="removeFile(file)">&times;</span>
        </div>
      </ng-container>
    </div>
    <div class="message-row">
      <textarea
             fullWidth
             [status]="getInputStatus()"
             (focus)="inputFocus = true"
             (blur)="inputFocus = false"
             (mouseenter)="inputHover = true"
             (mouseleave)="inputHover = false"
             [(ngModel)]="message"
             [class.with-button]="showButton"
             type="text"
             placeholder="{{ fileOver ? 'Drop file to send' : 'Type a message' }}"
             (keyup.enter)="sendMessage($event)"></textarea>
      <button nbButton
              [status]="getButtonStatus()"
              *ngIf="showButton"
              [class.with-icon]="!buttonTitle"
              (click)="sendMessage()"
              class="send-button">
        <nb-icon *ngIf="!buttonTitle; else title" [icon]="buttonIcon" pack="nebular-essentials"></nb-icon>
        <ng-template #title>{{ buttonTitle }}</ng-template>
      </button>
    </div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CustomChatFormComponent extends NbChatFormComponent {
  constructor(protected cd: ChangeDetectorRef, protected domSanitizer: DomSanitizer) {
    super(cd, domSanitizer);
  }

  sendMessage(event) {
    if(event && !event.ctrlKey){
      // We only "send" on a multi-line if the CTRL key is held down when hitting enter.
      return true; // skip sending, but don't indicate a negative value (hopefully prevent any blocking)
    }
    super.sendMessage();
  }
}
Destreyf commented 4 years ago

Just as a note, this may not work as intended for the chat component, so you may need to extend it as well and replace it's template logic to support nb-chat-form as well as custom-chat-form.

KyleCser commented 4 years ago

Using a key press combination to send is pretty standard in most web chat forms.

I would take your example a step further and add a parameter to conditionally display an input or textarea. Supporting a custom nb-chat-form would be another great alternative if it's not already possible.

filol commented 4 years ago

I am also in this need. I tried to override the different components but the input no longer appears :/ I did however override also nb-chat to update its variable which referred to nb-chat-form.

Any idea why it doesn't work? Is this feature planned? It is a standard today in different cats, I am surprised that it is not implemented here especially that the work is not very long to adapt it.

The stackblitz link: https://stackblitz.com/edit/angular-ivy-zdpyta

@yggg (sorry for the ping but it seems that nobody of your team follow this old issue)

zpalcnik commented 2 years ago

Hello, I'm having the same problem? How did you guys fix it? I'm trying to override component, but when I override it it just does not appear on screen.

sanketdiwale commented 2 years ago

Another way I have seen this handled in some chatboxes is to use "Shift key + Enter" as a way to allow for new line in the text box, while the normal enter key is used for send. I wonder if it would be easier to just add a case for handling the "Shift+Enter" alongside the normal send behavior and set the default type of input to always be a textarea (instead of having two input field types to choose from)