Skip to content
This repository was archived by the owner on Jan 11, 2024. It is now read-only.

Latest commit

 

History

History
376 lines (319 loc) · 15.8 KB

File metadata and controls

376 lines (319 loc) · 15.8 KB

BlackBerry Spark Communications Services

Threaded Chat Sample for JavaScript

The Threaded Chat sample application demonstrates how a user can post comments on other messages in a chat to create threaded conversations using the Chat Message References feature of BlackBerry Spark Communications Services.

This example utilizes the Support library to quickly create a basic chat application. For a more rich chat application experience, please see the Rich Chat app provided with the SDK.

This example builds on the Simple Chat example that demonstrates how you can create a basic chat application in a domain with user authentication disabled and with the BlackBerry Key Management Service enabled.

Features

This example expands on the functionality of the Simple Chat example to allow the logged-in user to:

  • Post a comment on a message in a chat
  • View comments on a message as a threaded conversation
  • View inline notification when someone makes a comment on a message

Getting Started

This example requires the Spark Communications SDK, which you can find along with related resources at the locations below.

YouTube Getting Started Video

Getting started video

This example application works in a sandbox domain with user authentication disabled and the BlackBerry Key Management Service enabled. See the Download & Configure section of the Developer Guide to get started configuring a domain in the sandbox.

When you have a domain in the sandbox, edit Threaded Chat's config_mock.js file to configure the example with your domain ID and a key passcode.

Set the SDK_CONFIG.domain parameter to your sandbox domain ID.

const SDK_CONFIG = {
  domain: 'your_domain_id'
};

Set the KEY_PASSCODE parameter to the string used to protect the logged-in user's keys stored in the BlackBerry Key Management Service. Real applications should not use the same passcode for all users. However, it allows this example application to be smaller and focus on demonstrating its call functionality instead of passcode management.

const KEY_PASSCODE = 'passcode';

Run yarn install in the Threaded Chat application directory to install the required packages.

When you run the Threaded Chat application, it will prompt you for a user ID. Because you've configured your domain to have user authentication disabled, you can enter any string you like for the user ID and an SDK identity will be created for it. Other applications that you run in the same domain will be able to find this identity by this user ID.

The Threaded Chat example application cannot initiate a chat. Configure the Rich Chat example application to use your domain and initiate a chat with the user logged into Threaded Chat.

Walkthrough

Before interaction with the user's chats can begin, the user must be authenticated and the SDK started.

Follow this guide for a walkthrough of how the threaded message list component defined for this example builds on the bbmChatMessageList and bbmChatInput components from the Support library to:

Extend the bbmChatMessageList component

The threaded message list component uses the bbmChatMessageList component's template to customize how each message in the chat should appear.

The top-level messages are messages that do not themselves reference another message. These are displayed without any special indentation or decoration. Each top-level message may be referenced by clicking on the chevron that appears when your mouse hovers over the message and selecting 'Comment' from the menu that appears.

The comment messages are messages that reference one of the top-level messages. These are listed beneath the top-level message that they reference in the order that they were received.

  <!--
    This defines the contents of the menu that appears when clicking on the
    chevron associated with any given top-level chat message.
  -->
  <div class="chevronDropdown" id="chevronDropdown"
       style="margin-left:9px;margin-top:9px;">
    <div class="bbmChatMenuButton" on-click="commentMessage">Comment</div>
  </div>

  <!--
    Extend the bbmChatmessageList component so that we can display a
    top-level message in a chat with any messages that reference it nested
    beneath it.
  -->
  <bbm-chat-message-list id="list" items="[]" as="message">
    <template id="bubbleTemplate">
      <!-- Visible if this is a status message. -->
      <div class="messageRow">
        <div class="status
             " style$="display:[[message.isStatus]]">[[message.content]]</div>
        <div class="messageRow" style$="display:[[message.isText]]">
          <!--
            The main bubble wrapper for a top-level message that does not
            reference another message.
          -->
          <div class="bubble-wrapper" style$="display:[[message.isBubble]]">
            <!-- Avatar -->
            <img class="bubble-avatar" src="[[message.avatar]]"/>
            <!-- Bubble content with header -->
            <div class="bubble">
              <!-- First row -->
              <div class="firstRow">
                <div>[[message.username]]</div>
                <div>[[message.timestamp.formattedTime]]</div>
              </div>
              <!-- Second row -->
              <div class="secondRowWithChevron" on-mouseenter="showChevron"
                   on-mouseleave="hideChevron">
                <div class="secondRow"
                     style$="margin-left: [[message.indent]]; background-color: [[message.backgroundColor]]">
                  <!-- Text content -->
                  <div style="flex-direction: column; margin: 0px 5px 0px 5px;">
                    <div style$="display:[[message.isText]];">
                      <div class="bubble-content">
                        [[message.content]]
                      </div>
                    </div>
                  </div>
                </div>
                <!--
                  The chevron menu icon that will appear when the user's
                  mouse hovers over the message.  When clicked, the
                  chevronDropDown menu will be shown.
                -->
                <div class="chevronPlaceholder">
                  <div class="chevron"
                    style$="background-image: url('[[getChevronImage()]]')"
                    on-click="showChevronDropdown">
                  </div>
                </div>
              </div>
            </div>
          </div>
           <!--
             The container for the messages that reference the above
             top-level message.
           -->
          <template is="dom-repeat" items="{{message.refBys}}">
            <div class="refMessageRow"
                 style$="margin-left: [[message.childIndent]]; background-color: [[message.childBackgroundColor]]">
              <div class="child-bubble-wrapper">
                <!-- Avatar -->
                <img class="child-avatar" src="[[item.childMessageAvatar]]"/>
                <!-- Bubble content with header -->
                <div class="child-bubble">
                  <!-- First row -->
                  <div class="child-firstRow">
                    <div>[[item.childMessageUsername]]</div>
                    <div>[[item.timestamp.formattedTime]]</div>
                  </div>
                  <!-- Second row -->
                  <div class="child-secondRow"
                       style$="background-color: [[item.bubbleBackgroundColor]]">
                    <!-- Text content -->
                    <div style="flex-direction: column; margin: 0px 5px 0px 5px;">
                      <div class="child-bubble-content">
                        [[item.childMessageContent]]
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </div>
      </div>
    </template>
  </bbm-chat-message-list>

