4.1.0

Breaking Changes:

While there have been no major breaking changes, there have been some minor changes that could impact a few customers

  • WEB-1779: Now throws error if calling Layer.UI.setupMixins({...}) after calling Layer.init()
    • Previously, this failed silently to apply the mixins
  • Layer.Constants.WIDTH no longer exists and is no longer used
  • Minor CSS Class names and theme changes
  • ImageModel no longer has a url property; see fetchUrl(callback) instead
  • message-type-response-summmary-v2 renamed to message-type-response-summary-v2. More is sometimes better. More spell checkering is better than more m’s every time.
  • message-type-response-summmary-v1 renamed to message-type-response-summary-v1; Most projects should not be using this!

Message List Avatar Breaking Changes

Previously, hiding and showing of Avatars within the Message List was managed directly via Style sheets:

Avatars were previously shown using less variables:

@message-item-text-indent: 12px + 12px + 32px;
@mesage-item-show-avatars: block;

Avatars were previously hidden using:

@message-item-text-indent: 12px + 12px;
@mesage-item-show-avatars: none;

These variables are no longer used; Instead, the Message List supports the following properties:

  • conversationView.canShowMyAvatars: Set to false to disable showing Avatars of the current authenticated user
  • conversationView.canShowOtherAvatars: Set to false to disable showing Avatars of other participants in the conversation
  • conversationView.marginWithMyAvatar: set to a number to indicate how large a margin to use for display name, sent time and message status for message I send, and where my avatar is showing
  • conversationView.marginWithoutMyAvatar: set to a number to indicate how large a margin to use for display name, sent time and message status for message I send, and where my avatar is hidden
  • conversationView.marginWithOtherAvatar: set to a number to indicate how large a margin to use for display name, sent time and message status for message I receive and where the sender’s avatar is showing
  • conversationView.marginWithoutOtherAvatar: set to a number to indicate how large a margin to use for display name, sent time and message status for message I receive and where the sender’s avatar is hidden
  • Assuming that the canShowMyAvatars and canShowOtherAvatars properties are left alone, avatars are shown if width permits; width settings are as follows:
    • Layer.Settings.conversationViewWidths.small: 320: If the width puts the Conversation View in a category smaller than the Small size of 320px, then show no avatars. If the Conversation View is classed as “Small” then only show other participant’s avatars not the current user’s avatar.
    • Layer.Settings.conversationViewWidths.medium: 480: If the Conversation View is categorized as “Medium” or “Large”, show all avatars.
    • Settings can be changed from Layer.init()

Impact of this change:

  • Apps that had taken steps to hide avatars may have them showing again and will need to use the above properties to hide them again
  • Apps that used @message-item-text-indent to control indentation will no longer have those values be applied

New Features and Concepts

Managing widths and layout

The settings that can be passed into Layer.init() now accept a conversationViewWidths property that is used to redefine when the Conversation View is considered to be Tiny, Small, Medium or Large. These settings influence the following behaviors:

  • Tiny: 0px - 320px
    • Show no avatars in the message list
    • Messages use 95% of the width of the Conversation View
    • layer-conversation-view-width-tiny CSS class is added to the View
  • Small: 320px - 480px
    • Show avatar for messages received, but not for messages sent
    • Messages use 95% of the width of the Conversation View
    • layer-conversation-view-width-small CSS class is added to the View
  • Medium: 480px - 640px
    • Show avatar for messages sent and received
    • Messages use 80% of the width of the Conversation View
    • layer-conversation-view-width-medium CSS class is added to the View
  • Large: 640px and up
    • Show avatar for messages sent and received
    • Messages use 70% of the width of the Conversation View
    • layer-conversation-view-width-large CSS class is added to the View

The pixel sizes associated with these values can be customized using:

Layer.init({
    conversationViewWidths: {
        small: 400,
        medium:  600,
        large: 800
    }
});

Further customizations (for those placing other components in the margins of the Message Items) can be done by setting the amount of width to indent messages when avatars are showing, and when they are hidden:

Layer.init({
    mixins: {
        "layer-message-list": {
            properties: {
                marginWithMyAvatar: {
                    value: 98
                },
                marginWithoutMyAvatar: {
                    value: 48
                },
                marginWithOtherAvatar: {
                    value: 90
                },
                marginWithoutOtherAvatar: {
                    value: 40
                }
            }
        }
    }
});

The above code changes away from default values used by the Message List for setting margins, and adjusts those margins to account for both the case where My avatar (or other participant’s avatars) are showing, as well as the case where they are hidden.

These values may be updated at runtime:

myConversationView.nodes.list.marginWithOtherAvatar = 85;

Large Message Viewer

