UNPKG

@cobuildlab/8base-chat

Version:

Chat component that uses 8base

861 lines (805 loc) 172 kB
import { Column, SelectField, Avatar, Icon, Button, Modal, Dropdown, Tooltip, Menu, Dialog, ModalContext, InputField, Switch, withModal, createTheme, BoostProvider } from '@8base/boost'; import get from 'lodash/get'; import React__default, { createContext, useContext, useCallback, useMemo, createElement, useRef, useEffect, useLayoutEffect, useState } from 'react'; import { withMutation, withQuery, Query, compose, withApollo, ApolloProvider } from 'react-apollo'; import invariant, { InvariantError } from 'ts-invariant'; import { SubscriptionLink } from '@8base/apollo-links'; import { InMemoryCache } from 'apollo-cache-inmemory'; import { ApolloClient } from 'apollo-client'; import { ApolloLink, split, getOperationName } from 'apollo-link'; import { BatchHttpLink } from 'apollo-link-batch-http'; import { setContext } from 'apollo-link-context'; import { onError } from 'apollo-link-error'; import { HttpLink } from 'apollo-link-http'; import { getMainDefinition } from 'apollo-utilities'; import debounce from 'lodash/debounce'; import hoistNonReactStatics from 'hoist-non-react-statics'; import cx from 'classnames'; import gql from 'graphql-tag'; import PubSub from 'pubsub-js'; import uniqBy from 'lodash/uniqBy'; import 'emoji-mart/css/emoji-mart.css'; import data from 'emoji-mart/data/emojione.json'; import { FileInput } from '@8base/file-input'; import NimblePicker from 'emoji-mart/dist-es/components/picker/nimble-picker'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __awaiter(thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); } function __generator(thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } } function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; } var ChannelMember = { hasUnreads: function (member) { var lastReadTS = member.lastReadTS, channel = member.channel, user = member.user; var msgItems = get(channel, 'messages.items', []); var _a = msgItems[msgItems.length - 1] || {}, _b = _a.createdBy, createdBy = _b === void 0 ? {} : _b, _c = _a.createdAt, createdAt = _c === void 0 ? null : _c; var userId = user && user.id; if (createdBy.id === userId) { return false; } if (!lastReadTS && createdAt) { return true; } if (createdAt) { var lastReadDate = new Date(lastReadTS); var lastChannelMsgDate = new Date(createdAt); return lastReadDate.getTime() <= lastChannelMsgDate.getTime(); } return false; }, }; var resolvers = { ChannelMember: ChannelMember, }; function genOptimisticId() { return "optimistic-" + Math.round(Math.random() * 1000000); } function isOptimisticId(id) { if (typeof id !== 'string') { return false; } return id.startsWith('optimistic'); } // -- MAIN /** * Generates name for Group using members first names. * @param names First names of users * @example * getGroupName(['A', 'B', 'C']) // -> A, B & C */ function getGroupName(names) { var cloneNames = names.slice(); var endName = cloneNames.pop(); return cloneNames.join(', ') + (" & " + endName); } function getDmName(members, currentUserId) { var dmMembers = members.items.filter(function (el) { return el.user && el.user.id !== currentUserId; }); var firstNames = dmMembers.map(function (el) { return el.user.firstName || '-'; }); return dmMembers.length === 1 ? dmMembers[0].user.firstName + " " + dmMembers[0].user.lastName : getGroupName(firstNames); } function getExtension(filename) { if (typeof filename !== 'string') { return ''; } var match = filename.match(/^.+\.(\w+)$/); return match ? match[1] : ''; } function isImage(extension) { return /^(gif|jpe?g|png|svg|tiff|webp)$/.test(extension); } function isPreviewSupported(extension) { return /^(gif|jpe?g|png|tiff|pdf|pptx?|xlsx?|odt|odf|html?|txt|ai|psd)$/.test(extension); } // -- CONSTANTS var HTML_ENTITIES = [['&', '&amp;'], ['<', '&lt;'], ['>', '&gt;']]; // -- UTILS function getMessageTimestamp(ts) { var date = new Date(ts); var currentDate = new Date(); var timeOpts = { hour: '2-digit', minute: '2-digit', }; var dateOpts = { year: currentDate.getFullYear() === date.getFullYear() ? undefined : '2-digit', month: '2-digit', day: '2-digit', }; return date.toLocaleTimeString('default', timeOpts) + " " + date.toLocaleDateString('default', dateOpts); } /** * Sanitizes a message by replacing control characters with HTML entities. * @param message */ function sanitizeMessage(message) { for (var _i = 0, HTML_ENTITIES_1 = HTML_ENTITIES; _i < HTML_ENTITIES_1.length; _i++) { var _a = HTML_ENTITIES_1[_i], character = _a[0], entity = _a[1]; message = message.replace(new RegExp(character, 'g'), entity); } return message; } /** * Replaces HTML entities with characters. * @param message */ function desanitizeMessage(message) { // '&' should be replaced last var htmlEntities = HTML_ENTITIES.slice().sort(function (a, b) { return a[0] === '&' ? 1 : b[0] === '&' ? -1 : 0; }); for (var _i = 0, htmlEntities_1 = htmlEntities; _i < htmlEntities_1.length; _i++) { var _a = htmlEntities_1[_i], character = _a[0], entity = _a[1]; message = message.replace(new RegExp(entity, 'g'), character); } return message; } /** * Checks if current environment is 'development' */ function isDevEnv() { return process.env.NODE_ENV === 'development'; } /** * Calls console[type] with provided args * Useful to distinguish logs that should be in production * @param type - type of console (e.g. log, error) * @param args */ function log(type) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } var fn = console[type]; return fn.apply(void 0, args); } /** * Makes promise cancelable * @author istarkov */ function makeCancelable(promise) { var hasCanceled = false; var wrappedPromise = new Promise(function (resolve, reject) { promise.then(function (val) { return (hasCanceled ? reject({ isCanceled: true }) : resolve(val)); }, function (error) { return (hasCanceled ? reject({ isCanceled: true }) : reject(error)); }); }); return { promise: wrappedPromise, cancel: function () { hasCanceled = true; }, }; } /** * Trims empty lines. * @param text * @param moreThan - specifies when to trim empty lines. * For example, if there are more empty lines in a row than [moreThan] * then it trims */ function trimEmptyLines(text, moreThan) { var replacement = new Array(moreThan - 1).fill('\n').join(''); return text.replace(/\n{3,}/g, replacement); } /** * Returns all results matching a string against regular expression * @param str * @param regex */ function matchAll(str, regex) { var matches = []; var match; // tslint:disable-next-line: no-conditional-assignment while ((match = regex.exec(str)) !== null) { matches.push(match); } return matches; } function hasHttpProtocol(url) { return /^https?:\/\//.test(url); } // -- MAIN function createApolloClient(_a) { var uri = _a.uri, token = _a.token, workspaceId = _a.workspaceId; var batchHttpLink = new BatchHttpLink({ uri: uri }); var httpLink = new HttpLink({ uri: uri }); var subscriptionLink = new SubscriptionLink({ uri: 'wss://ws.8base.com', getAuthState: function () { return ({ token: token, workspaceId: workspaceId, }); }, onAuthError: function (error) { log('log', '[Subscription error]:', error); }, }); var onErrorLink = onError(function (_a) { var graphQLErrors = _a.graphQLErrors, networkError = _a.networkError; if (graphQLErrors) { graphQLErrors.map(function (_a) { var message = _a.message, locations = _a.locations, path = _a.path; return log('log', "[GraphQL error]: Message: " + message + ", Location: " + locations + ", Path: " + path); }); } if (networkError) { log('log', '[Network error]:', networkError); } }); var authLink = setContext(function (_, _a) { var headers = _a.headers; return ({ headers: __assign({}, headers, { authorization: token ? "Bearer " + token : '' }), }); }); var networkLink = split(function (_a) { var query = _a.query; var definition = getMainDefinition(query); return (definition.kind === 'OperationDefinition' && definition.operation === 'subscription'); }, subscriptionLink, split(function (operation) { return operation.getContext().important === true; }, httpLink, batchHttpLink)); var cache = new InMemoryCache(); return new ApolloClient({ link: ApolloLink.from([authLink, onErrorLink, networkLink]), cache: cache, resolvers: resolvers, }); } var css = { "base": "mca04a1eb8_f4 mc0332c294_base" }; // -- MAIN var ChatContext = createContext({ openedChannel: null, user: null, setChannel: function () { }, setTabs: function () { }, isSidebarVisible: true, tabs: [], usersFilter: null, }); // -- MAIN function withContext(_a) { var context = _a.context, keys = _a.keys; return function enhancer(Component) { function WithContext(props) { var contextValue = useContext(context); var result = contextValue; if (keys) { result = {}; for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { var key = keys_1[_i]; result[key] = contextValue[key]; } } // @ts-ignore TODO: resolve type conflict return React__default.createElement(Component, __assign({}, props, result)); } return hoistNonReactStatics(WithContext, Component); }; } var css$1 = { "list": "mcffb11d07_list", "item": "mcffb11d07_item" }; // -- COMPONENTS function Item(_a) { var className = _a.className, children = _a.children, domAttrs = __rest(_a, ["className", "children"]); var cn = cx(className, css$1.item); return (React__default.createElement("li", __assign({ className: cn }, domAttrs), children)); } // -- MAIN function List(_a) { var className = _a.className, children = _a.children, domAttrs = __rest(_a, ["className", "children"]); var cn = cx(className, css$1.list); return (React__default.createElement("ul", __assign({ className: cn }, domAttrs), children)); } List.Item = Item; // -- COMPONENTS function SelectBrowserListItem(_a) { var label = _a.label, value = _a.value, onItemSelect = _a.onItemSelect, children = _a.children; var onClick = useCallback(function () { onItemSelect({ label: label, value: value }); }, []); return React__default.createElement(List.Item, { onClick: onClick }, children); } // -- MAIN function SelectBrowser(_a) { var availableOptions = _a.availableOptions, onItemSelect = _a.onItemSelect, loading = _a.loading, className = _a.className, OptionBody = _a.optionBody, selectProps = __rest(_a, ["availableOptions", "onItemSelect", "loading", "className", "optionBody"]); var cnList = cx(className.list); return (React__default.createElement(Column, { gap: "sm", alignItems: "stretch" }, React__default.createElement(SelectField, __assign({ stretch: true, menuIsOpen: false }, selectProps)), loading ? (React__default.createElement("div", null, "Loading...")) : (React__default.createElement(List, { className: cnList }, availableOptions.map(function (option) { return (React__default.createElement(SelectBrowserListItem, __assign({ key: option.value, onItemSelect: onItemSelect }, option), OptionBody ? React__default.createElement(OptionBody, __assign({}, option)) : option.label)); }))))); } SelectBrowser.defaultProps = { className: {}, }; var css$2 = { "base": "mc9cc640c5_base", "stacked-avatar": "mc9cc640c5_stacked-avatar", "rest-user-count": "mca04a1eb8_f5 mc9cc640c5_rest-user-count" }; // -- MAIN function StackedAvatars(_a) { var avatars = _a.avatars, size = _a.size, totalUsers = _a.totalUsers, className = _a.className; var cn = cx(className, css$2.base); var restUserCount = !!totalUsers ? totalUsers - avatars.length : 0; return (React__default.createElement("div", { className: cn }, avatars.map(function (_a) { var id = _a.id, avatar = __rest(_a, ["id"]); return (React__default.createElement(Avatar, __assign({ key: id, size: size, className: css$2['stacked-avatar'] }, avatar))); }), restUserCount > 0 && (React__default.createElement("span", { className: css$2['rest-user-count'] }, "+", restUserCount)))); } StackedAvatars.defaultProps = { size: 'md', }; var css$3 = { "option-body": "mcd1005020_option-body" }; // -- COMPONENTS function OptionBody(_a) { var label = _a.label, members = _a.members; var totalUsers = members ? members.count : 0; var avatars = members ? members.items.map(function (el) { return ({ id: el.id, src: el.user && el.user.avatar && el.user.avatar.downloadUrl, firstName: el.user && el.user.firstName, lastName: el.user && el.user.lastName, }); }) : []; return (React__default.createElement("div", { className: css$3['option-body'] }, React__default.createElement("span", null, label), React__default.createElement(StackedAvatars, { avatars: avatars, size: "sm", totalUsers: totalUsers }))); } // -- MAIN function ChannelsBrowser(_a) { var channels = _a.channels, input = _a.input, selectProps = __rest(_a, ["channels", "input"]); var options = channels.map(function (el) { return (__assign({}, el, { label: el.name, value: el.id })); }); var availableOptions = options.filter(function (item) { return item.value !== input.value; }); return (React__default.createElement(SelectBrowser, __assign({}, selectProps, { input: input, options: options, availableOptions: availableOptions, optionBody: OptionBody }))); } var css$4 = { "form": "mcb1c929e9_form" }; // -- MAIN function DialogForm(_a) { var children = _a.children, className = _a.className, rest = __rest(_a, ["children", "className"]); var cn = cx(className, css$4.form); return (React__default.createElement("form", __assign({ className: cn }, rest), children)); } var css$5 = { "utilities": "\"../../../styles/utilities.css\"", "wrapper": "mc83798da4_wrapper", "header": "mc83798da4_header", "back-btn": "mca04a1eb8_btn-reset mc83798da4_back-btn", "back-btn-icon": "mc83798da4_back-btn-icon", "info": "mca04a1eb8_f4 mca04a1eb8_txt-ellipsis mc83798da4_info", "filename": "mca04a1eb8_txt-ellipsis mc83798da4_filename", "date": "mc83798da4_date", "preview-frame": "mc83798da4_preview-frame" }; function getUploadedOnText(dateStr) { var date = new Date(dateStr); var localDate = date.toLocaleDateString('default', { month: '2-digit', day: '2-digit', year: 'numeric', }); var localTime = date.toLocaleTimeString('default', { hour: '2-digit', minute: '2-digit', }); return "Uploaded on " + localDate + " at " + localTime; } // -- CONSTANTS var DOCUMENT_PREVIEW_ID = 'DOCUMENT_PREVIEW_ID'; // -- MAIN function DocumentPreview() { var modalRender = useCallback(function (_a) { var args = _a.args, onClose = _a.onClose; return (React__default.createElement("div", { className: css$5.wrapper }, React__default.createElement("div", { className: css$5.header }, React__default.createElement("div", null, React__default.createElement("button", { className: css$5['back-btn'], onClick: function () { return onClose(); } }, React__default.createElement(Icon, { className: css$5['back-btn-icon'], name: "ArrowLeft" }), React__default.createElement("span", null, "Back"))), React__default.createElement("div", { className: css$5.info }, React__default.createElement("div", { className: css$5.filename }, args.filename || '-'), React__default.createElement("div", { className: css$5.date }, getUploadedOnText(args.createdAt))), args.downloadUrl && (React__default.createElement("div", null, React__default.createElement(Button, { tagName: "a", href: args.downloadUrl, target: "_blank", rel: "noopener noreferrer" }, "Download")))), React__default.createElement("iframe", { className: css$5['preview-frame'], src: args.previewUrl, title: args.filename }))); }, []); return React__default.createElement(Modal, { id: DOCUMENT_PREVIEW_ID }, modalRender); } DocumentPreview.id = DOCUMENT_PREVIEW_ID; var css$6 = { "base": "mc89212e8a_base", "color-primary": "mc89212e8a_color-primary", "size-md": "mc89212e8a_size-md" }; function DotIndicator(_a) { var color = _a.color, className = _a.className, size = _a.size, domAttrs = __rest(_a, ["color", "className", "size"]); var cn = cx(className, css$6.base, color && css$6["color-" + color], size && css$6["size-" + size]); return React__default.createElement("div", __assign({ className: cn }, domAttrs)); } DotIndicator.defaultProps = { color: 'primary', size: 'md', }; // -- MAIN function ActionButton(_a) { var children = _a.children, isSquared = _a.isSquared, tagName = _a.tagName, domAttrs = __rest(_a, ["children", "isSquared", "tagName"]); var Tag = tagName; return (React__default.createElement(React__default.Fragment, null, isSquared ? (React__default.createElement(Button, __assign({ tagName: tagName, squared: true, color: "neutral", variant: "outlined", size: "sm" }, domAttrs), children)) : (React__default.createElement(Tag, __assign({}, domAttrs), children)))); } ActionButton.defaultProps = { tagName: 'button', }; var css$7 = { "action": "mc0e3a9eaf_action", "squared-action": "mc0e3a9eaf_action mc0e3a9eaf_squared-action", "action-transparent": "mc0e3a9eaf_action mca04a1eb8_btn-reset mc0e3a9eaf_action-transparent", "owner-action": "mc0e3a9eaf_action mca04a1eb8_btn-reset mc0e3a9eaf_action-transparent mc0e3a9eaf_owner-action", "foreign-action": "mc0e3a9eaf_action mca04a1eb8_btn-reset mc0e3a9eaf_action-transparent mc0e3a9eaf_foreign-action", "tooltip": "mc0e3a9eaf_tooltip" }; // -- MAIN function FileActions(_a) { var moreActions = _a.moreActions, downloadUrl = _a.downloadUrl, isSquared = _a.isSquared, isOwner = _a.isOwner; var cnAction = cx(isSquared ? css$7['squared-action'] : isOwner ? css$7['owner-action'] : css$7['foreign-action']); // TODO: it's not good practice to stop propagation. May be we should refactor it var onClickAction = useCallback(function (e) { e.stopPropagation(); }, []); return (React__default.createElement(React__default.Fragment, null, moreActions && moreActions.length > 0 && (React__default.createElement(ActionButton, { onClick: onClickAction, className: cnAction, isSquared: isSquared }, React__default.createElement(Dropdown, { defaultOpen: false }, React__default.createElement(Dropdown.Head, null, React__default.createElement(Tooltip, { className: css$7.tooltip, message: "More actions", placement: "top", cursor: "pointer", eventsEnabled: false }, React__default.createElement(Icon, { name: "More" }))), React__default.createElement(Dropdown.Body, { pin: "left", withPortal: true, preventOverflow: true, placement: "left" }, function (dropdownOpts) { return (React__default.createElement(Menu, null, moreActions.map(function (item) { return (React__default.createElement(Menu.Item, { key: item.title, // tslint:disable-next-line: jsx-no-lambda onClick: function () { return item.onClick(dropdownOpts); } }, item.title)); }))); })))), downloadUrl && (React__default.createElement(ActionButton, { tagName: "a", onClick: onClickAction, className: cnAction, isSquared: isSquared, href: downloadUrl, target: "_blank", rel: "noopener noreferrer" }, React__default.createElement(Tooltip, { className: css$7.tooltip, message: "Download", placement: "top", cursor: "pointer", eventsEnabled: false }, React__default.createElement(Icon, { name: "Download" })))))); } var offset = 0; var InfiniteScroll = /** @class */ (function (_super) { __extends(InfiniteScroll, _super); function InfiniteScroll(props) { var _this = _super.call(this, props) || this; _this.onScroll = function () { return __awaiter(_this, void 0, void 0, function () { var _a, parentNode, loadMore, threshold, hasNextPage, isReverse, oldScrollHeight, shouldLoadMore; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.props, parentNode = _a.parentNode, loadMore = _a.loadMore, threshold = _a.threshold, hasNextPage = _a.hasNextPage, isReverse = _a.isReverse; offset = parentNode.scrollTop - threshold; if (this.state.isLoadingNext || !hasNextPage) { return [2 /*return*/]; } oldScrollHeight = parentNode.scrollHeight; shouldLoadMore = offset <= 0; if (!shouldLoadMore) { return [2 /*return*/]; } this.setState({ isLoadingNext: true, }); return [4 /*yield*/, loadMore()]; case 1: _b.sent(); if (isReverse) { parentNode.scrollTop = parentNode.scrollHeight - oldScrollHeight + threshold + offset; } this.setState({ isLoadingNext: false, }); return [2 /*return*/]; } }); }); }; _this.state = { isLoadingNext: false, }; return _this; } InfiniteScroll.prototype.componentDidMount = function () { this.props.parentNode.addEventListener('scroll', this.onScroll); }; InfiniteScroll.prototype.componentWillUnmount = function () { this.props.parentNode.removeEventListener('scroll', this.onScroll); }; InfiniteScroll.prototype.render = function () { var _a = this.props, children = _a.children, hasNextPage = _a.hasNextPage, loader = _a.loader, isReverse = _a.isReverse; return (React__default.createElement(React__default.Fragment, null, hasNextPage && isReverse && loader, children, hasNextPage && !isReverse && loader)); }; InfiniteScroll.defaultProps = { isReverse: false, threshold: 350, }; return InfiniteScroll; }(React__default.Component)); var css$8 = { "normal": "mc10430a93_normal", "content": "mc10430a93_content", "body": "mc10430a93_body", "body-with-arrow": "mc10430a93_body mc10430a93_body-with-arrow", "timestamp": "mca04a1eb8_f5 mc10430a93_timestamp", "avatar": "mc10430a93_avatar", "own": "mc10430a93_normal mc10430a93_own" }; // -- MAIN function Message(_a) { var className = _a.className, isOwner = _a.isOwner, hasAvatar = _a.hasAvatar, children = _a.children, timestamp = _a.timestamp, avatar = _a.avatar, hasArrow = _a.hasArrow, onClickBody = _a.onClickBody; var cn = cx(className.wrapper, isOwner ? css$8.own : css$8.normal); var cnBody = cx(className.body, hasArrow ? css$8['body-with-arrow'] : css$8.body); return (React__default.createElement("div", { className: cn }, hasAvatar && (React__default.createElement(Tooltip, { message: avatar.firstName + " " + avatar.lastName }, React__default.createElement(Avatar, { className: css$8.avatar, size: "sm", src: avatar.src, firstName: avatar.firstName, lastName: avatar.lastName }))), React__default.createElement("div", { className: css$8.content }, React__default.createElement("div", { className: cnBody, onClick: onClickBody }, children), timestamp && React__default.createElement("div", { className: css$8.timestamp }, timestamp)))); } Message.defaultProps = { avatar: {}, className: {}, hasArrow: true, }; var css$9 = { "body": "mc651066b8_body", "actions": "mc651066b8_actions", "icon": "mc651066b8_icon", "name": "mca04a1eb8_f3 mca04a1eb8_txt-ellipsis mc651066b8_name" }; // -- MAIN function MessageFile(_a) { var filename = _a.filename, actions = _a.actions, className = _a.className, msgProps = __rest(_a, ["filename", "actions", "className"]); var cnMessage = useMemo(function () { return ({ wrapper: cx(className.wrapper, css$9.message), body: cx(className.body, css$9.body), }); }, [className]); return (React__default.createElement(Message, __assign({ className: cnMessage }, msgProps), React__default.createElement(Icon, { className: css$9.icon, name: "Document", color: msgProps.isOwner && 'PRIMARY' }), React__default.createElement("span", { className: css$9.name }, filename || '-'), actions && React__default.createElement("div", { className: css$9.actions }, actions))); } var css$a = { "base": "mc27668e3b_base", "img": "mc27668e3b_img", "actions": "mc27668e3b_actions", "body": "mc27668e3b_body" }; // -- MAIN function MessageImage(_a) { var downloadUrl = _a.downloadUrl, actions = _a.actions, className = _a.className, msgProps = __rest(_a, ["downloadUrl", "actions", "className"]); var cnMessage = useMemo(function () { return ({ wrapper: className.wrapper, body: cx(className.body, css$a.body), }); }, [className]); return (React__default.createElement(Message, __assign({}, msgProps, { className: cnMessage, hasArrow: false }), React__default.createElement("div", { className: css$a.base }, React__default.createElement("img", { className: css$a.img, src: downloadUrl }), React__default.createElement("div", { className: css$a.actions }, actions)))); } MessageImage.defaultProps = { className: {}, }; var css$b = { "base": "mc99c2c001_base", "normal": "mc99c2c001_base mc99c2c001_normal", "own": "mc99c2c001_base mc99c2c001_own" }; // -- MAIN function MessageLink(_a) { var isOwner = _a.isOwner, rest = __rest(_a, ["isOwner"]); var cn = cx(isOwner ? css$b.own : css$b.normal); return React__default.createElement("a", __assign({}, rest, { className: cn })); } var css$c = { "wrapper": "mc48bd1f67_wrapper", "value": "mc48bd1f67_value", "textarea": "mc48bd1f67_textarea" }; // -- MAIN function TextAreaAutoHeight(_a) { var className = _a.className, value = _a.value, textareaAttrs = __rest(_a, ["className", "value"]); var cnWrapper = cx(className.wrapper, css$c.wrapper); var cnTextarea = cx(className.textarea, css$c.textarea); return (React__default.createElement("div", { className: cnWrapper }, React__default.createElement("div", { className: css$c.value }, value, '\n'), React__default.createElement("textarea", __assign({ className: cnTextarea, value: value }, textareaAttrs)))); } TextAreaAutoHeight.defaultProps = { className: {}, }; var css$d = { "option-avatar": "mcd671c518_option-avatar" }; // -- MAIN function Option(props) { var data = props.data, innerProps = props.innerProps; var style = { display: 'flex', alignItems: 'center', }; return (React__default.createElement("div", __assign({}, innerProps, { style: style }), React__default.createElement(Avatar, { className: css$d['option-avatar'], src: data.src, size: "sm", firstName: data.firstName, lastName: data.lastName }), React__default.createElement("span", null, data.label))); } // -- MAIN var components = { Option: Option }; function UserSelectField(props) { return React__default.createElement(SelectField, __assign({}, props, { components: components })); } var css$e = { "avatar": "mc6739a50e_avatar" }; // -- COMPONENTS function OptionBody$1(_a) { var label = _a.label, avatar = _a.avatar, firstName = _a.firstName, lastName = _a.lastName; return (React__default.createElement(React__default.Fragment, null, React__default.createElement(Avatar, { size: "sm", src: avatar && avatar.downloadUrl, firstName: firstName, lastName: lastName, className: css$e.avatar }), React__default.createElement("span", null, label))); } // -- MAIN function UsersBrowser(_a) { var users = _a.users, selectProps = __rest(_a, ["users"]); var availableOptions = users.map(function (el) { return (__assign({}, el, { label: el.firstName + " " + el.lastName, value: el.id })); }); return (React__default.createElement(SelectBrowser, __assign({}, selectProps, { availableOptions: availableOptions, optionBody: OptionBody$1, multiple: true }))); } var UserFullnameFragmentDoc = gql(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n fragment UserFullname on User {\n id\n firstName\n lastName\n}\n "], ["\n fragment UserFullname on User {\n id\n firstName\n lastName\n}\n "]))); var ImageFragmentDoc = gql(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n fragment Image on File {\n id\n downloadUrl\n}\n "], ["\n fragment Image on File {\n id\n downloadUrl\n}\n "]))); var ChannelMemberFragmentDoc = gql(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n fragment ChannelMember on ChannelMember {\n id\n user {\n ...UserFullname\n avatar {\n ...Image\n }\n }\n}\n ", "\n", ""], ["\n fragment ChannelMember on ChannelMember {\n id\n user {\n ...UserFullname\n avatar {\n ...Image\n }\n }\n}\n ", "\n", ""])), UserFullnameFragmentDoc, ImageFragmentDoc); var ChannelIdentityCommonFragmentDoc = gql(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n fragment ChannelIdentityCommon on ChannelMember {\n id\n user {\n id\n }\n lastReadTS\n hasUnreads @client\n}\n "], ["\n fragment ChannelIdentityCommon on ChannelMember {\n id\n user {\n id\n }\n lastReadTS\n hasUnreads @client\n}\n "]))); var ChannelPreviewCommonFragmentDoc = gql(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n fragment ChannelPreviewCommon on Channel {\n id\n name\n public\n type\n createdBy {\n id\n }\n messages(last: 1) {\n items {\n createdAt\n createdBy {\n id\n }\n }\n }\n}\n "], ["\n fragment ChannelPreviewCommon on Channel {\n id\n name\n public\n type\n createdBy {\n id\n }\n messages(last: 1) {\n items {\n createdAt\n createdBy {\n id\n }\n }\n }\n}\n "]))); var ChannelPreviewFragmentDoc = gql(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n fragment ChannelPreview on Channel {\n ...ChannelPreviewCommon\n members {\n count\n }\n}\n ", ""], ["\n fragment ChannelPreview on Channel {\n ...ChannelPreviewCommon\n members {\n count\n }\n}\n ", ""])), ChannelPreviewCommonFragmentDoc); var ChannelIdentityFragmentDoc = gql(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n fragment ChannelIdentity on ChannelMember {\n ...ChannelIdentityCommon\n channel {\n ...ChannelPreview\n }\n}\n ", "\n", ""], ["\n fragment ChannelIdentity on ChannelMember {\n ...ChannelIdentityCommon\n channel {\n ...ChannelPreview\n }\n}\n ", "\n", ""])), ChannelIdentityCommonFragmentDoc, ChannelPreviewFragmentDoc); var DmPreviewFragmentDoc = gql(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n fragment DmPreview on Channel {\n ...ChannelPreviewCommon\n members {\n count\n items {\n user {\n ...UserFullname\n }\n }\n }\n}\n ", "\n", ""], ["\n fragment DmPreview on Channel {\n ...ChannelPreviewCommon\n members {\n count\n items {\n user {\n ...UserFullname\n }\n }\n }\n}\n ", "\n", ""])), ChannelPreviewCommonFragmentDoc, UserFullnameFragmentDoc); var DmIdentityFragmentDoc = gql(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n fragment DmIdentity on ChannelMember {\n ...ChannelIdentityCommon\n channel {\n ...DmPreview\n }\n}\n ", "\n", ""], ["\n fragment DmIdentity on ChannelMember {\n ...ChannelIdentityCommon\n channel {\n ...DmPreview\n }\n}\n ", "\n", ""])), ChannelIdentityCommonFragmentDoc, DmPreviewFragmentDoc); var UserPreviewFragmentDoc = gql(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n fragment UserPreview on User {\n ...UserFullname\n avatar {\n ...Image\n }\n}\n ", "\n", ""], ["\n fragment UserPreview on User {\n ...UserFullname\n avatar {\n ...Image\n }\n}\n ", "\n", ""])), UserFullnameFragmentDoc, ImageFragmentDoc); var AttachmentFragmentDoc = gql(templateObject_11 || (templateObject_11 = __makeTemplateObject(["\n fragment Attachment on File {\n id\n createdAt\n fileId\n downloadUrl\n filename\n previewUrl\n}\n "], ["\n fragment Attachment on File {\n id\n createdAt\n fileId\n downloadUrl\n filename\n previewUrl\n}\n "]))); var MessageFragmentDoc = gql(templateObject_12 || (templateObject_12 = __makeTemplateObject(["\n fragment Message on Message {\n id\n createdAt\n createdBy {\n ...UserPreview\n }\n text\n attachments {\n items {\n ...Attachment\n }\n }\n}\n ", "\n", ""], ["\n fragment Message on Message {\n id\n createdAt\n createdBy {\n ...UserPreview\n }\n text\n attachments {\n items {\n ...Attachment\n }\n }\n}\n ", "\n", ""])), UserPreviewFragmentDoc, AttachmentFragmentDoc); var ChannelMessagesDocument = gql(templateObject_13 || (templateObject_13 = __makeTemplateObject(["\n query ChannelMessages($id: ID!, $filter: MessageFilter, $orderBy: [MessageOrderBy], $last: Int, $before: String) {\n channel(id: $id) {\n id\n messages(filter: $filter, last: $last, before: $before, orderBy: $orderBy) {\n count\n items {\n ...Message\n }\n }\n }\n}\n ", ""], ["\n query ChannelMessages($id: ID!, $filter: MessageFilter, $orderBy: [MessageOrderBy], $last: Int, $before: String) {\n channel(id: $id) {\n id\n messages(filter: $filter, last: $last, before: $before, orderBy: $orderBy) {\n count\n items {\n ...Message\n }\n }\n }\n}\n ", ""])), MessageFragmentDoc); function withChannelMessages(operationOptions) { return withQuery(ChannelMessagesDocument, __assign({ alias: 'withChannelMessages' }, operationOptions)); } var ChannelMembersDocument = gql(templateObject_14 || (templateObject_14 = __makeTemplateObject(["\n query ChannelMembers($id: ID!, $first: Int) {\n channel(id: $id) {\n id\n members(first: $first) {\n count\n items {\n ...ChannelMember\n }\n }\n }\n}\n ", ""], ["\n query ChannelMembers($id: ID!, $first: Int) {\n channel(id: $id) {\n id\n members(first: $first) {\n count\n items {\n ...ChannelMember\n }\n }\n }\n}\n ", ""])), ChannelMemberFragmentDoc); var ChannelMembersComponent = function (props) { return (createElement(Query, __assign({ query: ChannelMembersDocument }, props))); }; var ChannelFormDocument = gql(templateObject_15 || (templateObject_15 = __makeTemplateObject(["\n query ChannelForm($id: ID!) {\n channel(id: $id) {\n id\n name\n purpose\n }\n}\n "], ["\n query ChannelForm($id: ID!) {\n channel(id: $id) {\n id\n name\n purpose\n }\n}\n "]))); var ChannelsSearchDocument = gql(templateObject_16 || (templateObject_16 = __makeTemplateObject(["\n query ChannelsSearch($first: Int!, $searchText: String!, $userId: ID!) {\n channelsList(first: $first, filter: {name: {contains: $searchText}, members: {none: {user: {id: {equals: $userId}}}}, public: {equals: true}, type: {equals: \"channel\"}}) {\n items {\n id\n name\n members(first: 3) {\n count\n items {\n id\n user {\n ...UserFullname\n avatar {\n ...Image\n }\n }\n }\n }\n }\n }\n}\n ", "\n", ""], ["\n query ChannelsSearch($first: Int!, $searchText: String!, $userId: ID!) {\n channelsList(first: $first, filter: {name: {contains: $searchText}, members: {none: {user: {id: {equals: $userId}}}}, public: {equals: true}, type: {equals: \"channel\"}}) {\n items {\n id\n name\n members(first: 3) {\n count\n items {\n id\n user {\n ...UserFullname\n avatar {\n ...Image\n }\n }\n }\n }\n }\n }\n}\n ", "\n", ""])), UserFullnameFragmentDoc, ImageFragmentDoc); var ChannelCreateDocument = gql(templateObject_17 || (templateObject_17 = __makeTemplateObject(["\n mutation ChannelCreate($data: ChannelCreateInput!) {\n channelCreate(data: $data) {\n id\n name\n members {\n items {\n id\n user {\n id\n }\n }\n }\n }\n}\n "], ["\n mutation ChannelCreate($data: ChannelCreateInput!) {\n channelCreate(data: $data) {\n id\n name\n members {\n items {\n id\n user {\n id\n }\n }\n }\n }\n}\n "]))); function withChannelCreate(operationOptions) { return withMutation(ChannelCreateDocument, __assign({ alias: 'withChannelCreate' }, operationOptions)); } var ChannelDeleteDocument = gql(templateObject_18 || (templateObject_18 = __makeTemplateObject(["\n mutation ChannelDelete($id: ID!) {\n channelDelete(data: {id: $id}, force: true) {\n success\n }\n}\n "], ["\n mutation ChannelDelete($id: ID!) {\n channelDelete(data: {id: $id}, force: true) {\n success\n }\n}\n "]))); function withChannelDelete(operationOptions) { return withMutation(ChannelDeleteDocument, __assign({ alias: 'withChannelDelete' }, operationOptions)); } var FindOrCreateDmDocument = gql(templateObject_19 || (templateObject_19 = __makeTemplateObject(["\nmutation($usersIds: [ID!]!, $channelMembersFilter: ChannelMemberFilter){\n findOrCreateDM(data:{ usersIds: $usersIds, channelMembersFilter: $channelMembersFilter }){\n id\n name\n members {\n items {\n id\n user {\n id\n }\n }\n }\n }\n}\n "], ["\nmutation($usersIds: [ID!]!, $channelMembersFilter: ChannelMemberFilter){\n findOrCreateDM(data:{ usersIds: $usersIds, channelMembersFilter: $channelMembersFilter }){\n id\n name\n members {\n items {\n id\n user {\n id\n }\n }\n }\n }\n}\n "]))); function withFindOrCreateDm(operationOptions) { return withMutation(FindOrCreateDmDocument, __assign({ alias: 'withFindOrCreateDm' }, operationOptions)); } var ChannelMemberUpdateDocument = gql(templateObject_20 || (templateObject_20 = __makeTemplateObject(["\n mutation ChannelMemberUpdate($id: ID!, $lastReadTS: DateTime!) {\n channelMemberUpdate(data: {id: $id, lastReadTS: $lastReadTS}) {\n id\n lastReadTS\n }\n}\n "], ["\n mutation ChannelMemberUpdate($id: ID!, $lastReadTS: DateTime!) {\n channelMemberUpdate(data: {id: $id, lastReadTS: $lastReadTS}) {\n id\n lastReadTS\n }\n}\n "]))); function withChannelMemberUpdate(operationOptions) { return withMutation(ChannelMemberUpdateDocument, __assign({ alias: 'withChannelMemberUpdate' }, operationOptions)); } var ChannelMemberDeleteDocument = gql(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n mutation ChannelMemberDelete($id: ID!) {\n channelMemberDelete(data: {id: $id}) {\n success\n }\n}\n "], ["\n mutation ChannelMemberDelete($id: ID!) {\n channelMemberDelete(data: {id: $id}) {\n success\n }\n}\n "]))); function withChannelMemberDelete(operationOptions) { return withMutation(ChannelMemberDeleteDocument, __assign({ alias: 'withChannelMemberDelete' }, operationOptions)); } var ChannelMemberCreateDocument = gql(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n mutation ChannelMemberCreate($data: ChannelMemberCreateInput!) {\n channelMemberCreate(data: $data) {\n id\n }\n}\n "], ["\n mutation ChannelMemberCreate($data: ChannelMemberCreateInput!) {\n channelMemberCreate(data: $data) {\n id\n }\n}\n "]))); var ChannelUpdateDocument = gql(templateObject_23 || (templateObject_23 = __makeTemplateObject(["\n mutation ChannelUpdate($data: ChannelUpdateInput!) {\n channelUpdate(data: $data) {\n id\n }\n}\n "], ["\n mutation ChannelUpdate($data: ChannelUpdateInput!) {\n channelUpdate(data: $data) {\n id\n }\n}\n "]))); var UserChannelIdentitiesSubDocument = gql(templateObject_24 || (templateObject_24 = __makeTemplateObject(["\n subscription UserChannelIdentitiesSub($userId: ID!) {\n ChannelMember(filter: {mutation_in: [create], node: {channel: {members: {some: {user: {id: {equals: $userId}}}}}}}) {\n node {\n ...ChannelIdentity\n }\n }\n}\n ", ""], ["\n subscription UserChannelIdentitiesSub($userId: ID!) {\n ChannelMember(filter: {mutation_in: [create], node: {channel: {members: {some: {user: {id: {equals: $userId}}}}}}}) {\n node {\n ...ChannelIdentity\n }\n }\n}\n ", ""])), ChannelIdentityFragmentDoc); var FileDeleteDocument = gql(templateObject_25 || (templateObject_25 = __makeTemplateObject(["\n mutation FileDelete($data: FileDeleteInput!) {\n fileDelete(data: $data) {\n success\n }\n}\n "], ["\n mutation FileDelete($data: FileDeleteInput!) {\n fileDelete(data: $data) {\n success\n }\n}\n "]))); function withFileDelete(operationOptions) { return withMutation(FileDeleteDocument, __assign({ alias: 'withFileDelete' }, operationOptions)); } var MessageCreateDocument = gql(templateObject_26 || (templateObject_26 = __makeTemplateObject(["\n mutation MessageCreate($data: MessageCreateInput!) {\n messageCreate(data: $data) {\n ...Message\n }\n}\n ", ""], ["\n mutation MessageCreate($data: MessageCreateInput!) {\n messageCreate(data: $data) {\n ...Message\n }\n}\n ", ""])), MessageFragmentDoc); function withMessageCreate(operationOptions) { return withMutation(MessageCreateDocument, __assign({ alias: 'withMessageCreate' }, operationOptions)); } var MessageDeleteDocument = gql(templateObject_27 || (templateObject_27 = __makeTemplateObject(["\n mutation MessageDelete($data: MessageDeleteInput!) {\n messageDelete(data: $data) {\n success\n }\n}\n "], ["\n mutation MessageDelete($data: MessageDeleteInput!) {\n messageDelete(data: $data) {\n success\n }\n}\n "]))); function withMessageDelete(operationOptions) { return withMutation(MessageDeleteDocument, __assign({ alias: 'withMessageDelete' }, operationOptions)); } var MessageUpdateDocument = gql(templateObject_28 || (templateObject_28 = __makeTemplateObject(["\n mutation MessageUpdate($data: MessageUpdateInput!) {\n messageUpdate(data: $data) {\n id\n }\n}\n "], ["\n mutation MessageUpdate($data: MessageUpdateInput!) {\n messageUpdate(data: $data) {\n id\n }\n}\n "]))); function withMessageUpdate(operationOptions) { return withMutation(MessageUpdateDocument, __assign({ alias: 'withMessageUpdate' }, operationOptions)); } var UserChannelsMessagesSubDocument = gql(templateObject_29 || (templateObject_29 = __makeTemplateObject(["\n subscription UserChannelsMessagesSub($userId: ID!) {\n Message(filter: {mutation_in: [create, update], node: {channel: {members: {some: {user: {id: {equals: $userId}}}}}}}) {\n mutation\n node {\n ...Message\n isDeleted\n channel {\n id\n type\n }\n }\n }\n}\n ", ""], ["\n subscription UserChannelsMessagesSub($userId: ID!) {\n Message(filter: {mutation_in: [create, update], node: {channel: {members: {some: {user: {id: {equals: $userId}}}}}}}) {\n mutation\n node {\n ...Message\n isDeleted\n channel {\n id\n type\n }\n }\n }\n}\n ", ""])), MessageFragmentDoc); var UserChannelsPreviewDocument = gql(templateObject_30 || (templateObject_30 = __makeTemplateObject(["\n query UserChannelsPreview($id: ID, $channelMembersFilter: ChannelMemberFilter! = {}) {\n user(id: $id) {\n id\n channelIdentities(filter: {AND: [{channel: {type: {equals: \"channel\"}}}, $channelMembersFilter]}) {\n items {\n ...ChannelIdentity\n }\n }\n }\n}\n ", ""], ["\n query UserChannelsPreview($id: ID, $channelMember