From 3b085502a6ff846aedb82cd8d36834a34bce2399 Mon Sep 17 00:00:00 2001 From: Jam <1347620+JamsRepos@users.noreply.github.com> Date: Sat, 6 Apr 2024 21:02:13 +0100 Subject: [PATCH] =?UTF-8?q?refactor:=20=F0=9F=93=A6=20:zap:=20Remove=20mem?= =?UTF-8?q?bership=20and=20live=20chat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wizarr_backend/api/routes/__init__.py | 2 - .../api/routes/membership_api.py | 61 -- .../wizarr-frontend/src/api/authentication.ts | 27 - .../src/assets/configs/DefaultValues.ts | 2 - apps/wizarr-frontend/src/main.ts | 2 - .../components/Membership/Register.vue | 152 ----- .../src/modules/settings/pages/Main.vue | 18 - .../src/modules/settings/pages/Membership.vue | 150 ----- .../src/modules/settings/pages/Support.vue | 103 ---- .../src/modules/settings/router/children.ts | 15 - .../wizarr-frontend/src/plugins/easterEggs.ts | 156 ----- .../wizarr-frontend/src/plugins/rocketChat.ts | 16 - apps/wizarr-frontend/src/shims/widget.d.ts | 3 - apps/wizarr-frontend/src/stores/membership.ts | 0 apps/wizarr-frontend/src/stores/user.ts | 12 - .../src/ts/utils/rocketChat.ts | 532 ------------------ .../src/types/api/membership.ts | 9 - 17 files changed, 1260 deletions(-) delete mode 100644 apps/wizarr-backend/wizarr_backend/api/routes/membership_api.py delete mode 100644 apps/wizarr-frontend/src/modules/settings/components/Membership/Register.vue delete mode 100644 apps/wizarr-frontend/src/modules/settings/pages/Membership.vue delete mode 100644 apps/wizarr-frontend/src/modules/settings/pages/Support.vue delete mode 100644 apps/wizarr-frontend/src/plugins/easterEggs.ts delete mode 100644 apps/wizarr-frontend/src/plugins/rocketChat.ts delete mode 100644 apps/wizarr-frontend/src/shims/widget.d.ts delete mode 100644 apps/wizarr-frontend/src/stores/membership.ts delete mode 100644 apps/wizarr-frontend/src/ts/utils/rocketChat.ts delete mode 100644 apps/wizarr-frontend/src/types/api/membership.ts diff --git a/apps/wizarr-backend/wizarr_backend/api/routes/__init__.py b/apps/wizarr-backend/wizarr_backend/api/routes/__init__.py index b5d45a265..484fba110 100644 --- a/apps/wizarr-backend/wizarr_backend/api/routes/__init__.py +++ b/apps/wizarr-backend/wizarr_backend/api/routes/__init__.py @@ -32,7 +32,6 @@ from .jellyfin_api import api as jellyfin_api from .healthcheck_api import api as healthcheck_api from .server_api import api as server_api -from .membership_api import api as membership_api authorizations = { "jsonWebToken": { @@ -128,7 +127,6 @@ def handle_request_exception(error): api.add_namespace(users_api) api.add_namespace(utilities_api) api.add_namespace(webhooks_api) -api.add_namespace(membership_api) # Potentially remove this if it becomes unstable # api.add_namespace(live_notifications_api) diff --git a/apps/wizarr-backend/wizarr_backend/api/routes/membership_api.py b/apps/wizarr-backend/wizarr_backend/api/routes/membership_api.py deleted file mode 100644 index 4ef0d1d2a..000000000 --- a/apps/wizarr-backend/wizarr_backend/api/routes/membership_api.py +++ /dev/null @@ -1,61 +0,0 @@ -from flask import request -from flask_restx import Namespace, Resource -from flask_jwt_extended import jwt_required, current_user -from playhouse.shortcuts import model_to_dict -from json import loads, dumps - -from app.models.database.memberships import Memberships - -api = Namespace(name="Membership", description="Membership related operations", path="/membership") - -@api.route("/") -@api.route("") -class Membership(Resource): - """Membership related operations""" - - method_decorators = [jwt_required()] - - @api.doc(description="Get the membership status") - @api.response(200, "Successfully retrieved the membership status") - @api.response(500, "Internal server error") - def get(self): - """Get the membership status""" - # Get membership status where user_id is the current user - response = Memberships.get_or_none(Memberships.user_id == current_user["id"]) - - if not response: - return {"message": "No membership found"}, 404 - - return loads(dumps(model_to_dict(response), indent=4, sort_keys=True, default=str)), 200 - - - @api.doc(description="Set the membership status") - @api.response(200, "Successfully set the membership status") - @api.response(500, "Internal server error") - def post(self): - """Set the membership status""" - # Update the membership status if it exists - if Memberships.get_or_none(user_id=current_user["id"]): - response = Memberships.get_or_none(user_id=current_user["id"]) - response.token = request.json.get("token") - response.email = request.json.get("email") - response.save() - else: - response = Memberships.create(user_id=current_user["id"], email=request.json.get("email"), token=request.json.get("token")) - - return loads(dumps(model_to_dict(response), indent=4, sort_keys=True, default=str)), 200 - - - @api.doc(description="Delete the membership status") - @api.response(200, "Successfully deleted the membership status") - @api.response(500, "Internal server error") - def delete(self): - """Delete the membership status""" - # Delete the membership status if it exists - if Memberships.get_or_none(user_id=current_user["id"]): - response = Memberships.get_or_none(user_id=current_user["id"]) - response.delete_instance() - else: - return {"message": "No membership found"}, 404 - - return {"message": "Membership deleted"}, 200 diff --git a/apps/wizarr-frontend/src/api/authentication.ts b/apps/wizarr-frontend/src/api/authentication.ts index 07f8fbdfc..8d98c3351 100644 --- a/apps/wizarr-frontend/src/api/authentication.ts +++ b/apps/wizarr-frontend/src/api/authentication.ts @@ -2,7 +2,6 @@ import { errorToast, infoToast, successToast } from "../ts/utils/toasts"; import { startAuthentication, startRegistration } from "@simplewebauthn/browser"; import type { APIUser } from "@/types/api/auth/User"; -import type { Membership } from "@/types/api/membership"; import type { RegistrationResponseJSON } from "@simplewebauthn/typescript-types"; import type { WebAuthnError } from "@simplewebauthn/browser/dist/types/helpers/webAuthnError"; import { useAuthStore } from "@/stores/auth"; @@ -73,36 +72,10 @@ class Auth { authStore.setAccessToken(token); authStore.setRefreshToken(refresh_token); - // Handle membership update - const membership = await this.handleMembershipUpdate(); - userStore.setMembership(membership); - // Reset the user data return { user, token }; } - /** - * Handle Membership Update - * This function is used to handle membership updates - */ - async handleMembershipUpdate(): Promise { - // Get the membership from the database - const response = await this.axios - .get("/api/membership", { - disableErrorToast: true, - disableInfoToast: true, - }) - .catch(() => null); - - // Check if the response is successful - if (response?.status != 200) { - return null; - } - - // Get the membership from the response - return response.data; - } - /** * Get the current user * This method is used to get the current user diff --git a/apps/wizarr-frontend/src/assets/configs/DefaultValues.ts b/apps/wizarr-frontend/src/assets/configs/DefaultValues.ts index 92e1b95fa..7cc478425 100644 --- a/apps/wizarr-frontend/src/assets/configs/DefaultValues.ts +++ b/apps/wizarr-frontend/src/assets/configs/DefaultValues.ts @@ -1,6 +1,4 @@ export default { latest_info: "Welcome to Wizarr, you can always find the latest information about Wizarr here!", - membership_api: "https://api.wizarr.dev/membership", - livechat_api: "https://api.wizarr.dev/livechat", thank_you: "Thank you message has not been loaded from the remote configuration, please wait a few hours and try again.", }; diff --git a/apps/wizarr-frontend/src/main.ts b/apps/wizarr-frontend/src/main.ts index 5954fbdf3..8ea40d8ec 100644 --- a/apps/wizarr-frontend/src/main.ts +++ b/apps/wizarr-frontend/src/main.ts @@ -15,7 +15,6 @@ import FloatingVue from "floating-vue"; import Modal from "./plugins/modal"; import OpenLayersMap from "vue3-openlayers"; import ProgressOptions from "./assets/configs/DefaultProgress"; -import RocketChat from "./plugins/rocketChat"; import Sentry from "./plugins/sentry"; import ToastOptions from "./assets/configs/DefaultToasts"; import ToastPlugin from "vue-toastification"; @@ -61,7 +60,6 @@ app.use(Modal); app.use(WebShare); app.use(Firebase); app.use(Tours, { i18n: i18n }); -app.use(RocketChat); app.component("VueFeather", VueFeather); diff --git a/apps/wizarr-frontend/src/modules/settings/components/Membership/Register.vue b/apps/wizarr-frontend/src/modules/settings/components/Membership/Register.vue deleted file mode 100644 index 409fcf642..000000000 --- a/apps/wizarr-frontend/src/modules/settings/components/Membership/Register.vue +++ /dev/null @@ -1,152 +0,0 @@ - - - diff --git a/apps/wizarr-frontend/src/modules/settings/pages/Main.vue b/apps/wizarr-frontend/src/modules/settings/pages/Main.vue index 3fc0cdc40..0cda1244b 100644 --- a/apps/wizarr-frontend/src/modules/settings/pages/Main.vue +++ b/apps/wizarr-frontend/src/modules/settings/pages/Main.vue @@ -253,24 +253,6 @@ export default defineComponent({ }, ], }, - { - title: this.__("Members Only"), - description: this.__("These features are only available to paying members"), - pages: [ - { - title: this.__("Membership"), - description: this.__("View and manage your membership"), - icon: "fas fa-cloud", - url: "/admin/settings/membership", - }, - { - title: this.__("Live Support"), - description: this.__("Get live support from the server admins"), - icon: "fas fa-hands-helping", - url: "/admin/settings/support", - }, - ], - }, ], }; }, diff --git a/apps/wizarr-frontend/src/modules/settings/pages/Membership.vue b/apps/wizarr-frontend/src/modules/settings/pages/Membership.vue deleted file mode 100644 index 32810a6f1..000000000 --- a/apps/wizarr-frontend/src/modules/settings/pages/Membership.vue +++ /dev/null @@ -1,150 +0,0 @@ - - - diff --git a/apps/wizarr-frontend/src/modules/settings/pages/Support.vue b/apps/wizarr-frontend/src/modules/settings/pages/Support.vue deleted file mode 100644 index 8b63879c6..000000000 --- a/apps/wizarr-frontend/src/modules/settings/pages/Support.vue +++ /dev/null @@ -1,103 +0,0 @@ - - - diff --git a/apps/wizarr-frontend/src/modules/settings/router/children.ts b/apps/wizarr-frontend/src/modules/settings/router/children.ts index a80600883..bc0d2f0a7 100644 --- a/apps/wizarr-frontend/src/modules/settings/router/children.ts +++ b/apps/wizarr-frontend/src/modules/settings/router/children.ts @@ -103,21 +103,6 @@ const children: RouteRecordRaw[] = [ component: () => import("../pages/Sentry.vue"), meta: { header: "Bug Reporting", subheader: "Configure bug reporting" }, }, - { - path: "membership", - name: "admin-settings-membership", - component: () => import("../pages/Membership.vue"), - meta: { - header: "Membership", - subheader: "View Wizarr Cloud membership", - }, - }, - { - path: "support", - name: "admin-settings-support", - component: () => import("../pages/Support.vue"), - meta: { header: "Live Support", subheader: "Get live support" }, - }, ]; export default children; diff --git a/apps/wizarr-frontend/src/plugins/easterEggs.ts b/apps/wizarr-frontend/src/plugins/easterEggs.ts deleted file mode 100644 index 19d367224..000000000 --- a/apps/wizarr-frontend/src/plugins/easterEggs.ts +++ /dev/null @@ -1,156 +0,0 @@ -// Disable TypeScript check for this file -// @ts-nocheck - -const vuePluginEasterEggs = { - install: (app: App) => { - // Secret Thank You Modal - function _0x236d() { - function _0x37c3(_0xd7f0bb, _0x2d8166) { - const _0x338c07 = _0x338c(); - return ( - (_0x37c3 = function (_0x37c30d, _0x9fc42d) { - _0x37c30d = _0x37c30d - 0x67; - let _0x1dccdf = _0x338c07[_0x37c30d]; - return _0x1dccdf; - }), - _0x37c3(_0xd7f0bb, _0x2d8166) - ); - } - const _0x5584b9 = _0x37c3; - (function (_0x3943e1, _0x555293) { - const _0x3ae47c = _0x37c3, - _0x1bdedf = _0x3943e1(); - while (!![]) { - try { - const _0x165711 = -parseInt(_0x3ae47c(0x6e)) / 0x1 + parseInt(_0x3ae47c(0x72)) / 0x2 + (-parseInt(_0x3ae47c(0x68)) / 0x3) * (parseInt(_0x3ae47c(0x6a)) / 0x4) + (-parseInt(_0x3ae47c(0x6f)) / 0x5) * (parseInt(_0x3ae47c(0x74)) / 0x6) + -parseInt(_0x3ae47c(0x75)) / 0x7 + parseInt(_0x3ae47c(0x76)) / 0x8 + (parseInt(_0x3ae47c(0x6b)) / 0x9) * (parseInt(_0x3ae47c(0x6c)) / 0xa); - if (_0x165711 === _0x555293) break; - else _0x1bdedf["push"](_0x1bdedf["shift"]()); - } catch (_0x30745c) { - _0x1bdedf["push"](_0x1bdedf["shift"]()); - } - } - })(_0x338c, 0xab12d); - let spacebar = ![]; - window["addEventListener"](_0x5584b9(0x67), (_0x5bdb26) => { - const _0x14787c = _0x5584b9; - _0x5bdb26[_0x14787c(0x70)] === "Space" && - (spacebar - ? app[_0x14787c(0x6d)][_0x14787c(0x69)][_0x14787c(0x71)]["openModal"](app[_0x14787c(0x6d)][_0x14787c(0x69)]["$config"](_0x14787c(0x73)), { title: "Thank\x20You" }) - : ((spacebar = !![]), - setTimeout(() => { - spacebar = ![]; - }, 0x12c))); - }); - function _0x338c() { - const _0x583e15 = ["1179AZgvMQ", "283870BYWOMn", "config", "1367274ALBdOH", "20wQwnum", "code", "$modal", "174818AVBPtT", "thank_you", "1838466tfChtO", "1892884PWFccg", "7083168JANoZZ", "keydown", "15MzjTaC", "globalProperties", "901964aaoEGg"]; - _0x338c = function () { - return _0x583e15; - }; - return _0x338c(); - } - } - - // Secret Konami Code - function _0x41c5() { - function _0x39fb() { - const _0x21dce9 = ["3fPeQMp", "5700310Mrpprp", "shift", "35CAOihr", "_blank", "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "901480MKYshU", "ArrowDown", "ArrowUp", "4pStupS", "push", "154440uWTVil", "ArrowLeft", "stringify", "9aIGpmI", "174394mkAByB", "875565IhCDIK", "29364PnAhbv", "2054290jpFVQt", "length"]; - _0x39fb = function () { - return _0x21dce9; - }; - return _0x39fb(); - } - const _0x557cb7 = _0x258b; - (function (_0x29e878, _0x322589) { - const _0x3f073e = _0x258b, - _0x14a6cb = _0x29e878(); - while (!![]) { - try { - const _0x391153 = (parseInt(_0x3f073e(0x1dd)) / 0x1) * (-parseInt(_0x3f073e(0x1ec)) / 0x2) + (parseInt(_0x3f073e(0x1ed)) / 0x3) * (parseInt(_0x3f073e(0x1e6)) / 0x4) + -parseInt(_0x3f073e(0x1e8)) / 0x5 + (-parseInt(_0x3f073e(0x1ee)) / 0x6) * (parseInt(_0x3f073e(0x1e0)) / 0x7) + -parseInt(_0x3f073e(0x1e3)) / 0x8 + (parseInt(_0x3f073e(0x1eb)) / 0x9) * (-parseInt(_0x3f073e(0x1ef)) / 0xa) + parseInt(_0x3f073e(0x1de)) / 0xb; - if (_0x391153 === _0x322589) break; - else _0x14a6cb["push"](_0x14a6cb["shift"]()); - } catch (_0x35353d) { - _0x14a6cb["push"](_0x14a6cb["shift"]()); - } - } - })(_0x39fb, 0x2ab9a); - let keySequence = []; - const targetSequence = [_0x557cb7(0x1e5), _0x557cb7(0x1e4), _0x557cb7(0x1e9), "ArrowRight"]; - function checkKeySequence(_0x3dd1cd) { - const _0x345c6f = _0x557cb7; - keySequence[_0x345c6f(0x1e7)](_0x3dd1cd["key"]), keySequence[_0x345c6f(0x1dc)] > targetSequence[_0x345c6f(0x1dc)] && keySequence[_0x345c6f(0x1df)](), JSON[_0x345c6f(0x1ea)](keySequence) === JSON[_0x345c6f(0x1ea)](targetSequence) && (window["open"](_0x345c6f(0x1e2), _0x345c6f(0x1e1)), (keySequence = [])); - } - function _0x258b(_0x2bb2ec, _0x24c2de) { - const _0x39fb42 = _0x39fb(); - return ( - (_0x258b = function (_0x258b6a, _0x2945ea) { - _0x258b6a = _0x258b6a - 0x1dc; - let _0x4a92f6 = _0x39fb42[_0x258b6a]; - return _0x4a92f6; - }), - _0x258b(_0x2bb2ec, _0x24c2de) - ); - } - document["addEventListener"]("keydown", checkKeySequence); - } - - // Do a barrel roll - function _0x1c5c() { - const _0x4d0b66 = _0x5b59; - (function (_0x9150f, _0x36ae77) { - const _0x7d4938 = _0x5b59, - _0x4e8dad = _0x9150f(); - while (!![]) { - try { - const _0x6f2cfc = (parseInt(_0x7d4938(0xeb)) / 0x1) * (-parseInt(_0x7d4938(0xf8)) / 0x2) + (-parseInt(_0x7d4938(0xf5)) / 0x3) * (parseInt(_0x7d4938(0xf6)) / 0x4) + parseInt(_0x7d4938(0xfa)) / 0x5 + (parseInt(_0x7d4938(0xed)) / 0x6) * (parseInt(_0x7d4938(0xea)) / 0x7) + parseInt(_0x7d4938(0xf3)) / 0x8 + (parseInt(_0x7d4938(0xef)) / 0x9) * (parseInt(_0x7d4938(0xfc)) / 0xa) + (parseInt(_0x7d4938(0xf2)) / 0xb) * (-parseInt(_0x7d4938(0xe6)) / 0xc); - if (_0x6f2cfc === _0x36ae77) break; - else _0x4e8dad["push"](_0x4e8dad["shift"]()); - } catch (_0x3a22b4) { - _0x4e8dad["push"](_0x4e8dad["shift"]()); - } - } - })(_0x41c5, 0x91be3); - function _0x41c5() { - const _0x3377ed = ["shift", "transition", "1555498ZKsuZx", "1022491qhrcce", "key", "12bpscJO", "push", "9CQkVpp", "addEventListener", "style", "1794859BGGmcV", "9450952JWpDBO", "length", "30cJHGqO", "64888BPhwzg", "transform", "2HMLgcZ", "rotate(360deg)", "3833255aJUHNF", "stringify", "419020LdRrkl", "keydown", "48hvtLls", "transform\x202s\x20linear"]; - _0x41c5 = function () { - return _0x3377ed; - }; - return _0x41c5(); - } - let keySequence = []; - const targetSequence = ["r", "o", "l", "l"]; - function checkKeySequence(_0x2a1f18) { - const _0x236ea4 = _0x5b59; - keySequence[_0x236ea4(0xee)](_0x2a1f18[_0x236ea4(0xec)]); - keySequence[_0x236ea4(0xf4)] > targetSequence[_0x236ea4(0xf4)] && keySequence[_0x236ea4(0xe8)](); - if (JSON[_0x236ea4(0xfb)](keySequence) === JSON["stringify"](targetSequence)) { - const _0x14a3ff = document["documentElement"]; - (_0x14a3ff[_0x236ea4(0xf1)][_0x236ea4(0xe9)] = _0x236ea4(0xe7)), - (_0x14a3ff[_0x236ea4(0xf1)][_0x236ea4(0xf7)] = _0x236ea4(0xf9)), - setTimeout(() => { - const _0x6c400a = _0x236ea4; - (_0x14a3ff[_0x6c400a(0xf1)][_0x6c400a(0xe9)] = "none"), (_0x14a3ff[_0x6c400a(0xf1)]["transform"] = "none"); - }, 0x7d0), - (keySequence = []); - } - } - function _0x5b59(_0x3e9132, _0x27a597) { - const _0x41c558 = _0x41c5(); - return ( - (_0x5b59 = function (_0x5b5957, _0x1afc30) { - _0x5b5957 = _0x5b5957 - 0xe5; - let _0x588458 = _0x41c558[_0x5b5957]; - return _0x588458; - }), - _0x5b59(_0x3e9132, _0x27a597) - ); - } - document[_0x4d0b66(0xf0)](_0x4d0b66(0xe5), checkKeySequence); - } - - _0x236d(); - _0x41c5(); - _0x1c5c(); - }, -}; - -export default vuePluginEasterEggs; diff --git a/apps/wizarr-frontend/src/plugins/rocketChat.ts b/apps/wizarr-frontend/src/plugins/rocketChat.ts deleted file mode 100644 index 4e34b61f2..000000000 --- a/apps/wizarr-frontend/src/plugins/rocketChat.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { App } from 'vue'; -import RocketChat from '@/ts/utils/rocketChat'; - -declare module '@vue/runtime-core' { - interface ComponentCustomProperties { - $RocketChat: typeof RocketChat; - } -} - -const vuePluginRocketChat = { - install: (app: App) => { - app.config.globalProperties.$RocketChat = RocketChat; - }, -}; - -export default vuePluginRocketChat; diff --git a/apps/wizarr-frontend/src/shims/widget.d.ts b/apps/wizarr-frontend/src/shims/widget.d.ts deleted file mode 100644 index e6a05f52a..000000000 --- a/apps/wizarr-frontend/src/shims/widget.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module './widget.js' { - export function init(server: string): void; -} diff --git a/apps/wizarr-frontend/src/stores/membership.ts b/apps/wizarr-frontend/src/stores/membership.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/wizarr-frontend/src/stores/user.ts b/apps/wizarr-frontend/src/stores/user.ts index b4b586324..ba0cd2ff7 100644 --- a/apps/wizarr-frontend/src/stores/user.ts +++ b/apps/wizarr-frontend/src/stores/user.ts @@ -1,16 +1,13 @@ -import type { Membership } from '@/types/api/membership'; import type { APIUser as User } from '@/types/api/auth/User'; import { defineStore } from 'pinia'; interface UserStoreState { user: Partial | null; - membership: Membership | null; } export const useUserStore = defineStore('user', { state: (): UserStoreState => ({ user: null, - membership: null, }), getters: { getUser: (state) => { @@ -24,15 +21,6 @@ export const useUserStore = defineStore('user', { updateUser(user: Partial) { this.user = { ...this.user, ...user }; }, - setMembership(membership: Membership | null) { - this.membership = membership; - }, - updateMembership(membership: Partial) { - this.membership = { - ...this.membership, - ...membership, - } as Membership; - }, }, persist: true, }); diff --git a/apps/wizarr-frontend/src/ts/utils/rocketChat.ts b/apps/wizarr-frontend/src/ts/utils/rocketChat.ts deleted file mode 100644 index 045c1c777..000000000 --- a/apps/wizarr-frontend/src/ts/utils/rocketChat.ts +++ /dev/null @@ -1,532 +0,0 @@ -import mitt from 'mitt'; - -class RocketChat { - // Declare variables for the class - private widget: HTMLElement = document.createElement('div'); - private iframe: HTMLIFrameElement = document.createElement('iframe'); - private hookQueue: any[] = []; - private isReady = false; - private smallScreen = false; - private scrollPosition: number = 0; - private widget_height: number = 0; - private popup: Window | null = null; - - // Declare the current page - private currentPage = { - href: null as string | null, - title: null as string | null, - }; - - // Declare the valid callbacks - public validCallbacks = [ - 'chat-maximized', - 'chat-minimized', - 'chat-started', - 'chat-ended', - 'pre-chat-form-submit', - 'offline-form-submit', - 'show-widget', - 'hide-widget', - 'assign-agent', - 'agent-status-change', - 'queue-position-change', - 'no-agent-online', - ]; - - // Declare the mitt event emitter - private callbacks = mitt(); - - // Declare the Widget Size Constants - private WIDGET_OPEN_WIDTH = 365; - private WIDGET_OPEN_HEIGHT = 525; - private WIDGET_MINIMIZED_WIDTH = 54; - private WIDGET_MINIMIZED_HEIGHT = 54; - private WIDGET_MARGIN = 16; - - // Declare the config - private config = { - url: 'https://chat.wizarr.dev/livechat', - theme: { - title: 'Wizarr Support', - color: '#fc425d', - offlineTitle: 'Leave a message', - offlineColor: '#666666', - }, - }; - - constructor(url: string, config?: any) { - if (!url) throw new Error('Missing required parameter: url'); - - this.config.url = url; - - this.createWidget(url); - this.attachMessageListener(); - this.trackNavigation(); - - this.initialize({ config, ...this.config }); - } - - initialize(params: any) { - for (const method in params) { - if (!params.hasOwnProperty(method)) { - continue; - } - - this.log('WizarrChat: ', method, params[method]); - - switch (method) { - case 'customField': - const { key, value, overwrite } = params[method]; - this.setCustomField(key, value, overwrite); - continue; - case 'setCustomFields': - if (!Array.isArray(params[method])) { - console.log( - 'Error: Invalid parameters. Value must be an array of objects', - ); - continue; - } - params[method].forEach( - (data: { - key: string; - value: string; - overwrite: boolean; - }) => { - const { key, value, overwrite } = data; - this.setCustomField(key, value, overwrite); - }, - ); - continue; - case 'theme': - this.setTheme(params[method]); - continue; - case 'department': - this.setDepartment(params[method]); - continue; - case 'businessUnit': { - this.setBusinessUnit(params[method]); - continue; - } - case 'guestToken': - this.setGuestToken(params[method]); - continue; - case 'guestName': - this.setGuestName(params[method]); - continue; - case 'guestEmail': - this.setGuestEmail(params[method]); - continue; - case 'registerGuest': - this.registerGuest(params[method]); - continue; - case 'language': - this.setLanguage(params[method]); - continue; - case 'agent': - this.setAgent(params[method]); - continue; - default: - continue; - } - } - } - - log = - process.env.NODE_ENV === 'development' - ? (...args: any) => - window.console.log( - '%cwidget%c', - 'color: red', - 'color: initial', - ...args, - ) - : () => {}; - - createWidget(url: string) { - this.widget.className = 'rocketchat-widget'; - this.widget.style.position = 'fixed'; - this.widget.style.width = `${ - this.WIDGET_MARGIN + - this.WIDGET_MINIMIZED_WIDTH + - this.WIDGET_MARGIN - }px`; - this.widget.style.height = `${ - this.WIDGET_MARGIN + - this.WIDGET_MINIMIZED_HEIGHT + - this.WIDGET_MARGIN - }px`; - this.widget.style.maxHeight = '100vh'; - this.widget.style.bottom = '0'; - this.widget.style.right = '0'; - this.widget.style.zIndex = '12345'; - this.widget.dataset.state = 'closed'; - - const container = document.createElement('div'); - container.className = 'rocketchat-container'; - container.style.width = '100%'; - container.style.height = '100%'; - - this.iframe.id = 'rocketchat-iframe'; - this.iframe.src = url; - this.iframe.style.width = '100%'; - this.iframe.style.height = '100%'; - this.iframe.style.border = 'none'; - this.iframe.style.backgroundColor = 'transparent'; - - container.appendChild(this.iframe); - this.widget.appendChild(container); - document.body.appendChild(this.widget); - - const handleMediaQueryTest = (event: Partial) => { - if (!this.widget) return; - - this.smallScreen = event.matches ?? false; - this.updateWidgetStyle(this.widget.dataset.state === 'opened'); - this.callHook('setExpanded', this.smallScreen); - }; - - const mediaQueryList = window.matchMedia( - 'screen and (max-device-width: 480px)', - ); - mediaQueryList.addEventListener('change', handleMediaQueryTest); - handleMediaQueryTest(mediaQueryList); - } - - openWidget() { - if (this.widget.dataset.state === 'opened') return; - - this.widget_height = this.WIDGET_OPEN_HEIGHT; - this.updateWidgetStyle(true); - this.widget.dataset.state = 'opened'; - this.iframe.focus(); - this.emitCallback('chat-maximized'); - } - - resizeWidget(height: number) { - this.widget_height = height; - this.updateWidgetStyle(true); - this.widget.dataset.state = 'triggered'; - } - - closeWidget() { - if (this.widget.dataset.state === 'closed') { - return; - } - - this.updateWidgetStyle(false); - this.widget.dataset.state = 'closed'; - this.emitCallback('chat-minimized'); - } - - updateWidgetStyle(isOpened: boolean) { - if (this.smallScreen && isOpened) { - this.scrollPosition = document.documentElement.scrollTop; - document.body.classList.add('rc-livechat-mobile-full-screen'); - } else { - document.body.classList.remove('rc-livechat-mobile-full-screen'); - if (this.smallScreen) { - document.documentElement.scrollTop = this.scrollPosition; - } - } - - if (isOpened) { - this.widget.style.left = this.smallScreen ? '0' : 'auto'; - - /** - * If we use widget.style.height = smallScreen ? '100vh' : ... - * In above case some browser's viewport height is not rendered correctly - * so, as 100vh will resolve to 100% of the current viewport height, - * so fixed it to 100% avoiding problem for some browsers. Similar resolution - * for widget.style.width - */ - - this.widget.style.height = this.smallScreen - ? '100%' - : `${ - this.WIDGET_MARGIN + - this.widget_height + - this.WIDGET_MARGIN + - this.WIDGET_MINIMIZED_HEIGHT - }px`; - this.widget.style.width = this.smallScreen - ? '100%' - : `${ - this.WIDGET_MARGIN + - this.WIDGET_OPEN_WIDTH + - this.WIDGET_MARGIN - }px`; - } else { - this.widget.style.left = 'auto'; - this.widget.style.width = `${ - this.WIDGET_MARGIN + - this.WIDGET_MINIMIZED_WIDTH + - this.WIDGET_MARGIN - }px`; - this.widget.style.height = `${ - this.WIDGET_MARGIN + - this.WIDGET_MINIMIZED_HEIGHT + - this.WIDGET_MARGIN - }px`; - } - } - - ready() { - this.isReady = true; - if (this.hookQueue.length > 0) { - this.hookQueue.forEach((hookParams) => { - this.callHook.apply(this, hookParams); - }); - this.hookQueue = []; - } - } - - minimizeWindow() { - this.closeWidget(); - } - - restoreWindow() { - if (this.popup && this.popup.closed !== true) { - this.popup.close(); - this.popup = null; - } - this.openWidget(); - } - - openPopout() { - this.closeWidget(); - this.popup = window.open( - `${this.config.url}${ - this.config.url.lastIndexOf('?') > -1 ? '&' : '?' - }mode=popout`, - 'livechat-popout', - `width=${this.WIDGET_OPEN_WIDTH}, height=${this.widget_height}, toolbars=no`, - ); - this.popup!.focus(); - } - - removeWidget() { - document.body.removeChild(this.widget); - } - - callback(eventName: string, data?: any) { - this.emitCallback(eventName, data); - } - - showWidget() { - this.iframe.style.display = 'initial'; - this.emitCallback('show-widget'); - } - - hideWidget() { - this.iframe.style.display = 'none'; - this.emitCallback('hide-widget'); - } - - resetDocumentStyle() { - document.body.classList.remove('rc-livechat-mobile-full-screen'); - } - - setFullScreenDocumentMobile() { - this.smallScreen && - document.body.classList.add('rc-livechat-mobile-full-screen'); - } - - attachMessageListener() { - window.addEventListener( - 'message', - (msg) => { - if ( - typeof msg.data === 'object' && - msg.data.src !== undefined && - msg.data.src === 'rocketchat' - ) { - // @ts-ignore - if ( - this[msg.data.fn] !== undefined && - typeof this[msg.data.fn] === 'function' - ) { - const args = [].concat(msg.data.args || []); - this.log(`api.${msg.data.fn}`, ...args); - // @ts-ignore - this[msg.data.fn].apply(this, args); - } - } - }, - false, - ); - } - - trackNavigation() { - setInterval(() => { - if (document.location.href !== this.currentPage.href) { - this.pageVisited('url'); - this.currentPage.href = document.location.href; - } - - if (document.title !== this.currentPage.title) { - this.pageVisited('title'); - this.currentPage.title = document.title; - } - }, 800); - } - - registerCallback(eventName: string, fn: (data: any) => void) { - if (this.validCallbacks.indexOf(eventName) === -1) { - return false; - } - - return this.callbacks.on(eventName, fn); - } - - emitCallback(eventName: string, data?: any) { - if (typeof data !== 'undefined') { - this.callbacks.emit(eventName, data); - } else { - this.callbacks.emit(eventName); - } - } - - callHook(action: string, params?: any) { - if (!this.isReady) return this.hookQueue.push([action, params]); - - const data = { - src: 'rocketchat', - fn: action, - args: params, - }; - - if (!this.iframe) console.error('Iframe not found'); - if (!this.iframe.contentWindow) - console.error('Iframe content window not found'); - - if (!this.iframe?.contentWindow) return; - - this.iframe.contentWindow.postMessage(data, this.config.url); - } - - pageVisited(change: string) { - this.callHook('pageVisited', { - change, - location: JSON.parse(JSON.stringify(document.location)), - title: document.title, - }); - } - - setCustomField(key: string, value: string, overwrite: boolean) { - if (typeof overwrite === 'undefined') { - overwrite = true; - } - this.callHook('setCustomField', [key, value, overwrite]); - } - - setTheme(theme: string) { - this.callHook('setTheme', theme); - } - - setDepartment(department: string) { - this.callHook('setDepartment', department); - } - - setBusinessUnit(businessUnit: string) { - this.callHook('setBusinessUnit', businessUnit); - } - - clearBusinessUnit() { - this.callHook('clearBusinessUnit'); - } - - setGuestToken(token: string) { - this.callHook('setGuestToken', token); - } - - setGuestName(name: string) { - this.callHook('setGuestName', name); - } - - setGuestEmail(email: string) { - this.callHook('setGuestEmail', email); - } - - registerGuest(guest: string) { - this.callHook('registerGuest', guest); - } - - clearDepartment() { - this.callHook('clearDepartment'); - } - - setAgent(agent: string) { - this.callHook('setAgent', agent); - } - - setLanguage(language: string) { - this.callHook('setLanguage', language); - } - - showWidgets() { - this.callHook('showWidget'); - } - - hideWidgets() { - this.callHook('hideWidget'); - } - - maximizeWidget() { - this.callHook('maximizeWidget'); - } - - minimizeWidget() { - this.callHook('minimizeWidget'); - } - - // Callbacks - onChatMaximized(fn: (data: any) => void) { - this.registerCallback('chat-maximized', fn); - } - - onChatMinimized(fn: (data: any) => void) { - this.registerCallback('chat-minimized', fn); - } - - onChatStarted(fn: (data: any) => void) { - this.registerCallback('chat-started', fn); - } - - onChatEnded(fn: (data: any) => void) { - this.registerCallback('chat-ended', fn); - } - - onPrechatFormSubmit(fn: (data: any) => void) { - this.registerCallback('pre-chat-form-submit', fn); - } - - onOfflineFormSubmit(fn: (data: any) => void) { - this.registerCallback('offline-form-submit', fn); - } - - onWidgetShown(fn: (data: any) => void) { - this.registerCallback('show-widget', fn); - } - - onWidgetHidden(fn: (data: any) => void) { - this.registerCallback('hide-widget', fn); - } - - onAssignAgent(fn: (data: any) => void) { - this.registerCallback('assign-agent', fn); - } - - onAgentStatusChange(fn: (data: any) => void) { - this.registerCallback('agent-status-change', fn); - } - - onQueuePositionChange(fn: (data: any) => void) { - this.registerCallback('queue-position-change', fn); - } - - onServiceOffline(fn: (data: any) => void) { - this.registerCallback('no-agent-online', fn); - } -} - -export default RocketChat; diff --git a/apps/wizarr-frontend/src/types/api/membership.ts b/apps/wizarr-frontend/src/types/api/membership.ts deleted file mode 100644 index 3b66fd5cb..000000000 --- a/apps/wizarr-frontend/src/types/api/membership.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Generated by https://quicktype.io - -export interface Membership { - created: string; - id: number; - token: string; - email: string; - user_id: number; -}