Messages may now be shown with a Large Message Viewer. The Large Message Viewer is the <layer-message-viewer size="large" /> and allows Messages that have registered a large view can use an alternate layout for presenting more detailed information.

Typically, a Message that is setup for the Large Message Viewer:

  • Will have registered a Large View; <layer-audio-message-large-view /> is set by setting the Message Model’s static largeMessageRenderer as follows: AudioModel.largeMessageRenderer = 'layer-audio-message-large-view';
  • Typically a Message that supports this will have the action (i.e. the action performed when a user taps/clicks) set to layer-show-large-message. For example: AudioModel.defaultAction = 'layer-show-large-message';
  • A Message that is tapped/clicked and has its action set to layer-show-large-message will show within a Dialog; the <layer-dialog /> widget.

Large Message Views can be displayed anywhere, even outside of the <layer-dialog />; however, this is not as well tested as showing these with the Dialog.

Note that only Audio and Video messages have defined Large Message Views at this time.

Developers who have looked at early versions of the Large Message Viewer, the following changes should be noted:

  • Renames layer-open-expanded-view action to layer-show-large-message
  • Renames the Model static property messageRendererExpanded to largeMessageRenderer
  • Removes <layer-message-viewer-expanded/> in favor of <layer-message-viewer size='large' />
    • For the full <layer-message-viewer-expanded /> experience, put <layer-message-viewer size='large' /> inside of a <layer-dialog />
  • Renames <layer-feedback-message-expanded-view /> to <layer-feedback-message-large-view /> which is now rendered within the <layer-message-viewer size='large' />

These changes impact customers who adopted the incomplete Large Message View prior to its official release.

New Message Types

  • Adds Audio Message
  • Adds Video Message

File Upload Button detects if Audio/Video messages are part of the build, and if they are loaded, will send an Audio/Video message based on file type of the selected file.

Manual Query Class

UI Components that take Queries as inputs can now take raw data using the Manual Query class. This is useful if simply providing raw data received from Layer’s servers doesn’t serve your use case. Typically, you’d use this if fetching a list of Conversations, Messages or Identities from your own servers but still want to use Layer’s UI Components to render them.

var manualQuery = client.createQuery({
  model: Layer.Core.Query.Manual
});
manualQuery.addItems(conversationList);
manualQuery.addItem(conversation25);
conversationListWidget.query = manualQuery;

Query data can be manipulated at any time using addItem(), addItems(), removeItem(), removeItems() and reset(); UI components will rerender as these calls are made.

Analytics

To help your application track usage patterns of users, 3 analytics events have been added that your application can listen to in order to report usage to your preferred reporting service.

  • Message Viewed: similar to Messages Read, but will retrigger whenever a message is reviewed, or continues to be visible
  • Message Selected: Whenever a user selects a message in the Message List to trigger its action.
  • Carousel Scrolled: reports what carousel items are visible and that the user explicitly scrolled the carousel

Typescript Support

Basic typescript support has been added to the npm repository and is now part of the build process.

Refactored Code

  • Refactored Layer.Core.Client Class
    • Rips out Client Authenticator Parent class of the Layer Client; replaces all of its capabilities via Mixins
    • Migrates all optional components into Mixins

The resulting client should have the same API, but can now be put together to suit different goals, such as our standard usage within a browser, and a new SAPI-Web-XDK repository that allows for parsing and creating Messages/Message Models for use with Layer’s Server API.

  • Changes to Static Client properties:
    • CACHE_PURGE_INTERVAL is now an instance property settable from Layer.init() named cachePurgeInterval
    • TimeBetweenReauths is now an instance property settable from Layer.init() named timeBetweenReauths
    • ResetAfterOfflineDuration is now an instance property settable from Layer.init() named resetAfterOfflineDuration

Changes to these are potentially breaking changes; its expected however that use of these customizations has not been common.

  • Refactored Index Files (WEB-1763):
    • Can import standard build with import '@layerhq/web-xdk'
    • Can import minimal build (that includes UI) with import '@layerhq/web-xdk/index-lite'
    • Can import minimal build without UI with import '@layerhq/web-xdk/index-core'
    • Can import Everything with import '@layerhq/web-xdk/index-all'
    • Can import all Message Types with an additional import '@layerhq/web-xdk/ui/messages'
    • Adds simplistic dependency injection for switching between utilities for nodejs, Browsers, etc…

Typically its easiest to start development with index-all but the above options will help you refine your build as development progresses.

  • Refactors Model Classes
    • Most classes in src/core/models now support a Mixin mechanism for customizing their capabilities; this is primarily used to customize it for use with Client API vs Server API.
    • Adds mixins/message-capi for Client API specific operations for the Layer.Core.Message class (Server API operations are in a separate repository)
    • Adds mixins/message-type-model-capi for Client API specific operations for the Layer.Core.MessageType class (Server API operations are in a separate repository)
    • Layer.Core.MessagePart fetchStream() method now uses any part.body value it already has if it has it

