diff --git a/package-lock.json b/package-lock.json index 1c8b485..d1df5d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22 +1,23 @@ { "name": "creature-builder", - "version": "0.6.1", + "version": "0.8.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "creature-builder", - "version": "0.6.1", + "version": "0.8.0", "dependencies": { + "@assistantapps/assistantapps.api.client": "^0.0.18", "@chakra-ui/icons": "^2.0.0", "@chakra-ui/react": "^2.8.0", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@microsoft/signalr": "^6.0.5", "assert": "^2.0.0", - "axios": "^0.27.2", "crypto-browserify": "^3.12.0", "crypto-js": "^4.1.1", + "dotenv": "^16.3.1", "electron-is-dev": "^2.0.0", "framer-motion": "^10.15.0", "fs": "0.0.1-security", @@ -35,6 +36,7 @@ "react-syntax-highlighter": "^15.5.0", "react-toastify": "^9.0.1", "sass": "^1.64.2", + "stats.js": "^0.17.0", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "sweetalert2": "^11.4.17", @@ -18598,6 +18600,47 @@ "node": ">=6.0.0" } }, + "node_modules/@assistantapps/assistantapps.api.client": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@assistantapps/assistantapps.api.client/-/assistantapps.api.client-0.0.18.tgz", + "integrity": "sha512-rW07Hc0cwWT/jS+7snZCnRUDKSpspO5lnK5wYDMKYqpHAbKTcnPL7JHmdPmMDIhhh7sZ9aP1b8SJrj+OFM79qA==", + "dependencies": { + "@microsoft/signalr": "^7.0.5", + "dayjs": "^1.11.7" + }, + "engines": { + "node": ">=18.0" + } + }, + "node_modules/@assistantapps/assistantapps.api.client/node_modules/@microsoft/signalr": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-7.0.10.tgz", + "integrity": "sha512-tOEn32i5EatAx4sZbzmLgcBc2VbKQmx+F4rI2/Ioq2MnBaYcFxbDzOoZgISIS4IR9H1ij/sKoU8zQOAFC8GJKg==", + "dependencies": { + "abort-controller": "^3.0.0", + "eventsource": "^2.0.2", + "fetch-cookie": "^2.0.3", + "node-fetch": "^2.6.7", + "ws": "^7.4.5" + } + }, + "node_modules/@assistantapps/assistantapps.api.client/node_modules/eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@assistantapps/assistantapps.api.client/node_modules/fetch-cookie": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-2.1.0.tgz", + "integrity": "sha512-39+cZRbWfbibmj22R2Jy6dmTbAWC+oqun1f1FzQaNurkPDUP4C38jpeZbiXCR88RKRVDp8UcDrbFXkNhN+NjYg==", + "dependencies": { + "set-cookie-parser": "^2.4.8", + "tough-cookie": "^4.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", @@ -25305,15 +25348,6 @@ "node": ">=4" } }, - "node_modules/axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "dependencies": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, "node_modules/axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -27466,6 +27500,11 @@ "url": "https://opencollective.com/date-fns" } }, + "node_modules/dayjs": { + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", + "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -27961,11 +28000,14 @@ } }, "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, "node_modules/dotenv-expand": { @@ -29846,6 +29888,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -38183,6 +38226,14 @@ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" }, + "node_modules/react-scripts/node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, "node_modules/react-scripts/node_modules/emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", @@ -40207,6 +40258,11 @@ "node": ">= 0.8.0" } }, + "node_modules/set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -40536,6 +40592,11 @@ "node": ">= 6" } }, + "node_modules/stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -43420,6 +43481,43 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@assistantapps/assistantapps.api.client": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@assistantapps/assistantapps.api.client/-/assistantapps.api.client-0.0.18.tgz", + "integrity": "sha512-rW07Hc0cwWT/jS+7snZCnRUDKSpspO5lnK5wYDMKYqpHAbKTcnPL7JHmdPmMDIhhh7sZ9aP1b8SJrj+OFM79qA==", + "requires": { + "@microsoft/signalr": "^7.0.5", + "dayjs": "^1.11.7" + }, + "dependencies": { + "@microsoft/signalr": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/@microsoft/signalr/-/signalr-7.0.10.tgz", + "integrity": "sha512-tOEn32i5EatAx4sZbzmLgcBc2VbKQmx+F4rI2/Ioq2MnBaYcFxbDzOoZgISIS4IR9H1ij/sKoU8zQOAFC8GJKg==", + "requires": { + "abort-controller": "^3.0.0", + "eventsource": "^2.0.2", + "fetch-cookie": "^2.0.3", + "node-fetch": "^2.6.7", + "ws": "^7.4.5" + } + }, + "eventsource": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", + "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==" + }, + "fetch-cookie": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-2.1.0.tgz", + "integrity": "sha512-39+cZRbWfbibmj22R2Jy6dmTbAWC+oqun1f1FzQaNurkPDUP4C38jpeZbiXCR88RKRVDp8UcDrbFXkNhN+NjYg==", + "requires": { + "set-cookie-parser": "^2.4.8", + "tough-cookie": "^4.0.0" + } + } + } + }, "@babel/code-frame": { "version": "7.22.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", @@ -48307,15 +48405,6 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==" }, - "axios": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", - "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", - "requires": { - "follow-redirects": "^1.14.9", - "form-data": "^4.0.0" - } - }, "axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -49932,6 +50021,11 @@ "@babel/runtime": "^7.21.0" } }, + "dayjs": { + "version": "1.11.9", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", + "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -50308,9 +50402,9 @@ } }, "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" }, "dotenv-expand": { "version": "5.1.0", @@ -51739,6 +51833,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -57663,6 +57758,11 @@ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" }, + "dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" + }, "emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", @@ -59179,6 +59279,11 @@ "send": "0.18.0" } }, + "set-cookie-parser": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", + "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==" + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -59443,6 +59548,11 @@ "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", "dev": true }, + "stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==" + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", diff --git a/package.json b/package.json index 8a69715..f82184f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "creature-builder", - "version": "0.8.0", + "version": "0.8.1", "description": "Creature builder built for the No Man's Sky Hub built by AssistantNMS", "author": "AssistantNMS (Kurt Lourens)", "main": "public/electron.js", @@ -57,15 +57,16 @@ "tls": false }, "dependencies": { + "@assistantapps/assistantapps.api.client": "^0.0.18", "@chakra-ui/icons": "^2.0.0", "@chakra-ui/react": "^2.8.0", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@microsoft/signalr": "^6.0.5", "assert": "^2.0.0", - "axios": "^0.27.2", "crypto-browserify": "^3.12.0", "crypto-js": "^4.1.1", + "dotenv": "^16.3.1", "electron-is-dev": "^2.0.0", "framer-motion": "^10.15.0", "fs": "0.0.1-security", @@ -84,6 +85,7 @@ "react-syntax-highlighter": "^15.5.0", "react-toastify": "^9.0.1", "sass": "^1.64.2", + "stats.js": "^0.17.0", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0", "sweetalert2": "^11.4.17", diff --git a/public/assets/img/sceneBackground.jpg b/public/assets/img/sceneBackground.jpg new file mode 100644 index 0000000..3882cd8 Binary files /dev/null and b/public/assets/img/sceneBackground.jpg differ diff --git a/public/assets/img/skybox/space/bk.jpg b/public/assets/img/skybox/space/bk.jpg new file mode 100644 index 0000000..a6a1550 Binary files /dev/null and b/public/assets/img/skybox/space/bk.jpg differ diff --git a/public/assets/img/skybox/space/dn.jpg b/public/assets/img/skybox/space/dn.jpg new file mode 100644 index 0000000..cf871fa Binary files /dev/null and b/public/assets/img/skybox/space/dn.jpg differ diff --git a/public/assets/img/skybox/space/ft.jpg b/public/assets/img/skybox/space/ft.jpg new file mode 100644 index 0000000..33ad48b Binary files /dev/null and b/public/assets/img/skybox/space/ft.jpg differ diff --git a/public/assets/img/skybox/space/lt.jpg b/public/assets/img/skybox/space/lt.jpg new file mode 100644 index 0000000..b431be4 Binary files /dev/null and b/public/assets/img/skybox/space/lt.jpg differ diff --git a/public/assets/img/skybox/space/rt.jpg b/public/assets/img/skybox/space/rt.jpg new file mode 100644 index 0000000..6c06829 Binary files /dev/null and b/public/assets/img/skybox/space/rt.jpg differ diff --git a/public/assets/img/skybox/space/up.jpg b/public/assets/img/skybox/space/up.jpg new file mode 100644 index 0000000..1864fb8 Binary files /dev/null and b/public/assets/img/skybox/space/up.jpg differ diff --git a/public/assets/js/analytics.js b/public/assets/js/analytics.js deleted file mode 100644 index cc2ac70..0000000 --- a/public/assets/js/analytics.js +++ /dev/null @@ -1,9 +0,0 @@ -if (!!window.config.enableAnalytics) { - !function (t, e) { var o, n, p, r; e.__SV || (window.posthog = e, e._i = [], e.init = function (i, s, a) { function g(t, e) { var o = e.split("."); 2 == o.length && (t = t[o[0]], e = o[1]), t[e] = function () { t.push([e].concat(Array.prototype.slice.call(arguments, 0))) } } (p = t.createElement("script")).type = "text/javascript", p.async = !0, p.src = s.api_host + "/static/array.js", (r = t.getElementsByTagName("script")[0]).parentNode.insertBefore(p, r); var u = e; for (void 0 !== a ? u = e[a] = [] : a = "posthog", u.people = u.people || [], u.toString = function (t) { var e = "posthog"; return "posthog" !== a && (e += "." + a), t || (e += " (stub)"), e }, u.people.toString = function () { return u.toString(1) + ".people (stub)" }, o = "capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys".split(" "), n = 0; n < o.length; n++)g(u, o[n]); e._i.push([i, s, a]) }, e.__SV = 1) }(document, window.posthog || []); - posthog.init('phc_z2RdrVWTdB091SxgpVnfBX8oHsJjJnSdybcEYniJlGQ', { api_host: 'https://eu.posthog.com' }) -} - -function track(event, value) { - posthog?.capture?.(event, { property: value }); -} - diff --git a/public/humans.txt b/public/humans.txt index 8c609a3..fceeb40 100644 --- a/public/humans.txt +++ b/public/humans.txt @@ -5,7 +5,7 @@ Twitter: @KhaozTopsy From: Almere, The Netherlands /* SITE */ -Last update: 2023-08-14 +Last update: 2023-08-23 Language: English Doctype:HTML5 IDE: Visual Studio Code \ No newline at end of file diff --git a/public/index.html b/public/index.html index 62fe88a..881978d 100644 --- a/public/index.html +++ b/public/index.html @@ -1,5 +1,4 @@ Creature Builder by AssistantNMS
\ No newline at end of file + };
\ No newline at end of file diff --git a/public/sitemap.xml b/public/sitemap.xml index a2397d4..bc6fe78 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -5,7 +5,7 @@ https://creature.nmscd.com - 2023-08-14 + 2023-08-23 1.00 \ No newline at end of file diff --git a/seo/handlebar/index.hbs b/seo/handlebar/index.hbs index 0e012c7..a4ef9f5 100644 --- a/seo/handlebar/index.hbs +++ b/seo/handlebar/index.hbs @@ -80,7 +80,6 @@ window.config = { apiUrl: 'https://api.assistantapps.com', assistantAppsImgRoot: 'https://webcomp.assistantapps.com', - enableAnalytics: '%REACT_APP_ENABLE_ANALYTICS%' == 'true', }; @@ -115,10 +114,14 @@
+ + {{#if enableAnalytics}} + + {{/if}} - \ No newline at end of file diff --git a/src/appShell.tsx b/src/appShell.tsx index 3360872..fd265ba 100644 --- a/src/appShell.tsx +++ b/src/appShell.tsx @@ -1,20 +1,20 @@ +import { PlatformType } from '@assistantapps/assistantapps.api.client'; import { Box } from '@chakra-ui/react'; import React, { useContext, useEffect, useState } from 'react'; import { ToastContainer } from 'react-toastify'; -import { BuilderPage } from './page/builder/builderPage'; +import { Route, Router } from "wouter"; +import { AppDrawer } from './components/common/appDrawer'; import { Footer } from './components/common/footer'; import { Header } from './components/common/header'; import { currentServerVersionNum } from './constants/assistantApps'; -import { PlatformType } from './contracts/generated/AssistantApps/Enum/platformType'; -import { DependencyInjectionContext } from './integration/DependencyInjectionProvider'; -import { LoginPage } from './page/loginPage'; import { Routes } from './constants/routes'; -import { Route, Router } from "wouter"; -import { HomePage } from './page/homePage'; -import { AppDrawer } from './components/common/appDrawer'; +import { DependencyInjectionContext } from './integration/DependencyInjectionProvider'; import { AboutPage } from './page/aboutPage'; -import { NotFoundPage } from './page/notFoundPage'; +import { BuilderPage } from './page/builder/builderPage'; import { ChangelogPage } from './page/changelogPage'; +import { HomePage } from './page/homePage'; +import { LoginPage } from './page/loginPage'; +import { NotFoundPage } from './page/notFoundPage'; const currentLocation = () => window.location.hash.replace(/^#/, "") || "/"; @@ -46,7 +46,7 @@ export const AppShell: React.FC = () => { }, []); const updateCheck = async () => { - const apiResult = await assistantAppsApiService.getLatest([PlatformType.Windows]); + const apiResult = await assistantAppsApiService.getLatest([PlatformType.githubWindowsInstaller]); console.log({ updateCheck: { ...apiResult }, hasCheckedUpdate }) if (apiResult.isSuccess === false) return; diff --git a/src/components/donationFAB.tsx b/src/components/donationFAB.tsx index 6ac5ee0..c437330 100644 --- a/src/components/donationFAB.tsx +++ b/src/components/donationFAB.tsx @@ -10,7 +10,7 @@ export const DonationFAB: React.FC = (props: IProps) => { return ( <>
- +
diff --git a/src/components/objViewer/modelLoader.js b/src/components/objViewer/modelLoader.js index fb951b9..a7d6519 100644 --- a/src/components/objViewer/modelLoader.js +++ b/src/components/objViewer/modelLoader.js @@ -8,7 +8,7 @@ export const loadModel = ({ }) => { const loader = new FBXLoader(); loader.load( - `/assets/3d/${fileName}.fbx`, + `./assets/3d/${fileName}.fbx`, (model) => { model.scale.set(0.01, 0.01, 0.01); onLoad(model); diff --git a/src/components/objViewer/objInfoModal.tsx b/src/components/objViewer/objInfoModal.tsx index 40985e3..6a42a1a 100644 --- a/src/components/objViewer/objInfoModal.tsx +++ b/src/components/objViewer/objInfoModal.tsx @@ -64,7 +64,7 @@ export const ObjInfoModal: React.FC = (props: IProps) => { fileExtensions.map(fe => ( )) diff --git a/src/components/objViewer/objViewer.tsx b/src/components/objViewer/objViewer.tsx index 1beaeb5..e95e06b 100644 --- a/src/components/objViewer/objViewer.tsx +++ b/src/components/objViewer/objViewer.tsx @@ -1,7 +1,8 @@ import { CloseIcon } from '@chakra-ui/icons'; import { Center, Spinner, Text } from '@chakra-ui/react'; import { Component, createRef } from "react"; -import { Camera, Clock, HemisphereLight, Object3D, PerspectiveCamera, Scene, SpotLight, WebGLRenderer } from "three"; +import Stats from 'stats.js'; +import { Camera, Clock, FogExp2, HemisphereLight, Object3D, PerspectiveCamera, Scene, SpotLight, WebGLRenderer } from "three"; import { bgColour } from '../../constants/UIConstant'; import { cameraControls } from './cameraControls'; import { loadModel } from './modelLoader'; @@ -17,6 +18,8 @@ interface IProps { cameraPositionZ?: number; initPositionY?: number; meshNamesToFilterOutOnObjLoad?: Array; + showStats?: boolean; + lowQualityMode?: boolean; } interface IState { @@ -30,6 +33,7 @@ export class ObjViewer extends Component { renderer: any = {}; scene = new Scene(); clock = new Clock(); + stats = new Stats(); origCreatureMesh: Object3D | undefined; creatureMesh: Object3D | undefined; initPositionY: number = this.props.initPositionY ?? -1; @@ -53,20 +57,29 @@ export class ObjViewer extends Component { const cameraInit = this.props.cameraInitZoom ?? 1; const cameraPositionZ = this.props.cameraPositionZ ?? 8; - this.camera = new PerspectiveCamera((cameraInit * 40), width / height, 0.1, 1000); + this.camera = new PerspectiveCamera((cameraInit * 40), width / height, 0.1, 3000); this.camera.position.z = cameraPositionZ; this.camera.position.y = 5; + this.scene.fog = new FogExp2(0xcccccc, 0.002); this.renderer = new WebGLRenderer({ - alpha: true, - antialias: true, - preserveDrawingBuffer: true, + alpha: this.props.lowQualityMode !== true, + antialias: this.props.lowQualityMode !== true, + // preserveDrawingBuffer: true, + powerPreference: 'high-performance', }); this.renderer.shadowMap.enabled = true; this.renderer.setClearColor(bgColour); this.renderer.setSize(width, height); + this.renderer.setPixelRatio(window.devicePixelRatio); this.mount.appendChild(this.renderer.domElement); + this.stats.showPanel(0); + this.stats.dom.style.position = 'absolute'; + this.stats.dom.style.top = 'unset'; + this.stats.dom.style.bottom = '0'; + this.handleShowStatChange(this.props.showStats ?? false); + this.controls = cameraControls({ camera: this.camera, renderer: this.renderer, @@ -122,6 +135,9 @@ export class ObjViewer extends Component { console.error('Error occurred while updating creature meshes', ex); } } + if (prevProps.showStats !== this.props.showStats) { + this.handleShowStatChange(this.props.showStats ?? false); + } } componentWillUnmount() { @@ -187,7 +203,7 @@ export class ObjViewer extends Component { } this.scene.add(this.creatureMesh); - } + }; onObjLoad = (object: Object3D) => { if (this.origCreatureMesh != null) { @@ -201,8 +217,8 @@ export class ObjViewer extends Component { this.origCreatureMesh.traverse((n: any) => { if (n.isMesh) { - n.castShadow = true; - n.receiveShadow = true; + n.castShadow = this.props.lowQualityMode !== true; + n.receiveShadow = this.props.lowQualityMode !== true; if (n.material.map) n.material.map.anisotropy = 16; n.geometry.computeVertexNormals(); } @@ -215,7 +231,17 @@ export class ObjViewer extends Component { })); }; + handleShowStatChange = (showStats: boolean) => { + const statsExists = this.mount.contains(this.stats.dom); + if (showStats === true && statsExists === false) { + this.mount.appendChild(this.stats.dom); + } else if (showStats === false && statsExists === true) { + this.mount.removeChild(this.stats.dom) + } + } + animate = () => { + if (this.props.showStats === true) this.stats.begin(); this.controls.update(); // const time = Date.now() * 0.0005; @@ -230,6 +256,7 @@ export class ObjViewer extends Component { } this.renderer?.render?.(this.scene, this.camera); + if (this.props.showStats === true) this.stats.end(); this.frameId = window.requestAnimationFrame(this.animate); }; @@ -246,7 +273,25 @@ export class ObjViewer extends Component { this.renderer} + getScreenshotData={() => { + this.setState(() => ({ + hasLoaded: false, + })); + this.renderer.setClearColor(bgColour, 0); + this.renderer?.render?.(this.scene, this.camera); + + const screenshotDataUrl = this.renderer.domElement.toDataURL(); + + this.renderer.setClearColor(bgColour); + this.renderer?.render?.(this.scene, this.camera); + + return { + dataUrl: screenshotDataUrl, + width: this.mount.clientWidth, + height: this.mount.clientHeight, + }; + }} + setHasLoaded={(hasLoaded: boolean) => this.setState(() => ({ hasLoaded }))} onRepeatClick={(enable: boolean) => { this.enableRotate = enable; }} diff --git a/src/components/objViewer/objViewerControls.tsx b/src/components/objViewer/objViewerControls.tsx index e47a5be..6eae710 100644 --- a/src/components/objViewer/objViewerControls.tsx +++ b/src/components/objViewer/objViewerControls.tsx @@ -1,8 +1,8 @@ -import { DownloadIcon, RepeatIcon, InfoOutlineIcon } from '@chakra-ui/icons'; +import { DownloadIcon, InfoOutlineIcon, RepeatIcon } from '@chakra-ui/icons'; import { Tooltip } from '@chakra-ui/react'; import { useState } from "react"; -import { bgColour } from '../../constants/UIConstant'; -import { delay } from '../../helper/asyncHelper'; +import { IScreenshotDataProps } from '../../contracts/screenshotDataProps'; +import { addWatermarkToImage } from '../../helper/canvasHelper'; import { createImageFromSrcAsync, downloadFile } from '../../helper/fileHelper'; import { ObjInfoModal } from './objInfoModal'; @@ -10,7 +10,8 @@ interface IProps { creatureId: string; enableRotate: boolean; onRepeatClick: (enable: boolean) => void; - accessRenderer: () => any; + getScreenshotData: () => IScreenshotDataProps; + setHasLoaded: (hasLoaded: boolean) => void; } export const ObjViewerControls: React.FC = (props: IProps) => { @@ -43,54 +44,19 @@ export const ObjViewerControls: React.FC = (props: IProps) => { boxSize={iconSize} className="pointer" onClick={async () => { - const renderer = props.accessRenderer(); - renderer.setClearColor(bgColour, 0); - const loaderNode = document.querySelector('#obj-preview-loader'); - if (loaderNode) { - (loaderNode as any).style.zIndex = 4; - } - - const tempCanvas = document.createElement('canvas'); - const canvasWidth = renderer.domElement.width; - const canvasHeight = renderer.domElement.height; - tempCanvas.width = canvasWidth; - tempCanvas.height = canvasHeight; - - const tempCanvasCtx = tempCanvas.getContext('2d'); - if (tempCanvasCtx == null) return; - - const watermarkImgWidth = 150; - const watermarkImgHeight = 80; - const watermarkImgPadding = 10; - const watermarkImgFromDataStr = await createImageFromSrcAsync( - '/assets/img/watermark.png', - watermarkImgWidth, - watermarkImgHeight - ); + const screenshotData = props.getScreenshotData(); const imgFromDataStr = await createImageFromSrcAsync( - renderer.domElement.toDataURL(), - canvasWidth, - canvasHeight, - ); - - tempCanvasCtx.drawImage(imgFromDataStr, 0, 0); - tempCanvasCtx.drawImage( - watermarkImgFromDataStr, - canvasWidth - (watermarkImgWidth + watermarkImgPadding), - canvasHeight - watermarkImgHeight, - watermarkImgWidth, - watermarkImgHeight, + screenshotData.dataUrl, + screenshotData.width, + screenshotData.height, ); - await delay(250); + const finalImage = await addWatermarkToImage(imgFromDataStr, screenshotData); + if (finalImage == null) return; - const finalImage = tempCanvas.toDataURL(); downloadFile(finalImage, props.creatureId); - renderer.setClearColor(bgColour); - if (loaderNode) { - (loaderNode as any).style.zIndex = null; - } + props.setHasLoaded(true); }} /> diff --git a/src/components/objViewer/skyboxLoader.ts b/src/components/objViewer/skyboxLoader.ts new file mode 100644 index 0000000..5fd7978 --- /dev/null +++ b/src/components/objViewer/skyboxLoader.ts @@ -0,0 +1,18 @@ +import { BackSide, MeshBasicMaterial, TextureLoader } from "three"; + +interface ISkyBoxProps { + folderName: string; + fileType: string; +} + +export const createMaterialArray = (props: ISkyBoxProps) => { + const basePath = '/assets/img/skybox'; + const sides = ['ft', 'bk', 'up', 'dn', 'rt', 'lt']; + const materials = sides.map(side => { + const url = `${basePath}/${props.folderName}/${side}${(props.fileType ?? '.jpg')}`; + const texture = new TextureLoader().load(url); + return new MeshBasicMaterial({ map: texture, side: BackSide }); + }); + + return materials; +} \ No newline at end of file diff --git a/src/constants/contentCreatorCreatures.ts b/src/constants/contentCreatorCreatures.ts index bbdd74e..4ad2d35 100644 --- a/src/constants/contentCreatorCreatures.ts +++ b/src/constants/contentCreatorCreatures.ts @@ -15,7 +15,7 @@ export interface IContentCreatorCreatures { export const contentCreatorCreatures: Array = [ { - baseFolder: '/assets/creature/meogi-theworm', + baseFolder: './assets/creature/meogi-theworm', jsonPath: 'creature.json', creatureName: 'The worm 0', creator: 'MEOGI', @@ -30,7 +30,7 @@ export const contentCreatorCreatures: Array = [ }, }, { - baseFolder: '/assets/creature/meogi-theworm1', + baseFolder: './assets/creature/meogi-theworm1', jsonPath: 'creature.json', creatureName: 'The worm 1', creator: 'MEOGI', @@ -45,7 +45,7 @@ export const contentCreatorCreatures: Array = [ }, }, { - baseFolder: '/assets/creature/meogi-theworm2', + baseFolder: './assets/creature/meogi-theworm2', jsonPath: 'creature.json', creatureName: 'The worm 2', creator: 'MEOGI', diff --git a/src/constants/externalUrl.ts b/src/constants/externalUrl.ts index 8fe0467..f90f2e3 100644 --- a/src/constants/externalUrl.ts +++ b/src/constants/externalUrl.ts @@ -1,6 +1,6 @@ export const ExternalUrl = { nmsHubDiscord: 'https://discord.gg/5hrYrjtWQg', - meogiYT: 'https://www.youtube.com/c/MEOGI', + meogiYT: 'https://www.youtube.com/@Meogione', silent: 'https://www.youtube.com/channel/UC9G1Ds0NlZngSvhIaJDgLWQ', assistantNMS: 'https://nmsassistant.com', nmscd: 'https://nmscd.com', @@ -18,7 +18,7 @@ export const ExternalImages = { meogi: 'https://yt3.ggpht.com/GAZQndl844qHRyPW7vDwDJJos01TFx7i4OqKX-Qco293KN3q9YAB5QC2aCJ3XxSS-uSdIrYHVg=s88-c-k-c0x00ffffff-no-rj', nmsHub: 'https://cdn.discordapp.com/icons/780508359375454208/a_82923637ed4e1c4a1f7ac1b1c3aa4410.webp', monkeyMan: 'https://avatars.githubusercontent.com/u/8000597?v=4', - nmsdk: '/assets/img/nmsdk.png', + nmsdk: './assets/img/nmsdk.png', } diff --git a/src/contracts/generated/AssistantApps/.gitkeep b/src/contracts/generated/AssistantApps/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/contracts/generated/AssistantApps/Enum/oAuthProviderType.ts b/src/contracts/generated/AssistantApps/Enum/oAuthProviderType.ts deleted file mode 100644 index 44ced7c..0000000 --- a/src/contracts/generated/AssistantApps/Enum/oAuthProviderType.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* Auto Generated */ - -export enum OAuthProviderType { - unknown, - google, -} diff --git a/src/contracts/generated/AssistantApps/Enum/platformType.ts b/src/contracts/generated/AssistantApps/Enum/platformType.ts deleted file mode 100644 index 9a5bc44..0000000 --- a/src/contracts/generated/AssistantApps/Enum/platformType.ts +++ /dev/null @@ -1,7 +0,0 @@ -export enum PlatformType { - Android, - Apple, - Web, - API, - Windows, -} \ No newline at end of file diff --git a/src/contracts/generated/AssistantApps/ViewModel/.gitkeep b/src/contracts/generated/AssistantApps/ViewModel/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/src/contracts/generated/AssistantApps/ViewModel/Version/versionSearchViewModel.ts b/src/contracts/generated/AssistantApps/ViewModel/Version/versionSearchViewModel.ts deleted file mode 100644 index 66fb0f4..0000000 --- a/src/contracts/generated/AssistantApps/ViewModel/Version/versionSearchViewModel.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* Auto Generated */ - -export interface VersionSearchViewModel { - appGuid: any; - platforms: any[]; - languageCode: string; - page: number; -} diff --git a/src/contracts/generated/AssistantApps/ViewModel/Version/versionViewModel.ts b/src/contracts/generated/AssistantApps/ViewModel/Version/versionViewModel.ts deleted file mode 100644 index 3e20891..0000000 --- a/src/contracts/generated/AssistantApps/ViewModel/Version/versionViewModel.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* Auto Generated */ - -export interface VersionViewModel { - guid: any; - appGuid: any; - markdown: string; - buildName: string; - buildNumber: number; - platforms: any[]; - activeDate: Date; -} diff --git a/src/contracts/generated/AssistantApps/ViewModel/oAuthUserViewModel.ts b/src/contracts/generated/AssistantApps/ViewModel/oAuthUserViewModel.ts deleted file mode 100644 index a12c61b..0000000 --- a/src/contracts/generated/AssistantApps/ViewModel/oAuthUserViewModel.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* Auto Generated */ - -import { OAuthProviderType } from "./../Enum/oAuthProviderType"; - -export interface OAuthUserViewModel { - oAuthType: OAuthProviderType; - accessToken: string; - tokenId: string; - profileUrl: string; - username: string; - email: string; -} diff --git a/src/contracts/screenshotDataProps.ts b/src/contracts/screenshotDataProps.ts new file mode 100644 index 0000000..f00d1b1 --- /dev/null +++ b/src/contracts/screenshotDataProps.ts @@ -0,0 +1,5 @@ +export interface IScreenshotDataProps { + dataUrl: any; + width: number; + height: number; +} \ No newline at end of file diff --git a/src/helper/canvasHelper.ts b/src/helper/canvasHelper.ts new file mode 100644 index 0000000..1a79e79 --- /dev/null +++ b/src/helper/canvasHelper.ts @@ -0,0 +1,37 @@ +import { IScreenshotDataProps } from "../contracts/screenshotDataProps"; +import { delay } from "./asyncHelper"; +import { createImageFromSrcAsync } from "./fileHelper"; + +export const addWatermarkToImage = async ( + imgFromDataStr: any, + screenshotData: IScreenshotDataProps +) => { + const tempCanvas = document.createElement('canvas'); + tempCanvas.width = screenshotData.width; + tempCanvas.height = screenshotData.height; + + const tempCanvasCtx = tempCanvas.getContext('2d'); + if (tempCanvasCtx == null) return; + + const watermarkImgWidth = 150; + const watermarkImgHeight = 80; + const watermarkImgPadding = 10; + const watermarkImgFromDataStr = await createImageFromSrcAsync( + './assets/img/watermark.png', + watermarkImgWidth, + watermarkImgHeight + ); + + tempCanvasCtx.drawImage(imgFromDataStr, 0, 0); + tempCanvasCtx.drawImage( + watermarkImgFromDataStr, + screenshotData.width - (watermarkImgWidth + watermarkImgPadding), + screenshotData.height - watermarkImgHeight, + watermarkImgWidth, + watermarkImgHeight, + ); + + await delay(250); + + return tempCanvas.toDataURL(); +} \ No newline at end of file diff --git a/src/page/builder/builderPageResultPreview.tsx b/src/page/builder/builderPageResultPreview.tsx index 4d3b6b4..6c6a0ba 100644 --- a/src/page/builder/builderPageResultPreview.tsx +++ b/src/page/builder/builderPageResultPreview.tsx @@ -22,8 +22,12 @@ interface IBuilderPageResultPreviewProps { export const BuilderPageResultPreview: React.FC = (props: IBuilderPageResultPreviewProps) => { const { toastService } = useContext(DependencyInjectionContext); - const showPreview = props.settings.showModelPreview; - const showJsonPreview = props.settings.showJsonPreview; + const { + showModelPreview, + showJsonPreview, + showStats, + lowQualityMode, + } = props.settings; const json = props.getJsonFromMappings(props.mappingString + ',' + props.descriptorId); if (props.selectedPet.CreatureId == null) { @@ -79,20 +83,22 @@ export const BuilderPageResultPreview: React.FC return ( { - showPreview && ( + showModelPreview && ( diff --git a/src/page/builder/builderPageSettingsRow.tsx b/src/page/builder/builderPageSettingsRow.tsx index fc5a572..4698614 100644 --- a/src/page/builder/builderPageSettingsRow.tsx +++ b/src/page/builder/builderPageSettingsRow.tsx @@ -1,3 +1,4 @@ +import { SettingsIcon } from '@chakra-ui/icons'; import { Button, Spacer, Wrap, WrapItem } from '@chakra-ui/react'; import React, { useState } from 'react'; import { ContentCreatorCreaturesBottomModalSheet } from '../../components/dialog/contentCreatorCreaturesBottomModalSheet'; @@ -13,6 +14,8 @@ export interface IBuilderPageSettings { showJsonPreview: boolean; showModelPreview: boolean; showPetAccessory: boolean; + showStats: boolean; + lowQualityMode: boolean; } export const initialSettings: IBuilderPageSettings = { @@ -21,6 +24,8 @@ export const initialSettings: IBuilderPageSettings = { showJsonPreview: true, showModelPreview: true, showPetAccessory: false, + showStats: false, + lowQualityMode: false, } interface ISettingOption { @@ -42,8 +47,7 @@ interface IProps { export const BuilderPageSettingsRow: React.FC = (props: IProps) => { const [isJsonExplanationOpen, setJsonExplanationOpen] = useState(false); const [isContentCreatorModalOpen, setContentCreatorModalOpen] = useState(false); - const showSettings = true - // const [showSettings, setShowSettings] = useState(true); + const [showSettings, setShowSettings] = useState(false); const toggleJsonExplanation = (isOpen: boolean) => { toggleHtmlNodeClass('body', 'noscroll', isOpen); @@ -75,6 +79,15 @@ export const BuilderPageSettingsRow: React.FC = (props: IProps) => { width: '250px' } }, + { + id: 'advancedMode', + propName: 'advancedMode', + label: 'Enable Advanced Mode', + component: SettingSwitch, + }, + ]; + + const miscSettingOptions: Array = [ { id: 'showPetAccessory', propName: 'showPetAccessory', @@ -88,58 +101,80 @@ export const BuilderPageSettingsRow: React.FC = (props: IProps) => { } }, { - id: 'advancedMode', - propName: 'advancedMode', - label: 'Enable Advanced Mode', + id: 'lowQualityMode', + propName: 'lowQualityMode', + label: 'Reduce preview quality', component: SettingSwitch, + show: (current: IBuilderPageSettings) => ( + current.showModelPreview === true + ), + }, + { + id: 'showStats', + propName: 'showStats', + label: 'Show FPS', + component: SettingSwitch, + additionalProps: { + width: '170px' + } }, ]; + const renderSettingOption = (opt: ISettingOption) => { + const Comp = opt.component; + const value = (props.settings as any)?.[opt.propName]; + + const hideOpt = opt.show?.(props.settings) === false; + if (hideOpt) return null; + + return ( + + { + props.setSettings((prev: IBuilderPageSettings) => ({ + ...prev, + [opt.propName]: newValue, + })); + props.triggerJsonInterval(); + }} + /> + + ); + } + return ( <> - 0 ? '3' : ''} spacing={controlSpacing / 2}> + 0 ? '3' : ''} + spacing={controlSpacing / 2} + > - - {/* - - - - - */} { - (showSettings ? settingOptions : []).map((opt: ISettingOption) => { - const Comp = opt.component; - const value = (props.settings as any)?.[opt.propName]; - - const hideOpt = opt.show?.(props.settings) === false; - if (hideOpt) return null; - - return ( - - { - props.setSettings((prev: IBuilderPageSettings) => ({ - ...prev, - [opt.propName]: newValue, - })); - props.triggerJsonInterval(); - }} - /> - - ); - }) + (miscSettingOptions.filter(so => so.show?.(props.settings) === true).length > 0) && ( + + + + ) } + + 0 ? '3' : ''} spacing={controlSpacing / 2}> + {settingOptions.map(renderSettingOption)} {/* */} + { + showSettings && ( + 0 ? '3' : ''} spacing={controlSpacing / 2}> + {miscSettingOptions.map(renderSettingOption)} + + + ) + } >> { - const result = await this.post, VersionSearchViewModel>( - ApiUrls.versionSearch, search, - (response: any) => { - return { - ...response.data, - isSuccess: true, - errorMessage: '', - }; - }); + const result = await this._api.version.readAllHistory( + search.appGuid, + search.languageCode, + search.platforms, + search.page + ); return result as ResultWithValueAndPagination>; } getLatest(platforms: Array): Promise> { - let queryPath = ''; - for (const queryParam in platforms) { - if (queryParam == null || queryParam.length < 1) continue; - if (queryPath.length > 0) { - queryPath = queryPath + '&'; - } - queryPath = queryPath + '=' + queryParam; - } - const url = `${ApiUrls.appVersion}/${assistantAppsAppGuid}?${queryPath}`; - - return this.get(url); + // return this._api.version.readLatest(assistantAppsAppGuid, platforms); + return this._api.version.readLatest(assistantAppsAppGuid); } - async activateLicence(licenceKey: string): Promise> { - const url = `${ApiUrls.licenceActivate}/${assistantAppsAppGuid}/${licenceKey}`; - const apiResonse = await this.get(url); - if (apiResonse.isSuccess) return apiResonse; - - const errorList: Array = []; - const errProp = (apiResonse as any)?.excBody; - if (typeof errProp === 'object') { - const errorObj = errProp?.errors ?? {}; - for (const errProp in errorObj) { - if (Object.prototype.hasOwnProperty.call(errorObj, errProp)) { - const mesg = errorObj[errProp]; - errorList.push(mesg); - } - } - } else { - errorList.push(errProp ?? ''); - } - - return { ...apiResonse, errorMessage: errorList.join('. ') }; + activateLicence(licenceKey: string): Promise> { + return this._api.licence.activate(assistantAppsAppGuid, licenceKey); } - async activateLicenceForPatron(uniqueId: string): Promise> { - debugger; - const url = `${ApiUrls.licenceActivateForPatron}/${assistantAppsAppGuid}/${uniqueId}`; - const apiResonse = await this.get(url); - if (apiResonse.isSuccess) return apiResonse; - - const errorList: Array = []; - const errProp = (apiResonse as any)?.excBody; - if (typeof errProp === 'object') { - const errorObj = errProp?.errors ?? {}; - for (const errProp in errorObj) { - if (Object.prototype.hasOwnProperty.call(errorObj, errProp)) { - const mesg = errorObj[errProp]; - errorList.push(mesg); - } - } - } else { - errorList.push(errProp ?? ''); - } - - return { ...apiResonse, errorMessage: errorList.join('. ') }; + activateLicenceForPatron(uniqueId: string): Promise> { + return this._api.licence.activateForPatron(assistantAppsAppGuid, uniqueId); } verifyLicence(licenceHash: string): Promise { - const url = `${ApiUrls.licenceVerify}/${assistantAppsAppGuid}/${licenceHash}`; - return this.get(url); + return this._api.licence.verify(assistantAppsAppGuid, licenceHash); } // Auth @@ -107,18 +52,18 @@ export class AssistantAppsApiService extends BaseApiService { let userGuid = ''; let timeTillExpiry = 0; let expiryDate = new Date(); - const apiResult = await this.post(ApiUrls.authUrl, oAuthObj, (headers) => { - const token = headers.token; - timeTillExpiry = headers.tokenexpiry; - userGuid = headers.userguid; - - this.setInterceptors(token); - expiryDate = getExpiryDateUtc(timeTillExpiry); - - this._store.set(storageType.token, token, expiryDate); - this._store.set(storageType.userGuid, userGuid, expiryDate); - this._store.set(storageType.userName, oAuthObj.username, expiryDate); - }); + const apiResult = await this._api.account.loginWithGoogleAuth( + oAuthObj, + (userAcc: IUserLogin) => { + const token = userAcc.token; + expiryDate = userAcc.tokenExpiryDate; + userGuid = userAcc.userGuid; + + this._store.set(storageType.token, token, expiryDate); + this._store.set(storageType.userGuid, userGuid, expiryDate); + this._store.set(storageType.userName, oAuthObj.username, expiryDate); + } + ); const loginData: ILoginProps = { userGuid: userGuid, diff --git a/src/services/api/BaseApiService.ts b/src/services/api/BaseApiService.ts deleted file mode 100644 index dc9baa6..0000000 --- a/src/services/api/BaseApiService.ts +++ /dev/null @@ -1,53 +0,0 @@ -import axios from 'axios'; -import { ResultWithValue } from '../../contracts/results/ResultWithValue'; -import { anyObject } from '../../helper/typescriptHacks'; - -declare global { - interface Window { config: any } -} - -export class BaseApiService { - private _baseUrl: String = window.config?.apiUrl ?? 'https://assistantapps.com'; - constructor(newBaseUrl?: String) { - if (newBaseUrl != null) this._baseUrl = newBaseUrl; - } - protected async get(url: string): Promise> { - try { - const result = await axios.get(`${this._baseUrl}/${url}`); - return { - isSuccess: true, - value: result.data, - errorMessage: '' - } - } catch (ex) { - return { - isSuccess: false, - value: anyObject, - errorMessage: (ex as any).message, - excBody: (ex as any)?.response?.data, - } as any - } - } - - protected async post(url: string, data: TK, customMapper?: (data: any) => any): Promise> { - try { - const result = await axios.post(`${this._baseUrl}/${url}`, data); - if (customMapper != null) return customMapper(result); - return { - isSuccess: true, - value: result.data, - errorMessage: '' - } - } catch (ex) { - return { - isSuccess: false, - value: anyObject, - errorMessage: (ex as any).message - } - } - } - - setInterceptors = (token: string) => { - axios.defaults.headers.common['Authorization'] = 'Bearer ' + token; - }; -} diff --git a/webpack.config.js b/webpack.config.js index 9f8f492..6e50f20 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,7 +1,10 @@ +const fs = require('fs'); const path = require('path'); const HandlebarsPlugin = require("handlebars-webpack-plugin"); const moveFile = require('@npmcli/move-file'); +const dotenv = require('dotenv'); + const bundleFileName = 'bundle'; const dirName = 'public'; const distPath = path.resolve(__dirname, dirName); @@ -21,6 +24,12 @@ const moveNonHtmlHandlebarGeneratedFile = (filename, handlebarFilename, newName) } module.exports = (env, argv) => { + const projectData = fs.readFileSync(path.join(__dirname, "seo/data/project.json"), { encoding: 'utf8' }); + const localData = { + ...JSON.parse(projectData), + enableAnalytics: dotenv.config().parsed.REACT_APP_ENABLE_ANALYTICS == 'true' + }; + return { mode: argv.mode === "production" ? "production" : "development", entry: [ @@ -45,7 +54,7 @@ module.exports = (env, argv) => { // // data passed to main hbs template: `main-template(data)` // data: require("./webpack/data/project.json"), // or add it as filepath to rebuild data on change using webpack-dev-server - data: path.join(__dirname, "seo/data/project.json"), + data: localData, // globbed path to partials, where folder/filename is unique partials: [