Display a threaded conversation

Please refer to the Developer Guide for an overview of Chat Message References.

Each SparkCommunications.Messenger.ChatMessage instance contains a list of outgoing and incoming references.

All top-level messages that are not referenced will be displayed in their own message bubble.

The SparkCommunications.Messenger.ChatMessage.ref property, when present, indicates that the message references another message in the chat. In this example, the reference will be for one of the top-level messages. When a message arrives that references a top-level message, a 'system' message will be injected into the chat indicating who commented on what message.

The following code snippet can be found in the js/threadedChat.js file in the format function of the threaded chat message list component.

  if(message.ref) {
    // The message being formatted references a top-level message.  This
    // example only references a single message at a time.
    //
    // We format this message as a 'system' message to be injected into
    // the chat message list.
    if(message.ref && message.ref[0]
        && message.ref[0].tag === REFERENCE_TAG_THREADED) {
     this.formatCommentSystemMessage(message.ref[0].messageId, ret);
    }
  }

The SparkCommunications.Messenger.ChatMessage.refBy property, when present, indicates that the message is referenced by another message in the chat. In this example, only top-level messages are referenced by other messages. So, the messageIds of the comments associated with a top-level message can be obtained by looking at the messageIds array of the reference with the Threaded tag.

The following code snippet can be found in the js/threadedChat.js file in the format function of the threaded chat message list component.

  if(message.refBy) {
    // The message being formatted is referenced by at least one other
    // message.  Format each of the messages that reference this messages
    // as 'comment' messages.
    ret.refBys = [];
    for (const ref of message.refBy) {
      if (ref.tag === REFERENCE_TAG_THREADED) {
        for (const messageId of ref.messageIds) {
          this.formatCommentMessage(messageId, ret);
        }
        // We've handled the only reference tag type we care about, so we
        // can exit the loop early.
        break;
      }
      // Ignore all other reference tag types.
    }
  }

Make a commment on a message

The function for sending a source message that refers to a target message is integrated into the bbmChatInput component. Your application needs to provide the bbmChatInput component with the details of the message being referenced.

The commentMessage() function on the threaded chat message list component is called when the 'Comment' option is selected from the chevron drop down menu. This will trigger the messageReference event to be fired and the bbmChatInput component to gain focus.

  /**
   * Dispatch an event to notify listeners that a message is being commented
   * on.
   */
  commentMessage() {
    // Dispatch the 'messageReference' event.
    this.dispatchEvent(new CustomEvent('messageReference', {
      'detail': {
        // The messageId of the message being referenced.
        targetMessageId: this.selectedMessage.message.messageId,
        // The reference tag to use when referencing the message.
        refTag: REFERENCE_TAG_THREADED,
        // What text to show when we are composing a comment on the
        // referenced message.
        content:
          `${REFERENCE_COMMENT_FIELD_TEXT} "${this.selectedMessage.content}"`,
        // What text to show as the comment.
        textMessage: ""
      }
    }));
    chatInput.focus();
  }

In order for the bbmChatInput component to reference the message identified in the messageReference event, an event listener must be configured on the threaded chat message list component.

  // When a message is referenced, we will show the referenced message
  // information in the bbmChatInput component.
  chatMessageList.addEventListener('messageReference', e => {
    chatInput.showRefField(e);
  });

When the user enters their comment and presses Enter or clicks the Send button, the top-level message will be referenced by the message that sends the comment.

License

These examples are released as Open Source and licensed under the Apache 2.0 License.

Reporting Issues and Feature Requests

If you find a issue in one of the Samples or have a Feature Request, simply file an issue.