From 33cbe86daca3398f1ede93a425c183b3fb73cddc Mon Sep 17 00:00:00 2001 From: lvalics Date: Fri, 26 Jan 2024 20:26:03 +0000 Subject: [PATCH 1/6] Full Screen Fix. --- dj_backend_server/web/templates/chat.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dj_backend_server/web/templates/chat.html b/dj_backend_server/web/templates/chat.html index f80b9582..b173c00a 100644 --- a/dj_backend_server/web/templates/chat.html +++ b/dj_backend_server/web/templates/chat.html @@ -22,7 +22,8 @@ window.onload = function () { initializeChatWidget({ token: "{{ bot.token }}", - isFullScreen: true, + position: "fullScreen", + defaultOpen: true, }); }; From 9ec68bf3ac8683cfb85ee692e943027690b5b77c Mon Sep 17 00:00:00 2001 From: lvalics Date: Sun, 28 Jan 2024 08:23:33 +0000 Subject: [PATCH 2/6] One version, working partially. --- .../web/templates/settings-theme.html | 139 +++++++++++------- 1 file changed, 84 insertions(+), 55 deletions(-) diff --git a/dj_backend_server/web/templates/settings-theme.html b/dj_backend_server/web/templates/settings-theme.html index 44d2f286..338cde20 100644 --- a/dj_backend_server/web/templates/settings-theme.html +++ b/dj_backend_server/web/templates/settings-theme.html @@ -29,49 +29,32 @@

{{ bot.name }}: try &

Try & Share!

Here you can try and play with your bot, also you can share it or embed - it in your web apps
+ it in your web apps. Anyone with this link will be able to interact + with your chatbot
-
- -
- -
-
- - - + +
+ + + +
+
-
+
- - +
-
+
- - +
@@ -220,21 +215,55 @@

Try & Share!