Websocket fixes

Fixes aimed at websocket stability:

  • Changes exponential backoff for websocket reconnect
  • Refactors Online State Manager and how it handles invalid websockets
  • Adds client events for debugging; see API Reference for details.
    • websocket:connecting
    • websocket:disconnecting
    • websocket:replaying-events
    • websocket:scheduling-reconnect
    • websocket:schedule-reconnect
    • websocket:ignore-skipped-counter
  • If multiple anomolies in a websocket connection will not attempt recovery until frequency of such errors is less than once per minute

Other Changes

  • Image Messages
    • If sent using the File Upload Button (or drag and drop) no longer use the file name as a title; Images default to being sent without a title.
    • If sent without a title, now have a maximum height of 450px and a maximum width based on the width of the Message List
    • Image Viewer now shows a loading indicator
    • Fixes rendering/scaling of images for IE11; note that this uses background-image and hides the <img /> tag so this may impact CSS used if you support IE11
  • File Message
    • File Message maximum width is reduced
  • Message Type Model Changes
    • Adds presend() method that will generate a message and call message.presend() so that users may preview it in their Message List without having sent it yet.
    • Supports concept of Slots for organizing Message Metadata (optional – for use in designing Custom Messages)
  • Response Message Changes (WEB-1766)
    • Adds getOperationsForState(stateName) to get the list of operations to be sent (or already sent) to the server
    • Adds getStateChanges() which returns the Change Events associated with the operations to be sent to the server.
    • Adds getResponseSummary() to get the Response Summary instance that this Resonse Message is being sent/was sent to update.
  • Changes to the Message Viewer Component (<layer-message-viewer />)
    • Adds a size property that can be set to large for the Large version of a given Message (not supported for all Message Types yet)
    • Removes the widthType property; see instead the width property which lets a Message Type View force the Message Viewer Width to a fixed pixel value.
    • Removes the preferredMaxWidth and preferredMinWidth properties
  • The Standard Message View Container (<layer-standard-message-view-container />) now supports inserting controls via container.customControls = nodes
    • This is used by Link Message and Location Message to insert an arrow indicating the message can be clicked
    • This is used by the Audio Message to insert a Play button
  • The Message View Mixin used to implement all Custom Messages:
    • Changes to how Message sizes are controlled adding height, width, maxWidth and minWidth properties
    • now only calls onAfterCreate after the root part of the message has loaded
      • Calls to onAfterCreate are blocked if the Root Message Part is > 2KB and still being asynchronously fetched
      • Call to onAfterCreate will be called after fetch is completed
    • Now provides getMaxMessageWidth() method for getting the available width for the Message to render in
  • Component base class now supports properties where type: Object is part of the definition; will deserialize JSON property values.
  • WEB-1779: Now throws error if calling Layer.UI.setupMixins({...}) after calling Layer.init()
  • Increases priority of DOM nodes with layer-replaceable-name="foo" within your HTML over widget.replaceableContent = {foo: nodes} within your Javascript
  • message-type-response-summmary-v2 renamed to message-type-response-summary-v2
  • message-type-response-summmary-v1 renamed to message-type-response-summary-v1; Most projects should not be using this!
  • Supported Image Types, Audio Types and Video Types can be set in the settings via Layer.init({imageMIMETypes: ['image/gif'], audioMIMETypes: ['audio/mp3'], videoMIMETypes: ['video/mp4']}); but the default values indicate values that Layer Messages have been tested against.
  • File Upload Button can now reslect the same file twice in a row
  • The Conversation View now provides a width property is set whenever the window resizes; apps may need to set this if they use sliders or other internal size changes. Changes in this property are used to notify the Conversation View and Message List that they have resized and may need to adjust margins and whether avatars are showing.
  • WEB-1792: Adds Replaceable Content section named conversationViewTop to the top of the Conversation View; this can be used to render temporary or persisted content on top of the Message List
  • Fixes bug where if Conversation is not loaded, Message Status cannot be rendered
  • WEB-1620: Adds a prompt to ask users if they want to enable notifications
    • Adds <layer-prompt /> widget
    • <layer-notifier /> widget now uses the prompt to ask users if they want to enable notifications
    • If users click Yes, the browser’s permissions UI will be presented
    • If users click No, the prompt won’t be shown again
    • Notifier.enableNotificationPrompt can be set to customize the prompt message
  • WEB-1797: Adds MessageTypeModel static FileBehaviorsForProperty() method for setting up properties that manage files/blobs
  • WEB-1781: Improved link and address detection
    • Detects and links mailto: and tel: URIs
    • Detects and links email addresses within messages even if not preceded by a mailto:
  • WEB-1752: Layer.UI.components.Avatar Component now accepts avatarComponent.item = identity; as another option for setting the Avatar’s Identity
  • WEB-1707 : Use Layer.Utils.getLogs() to get logs to dump to a logging service
    • Use Layer.init({ logSize: 500 }) to change the number of lines of logging data that is tracked
  • Updated babel settings, updated build process
  • Fixes line wrapping of text messages in Firefox
  • Fixes URL detection to handle multi-line expressions that contain a URL that goes from the start to the end of a line
  • Removes all CommonJS module usage from internal components; note that CommonJS is still used when doing import '@layerhq/web-xdk'; this will be treated as a potential breaking; changing the main import to use ES6 module exports will happen in the next Major release.
  • Removes all SVG background images, and adds SVG as stylable DOM nodes wherever they are used in the UI
    • All Message Views that show icons in their title bars should now provide getIcon() method to get an SVG image, rather than getIconClass() method which got a CSS class to drive background images (getIconClass() should continue to be supported for now)
    • <layer-titled-message-view-container /> property icon renamed to iconClass
    • Dialog Close Button will now render differently and CSS may need to be updated
    • File Upload Button will now render differently and CSS may need to be updated

