letsjam
Version:
Ship products faster by adding jam to any project!
1,499 lines (1,284 loc) • 209 kB
JavaScript
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var emotion = require('emotion');
var Mousetrap = _interopDefault(require('mousetrap'));
var jsBase64 = require('js-base64');
var moment = _interopDefault(require('moment'));
var draftJs = require('draft-js');
var ReactTooltip = _interopDefault(require('react-tooltip'));
var Editor = _interopDefault(require('draft-js-plugins-editor'));
var createMentionPlugin = require('draft-js-mention-plugin');
var createMentionPlugin__default = _interopDefault(createMentionPlugin);
var createLinkifyPlugin = _interopDefault(require('draft-js-linkify-plugin'));
var createToolbarPlugin = _interopDefault(require('draft-js-static-toolbar-plugin'));
var emojiMart = require('emoji-mart');
var tooltip = require('@reach/tooltip');
var reactSpring = require('react-spring');
var DeviceDetector = _interopDefault(require('device-detector-js'));
var io = _interopDefault(require('socket.io-client'));
var optimalSelect = require('optimal-select');
var ChipInput = _interopDefault(require('material-ui-chip-input'));
var MutationObserver = _interopDefault(require('react-mutation-observer'));
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _taggedTemplateLiteralLoose(strings, raw) {
if (!raw) {
raw = strings.slice(0);
}
strings.raw = raw;
return strings;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _createForOfIteratorHelperLoose(o) {
var i = 0;
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) return function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
};
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
i = o[Symbol.iterator]();
return i.next.bind(i);
}
function _templateObject3() {
var data = _taggedTemplateLiteralLoose(["\n\t\t\t\t\twidth: 30px;\n\t\t\t\t\theight: 30px;\n\t\t\t\t"]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = _taggedTemplateLiteralLoose(["\n\t\t\t\t\tbackground: linear-gradient(\n\t\t\t\t\t\t\t0deg,\n\t\t\t\t\t\t\trgba(115, 229, 191, 0.2),\n\t\t\t\t\t\t\trgba(115, 229, 191, 0.2)\n\t\t\t\t\t\t),\n\t\t\t\t\t\t#ffffff;\n\t\t\t\t"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = _taggedTemplateLiteralLoose(["\n\t\t\t\twidth: 60px;\n\t\t\t\theight: 60px;\n\t\t\t\tborder-radius: 50px;\n\t\t\t\tposition: fixed;\n\t\t\t\tbottom: 2rem;\n\t\t\t\tright: 2rem;\n\t\t\t\tbox-shadow: 0px 4px 10px rgba(0, 0, 0, 0.15);\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\tz-index: 1;\n\t\t\t\ttransition: all 0.4s ease-in-out;\n\t\t\t\tbackground: #f8f9fb;\n\t\t\t\tcursor: pointer;\n\t\t\t\tfont-size: 14px;\n\t\t\t\tz-index: 1000000;\n\n\t\t\t\t", "\n\t\t\t"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
function JamButton(props) {
return React__default.createElement("div", {
onClick: props.toggleJamMode,
className: emotion.css(_templateObject(), props.jamTime && emotion.css(_templateObject2()))
}, React__default.createElement("img", {
src: "https://strawberryjam.nyc3.cdn.digitaloceanspaces.com/icon.png",
className: emotion.css(_templateObject3())
}));
}
function useKeyBinding(keys, callback) {
var callbackRef = React.useRef();
React.useEffect(function () {
callbackRef.current = callback;
}, [callback]);
React.useEffect(function () {
Mousetrap.bind(keys, function () {
if (callbackRef.current) {
callbackRef.current();
}
});
return function () {
Mousetrap.unbind(keys);
};
}, [keys, callbackRef]);
}
function KeyboardShortcuts(props) {
useKeyBinding("j a m", function () {
props.onToggleJamMode();
});
useKeyBinding("p a m", function () {
console.log("missing the office");
});
return null;
}
function SuperShortcuts(props) {
useKeyBinding("shift+u", function () {
props.onToggleUpdates();
});
useKeyBinding("shift+right", function () {
var nextThread = props.currentOpenThread + 1;
if (nextThread === props.threads.length) {
nextThread = 0;
}
props.onChangeOpenThread(nextThread);
if (props.threads[nextThread] !== undefined && props.threads[nextThread].y !== undefined) {
window.scrollTo(0, props.threads[nextThread].y - 100);
}
});
useKeyBinding("shift+left", function () {
var prevThread = props.currentOpenThread - 1;
if (prevThread < 0) {
prevThread = props.threads.length - 1;
}
props.onChangeOpenThread(prevThread);
if (props.threads[prevThread] !== undefined && props.threads[prevThread].y !== undefined) {
window.scrollTo(0, props.threads[prevThread].y - 100);
}
});
useKeyBinding("command+enter", function () {
props.onMessageSend();
});
return null;
}
var API_HOSTNAME = "https://app.jam.dev";
var SOCKET_SERVER = "https://socket-server.jam.dev";
var support = {
searchParams: 'URLSearchParams' in self,
iterable: 'Symbol' in self && 'iterator' in Symbol,
blob:
'FileReader' in self &&
'Blob' in self &&
(function() {
try {
new Blob();
return true
} catch (e) {
return false
}
})(),
formData: 'FormData' in self,
arrayBuffer: 'ArrayBuffer' in self
};
function isDataView(obj) {
return obj && DataView.prototype.isPrototypeOf(obj)
}
if (support.arrayBuffer) {
var viewClasses = [
'[object Int8Array]',
'[object Uint8Array]',
'[object Uint8ClampedArray]',
'[object Int16Array]',
'[object Uint16Array]',
'[object Int32Array]',
'[object Uint32Array]',
'[object Float32Array]',
'[object Float64Array]'
];
var isArrayBufferView =
ArrayBuffer.isView ||
function(obj) {
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
};
}
function normalizeName(name) {
if (typeof name !== 'string') {
name = String(name);
}
if (/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(name)) {
throw new TypeError('Invalid character in header field name')
}
return name.toLowerCase()
}
function normalizeValue(value) {
if (typeof value !== 'string') {
value = String(value);
}
return value
}
// Build a destructive iterator for the value list
function iteratorFor(items) {
var iterator = {
next: function() {
var value = items.shift();
return {done: value === undefined, value: value}
}
};
if (support.iterable) {
iterator[Symbol.iterator] = function() {
return iterator
};
}
return iterator
}
function Headers(headers) {
this.map = {};
if (headers instanceof Headers) {
headers.forEach(function(value, name) {
this.append(name, value);
}, this);
} else if (Array.isArray(headers)) {
headers.forEach(function(header) {
this.append(header[0], header[1]);
}, this);
} else if (headers) {
Object.getOwnPropertyNames(headers).forEach(function(name) {
this.append(name, headers[name]);
}, this);
}
}
Headers.prototype.append = function(name, value) {
name = normalizeName(name);
value = normalizeValue(value);
var oldValue = this.map[name];
this.map[name] = oldValue ? oldValue + ', ' + value : value;
};
Headers.prototype['delete'] = function(name) {
delete this.map[normalizeName(name)];
};
Headers.prototype.get = function(name) {
name = normalizeName(name);
return this.has(name) ? this.map[name] : null
};
Headers.prototype.has = function(name) {
return this.map.hasOwnProperty(normalizeName(name))
};
Headers.prototype.set = function(name, value) {
this.map[normalizeName(name)] = normalizeValue(value);
};
Headers.prototype.forEach = function(callback, thisArg) {
for (var name in this.map) {
if (this.map.hasOwnProperty(name)) {
callback.call(thisArg, this.map[name], name, this);
}
}
};
Headers.prototype.keys = function() {
var items = [];
this.forEach(function(value, name) {
items.push(name);
});
return iteratorFor(items)
};
Headers.prototype.values = function() {
var items = [];
this.forEach(function(value) {
items.push(value);
});
return iteratorFor(items)
};
Headers.prototype.entries = function() {
var items = [];
this.forEach(function(value, name) {
items.push([name, value]);
});
return iteratorFor(items)
};
if (support.iterable) {
Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
}
function consumed(body) {
if (body.bodyUsed) {
return Promise.reject(new TypeError('Already read'))
}
body.bodyUsed = true;
}
function fileReaderReady(reader) {
return new Promise(function(resolve, reject) {
reader.onload = function() {
resolve(reader.result);
};
reader.onerror = function() {
reject(reader.error);
};
})
}
function readBlobAsArrayBuffer(blob) {
var reader = new FileReader();
var promise = fileReaderReady(reader);
reader.readAsArrayBuffer(blob);
return promise
}
function readBlobAsText(blob) {
var reader = new FileReader();
var promise = fileReaderReady(reader);
reader.readAsText(blob);
return promise
}
function readArrayBufferAsText(buf) {
var view = new Uint8Array(buf);
var chars = new Array(view.length);
for (var i = 0; i < view.length; i++) {
chars[i] = String.fromCharCode(view[i]);
}
return chars.join('')
}
function bufferClone(buf) {
if (buf.slice) {
return buf.slice(0)
} else {
var view = new Uint8Array(buf.byteLength);
view.set(new Uint8Array(buf));
return view.buffer
}
}
function Body() {
this.bodyUsed = false;
this._initBody = function(body) {
this._bodyInit = body;
if (!body) {
this._bodyText = '';
} else if (typeof body === 'string') {
this._bodyText = body;
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
this._bodyBlob = body;
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
this._bodyFormData = body;
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this._bodyText = body.toString();
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
this._bodyArrayBuffer = bufferClone(body.buffer);
// IE 10-11 can't handle a DataView body.
this._bodyInit = new Blob([this._bodyArrayBuffer]);
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
this._bodyArrayBuffer = bufferClone(body);
} else {
this._bodyText = body = Object.prototype.toString.call(body);
}
if (!this.headers.get('content-type')) {
if (typeof body === 'string') {
this.headers.set('content-type', 'text/plain;charset=UTF-8');
} else if (this._bodyBlob && this._bodyBlob.type) {
this.headers.set('content-type', this._bodyBlob.type);
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
}
}
};
if (support.blob) {
this.blob = function() {
var rejected = consumed(this);
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return Promise.resolve(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as blob')
} else {
return Promise.resolve(new Blob([this._bodyText]))
}
};
this.arrayBuffer = function() {
if (this._bodyArrayBuffer) {
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
} else {
return this.blob().then(readBlobAsArrayBuffer)
}
};
}
this.text = function() {
var rejected = consumed(this);
if (rejected) {
return rejected
}
if (this._bodyBlob) {
return readBlobAsText(this._bodyBlob)
} else if (this._bodyArrayBuffer) {
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
} else if (this._bodyFormData) {
throw new Error('could not read FormData body as text')
} else {
return Promise.resolve(this._bodyText)
}
};
if (support.formData) {
this.formData = function() {
return this.text().then(decode)
};
}
this.json = function() {
return this.text().then(JSON.parse)
};
return this
}
// HTTP methods whose capitalization should be normalized
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'];
function normalizeMethod(method) {
var upcased = method.toUpperCase();
return methods.indexOf(upcased) > -1 ? upcased : method
}
function Request(input, options) {
options = options || {};
var body = options.body;
if (input instanceof Request) {
if (input.bodyUsed) {
throw new TypeError('Already read')
}
this.url = input.url;
this.credentials = input.credentials;
if (!options.headers) {
this.headers = new Headers(input.headers);
}
this.method = input.method;
this.mode = input.mode;
this.signal = input.signal;
if (!body && input._bodyInit != null) {
body = input._bodyInit;
input.bodyUsed = true;
}
} else {
this.url = String(input);
}
this.credentials = options.credentials || this.credentials || 'same-origin';
if (options.headers || !this.headers) {
this.headers = new Headers(options.headers);
}
this.method = normalizeMethod(options.method || this.method || 'GET');
this.mode = options.mode || this.mode || null;
this.signal = options.signal || this.signal;
this.referrer = null;
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
throw new TypeError('Body not allowed for GET or HEAD requests')
}
this._initBody(body);
}
Request.prototype.clone = function() {
return new Request(this, {body: this._bodyInit})
};
function decode(body) {
var form = new FormData();
body
.trim()
.split('&')
.forEach(function(bytes) {
if (bytes) {
var split = bytes.split('=');
var name = split.shift().replace(/\+/g, ' ');
var value = split.join('=').replace(/\+/g, ' ');
form.append(decodeURIComponent(name), decodeURIComponent(value));
}
});
return form
}
function parseHeaders(rawHeaders) {
var headers = new Headers();
// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
// https://tools.ietf.org/html/rfc7230#section-3.2
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
var parts = line.split(':');
var key = parts.shift().trim();
if (key) {
var value = parts.join(':').trim();
headers.append(key, value);
}
});
return headers
}
Body.call(Request.prototype);
function Response(bodyInit, options) {
if (!options) {
options = {};
}
this.type = 'default';
this.status = options.status === undefined ? 200 : options.status;
this.ok = this.status >= 200 && this.status < 300;
this.statusText = 'statusText' in options ? options.statusText : 'OK';
this.headers = new Headers(options.headers);
this.url = options.url || '';
this._initBody(bodyInit);
}
Body.call(Response.prototype);
Response.prototype.clone = function() {
return new Response(this._bodyInit, {
status: this.status,
statusText: this.statusText,
headers: new Headers(this.headers),
url: this.url
})
};
Response.error = function() {
var response = new Response(null, {status: 0, statusText: ''});
response.type = 'error';
return response
};
var redirectStatuses = [301, 302, 303, 307, 308];
Response.redirect = function(url, status) {
if (redirectStatuses.indexOf(status) === -1) {
throw new RangeError('Invalid status code')
}
return new Response(null, {status: status, headers: {location: url}})
};
var DOMException = self.DOMException;
try {
new DOMException();
} catch (err) {
DOMException = function(message, name) {
this.message = message;
this.name = name;
var error = Error(message);
this.stack = error.stack;
};
DOMException.prototype = Object.create(Error.prototype);
DOMException.prototype.constructor = DOMException;
}
function fetch$1(input, init) {
return new Promise(function(resolve, reject) {
var request = new Request(input, init);
if (request.signal && request.signal.aborted) {
return reject(new DOMException('Aborted', 'AbortError'))
}
var xhr = new XMLHttpRequest();
function abortXhr() {
xhr.abort();
}
xhr.onload = function() {
var options = {
status: xhr.status,
statusText: xhr.statusText,
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
};
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
var body = 'response' in xhr ? xhr.response : xhr.responseText;
resolve(new Response(body, options));
};
xhr.onerror = function() {
reject(new TypeError('Network request failed'));
};
xhr.ontimeout = function() {
reject(new TypeError('Network request failed'));
};
xhr.onabort = function() {
reject(new DOMException('Aborted', 'AbortError'));
};
xhr.open(request.method, request.url, true);
if (request.credentials === 'include') {
xhr.withCredentials = true;
} else if (request.credentials === 'omit') {
xhr.withCredentials = false;
}
if ('responseType' in xhr && support.blob) {
xhr.responseType = 'blob';
}
request.headers.forEach(function(value, name) {
xhr.setRequestHeader(name, value);
});
if (request.signal) {
request.signal.addEventListener('abort', abortXhr);
xhr.onreadystatechange = function() {
// DONE (success or failure)
if (xhr.readyState === 4) {
request.signal.removeEventListener('abort', abortXhr);
}
};
}
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
})
}
fetch$1.polyfill = true;
if (!self.fetch) {
self.fetch = fetch$1;
self.Headers = Headers;
self.Request = Request;
self.Response = Response;
}
// the whatwg-fetch polyfill installs the fetch() function
// on the global object (window or self)
//
// Return that as the export for use in Webpack, Browserify etc.
var fetchNpmBrowserify = self.fetch.bind(self);
function _catch(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
var jamIsPublic = function jamIsPublic(JAM_ID) {
var res, json;
return Promise.resolve(_catch(function () {
return Promise.resolve(fetchNpmBrowserify(API_HOSTNAME + "/api/plugin/jam/" + JAM_ID + "/is_public", {
method: "GET",
headers: {
"Content-Type": "application/json"
}
})).then(function (_fetch) {
res = _fetch;
return Promise.resolve(res.json()).then(function (_res$json) {
json = _res$json;
return json["public"];
});
});
}, function () {
return false;
}));
};
var isAuthenticated = function isAuthenticated(JAM_ID) {
try {
var user;
return Promise.resolve(jamIsPublic(JAM_ID)).then(function (isPublic) {
if (isPublic) {
user = window.localStorage.getItem("jamUser");
return user ? true : false;
} else {
if (document.cookie.split(";").some(function (cookie) {
return cookie.trim().startsWith("jam_filled_cookie=");
})) {
return true;
} else {
return false;
}
}
});
} catch (e) {
return Promise.reject(e);
}
};
function getJamFilledCookie() {
try {
var v = document.cookie.match("(^|;) ?" + "jam_filled_cookie" + "=([^;]*)(;|$)");
var cookie = v ? v[0] : null;
if (!cookie) throw new Error("no cookie");
cookie = cookie.split(", domain=")[0];
if (cookie.includes("; ")) return cookie.replace("; ", "");
return cookie;
} catch (e) {
return "jam_filled_cookie=false";
}
}
function getUserIdFromJamFilledCookie() {
try {
var cookie = getJamFilledCookie();
var userId = jsBase64.Base64.decode(cookie.split(".")[1]).replace('{"_id":', "").split('"')[1];
return userId;
} catch (e) {
return false;
}
}
function getUserIdFromLocalStorage() {
return JSON.parse(window.localStorage.getItem("jamUser"))._id;
}
var isPermissioned = function isPermissioned(JAM_ID) {
try {
return Promise.resolve(fetchNpmBrowserify(API_HOSTNAME + "/api/plugin/jam/" + JAM_ID + "/check_user_allowed", {
method: "POST",
headers: {
"content-type": "application/json",
"jam-filled-cookie": getJamFilledCookie(),
"jam-filled-userid": getUserIdFromLocalStorage()
},
body: JSON.stringify({
userId: getUserIdFromJamFilledCookie()
})
})).then(function (res) {
return Promise.resolve(res.json()).then(function (json) {
return json.allowed;
});
});
} catch (e) {
return Promise.reject(e);
}
};
function _catch$1(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
var getUserByIdInJamFilledStorage = function getUserByIdInJamFilledStorage(JAM_ID) {
try {
var res, json;
return Promise.resolve(_catch$1(function () {
return Promise.resolve(fetchNpmBrowserify(API_HOSTNAME + "/api/user/" + getUserIdFromJamFilledCookie(), {
headers: {
"Content-Type": "application/json",
"jam-filled-cookie": getJamFilledCookie(),
"jam-filled-userid": getUserIdFromLocalStorage(),
jamid: JAM_ID
}
})).then(function (_fetch) {
res = _fetch;
return Promise.resolve(res.json()).then(function (_res$json) {
json = _res$json;
localStorage.setItem("jamUser", JSON.stringify(json.user));
return true;
});
});
}, function (e) {
console.log(e);
return false;
}));
} catch (e) {
return Promise.reject(e);
}
};
function getUserFromLocalStorage() {
if (localStorage.getItem("jamUser") && localStorage.getItem("jamUser") !== "undefined") {
return JSON.parse(localStorage.getItem("jamUser") || "");
} else return false;
}
function _catch$2(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
var getThreads = function getThreads(JAM_ID) {
var res, json;
return Promise.resolve(_catch$2(function () {
return Promise.resolve(fetchNpmBrowserify(API_HOSTNAME + "/api/plugin/jam/" + JAM_ID + "/threads", {
headers: {
"Content-Type": "application/json",
"jam-filled-cookie": getJamFilledCookie(),
"jam-filled-userid": getUserIdFromLocalStorage()
}
})).then(function (_fetch) {
res = _fetch;
return Promise.resolve(res.json()).then(function (_res$json) {
json = _res$json;
return json;
});
});
}, function () {
return false;
}));
};
function humanReadableTimeAgo(objectId) {
var commentDate = new Date(parseInt(objectId.substring(0, 8), 16) * 1000);
var string = moment(commentDate).fromNow();
if (string === "a few seconds ago") string = "just now";
string = string.replace("minutes", "min");
return string;
}
function idOrSection(str) {
if (str.includes("-") && str.includes("_")) {
return {
type: "id"
};
}
if (str.includes("@")) {
return {
type: "id"
};
}
if (str.length === 1) {
if (str.match(/[a-z]/i)) {
return {
type: "section"
};
} else {
return {
type: "id"
};
}
}
if (!isNaN(Number(str))) {
return {
type: "id"
};
}
if ((str.match(/[A-Z]/g) || []).length > 2 && (str.match(/[a-z]/g) || []).length > 2) {
return {
type: "id"
};
}
if ((str.match(/-/g) || []).length > 3 || (str.match(/_/g) || []).length > 3) {
return {
type: "id"
};
}
var arr = str.includes("-") ? str.split("-") : str.split("_");
var isIdArray = arr.map(function (substring) {
if ((substring.match(/[0-9]/g) || []).length > 0 && (substring.match(/[A-Za-z]/g) || []).length > 0) {
return true;
}
if ((substring.match(/[A-Z]/g) || []).length > 2 && (substring.match(/[a-z]/g) || []).length > 2) {
return true;
}
if (!isNaN(Number(substring))) {
return true;
}
if (substring === substring.toUpperCase()) {
return true;
}
return false;
});
if (isIdArray.indexOf(true) > -1) return {
type: "id"
};
return {
type: "section"
};
}
function isNotUndefined(value) {
return typeof value !== "undefined";
}
function createUrlPattern(host, pathname) {
var path = pathname.split("/");
var pathPatternArray = path.map(function (subpath) {
if (subpath.length === 0) return;
var _idOrSection = idOrSection(subpath),
type = _idOrSection.type;
if (type === "section") return subpath;
return "*";
});
var filtered = pathPatternArray.filter(isNotUndefined);
return {
host: host,
pathPatternArray: filtered
};
}
function checkUrlAgainstPattern(urlObj, urlPatternObj) {
if (urlObj.host !== urlPatternObj.host) {
return false;
}
if (urlObj.pathPatternArray.length !== urlPatternObj.pathPatternArray.length) {
return false;
}
var doItemsMatch = urlPatternObj.pathPatternArray.map(function (subpath, index) {
if (subpath === "*") return true;else if (subpath === urlObj.pathPatternArray[index]) return true;else return false;
});
if (doItemsMatch.indexOf(false) > -1) return false;else return true;
}
function positionCommentX(thread, type) {
var _createUrlPattern = createUrlPattern(window.location.host, window.location.pathname),
host = _createUrlPattern.host,
pathPatternArray = _createUrlPattern.pathPatternArray;
var correctPageToDisplayThreadOn = checkUrlAgainstPattern({
host: host,
pathPatternArray: pathPatternArray
}, {
host: thread.location.host,
pathPatternArray: JSON.parse(thread.location.path)
});
var element = document.querySelector(thread.location.selector);
if (!element || !correctPageToDisplayThreadOn) {
return -1000;
} else {
var rect = element.getBoundingClientRect();
var newX = rect.x + thread.location.percentFromLeft * rect.width;
var coords;
if (type == "preview") {
coords = document.querySelector("#jam--preview-thread-" + thread._id).getBoundingClientRect();
} else if (type == "thread") {
coords = document.querySelector("#jam--thread-container-" + thread._id) ? document.querySelector("#jam--thread-container-" + thread._id).getBoundingClientRect() : document.querySelector("#jam--preview-thread-" + thread._id).getBoundingClientRect();
} else {
throw new Error("TODO");
}
if (window.innerWidth < thread.x + coords.width) {
var amountToMoveLeft = thread.x + coords.width - window.innerWidth;
newX = thread.x - amountToMoveLeft - 5;
}
if (newX < 5 || thread.x < 5) {
newX = 5;
}
if (newX > coords.width / 2) {
newX = newX - coords.width / 2;
}
return newX;
}
}
function positionCommentY(thread, type) {
var _createUrlPattern = createUrlPattern(window.location.host, window.location.pathname),
host = _createUrlPattern.host,
pathPatternArray = _createUrlPattern.pathPatternArray;
var correctPageToDisplayThreadOn = checkUrlAgainstPattern({
host: host,
pathPatternArray: pathPatternArray
}, {
host: thread.location.host,
pathPatternArray: JSON.parse(thread.location.path)
});
var element = document.querySelector(thread.location.selector);
if (!element || !correctPageToDisplayThreadOn) {
return -1000;
} else {
var rect = element.getBoundingClientRect();
var newY = rect.y + window.scrollY + thread.location.percentFromTop * rect.height;
var coords;
if (type == "preview") {
coords = document.querySelector("#jam--preview-thread-" + thread._id).getBoundingClientRect();
} else if (type == "thread") {
coords = document.querySelector("#jam--thread-container-" + thread._id) ? document.querySelector("#jam--thread-container-" + thread._id).getBoundingClientRect() : document.querySelector("#jam--preview-thread-" + thread._id).getBoundingClientRect();
} else {
throw new Error("TODO");
}
var body = document.body;
var html = document.documentElement;
var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
if (height < thread.y + coords.height) {
var amountToMoveUp = thread.y + coords.height - height;
newY = thread.y - amountToMoveUp - 5;
}
if (newY < 5 || thread.y < 5) {
newY = 5;
}
return newY;
}
}
function generateReactionTooltip(emoji, upvotedUsers) {
if (upvotedUsers.length === 0) {
return "";
} else if (upvotedUsers.length === 1) {
return upvotedUsers[0] + " said " + emoji;
} else if (upvotedUsers.length === 2) {
return upvotedUsers[0] + " and " + upvotedUsers[1] + " said " + emoji;
} else if (upvotedUsers.length === 3) {
var tempArray = upvotedUsers.slice(0, upvotedUsers.length - 1);
return tempArray.join(", ") + " and " + upvotedUsers[upvotedUsers.length - 1] + " said " + emoji;
} else {
var _tempArray = upvotedUsers.slice(0, 3);
return _tempArray.join(", ") + " and others said " + emoji;
}
}
function JamPreview(props) {
var thread = props.thread;
var comments = thread.comments;
var lastComment = comments[comments.length - 1];
var messagePreview = React.useMemo(function () {
var jsonifiedCommentMessage = JSON.parse(lastComment.message);
var messageConvertedFromRaw = draftJs.convertFromRaw(jsonifiedCommentMessage);
var tempEditorState = draftJs.EditorState.createWithContent(messageConvertedFromRaw);
var commentText = tempEditorState.getCurrentContent().getPlainText("\x01");
return commentText.replace("\x01", " ");
}, [lastComment]);
var authors = React.useMemo(function () {
var authors = new Map();
for (var _iterator = _createForOfIteratorHelperLoose(comments), _step; !(_step = _iterator()).done;) {
var comment = _step.value;
if (!authors.has(comment.author.name)) {
authors.set(comment.author.name, comment.author);
}
if (authors.size >= 6) {
break;
}
}
return Array.from(authors.values());
}, [comments]);
var reactions = React.useMemo(function () {
var reactions = [];
for (var _iterator2 = _createForOfIteratorHelperLoose(comments.slice(0, 3)), _step2; !(_step2 = _iterator2()).done;) {
var comment = _step2.value;
if (comment.reactions) {
for (var _iterator3 = _createForOfIteratorHelperLoose(comment.reactions), _step3; !(_step3 = _iterator3()).done;) {
var reaction = _step3.value;
reactions.push({
emoji: reaction.emoji,
upvotedUsers: reaction.upvotedUsers
});
}
}
}
return reactions;
}, [comments]);
var _useState = React.useState(0),
positionedX = _useState[0],
setPositionedX = _useState[1];
var _useState2 = React.useState(0),
positionedY = _useState2[0],
setPositionedY = _useState2[1];
React.useLayoutEffect(function () {
setPositionedX(positionCommentX(thread, "thread"));
setPositionedY(positionCommentY(thread, "thread"));
}, [thread]);
return React__default.createElement("div", {
onClick: props.onClick,
key: "jam--preview-" + thread._id,
style: {
top: positionedY + "px",
left: positionedX + "px"
},
id: "jam--preview-thread-" + thread._id,
className: "jam--preview " + thread._id
}, React__default.createElement("div", {
className: "jam--preview-conainer-outer"
}, React__default.createElement("div", {
className: "jam--preview-avatars"
}, authors.map(function (author) {
return React__default.createElement("img", {
key: author._id,
src: author.avatar
});
})), React__default.createElement("div", {
className: "jam--preview-container"
}, React__default.createElement("div", {
className: "jam--preview-container-row"
}, React__default.createElement("p", {
className: "jam--preview-text"
}, messagePreview), React__default.createElement("div", {
className: "jam--preview-reply-date"
}, humanReadableTimeAgo(lastComment._id))), React__default.createElement("div", {
className: "jam--preview-container-row"
}, reactions.length > 0 && React__default.createElement("div", {
className: "jam--preview-reactions"
}, reactions.map(function (reaction, index) {
var tooltipText = generateReactionTooltip(reaction.emoji, reaction.upvotedUsers);
return React__default.createElement("div", {
key: "emoji-" + index,
className: "jam--preview-reaction",
"data-tip": tooltipText
}, reaction.emoji);
}))), React__default.createElement(ReactTooltip, {
place: "top",
type: "dark",
effect: "float"
}))), React__default.createElement("style", null, "\n\t\t\t\t.jam--preview {\n\t\t\t\t\tmax-width: 400px;\n\t\t\t\t\theight: 66px;\n\t\t\t\t\tbackground: #fff;\n\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tflex-direction: row;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\tjustify-content: space-around;\n\t\t\t\t\tborder-radius: 10px;\n\t\t\t\t\tbox-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);\n\t\t\t\t\tfont-family: \"SF Pro Text\",-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"Helvetica Neue\",Arial,\"Noto Sans\",sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\",\"Noto Color Emoji\";\n\t\t\t\t\tHelvetica, Arial, sans-serif;\n\t\t\t\t\tcolor: #2A3632;\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tfont-size: 14px;\n\t\t\t\t\tz-index: 1000000;\n\t\t\t\t\tpadding: 5px 10px;\n\t\t\t\t}\n\n\t\t\t\t@media screen and (max-width: 450px) {\n\t\t\t\t\t.jam--preview {\n\t\t\t\t\t\twidth: 365px;\n\t\t\t\t\t\tmargin-left: auto;\n\t\t\t\t\t\tmargin-right: auto;\n\t\t\t\t\t\tleft: 0 !important;\n\t\t\t\t\t\tright: 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-conainer-outer {\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tflex-direction: row;\n\t\t\t\t\twidth: 100%;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\tz-index: 1000000;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-container-row {\n\t\t\t\t\talign-items: center;\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tflex-direction: row;\n\t\t\t\t\twidth: 100%;\n\t\t\t\t\tfont-size: 14px;\n\t\t\t\t\toverflow: hidden;\n\t\t\t\t\tz-index: 1000000;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-container {\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tflex-direction: column;\n\t\t\t\t\tmax-width: 310px;\n\t\t\t\t\tz-index: 1000000;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-container:hover {\n\t\t\t\t\tcursor: pointer;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-avatars {\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tflex-direction: row;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\tmargin-right: 4px;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-avatars img {\n\t\t\t\t\tborder-radius: 50%;\n\t\t\t\t\theight: 40px;\n\t\t\t\t\twidth: 40px;\n\t\t\t\t\tbox-shadow: 0px 4px 10px rgba(0, 0, 0, 0.05);\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-avatars img:not(:first-child) {\n\t\t\t\t\tmargin-left: -13px;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-num-comments {\n\t\t\t\t\tfont-weight: 400;\n\t\t\t\t\tcolor: #142dbd;\n\t\t\t\t\tfont-size: 14px;\n\t\t\t\t\tmargin-right: 4px;\n\t\t\t\t\twhite-space: nowrap;\n\t\t\t\t\tline-height: 20px;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-reply-date {\n\t\t\t\t\tcolor: rgba(42, 54, 50, .5);\n\t\t\t\t\tfont-size: 14px;\n\t\t\t\t\twhite-space: nowrap;\n\t\t\t\t\tline-height: 20px;\n\t\t\t\t\tfont-weight: 400;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-text {\n\t\t\t\t\twhite-space: nowrap;\n\t\t\t\t\toverflow: hidden;\n\t\t\t\t\ttext-overflow: ellipsis;\n\t\t\t\t\tmargin: initial;\n\t\t\t\t\tmargin-right: 4px;\n\t\t\t\t\tmargin-left: 4px;\n\t\t\t\t\tline-height: 20px;\n\t\t\t\t\tfont-size: 14px;\n\t\t\t\t\tcolor: #3C81C7;\n\t\t\t\t\tbackground: rgba(100, 175, 250, .15);\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-notification {\n\t\t\t\t\talign-self: center;\n\t\t\t\t\tborder-radius: 50%;\n\t\t\t\t\tbackground: #e8180a;\n\t\t\t\t\theight: 8px;\n\t\t\t\t\twidth: 8px;\n\t\t\t\t\tfont-size: 14px;\n\t\t\t\t}\n\n\t\t\t\t#jam--eye-icon-toggle-preview {\n\t\t\t\t\tmargin-right: 6px;\n\t\t\t\t\tmargin-left: 2px;\n\t\t\t\t\topacity: 0.5;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-reactions {\n\t\t\t\t\tdisplay: flex;\n\t\t\t\t\tflex-direction: row;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\tpadding: 6px;\n\t\t\t\t\tmargin: 0 4px 0 0;\n\t\t\t\t\tjustify-content: center;\n\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\tmargin-top: 5px;\n\t\t\t\t\theight: 12px;\n\t\t\t\t}\n\n\t\t\t\t.jam--preview-reaction {\n\t\t\t\t\tmargin-top: 1em;\n\t\t\t\t\tmargin-bottom: 1em;\n\t\t\t\t\tfont-size: 10px;\n\t\t\t\t}\n\t\t\t"));
}
function _catch$3(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
var resolveThreadById = function resolveThreadById(threadId, JAM_ID) {
try {
var res, json;
return Promise.resolve(_catch$3(function () {
return Promise.resolve(fetchNpmBrowserify(API_HOSTNAME + "/api/plugin/jam/" + JAM_ID + "/threads/" + threadId + "/delete", {
method: "POST",
headers: {
"Content-Type": "application/json",
"jam-filled-cookie": getJamFilledCookie(),
"jam-filled-userid": getUserIdFromLocalStorage()
}
})).then(function (_fetch) {
res = _fetch;
return Promise.resolve(res.json()).then(function (_res$json) {
json = _res$json;
return json;
});
});
}, function (e) {
console.log(e);
}));
} catch (e) {
return Promise.reject(e);
}
};
function _catch$4(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
var addMessageToThread = function addMessageToThread(threadId, message, JAM_ID) {
var res, json;
return Promise.resolve(_catch$4(function () {
return Promise.resolve(fetch(API_HOSTNAME + "/api/plugin/jam/" + JAM_ID + "/threads/" + threadId, {
method: "POST",
headers: {
"Content-Type": "application/json",
"jam-filled-cookie": getJamFilledCookie(),
"jam-filled-userid": getUserIdFromLocalStorage()
},
body: JSON.stringify({
author: getUserIdFromLocalStorage(),
message: message
})
})).then(function (_fetch) {
res = _fetch;
return Promise.resolve(res.json()).then(function (_res$json) {
json = _res$json;
return json;
});
});
}, function () {
return false;
}));
};
function isALoomVideo(loomUrl) {
var loomRe = /http(()|(s)):\/\/((www.)|())loom.com\/((share)|(embed))\/.[^ ]*/g;
var loomUrlArr = loomRe.exec(loomUrl);
if (loomUrlArr === null) {
return null;
} else {
var embedUrl = loomUrlArr[0];
if (embedUrl.includes("share")) {
embedUrl = embedUrl.replace("share", "embed");
return embedUrl;
}
return embedUrl;
}
}
var hasCommandModifier = draftJs.KeyBindingUtil.hasCommandModifier;
function processKeyBinding(event) {
if (event.keyCode === 13 && hasCommandModifier(event)) {
return "jameditor-enter";
}
return draftJs.getDefaultKeyBinding(event);
}
var mentionsTheme = {
mention: "mention",
mentionSuggestions: "mentionSuggestions",
mentionSuggestionsEntry: "mentionSuggestionsEntry",
mentionSuggestionsEntryFocused: "mentionSuggestionsEntryFocused",
mentionSuggestionsEntryText: "mentionSuggestionsEntryText",
mentionSuggestionsEntryAvatar: "mentionSuggestionsEntryAvatar",
mentionSuggestionsEntryContainer: "mentionSuggestionsEntryContainer",
mentionSuggestionsEntryContainerRight: "mentionSuggestionsEntryContainerRight",
mentionSuggestionsEntryTitle: "mentionSuggestionsEntryTitle"
};
var linkifyPlugin = createLinkifyPlugin();
var staticToolbarPlugin = createToolbarPlugin();
function Entry(props) {
var mention = props.mention,
theme = props.theme,
parentProps = _objectWithoutPropertiesLoose(props, ["mention", "theme"]);
return React__default.createElement("div", Object.assign({}, parentProps), React__default.createElement("div", {
className: theme.mentionSuggestionsEntryContainer
}, React__default.createElement("div", {
className: theme.mentionSuggestionsEntryContainerLeft
}, React__default.createElement("img", {
src: mention.avatar,
className: theme.mentionSuggestionsEntryAvatar,
role: "presentation"
})), React__default.createElement("div", {
className: theme.mentionSuggestionsEntryContainerRight
}, React__default.createElement("div", {
className: theme.mentionSuggestionsEntryText
}, mention.name), React__default.createElement("div", {
className: theme.mentionSuggestionsEntryTitle
}, mention.title))));
}
function getEmbeddedVideoSrc(text) {
if (!text.includes("loom")) return null;
if (!(text.includes("share") || text.includes("embed"))) return null;
return isALoomVideo(text);
}
function JamEditor(props) {
var editorState = props.editorState,
mentions = props.mentions;
var editorRef = React.useRef(null);
var mentionPlugin = React.useMemo(function () {
return createMentionPlugin__default({
mentions: mentions,
entityMutability: "IMMUTABLE",
theme: mentionsTheme,
mentionPrefix: "@",
supportWhitespace: true
});
}, [mentions]);
var _useState = React.useState(props.mentions),
suggestions = _useState[0],
setSuggestions = _useState[1];
var _useState2 = React.useState(false),
readOnly = _useState2[0],
setReadOnly = _useState2[1];
var embedVideoSrc = React.useMemo(function () {
var state = draftJs.convertToRaw(editorState.getCurrentContent());
for (var _iterator = _createForOfIteratorHelperLoose(state.blocks), _step; !(_step = _iterator()).done;) {
var block = _step.value;
var text = block.text;
var _embedVideoSrc = getEmbeddedVideoSrc(text);
if (_embedVideoSrc !== null) return _embedVideoSrc;
}
return null;
}, [editorState]);
function handleChange(editorState) {
props.onEditorChange(editorState);
}
function handleSearchChange(_ref) {
var value = _ref.value;
setSuggestions(createMentionPlugin.defaultSuggestionsFilter(value, props.mentions));
}
function handleAddMention() {}
function handleKeyCommand(command, editorState) {
if (command === "jameditor-enter") {
setReadOnly(false);
props.onMessageSend();
return "handled";
}
var newState = draftJs.RichUtils.handleKeyCommand(editorState, command);
if (newState) {
handleChange(newState);
return "handled";
}
return "not-handled";
}
var MentionSuggestions = mentionPlugin.MentionSuggestions;
var plugins = [mentionPlugin, linkifyPlugin, staticToolbarPlugin];
return React__default.createElement("div", {
className: "jam--editor-draftjs-wrapper lds-grid"
}, React__default.createElement(Editor, {
editorState: props.editorState,
handleKeyCommand: handleKeyCommand,
onChange: handleChange,
plugins: plugins,
ref: function ref(_ref2) {
editorRef.current = _ref2;
},
placeholder: "Type a comment...",
keyBindingFn: processKeyBinding,
readOnly: readOnly
}), React__default.createElement(MentionSuggestions, {
onSearchChange: handleSearchChange,
suggestions: suggestions,
onAddMention: handleAddMention,
entryComponent: Entry
}), embedVideoSrc !== null && React__default.createElement("div", {
className: "jam--embed-video-container"
}, React__default.createElement("iframe", {
width: "100%",
height: "100%",
src: embedVideoSrc,
frameBorder: "0",
allowFullScreen: true
}), React__default.createElement("style", null, "\n\t\t\t\t\t\t.jam--embed-video-container {\n\t\t\t\t\t\t\tpadding: 15px;\n\t\t\t\t\t\t}\n\t\t\t\t\t")), React__default.createElement("style", null, "\n\t\t\t\t\t.jam--suggest-css {\n\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\tborder-radius: 5px;\n\t\t\t\t\t\tdisplay: flex;\n\t\t\t\t\t\talign-items: center;\n\t\t\t\t\t\tjustify-content: center;\n\t\t\t\t\t\theight: 30px;\n\t\t\t\t\t\tmargin-left: 12px;\n\t\t\t\t\t\tfont-family: \"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo,\n\t\t\t\t\t\t\tCourier, monospace;\n\t\t\t\t\t\tfont-size: 10px;\n\t\t\t\t\t\tmargin-bottom: 20px;\n\t\t\t\t\t\tfont-weight: 600;\n\t\t\t\t\t\tcolor: #47b38f;\n\t\t\t\t\t\tbackground: rgba(115, 229, 191, 0.15);\n\t\t\t\t\t\tborder: none;\n\t\t\t\t\t}\n\t\t\t\t\t.jam--editor-draftjs-wrapper {\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\tpadding: 0.5rem 0;\n\t\t\t\t\t}\n\t\t\t\t\t.DraftEditor-root {\n\t\t\t\t\t\twidth: 100%;\n\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t\tpadding: 0px 1rem 1rem;\n\t\t\t\t\t\tpadding-top: 0px;\n\t\t\t\t\t\tpadding-right: 1rem;\n\t\t\t\t\t\tpadding-bottom: 1rem;\n\t\t\t\t\t\tpadding-left: 1rem;\n\t\t\t\t\t\tfont-size: 14px;\n\t\t\t\t\t\tline-height: 20px;\n\t\t\t\t\t\tfont-weight: 400;\n\t\t\t\t\t\tcolor: #2a3632;\n\t\t\t\t\t}\n\n\t\t\t\t\t.DraftEditor-root a {\n\t\t\t\t\t\ttext-decoration: none;\n\t\t\t\t\t\tcolor: #3875fd;\n\t\t\t\t\t}\n\n\t\t\t\t\t.DraftEditor-editorContainer {\n\t\t\t\t\t\tbackground-color: rgba(255, 255, 255, 0);\n\t\t\t\t\t\tborder-left: 0.1px solid transparent;\n\t\t\t\t\t\tposition: relative;\n\t\t\t\t\t\ttext-align: left;\n\t\t\t\t\t\tz-index: 1;\n\t\t\t\t\t}\n\n\t\t\t\t\t.draftJsToolbar__buttonWrapper__1Dmqh {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t}\n\n\t\t\t\t\t.draftJsToolbar__button__qi1gf {\n\t\t\t\t\t\tbackground: #fbfbfb;\n\t\t\t\t\t\tcolor: #888;\n\t\t\t\t\t\tfont-size: 18px;\n\t\t\t\t\t\tborder: 0;\n\t\t\t\t\t\tpadding-top: 5px;\n\t\t\t\t\t\tvertical-align: bottom;\n\t\t\t\t\t\theight: 34px;\n\t\t\t\t\t\twidth: 36px;\n\t\t\t\t\t}\n\n\t\t\t\t\t.draftJsToolbar__button__qi1gf svg {\n\t\t\t\t\t\tfill: #888;\n\t\t\t\t\t}\n\n\t\t\t\t\t.draftJsToolbar__button__qi1gf:hover,\n\t\t\t\t\t.draftJsToolbar__button__qi1gf:focus {\n\t\t\t\t\t\tbackground: #f3f3f3;\n\t\t\t\t\t\toutline: 0; /* reset for :focus */\n\t\t\t\t\t}\n\n\t\t\t\t\t.draftJsToolbar__active__3qcpF {\n\t\t\t\t\t\tbackground: #efefef;\n\t\t\t\t\t\tcolor: #444;\n\t\t\t\t\t}\n\n\t\t\t\t\t.draftJsToolbar__active__3qcpF svg {\n\t\t\t\t\t\tfill: #444;\n\t\t\t\t\t}\n\t\t\t\t\t.draftJsToolbar__separator__3U7qt {\n\t\t\t\t\t\tdisplay: inline-block;\n\t\t\t\t\t\tborder-right: 1px solid #ddd;\n\t\t\t\t\t\theight: 24px;\n\t\t\t\t\t\tmargin: 0 0.5em;\n\t\t\t\t\t}\n\t\t\t\t\t.draftJsToolbar__toolbar__dNtBH {\n\t\t\t\t\t\tborder: none;\n\t\t\t\t\t\tpadding: 0.25rem;\n\t\t\t\t\t\tbackground: #fff;\n\t\t\t\t\t\tborder-radius: 2px;\n\t\t\t\t\t\tbox-shadow: none;\n\t\t\t\t\t\tz-index: 2;\n\t\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\t}\n\n\t\t\t\t\t.draftJsToolbar__toolbar__dNtBH:after {\n\t\t\t\t\t\tborder-color: rgba(255, 255, 255, 0);\n\t\t\t\t\t\tborder-top-color: #fff;\n\t\t\t\t\t\tborder-width: 4px;\n\t\t\t\t\t\tmargin-left: -4px;\n\t\t\t\t\t}\n\t\t\t\t\t.draftJsToolbar__toolbar__dNtBH:before {\n\t\t\t\t\t\tborder-color: rgba(221, 221, 221, 0);\n\t\t\t\t\t\tborder-top-color: #ddd;\n\t\t\t\t\t\tborder-width: 6px;\n\t\t\t\t\t\tmargin-left: -6px;\n\t\t\t\t\t}\n\t\t\t\t\t.DraftEditor-alignLeft .publi