{% block scripts %} {% endblock scripts %} From 5743ff9d4e014860b47078b37f204beb5c76d732 Mon Sep 17 00:00:00 2001 From: lvalics Date: Sun, 28 Jan 2024 08:49:51 +0000 Subject: [PATCH 3/6] Working version, need to work on design. --- .../static/dashboard/js/vendors/clipboard.js | 890 ++++++++++++++++++ .../dashboard/js/vendors/clipboard.min.js | 7 + .../web/templates/layout/app.html | 1 + .../web/templates/settings-theme.html | 228 ++--- dj_backend_server/web/templates/settings.html | 18 +- 5 files changed, 1003 insertions(+), 141 deletions(-) create mode 100644 dj_backend_server/web/static/dashboard/js/vendors/clipboard.js create mode 100644 dj_backend_server/web/static/dashboard/js/vendors/clipboard.min.js diff --git a/dj_backend_server/web/static/dashboard/js/vendors/clipboard.js b/dj_backend_server/web/static/dashboard/js/vendors/clipboard.js new file mode 100644 index 00000000..aeb826f0 --- /dev/null +++ b/dj_backend_server/web/static/dashboard/js/vendors/clipboard.js @@ -0,0 +1,890 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["ClipboardJS"] = factory(); + else + root["ClipboardJS"] = factory(); +})(this, function() { +return /******/ (function() { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ 686: +/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "default": function() { return /* binding */ clipboard; } +}); + +// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js +var tiny_emitter = __webpack_require__(279); +var tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter); +// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js +var listen = __webpack_require__(370); +var listen_default = /*#__PURE__*/__webpack_require__.n(listen); +// EXTERNAL MODULE: ./node_modules/select/src/select.js +var src_select = __webpack_require__(817); +var select_default = /*#__PURE__*/__webpack_require__.n(src_select); +;// CONCATENATED MODULE: ./src/common/command.js +/** + * Executes a given operation type. + * @param {String} type + * @return {Boolean} + */ +function command(type) { + try { + return document.execCommand(type); + } catch (err) { + return false; + } +} +;// CONCATENATED MODULE: ./src/actions/cut.js + + +/** + * Cut action wrapper. + * @param {String|HTMLElement} target + * @return {String} + */ + +var ClipboardActionCut = function ClipboardActionCut(target) { + var selectedText = select_default()(target); + command('cut'); + return selectedText; +}; + +/* harmony default export */ var actions_cut = (ClipboardActionCut); +;// CONCATENATED MODULE: ./src/common/create-fake-element.js +/** + * Creates a fake textarea element with a value. + * @param {String} value + * @return {HTMLElement} + */ +function createFakeElement(value) { + var isRTL = document.documentElement.getAttribute('dir') === 'rtl'; + var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS + + fakeElement.style.fontSize = '12pt'; // Reset box model + + fakeElement.style.border = '0'; + fakeElement.style.padding = '0'; + fakeElement.style.margin = '0'; // Move element out of screen horizontally + + fakeElement.style.position = 'absolute'; + fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically + + var yPosition = window.pageYOffset || document.documentElement.scrollTop; + fakeElement.style.top = "".concat(yPosition, "px"); + fakeElement.setAttribute('readonly', ''); + fakeElement.value = value; + return fakeElement; +} +;// CONCATENATED MODULE: ./src/actions/copy.js + + + +/** + * Create fake copy action wrapper using a fake element. + * @param {String} target + * @param {Object} options + * @return {String} + */ + +var fakeCopyAction = function fakeCopyAction(value, options) { + var fakeElement = createFakeElement(value); + options.container.appendChild(fakeElement); + var selectedText = select_default()(fakeElement); + command('copy'); + fakeElement.remove(); + return selectedText; +}; +/** + * Copy action wrapper. + * @param {String|HTMLElement} target + * @param {Object} options + * @return {String} + */ + + +var ClipboardActionCopy = function ClipboardActionCopy(target) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { + container: document.body + }; + var selectedText = ''; + + if (typeof target === 'string') { + selectedText = fakeCopyAction(target, options); + } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) { + // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange + selectedText = fakeCopyAction(target.value, options); + } else { + selectedText = select_default()(target); + command('copy'); + } + + return selectedText; +}; + +/* harmony default export */ var actions_copy = (ClipboardActionCopy); +;// CONCATENATED MODULE: ./src/actions/default.js +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + + + +/** + * Inner function which performs selection from either `text` or `target` + * properties and then executes copy or cut operations. + * @param {Object} options + */ + +var ClipboardActionDefault = function ClipboardActionDefault() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + // Defines base properties passed from constructor. + var _options$action = options.action, + action = _options$action === void 0 ? 'copy' : _options$action, + container = options.container, + target = options.target, + text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'. + + if (action !== 'copy' && action !== 'cut') { + throw new Error('Invalid "action" value, use either "copy" or "cut"'); + } // Sets the `target` property using an element that will be have its content copied. + + + if (target !== undefined) { + if (target && _typeof(target) === 'object' && target.nodeType === 1) { + if (action === 'copy' && target.hasAttribute('disabled')) { + throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); + } + + if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { + throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); + } + } else { + throw new Error('Invalid "target" value, use a valid Element'); + } + } // Define selection strategy based on `text` property. + + + if (text) { + return actions_copy(text, { + container: container + }); + } // Defines which selection strategy based on `target` property. + + + if (target) { + return action === 'cut' ? actions_cut(target) : actions_copy(target, { + container: container + }); + } +}; + +/* harmony default export */ var actions_default = (ClipboardActionDefault); +;// CONCATENATED MODULE: ./src/clipboard.js +function clipboard_typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return clipboard_typeof(obj); } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + + + + + + +/** + * Helper function to retrieve attribute value. + * @param {String} suffix + * @param {Element} element + */ + +function getAttributeValue(suffix, element) { + var attribute = "data-clipboard-".concat(suffix); + + if (!element.hasAttribute(attribute)) { + return; + } + + return element.getAttribute(attribute); +} +/** + * Base class which takes one or more elements, adds event listeners to them, + * and instantiates a new `ClipboardAction` on each click. + */ + + +var Clipboard = /*#__PURE__*/function (_Emitter) { + _inherits(Clipboard, _Emitter); + + var _super = _createSuper(Clipboard); + + /** + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + * @param {Object} options + */ + function Clipboard(trigger, options) { + var _this; + + _classCallCheck(this, Clipboard); + + _this = _super.call(this); + + _this.resolveOptions(options); + + _this.listenClick(trigger); + + return _this; + } + /** + * Defines if attributes would be resolved using internal setter functions + * or custom functions that were passed in the constructor. + * @param {Object} options + */ + + + _createClass(Clipboard, [{ + key: "resolveOptions", + value: function resolveOptions() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + this.action = typeof options.action === 'function' ? options.action : this.defaultAction; + this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; + this.text = typeof options.text === 'function' ? options.text : this.defaultText; + this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body; + } + /** + * Adds a click event listener to the passed trigger. + * @param {String|HTMLElement|HTMLCollection|NodeList} trigger + */ + + }, { + key: "listenClick", + value: function listenClick(trigger) { + var _this2 = this; + + this.listener = listen_default()(trigger, 'click', function (e) { + return _this2.onClick(e); + }); + } + /** + * Defines a new `ClipboardAction` on each click event. + * @param {Event} e + */ + + }, { + key: "onClick", + value: function onClick(e) { + var trigger = e.delegateTarget || e.currentTarget; + var action = this.action(trigger) || 'copy'; + var text = actions_default({ + action: action, + container: this.container, + target: this.target(trigger), + text: this.text(trigger) + }); // Fires an event based on the copy operation result. + + this.emit(text ? 'success' : 'error', { + action: action, + text: text, + trigger: trigger, + clearSelection: function clearSelection() { + if (trigger) { + trigger.focus(); + } + + window.getSelection().removeAllRanges(); + } + }); + } + /** + * Default `action` lookup function. + * @param {Element} trigger + */ + + }, { + key: "defaultAction", + value: function defaultAction(trigger) { + return getAttributeValue('action', trigger); + } + /** + * Default `target` lookup function. + * @param {Element} trigger + */ + + }, { + key: "defaultTarget", + value: function defaultTarget(trigger) { + var selector = getAttributeValue('target', trigger); + + if (selector) { + return document.querySelector(selector); + } + } + /** + * Allow fire programmatically a copy action + * @param {String|HTMLElement} target + * @param {Object} options + * @returns Text copied. + */ + + }, { + key: "defaultText", + + /** + * Default `text` lookup function. + * @param {Element} trigger + */ + value: function defaultText(trigger) { + return getAttributeValue('text', trigger); + } + /** + * Destroy lifecycle. + */ + + }, { + key: "destroy", + value: function destroy() { + this.listener.destroy(); + } + }], [{ + key: "copy", + value: function copy(target) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { + container: document.body + }; + return actions_copy(target, options); + } + /** + * Allow fire programmatically a cut action + * @param {String|HTMLElement} target + * @returns Text cutted. + */ + + }, { + key: "cut", + value: function cut(target) { + return actions_cut(target); + } + /** + * Returns the support of the given action, or all actions if no action is + * given. + * @param {String} [action] + */ + + }, { + key: "isSupported", + value: function isSupported() { + var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; + var actions = typeof action === 'string' ? [action] : action; + var support = !!document.queryCommandSupported; + actions.forEach(function (action) { + support = support && !!document.queryCommandSupported(action); + }); + return support; + } + }]); + + return Clipboard; +}((tiny_emitter_default())); + +/* harmony default export */ var clipboard = (Clipboard); + +/***/ }), + +/***/ 828: +/***/ (function(module) { + +var DOCUMENT_NODE_TYPE = 9; + +/** + * A polyfill for Element.matches() + */ +if (typeof Element !== 'undefined' && !Element.prototype.matches) { + var proto = Element.prototype; + + proto.matches = proto.matchesSelector || + proto.mozMatchesSelector || + proto.msMatchesSelector || + proto.oMatchesSelector || + proto.webkitMatchesSelector; +} + +/** + * Finds the closest parent that matches a selector. + * + * @param {Element} element + * @param {String} selector + * @return {Function} + */ +function closest (element, selector) { + while (element && element.nodeType !== DOCUMENT_NODE_TYPE) { + if (typeof element.matches === 'function' && + element.matches(selector)) { + return element; + } + element = element.parentNode; + } +} + +module.exports = closest; + + +/***/ }), + +/***/ 438: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +var closest = __webpack_require__(828); + +/** + * Delegates event to a selector. + * + * @param {Element} element + * @param {String} selector + * @param {String} type + * @param {Function} callback + * @param {Boolean} useCapture + * @return {Object} + */ +function _delegate(element, selector, type, callback, useCapture) { + var listenerFn = listener.apply(this, arguments); + + element.addEventListener(type, listenerFn, useCapture); + + return { + destroy: function() { + element.removeEventListener(type, listenerFn, useCapture); + } + } +} + +/** + * Delegates event to a selector. + * + * @param {Element|String|Array} [elements] + * @param {String} selector + * @param {String} type + * @param {Function} callback + * @param {Boolean} useCapture + * @return {Object} + */ +function delegate(elements, selector, type, callback, useCapture) { + // Handle the regular Element usage + if (typeof elements.addEventListener === 'function') { + return _delegate.apply(null, arguments); + } + + // Handle Element-less usage, it defaults to global delegation + if (typeof type === 'function') { + // Use `document` as the first parameter, then apply arguments + // This is a short way to .unshift `arguments` without running into deoptimizations + return _delegate.bind(null, document).apply(null, arguments); + } + + // Handle Selector-based usage + if (typeof elements === 'string') { + elements = document.querySelectorAll(elements); + } + + // Handle Array-like based usage + return Array.prototype.map.call(elements, function (element) { + return _delegate(element, selector, type, callback, useCapture); + }); +} + +/** + * Finds closest match and invokes callback. + * + * @param {Element} element + * @param {String} selector + * @param {String} type + * @param {Function} callback + * @return {Function} + */ +function listener(element, selector, type, callback) { + return function(e) { + e.delegateTarget = closest(e.target, selector); + + if (e.delegateTarget) { + callback.call(element, e); + } + } +} + +module.exports = delegate; + + +/***/ }), + +/***/ 879: +/***/ (function(__unused_webpack_module, exports) { + +/** + * Check if argument is a HTML element. + * + * @param {Object} value + * @return {Boolean} + */ +exports.node = function(value) { + return value !== undefined + && value instanceof HTMLElement + && value.nodeType === 1; +}; + +/** + * Check if argument is a list of HTML elements. + * + * @param {Object} value + * @return {Boolean} + */ +exports.nodeList = function(value) { + var type = Object.prototype.toString.call(value); + + return value !== undefined + && (type === '[object NodeList]' || type === '[object HTMLCollection]') + && ('length' in value) + && (value.length === 0 || exports.node(value[0])); +}; + +/** + * Check if argument is a string. + * + * @param {Object} value + * @return {Boolean} + */ +exports.string = function(value) { + return typeof value === 'string' + || value instanceof String; +}; + +/** + * Check if argument is a function. + * + * @param {Object} value + * @return {Boolean} + */ +exports.fn = function(value) { + var type = Object.prototype.toString.call(value); + + return type === '[object Function]'; +}; + + +/***/ }), + +/***/ 370: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +var is = __webpack_require__(879); +var delegate = __webpack_require__(438); + +/** + * Validates all params and calls the right + * listener function based on its target type. + * + * @param {String|HTMLElement|HTMLCollection|NodeList} target + * @param {String} type + * @param {Function} callback + * @return {Object} + */ +function listen(target, type, callback) { + if (!target && !type && !callback) { + throw new Error('Missing required arguments'); + } + + if (!is.string(type)) { + throw new TypeError('Second argument must be a String'); + } + + if (!is.fn(callback)) { + throw new TypeError('Third argument must be a Function'); + } + + if (is.node(target)) { + return listenNode(target, type, callback); + } + else if (is.nodeList(target)) { + return listenNodeList(target, type, callback); + } + else if (is.string(target)) { + return listenSelector(target, type, callback); + } + else { + throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); + } +} + +/** + * Adds an event listener to a HTML element + * and returns a remove listener function. + * + * @param {HTMLElement} node + * @param {String} type + * @param {Function} callback + * @return {Object} + */ +function listenNode(node, type, callback) { + node.addEventListener(type, callback); + + return { + destroy: function() { + node.removeEventListener(type, callback); + } + } +} + +/** + * Add an event listener to a list of HTML elements + * and returns a remove listener function. + * + * @param {NodeList|HTMLCollection} nodeList + * @param {String} type + * @param {Function} callback + * @return {Object} + */ +function listenNodeList(nodeList, type, callback) { + Array.prototype.forEach.call(nodeList, function(node) { + node.addEventListener(type, callback); + }); + + return { + destroy: function() { + Array.prototype.forEach.call(nodeList, function(node) { + node.removeEventListener(type, callback); + }); + } + } +} + +/** + * Add an event listener to a selector + * and returns a remove listener function. + * + * @param {String} selector + * @param {String} type + * @param {Function} callback + * @return {Object} + */ +function listenSelector(selector, type, callback) { + return delegate(document.body, selector, type, callback); +} + +module.exports = listen; + + +/***/ }), + +/***/ 817: +/***/ (function(module) { + +function select(element) { + var selectedText; + + if (element.nodeName === 'SELECT') { + element.focus(); + + selectedText = element.value; + } + else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') { + var isReadOnly = element.hasAttribute('readonly'); + + if (!isReadOnly) { + element.setAttribute('readonly', ''); + } + + element.select(); + element.setSelectionRange(0, element.value.length); + + if (!isReadOnly) { + element.removeAttribute('readonly'); + } + + selectedText = element.value; + } + else { + if (element.hasAttribute('contenteditable')) { + element.focus(); + } + + var selection = window.getSelection(); + var range = document.createRange(); + + range.selectNodeContents(element); + selection.removeAllRanges(); + selection.addRange(range); + + selectedText = selection.toString(); + } + + return selectedText; +} + +module.exports = select; + + +/***/ }), + +/***/ 279: +/***/ (function(module) { + +function E () { + // Keep this empty so it's easier to inherit from + // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) +} + +E.prototype = { + on: function (name, callback, ctx) { + var e = this.e || (this.e = {}); + + (e[name] || (e[name] = [])).push({ + fn: callback, + ctx: ctx + }); + + return this; + }, + + once: function (name, callback, ctx) { + var self = this; + function listener () { + self.off(name, listener); + callback.apply(ctx, arguments); + }; + + listener._ = callback + return this.on(name, listener, ctx); + }, + + emit: function (name) { + var data = [].slice.call(arguments, 1); + var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); + var i = 0; + var len = evtArr.length; + + for (i; i < len; i++) { + evtArr[i].fn.apply(evtArr[i].ctx, data); + } + + return this; + }, + + off: function (name, callback) { + var e = this.e || (this.e = {}); + var evts = e[name]; + var liveEvents = []; + + if (evts && callback) { + for (var i = 0, len = evts.length; i < len; i++) { + if (evts[i].fn !== callback && evts[i].fn._ !== callback) + liveEvents.push(evts[i]); + } + } + + // Remove event from queue to prevent memory leak + // Suggested by https://github.com/lazd + // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 + + (liveEvents.length) + ? e[name] = liveEvents + : delete e[name]; + + return this; + } +}; + +module.exports = E; +module.exports.TinyEmitter = E; + + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ if(__webpack_module_cache__[moduleId]) { +/******/ return __webpack_module_cache__[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/compat get default export */ +/******/ !function() { +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function() { return module['default']; } : +/******/ function() { return module; }; +/******/ __webpack_require__.d(getter, { a: getter }); +/******/ return getter; +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/define property getters */ +/******/ !function() { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = function(exports, definition) { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ }(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ !function() { +/******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } +/******/ }(); +/******/ +/************************************************************************/ +/******/ // module exports must be returned from runtime so entry inlining is disabled +/******/ // startup +/******/ // Load entry module and return exports +/******/ return __webpack_require__(686); +/******/ })() +.default; +}); \ No newline at end of file diff --git a/dj_backend_server/web/static/dashboard/js/vendors/clipboard.min.js b/dj_backend_server/web/static/dashboard/js/vendors/clipboard.min.js new file mode 100644 index 00000000..1103f811 --- /dev/null +++ b/dj_backend_server/web/static/dashboard/js/vendors/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1 + diff --git a/dj_backend_server/web/templates/settings-theme.html b/dj_backend_server/web/templates/settings-theme.html index 338cde20..ae546d9b 100644 --- a/dj_backend_server/web/templates/settings-theme.html +++ b/dj_backend_server/web/templates/settings-theme.html @@ -5,10 +5,10 @@ {% block content %} -
+

{{ bot.name }}: try & share ✨

    @@ -31,6 +31,8 @@

    Try & Share!

    Here you can try and play with your bot, also you can share it or embed it in your web apps. Anyone with this link will be able to interact with your chatbot
    + +
    @@ -38,19 +40,18 @@

    Try & Share!

    -
    - - - -
    - + + + + + +
@@ -77,69 +78,72 @@

Try & Share!

1. Copy the following code into your website head - script + script + + +
@@ -171,35 +175,32 @@

Try & Share!

1. Copy the following code into your website head - script +
- - -
- 2. Please read this documentation to see all the options for the - search widget -
@@ -215,55 +216,8 @@

Try & Share!

{% block scripts %} {% endblock scripts %} diff --git a/dj_backend_server/web/templates/settings.html b/dj_backend_server/web/templates/settings.html index c92c7763..a5bf324f 100644 --- a/dj_backend_server/web/templates/settings.html +++ b/dj_backend_server/web/templates/settings.html @@ -37,7 +37,8 @@

General Settings

- + +
@@ -48,9 +49,16 @@

General Settings

- - + + + + +
@@ -216,5 +224,7 @@

Delete the bot

document.getElementById('promptMessage').value = Prompts[promptCase]; } + new ClipboardJS('.btn'); + {% endblock %} \ No newline at end of file From cf50cb4bb210850e8241e878e585e56d9bed206d Mon Sep 17 00:00:00 2001 From: lvalics Date: Sun, 28 Jan 2024 08:55:56 +0000 Subject: [PATCH 4/6] Copied message. Still not ok the design. --- .../web/templates/settings-theme.html | 15 +++++++++++++++ dj_backend_server/web/templates/settings.html | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/dj_backend_server/web/templates/settings-theme.html b/dj_backend_server/web/templates/settings-theme.html index ae546d9b..387af67c 100644 --- a/dj_backend_server/web/templates/settings-theme.html +++ b/dj_backend_server/web/templates/settings-theme.html @@ -217,7 +217,22 @@

Try & Share!

{% endblock scripts %} diff --git a/dj_backend_server/web/templates/settings.html b/dj_backend_server/web/templates/settings.html index a5bf324f..0474dbad 100644 --- a/dj_backend_server/web/templates/settings.html +++ b/dj_backend_server/web/templates/settings.html @@ -226,5 +226,22 @@

Delete the bot

new ClipboardJS('.btn'); + var clipboard = new ClipboardJS('.btn'); + + clipboard.on('success', function(e) { + var copySuccessMessage = document.getElementById('copy-success-message'); + copySuccessMessage.textContent = 'Copied'; + setTimeout(function() { + copySuccessMessage.textContent = ''; + }, 1000); + + e.clearSelection(); + }); + + clipboard.on('error', function(e) { + console.error('Action:', e.action); + console.error('Trigger:', e.trigger); + }); + {% endblock %} \ No newline at end of file From dbdd06c77a0706237f1603e1f9485b81d50652bf Mon Sep 17 00:00:00 2001 From: lvalics Date: Sun, 28 Jan 2024 09:13:47 +0000 Subject: [PATCH 5/6] Working the copy --- .../web/templates/settings-theme.html | 16 +++++++++++----- dj_backend_server/web/templates/settings.html | 6 ++++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dj_backend_server/web/templates/settings-theme.html b/dj_backend_server/web/templates/settings-theme.html index 387af67c..0904af18 100644 --- a/dj_backend_server/web/templates/settings-theme.html +++ b/dj_backend_server/web/templates/settings-theme.html @@ -44,13 +44,15 @@

Try & Share!

+ + - + @@ -80,13 +82,16 @@

Try & Share!

1. Copy the following code into your website head script + + + - +