4.0.4

  • WEB-1796: Fixes Image Orientation for rotated images sent via Safari
  • WEB-1785: Fixes rendering of Product Choices that have no selections
  • WEB-1782: Adds headers to help server identify clients causing problems

4.0.3

  • Fixes identity metadata so that it is always an Object even when there is no value in the object
  • Adds Property Type for UI Components of type: Object
  • replaceableContent can now be set as an attribute and will be converted to Object: <my-widget replaceable-content='{"name": "value"}'></my-widget>
  • WEB-1765: Adds presend() method to all Message Type Models so that messages created from Models can be previewed in the Message List.
  • Fixes rendering of Date Sent for messages that were presend() before they were send()
  • Refactors imports for Messaging Models/Components into src/ui/messages/index and src/ui/messages/index-lite (typical apps do not use this directly)
  • WEB-1772: No longer pings to check if server is available unless client is ready and authenticated
  • WEB-1763: No longer requires all imports follow the same path; one component may import @layerhq/webxdk and another @layerhq/webxdk/index-lite without generating conflicts or duplication
  • Replaceable Content: Increases priority of DOM nodes with layer-replaceable-name="foo" within your HTML over widget.replaceableContent = {foo: nodes}; if both are used, the DOM nodes with the attribute will be used and the other ignored.
  • WEB-1762: Use passive scroll listeners
  • WEB-1783: text/plain and legacy messages from Layer UI/Atlas now render in the Conversation List

4.0.2

  • Adds logging mode for doing timing; Layer.init({ appId, logLevel: Layer.Constants.LOG.TIMING })
  • Changes message-type-response-summary reset() to not unregister registered states
  • Adds better validation of localStorage before using it
  • WEB-1755: Refactors Emoji Support:
    • The Emoji text processor no longer parses for :smile: and :-); it is now used solely for those wanting Twemoji’s standard emojis that work cross platform and provides consistent emojis across all platforms. This continues to be an optional part of the build; included for those who use import '@layerhq/web-xdk' and left out for those who do import '@layerhq/web-xdk/index-lite'.
    • The Compose Bar now detects :smile: and :-) and translates them into Emoji characters that can be understood by Android and iOS native apps. This is currently handled via remarkable-emoji.
  • Adds CONTRIBUTING.md guidelines for submitting PRs to this repository.
  • WEB-1756: Google Maps API Key is now an input to Layer.init({ appId, googleMapsKey: 'my-key' }); without this, Location Messages will not work. Previously there was an undocumented hack to make this work.
  • WEB-1757: isCurrentParticipant is now recalculated any time the participant list changes, and triggers change events when its value changes
  • Replaceable Content:
    • on searching child nodes now ignores Text Nodes
    • now correctly finds layer-replaceable-name in browsers that require the Webcomponents Polyfill.
  • Tweak to button height styling prevents raw JS sample app from having unexpected Button Heights

4.0.1

  • WEB-1731: Adds AltMIMETypes
    • A Model can represent more than one MIME Type
    • A Model can represent the same MIME Type but with different version numbers in the version string
  • WEB-1731: Adds versioning for the Response Summary class, enabling backwards compatability with prerelease structures
  • Fixes Toast Notification CSS to prevent overflow

4.0.0

  • Merges UI and SDK into a single repository
  • Redefines all UI Components
  • Adds a system for defining Message Types
  • Provides a library of Message Types
  • Provides a system for Interactive Messages
Upgrade Guide Previewing Messages