UNPKG

supafeedback

Version:

Website Feedback Recorder is an innovative npm package designed to streamline the process of collecting user feedback and bug reports for your website. By integrating this package, users can easily record their screen as they navigate through your site, a

630 lines (624 loc) 23.4 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } function _regeneratorRuntime() { _regeneratorRuntime = function () { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function (t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function (t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(typeof e + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function (e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function () { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function (e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function (t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function (t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function (t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function (t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function (e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } var style = /*#__PURE__*/document.createElement('style'); style.innerHTML = "\n\n#supafeedback-modal{\n font-family: Arial, sans-serif;\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0,0,0,0.5);\n z-index: 9999;\n}\n\n.supafeedback-content {\n margin: 100px auto;\n padding: 20px;\n background-color: white;\n border-radius: 5px;\n box-shadow: 0 0 10px rgba(0,0,0,0.5);\n width: 70%;\n max-width: 500px;\n position: relative;\n}\n\n.supafeedback-close {\n position: absolute;\n top: 5px;\n right: 5px;\n cursor: pointer;\n}\n\n.supafeedback-form {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.supafeedback-form input, .supafeedback-form textarea {\n padding: 10px;\n border-radius: 5px;\n border: 1px solid purple;\n resize: none;\n}\n\n.supafeedback-title {\n font-size: 24px;\n margin: 0;\n margin-bottom: 8px;\n}\n\n.supafeedback-btn-main {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 9999;\n}\n\n.supafeedback-btn {\n font-family: Arial, sans-serif;\n padding: 4px;\n background-color: transparent;\n color: purple;\n cursor: pointer;\n border-radius: 5px;\n border: 2px solid #9370DB;\n}\n\n.supafeedback-btn-active, .supafeedback-btn:focus, .supafeedback-btn:hover {\n border: 2px solid purple;\n color: white;\n background-color: purple; \n transition: 0.5s; \n}\n\n.supafeedback-btn:hover {\n border: 2px solid purple;\n}\n\n"; document.head.appendChild(style); var initialized = false; var modalState = false; var mediaRecorder = null; var recordedChunks = []; var videoBlob = null; var initSupaFeedback = function initSupaFeedback(token) { if (initialized) { return; } // add a div to the body var div = document.getElementById('supafeedback'); if (!div) { div = document.createElement('div'); div.id = 'supafeedback'; div.className = 'supafeedback-btn supafeedback-btn-main'; } div.innerHTML = 'Report a bug'; div.onclick = function () { if (!modalState) { openModal(token); } }; if (!document.getElementById('supafeedback')) { document.body.appendChild(div); } initialized = true; }; var openModal = function openModal(accessToken) { modalState = true; var modal = document.getElementById('supafeedback-modal'); if (modal) { modal.style.display = 'block'; return; } modal = document.createElement('div'); modal.id = 'supafeedback-modal'; modal.onclick = function (e) { closeModal(); e.stopPropagation(); }; var content = document.createElement('div'); content.className = 'supafeedback-content'; content.onclick = function (e) { e.stopPropagation(); }; var close = document.createElement('div'); close.innerHTML = 'X'; close.className = 'supafeedback-close'; close.onclick = function () { closeModal(); }; var title = document.createElement('h1'); title.className = 'supafeedback-title'; title.innerHTML = 'Report a bug'; var form = document.createElement('form'); form.className = 'supafeedback-form'; form.onsubmit = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(e) { var submit, formData, response; return _regeneratorRuntime().wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: e.preventDefault(); // disable submit button and change text submit = document.querySelector('#supafeedback-submit'); if (submit) { submit.setAttribute('disabled', 'true'); submit.innerHTML = 'Uploading...'; } if (videoBlob) { _context.next = 6; break; } console.error('No video recorded'); return _context.abrupt("return"); case 6: formData = new FormData(); formData.append('file', videoBlob, 'bug_report.webm'); formData.append('description', document.querySelector('textarea').value); _context.prev = 9; _context.next = 12; return fetch('https://zb5qarphvg.execute-api.ap-south-1.amazonaws.com/SFB/upload', { method: 'POST', body: formData, headers: { 'x-access-token': accessToken } }); case 12: response = _context.sent; if (response.ok) { console.log('Video uploaded successfully'); closeModal(); form.reset(); videoBlob = null; // Reset the recorded chunks recordedChunks = []; //change the button text if (submit) { submit.removeAttribute('disabled'); submit.innerHTML = 'Submit'; } } else { console.error('Video upload failed'); //change the button text if (submit) { submit.removeAttribute('disabled'); submit.innerHTML = 'Submit'; } } _context.next = 20; break; case 16: _context.prev = 16; _context.t0 = _context["catch"](9); console.error('Error uploading video:', _context.t0); //change the button text if (submit) { submit.removeAttribute('disabled'); submit.innerHTML = 'Error Submitting, Please submit again'; } case 20: case "end": return _context.stop(); } }, _callee, null, [[9, 16]]); })); return function (_x) { return _ref.apply(this, arguments); }; }(); var input = document.createElement('textarea'); input.name = 'description'; input.rows = 6; input.placeholder = 'Enter your bug report'; input.required = true; input.className = 'supafeedback-input'; var helpText = document.createElement('p'); helpText.innerHTML = 'Record a video of the bug and describe it above'; var recordScreen = document.createElement('button'); recordScreen.id = 'supafeedback-record-screen'; recordScreen.type = 'button'; recordScreen.innerHTML = videoBlob ? 'Re-record' : 'Record screen'; recordScreen.className = 'supafeedback-btn'; recordScreen.onclick = function () { closeModal(); startScreenRecording(accessToken); console.log('Recording screen'); }; var submit = document.createElement('button'); submit.id = 'supafeedback-submit'; submit.type = 'submit'; submit.innerHTML = 'Submit'; submit.className = 'supafeedback-btn'; var videoContainer = document.createElement('div'); videoContainer.id = 'video-container'; videoContainer.style.display = 'none'; // Hidden initially var videoElement = document.createElement('video'); videoElement.id = 'recorded-video'; videoElement.controls = true; videoElement.style.width = '100%'; videoElement.style.height = 'auto'; videoContainer.appendChild(videoElement); form.appendChild(input); form.appendChild(helpText); form.appendChild(videoContainer); form.appendChild(recordScreen); form.appendChild(submit); content.appendChild(close); content.appendChild(title); content.appendChild(form); modal.appendChild(content); document.body.appendChild(modal); }; var closeModal = function closeModal() { var modal = document.getElementById('supafeedback-modal'); if (modal) { modalState = false; modal.style.display = 'none'; // remove the video container var videoContainer = document.getElementById('video-container'); if (videoContainer) { videoContainer.style.display = 'none'; // Hide video container videoBlob = null; recordedChunks = []; //change the button text var recordScreen = document.querySelector('#supafeedback-record-screen'); if (recordScreen) { recordScreen.innerHTML = 'Record screen'; } } } }; var startScreenRecording = /*#__PURE__*/function () { var _ref2 = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(accessToken) { var stream, mainButton, count, interval; return _regeneratorRuntime().wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: _context3.prev = 0; _context3.next = 3; return navigator.mediaDevices.getDisplayMedia({ video: true }); case 3: stream = _context3.sent; mediaRecorder = new MediaRecorder(stream); //Change the button text to count down mainButton = document.querySelector('#supafeedback'); if (mainButton) { mainButton.innerHTML = 'Recording will stop in 10'; } count = 9; interval = setInterval(function () { if (count > 0) { if (mainButton) { mainButton.innerHTML = "Recording will stop in " + count.toString(); } count--; } else { clearInterval(interval); if (mainButton) { mainButton.innerHTML = 'Report a bug'; } } }, 1000); mediaRecorder.ondataavailable = function (event) { if (event.data.size > 0) { recordedChunks.push(event.data); } }; mediaRecorder.onstop = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() { var blob, url, videoElement, videoContainer, recordScreen; return _regeneratorRuntime().wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: clearInterval(interval); if (mainButton) { mainButton.innerHTML = 'Report a bug'; } stream.getTracks().forEach(function (track) { return track.stop(); }); openModal(accessToken); blob = new Blob(recordedChunks, { type: 'video/webm' }); url = URL.createObjectURL(blob); // Display the recorded video videoElement = document.getElementById('recorded-video'); if (videoElement) { videoElement.src = url; videoContainer = document.getElementById('video-container'); if (videoContainer) { videoContainer.style.display = 'block'; // Show video container } } //change the button text recordScreen = document.querySelector('#supafeedback-record-screen'); if (recordScreen) { recordScreen.innerHTML = 'Re-record'; } // Save the video blob videoBlob = blob; console.log('Video blob:', videoBlob); case 12: case "end": return _context2.stop(); } }, _callee2); })); mediaRecorder.start(); setTimeout(function () { var _mediaRecorder; (_mediaRecorder = mediaRecorder) == null || _mediaRecorder.stop(); }, 10000); // Record for 10 seconds _context3.next = 18; break; case 15: _context3.prev = 15; _context3.t0 = _context3["catch"](0); console.error('Error: ' + _context3.t0); case 18: case "end": return _context3.stop(); } }, _callee3, null, [[0, 15]]); })); return function startScreenRecording(_x2) { return _ref2.apply(this, arguments); }; }(); exports.initSupaFeedback = initSupaFeedback; //# sourceMappingURL=supafeedback.cjs.development.js.map