Browse Source

chore(devx): Add 'eslint' to suite.

jackyalcine 2 months ago
parent
commit
4daa8a4efd
Signed by: Jacky Alciné <yo@jacky.wtf> GPG Key ID: 537A4F904B15268D
11 changed files with 1162 additions and 410 deletions
  1. 23
    0
      .eslintrc.js
  2. 0
    11
      config/dev.exs
  3. 0
    1
      mix.exs
  4. 938
    199
      package-lock.json
  5. 14
    5
      package.json
  6. 0
    7
      tslint.json
  7. 56
    56
      web/static/js/internal.ts
  8. 9
    9
      web/static/js/lib/qrcode.ts
  9. 6
    6
      web/static/js/page.ts
  10. 22
    22
      web/static/js/settings.ts
  11. 94
    94
      web/static/js/setup.ts

+ 23
- 0
.eslintrc.js View File

@@ -0,0 +1,23 @@
1
+module.exports = {
2
+  env: {
3
+    browser: true,
4
+    es6: true
5
+  },
6
+  extends: [
7
+    'standard'
8
+  ],
9
+  globals: {
10
+    Atomics: 'readonly',
11
+    SharedArrayBuffer: 'readonly'
12
+  },
13
+  parser: '@typescript-eslint/parser',
14
+  parserOptions: {
15
+    ecmaVersion: 2018,
16
+    sourceType: 'module'
17
+  },
18
+  plugins: [
19
+    '@typescript-eslint'
20
+  ],
21
+  rules: {
22
+  }
23
+}

+ 0
- 11
config/dev.exs View File

@@ -25,14 +25,3 @@ config :koype, Koype.Web.Endpoint,
25 25
 config :logger, level: :debug
26 26
 
27 27
 config :phoenix, :stacktrace_depth, 50
28
-
29
-config :git_hooks,
30
-  verbose: true,
31
-  hooks: [
32
-    pre_commit: [
33
-      mix_tasks: [
34
-        "format",
35
-        "inch --no-protected --only-undocumented --pedantic"
36
-      ]
37
-    ]
38
-  ]

+ 0
- 1
mix.exs View File

@@ -107,7 +107,6 @@ defmodule Koype.Mixfile do
107 107
       {:floki, "~> 0.20.0", override: true},
108 108
       {:furlex, "~> 0.3.0"},
109 109
       {:gettext, "~> 0.11"},
110
-      {:git_hooks, "~> 0.2.0", only: :dev},
111 110
       {:guardian, "~> 1.0"},
112 111
       {:guardian_db, "~> 1.0"},
113 112
       {:hackney, "~> 1.9"},

+ 938
- 199
package-lock.json
File diff suppressed because it is too large
View File


+ 14
- 5
package.json View File

@@ -13,6 +13,11 @@
13 13
     "type": "git",
14 14
     "url": "git@git.jacky.wtf:indieweb/koype.git"
15 15
   },
16
+  "husky": {
17
+    "hooks": {
18
+      "pre-commit": "mix format && mix inch --no-protected"
19
+    }
20
+  },
16 21
   "author": "Jacky Alciné <yo@jacky.wtf> (https://jacky.wtf/)",
17 22
   "license": "AGPL-3.0-only",
18 23
   "dependencies": {
@@ -69,7 +74,15 @@
69 74
     "@types/stylelint": "9.10.0",
70 75
     "@types/voca": "1.4.0",
71 76
     "@types/webfontloader": "1.6.28",
77
+    "@typescript-eslint/eslint-plugin": "2.3.0",
78
+    "@typescript-eslint/parser": "2.3.0",
72 79
     "axios-mock-adapter": "1.15.0",
80
+    "eslint": "6.4.0",
81
+    "eslint-config-standard": "14.1.0",
82
+    "eslint-plugin-import": "2.18.2",
83
+    "eslint-plugin-node": "10.0.0",
84
+    "eslint-plugin-promise": "4.2.1",
85
+    "eslint-plugin-standard": "4.0.1",
73 86
     "husky": "1.3.1",
74 87
     "jest": "24.1.0",
75 88
     "log-with-style": "0.3.0",
@@ -77,10 +90,6 @@
77 90
     "prettier": "1.15.3",
78 91
     "stylelint": "9.9.0",
79 92
     "stylelint-config-recommended-scss": "3.2.0",
80
-    "stylelint-scss": "3.4.0",
81
-    "ts-jest": "23.10.5",
82
-    "tslint": "5.11.0",
83
-    "tslint-config-prettier": "1.17.0",
84
-    "tslint-immutable": "5.0.0"
93
+    "stylelint-scss": "3.4.0"
85 94
   }
86 95
 }

+ 0
- 7
tslint.json View File

@@ -1,7 +0,0 @@
1
-{
2
-  "extends": [
3
-    "tslint:latest",
4
-    "tslint-config-prettier",
5
-    "tslint-immutable"
6
-  ]
7
-}

+ 56
- 56
web/static/js/internal.ts View File

@@ -22,96 +22,96 @@
22 22
  * @todo Remove leaflet from here.
23 23
  */
24 24
 
25
-import * as Feather from "feather-icons";
26
-import * as Ladda from "ladda";
27
-import timeago from "timeago.js";
28
-import * as WebFont from "webfontloader";
29
-
30
-function buildHiddenInput(name: string, value: string): HTMLInputElement {
31
-  const input = document.createElement("input");
32
-  input.type = "hidden";
33
-  input.name = name;
34
-  input.value = value;
35
-  return input;
25
+import * as Feather from 'feather-icons'
26
+import * as Ladda from 'ladda'
27
+import timeago from 'timeago.js'
28
+import * as WebFont from 'webfontloader'
29
+
30
+function buildHiddenInput (name: string, value: string): HTMLInputElement {
31
+  const input = document.createElement('input')
32
+  input.type = 'hidden'
33
+  input.name = name
34
+  input.value = value
35
+  return input
36 36
 }
37 37
 
38
-function handleLinkClick(link: Element) {
39
-  const message = link.getAttribute("data-confirm");
38
+function handleLinkClick (link: Element) {
39
+  const message = link.getAttribute('data-confirm')
40 40
 
41 41
   if (message && !confirm(message)) {
42
-    return;
42
+    return
43 43
   }
44 44
 
45
-  const to = link.getAttribute("data-to") as string;
46
-  const method = buildHiddenInput("_method", link.getAttribute("data-method")!);
47
-  const csrf = buildHiddenInput("_csrf_token", link.getAttribute("data-csrf")!);
48
-  const form = document.createElement("form") as HTMLFormElement;
45
+  const to = link.getAttribute('data-to') as string
46
+  const method = buildHiddenInput('_method', link.getAttribute('data-method')!)
47
+  const csrf = buildHiddenInput('_csrf_token', link.getAttribute('data-csrf')!)
48
+  const form = document.createElement('form') as HTMLFormElement
49 49
 
50
-  form.method = "post";
51
-  form.action = to;
52
-  form.style.display = "hidden";
50
+  form.method = 'post'
51
+  form.action = to
52
+  form.style.display = 'hidden'
53 53
 
54
-  form.appendChild(csrf);
55
-  form.appendChild(method);
56
-  document.body.appendChild(form);
57
-  form.submit();
54
+  form.appendChild(csrf)
55
+  form.appendChild(method)
56
+  document.body.appendChild(form)
57
+  form.submit()
58 58
 }
59 59
 
60
-function pageLoad() {
61
-  loadFonts();
60
+function pageLoad () {
61
+  loadFonts()
62 62
   const timeAgoElems = document.querySelectorAll(
63
-    "[datetime]:not([data-timeago-skip])"
64
-  );
65
-  timeago().render(timeAgoElems);
63
+    '[datetime]:not([data-timeago-skip])'
64
+  )
65
+  timeago().render(timeAgoElems)
66 66
 
67 67
   const formatDateElems = document.querySelectorAll(
68
-    "[datetime][data-date-format]"
69
-  );
68
+    '[datetime][data-date-format]'
69
+  )
70 70
   formatDateElems.forEach((elem: Element) => {
71
-    const htmlElem = elem as HTMLElement;
72
-    htmlElem.classList.add("o-10");
73
-    htmlElem.classList.add("glow");
71
+    const htmlElem = elem as HTMLElement
72
+    htmlElem.classList.add('o-10')
73
+    htmlElem.classList.add('glow')
74 74
 
75 75
     setTimeout(() => {
76
-      htmlElem.classList.remove("o-10");
76
+      htmlElem.classList.remove('o-10')
77 77
       htmlElem.innerText = new Date(
78 78
         Date.parse(htmlElem.innerText)
79
-      ).toLocaleString();
80
-    }, 750);
81
-  });
79
+      ).toLocaleString()
80
+    }, 750)
81
+  })
82 82
 
83
-  Ladda.bind("button[type=submit]");
84
-  Ladda.bind("a[data-method]");
83
+  Ladda.bind('button[type=submit]')
84
+  Ladda.bind('a[data-method]')
85 85
 
86
-  const images = document.querySelectorAll("img");
86
+  const images = document.querySelectorAll('img')
87 87
   images.forEach(image => {
88
-    image.addEventListener("error", () => {
89
-      image.classList.add("o-0");
90
-    });
91
-  });
88
+    image.addEventListener('error', () => {
89
+      image.classList.add('o-0')
90
+    })
91
+  })
92 92
 }
93 93
 
94
-function loadFonts() {
94
+function loadFonts () {
95 95
   WebFont.load({
96 96
     custom: {
97
-      families: ["Alegreya Sans", "Source Code Pro", "Alegreya"],
98
-      urls: ["/~/core/assets/fonts.css"]
97
+      families: ['Alegreya Sans', 'Source Code Pro', 'Alegreya'],
98
+      urls: ['/~/core/assets/fonts.css']
99 99
     }
100
-  });
100
+  })
101 101
 
102
-  Feather.replace();
102
+  Feather.replace()
103 103
 }
104 104
 
105 105
 window.addEventListener(
106
-  "load",
106
+  'load',
107 107
   () => {
108
-    pageLoad();
108
+    pageLoad()
109 109
     try {
110 110
     } catch (e) {
111
-      return;
111
+
112 112
     }
113 113
   },
114 114
   false
115
-);
115
+)
116 116
 
117
-window.Ladda = Ladda;
117
+window.Ladda = Ladda

+ 9
- 9
web/static/js/lib/qrcode.ts View File

@@ -20,23 +20,23 @@
20 20
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 21
  */
22 22
 
23
-import QArt from "qartjs";
23
+import QArt from 'qartjs'
24 24
 
25
-export default function renderQRCode(
25
+export default function renderQRCode (
26 26
   containerElem: HTMLElement,
27 27
   data: string,
28 28
   imagePath: string = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"/>'
29 29
 ) {
30 30
   const qartInstance = new QArt({
31
-    filter: "color",
31
+    filter: 'color',
32 32
     imagePath,
33
-    size: "256",
33
+    size: '256',
34 34
     value: data
35
-  });
35
+  })
36 36
 
37
-  qartInstance.make(containerElem);
37
+  qartInstance.make(containerElem)
38 38
   const canvas: HTMLCanvasElement = containerElem.querySelector(
39
-    "canvas"
40
-  ) as HTMLCanvasElement;
41
-  canvas.classList.add("center ma0");
39
+    'canvas'
40
+  ) as HTMLCanvasElement
41
+  canvas.classList.add('center ma0')
42 42
 }

+ 6
- 6
web/static/js/page.ts View File

@@ -22,17 +22,17 @@
22 22
  * @todo Remove leaflet from here.
23 23
  */
24 24
 
25
-import { Socket } from "phoenix";
26
-import * as PhoenixHTML from "phoenix_html";
25
+import { Socket } from 'phoenix'
26
+import * as PhoenixHTML from 'phoenix_html'
27 27
 
28 28
 window.addEventListener(
29
-  "load",
29
+  'load',
30 30
   () => {
31 31
     try {
32
-      PhoenixHTML();
32
+      PhoenixHTML()
33 33
     } catch (e) {
34
-      return;
34
+
35 35
     }
36 36
   },
37 37
   false
38
-);
38
+)

+ 22
- 22
web/static/js/settings.ts View File

@@ -20,39 +20,39 @@
20 20
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 21
  */
22 22
 
23
-import renderQRCode from './lib/qrcode';
23
+import renderQRCode from './lib/qrcode'
24 24
 
25
-window.addEventListener("load", function startSettingsPage() {
26
-  const componentElem: HTMLInputElement = document.querySelector("input[name=component]");
27
-  switch (componentElem.getAttribute("value")) {
28
-    case "endpoints": setupEndpointPage();
29
-    case "totp": renderQrCode();
25
+window.addEventListener('load', function startSettingsPage () {
26
+  const componentElem: HTMLInputElement = document.querySelector('input[name=component]')
27
+  switch (componentElem.getAttribute('value')) {
28
+    case 'endpoints': setupEndpointPage()
29
+    case 'totp': renderQrCode()
30 30
   }
31 31
 
32
-  function renderQrCode() {
33
-    renderQRCode(document.querySelector("#qrCode"), document.querySelector("#totpSecret").getAttribute("value"));
32
+  function renderQrCode () {
33
+    renderQRCode(document.querySelector('#qrCode'), document.querySelector('#totpSecret').getAttribute('value'))
34 34
   }
35 35
 
36
-  function setupEndpointPage() {
37
-    function setUpToggle(checkBoxSelector, inputSelector) {
38
-      const checkbox: HTMLInputElement = document.querySelector(checkBoxSelector);
36
+  function setupEndpointPage () {
37
+    function setUpToggle (checkBoxSelector, inputSelector) {
38
+      const checkbox: HTMLInputElement = document.querySelector(checkBoxSelector)
39 39
 
40
-      checkbox.addEventListener("change", () => {
41
-        const inputElem = document.querySelector(inputSelector);
42
-        inputElem.toggleAttribute("readonly", checkbox.checked);
43
-        inputElem.toggleAttribute("disabled", checkbox.checked);
44
-      });
40
+      checkbox.addEventListener('change', () => {
41
+        const inputElem = document.querySelector(inputSelector)
42
+        inputElem.toggleAttribute('readonly', checkbox.checked)
43
+        inputElem.toggleAttribute('disabled', checkbox.checked)
44
+      })
45 45
     }
46 46
 
47 47
     const toggleFields = [
48 48
       {
49 49
         checkbox: "input[name='inbuilt[indieauth.auth]']",
50
-        elem: "input#endpoint-indieauth-auth"
50
+        elem: 'input#endpoint-indieauth-auth'
51 51
       }
52
-    ];
52
+    ]
53 53
 
54 54
     toggleFields.forEach((field) => {
55
-      setUpToggle(field.checkbox, field.elem);
56
-    });
57
- }
58
-});
55
+      setUpToggle(field.checkbox, field.elem)
56
+    })
57
+  }
58
+})

+ 94
- 94
web/static/js/setup.ts View File

@@ -20,162 +20,162 @@
20 20
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 21
  */
22 22
 
23
-import Quill from "quill";
24
-import { slugify, snakeCase } from "voca";
25
-import renderQRCode from "./lib/qrcode";
23
+import Quill from 'quill'
24
+import { slugify, snakeCase } from 'voca'
25
+import renderQRCode from './lib/qrcode'
26 26
 
27
-const placeHolderText = `Koype is a self-hostable IndieWeb engine for everyone.`;
27
+const placeHolderText = 'Koype is a self-hostable IndieWeb engine for everyone.'
28 28
 
29
-function usernameify(str: string): string {
30
-  return snakeCase(str);
29
+function usernameify (str: string): string {
30
+  return snakeCase(str)
31 31
 }
32 32
 
33
-function preferNickname(): boolean {
33
+function preferNickname (): boolean {
34 34
   const preferredElem: HTMLInputElement = document.querySelector(
35
-    "input[name=prefer_nickname]"
36
-  )! as HTMLInputElement;
37
-  return preferredElem.checked;
35
+    'input[name=prefer_nickname]'
36
+  )! as HTMLInputElement
37
+  return preferredElem.checked
38 38
 }
39 39
 
40
-function configureNoteEditor(): void {
40
+function configureNoteEditor (): void {
41 41
   const editorElem: HTMLTextAreaElement = document.querySelector(
42
-    "textarea[name=note]"
43
-  ) as HTMLTextAreaElement;
42
+    'textarea[name=note]'
43
+  ) as HTMLTextAreaElement
44 44
   const notePreview: HTMLTextAreaElement = document.querySelector(
45
-    "#note"
46
-  ) as HTMLTextAreaElement;
45
+    '#note'
46
+  ) as HTMLTextAreaElement
47 47
   const quillOptions: QuillOptionsStatic = {
48 48
     modules: {
49 49
       toolbar: {
50
-        container: [["bold", "italic", "underline", "strike"]]
50
+        container: [['bold', 'italic', 'underline', 'strike']]
51 51
       }
52 52
     },
53
-    placeholder: "Tell me about yourself.",
53
+    placeholder: 'Tell me about yourself.',
54 54
     readOnly: false,
55
-    theme: "bubble"
56
-  };
57
-  const editor: Quill = new Quill("#noteEditor", quillOptions);
55
+    theme: 'bubble'
56
+  }
57
+  const editor: Quill = new Quill('#noteEditor', quillOptions)
58 58
 
59
-  editor.on("text-change", delta => {
60
-    const editorText = editor.getText() as string;
59
+  editor.on('text-change', delta => {
60
+    const editorText = editor.getText() as string
61 61
 
62
-    if (editorText !== "") {
63
-      notePreview.innerHTML = editorText;
64
-      editorElem.innerText = editorText;
62
+    if (editorText !== '') {
63
+      notePreview.innerHTML = editorText
64
+      editorElem.innerText = editorText
65 65
     } else {
66
-      notePreview.textContent = placeHolderText;
67
-      editorElem.innerText = "";
66
+      notePreview.textContent = placeHolderText
67
+      editorElem.innerText = ''
68 68
     }
69
-  });
69
+  })
70 70
 }
71 71
 
72
-function configureNameFields(): void {
72
+function configureNameFields (): void {
73 73
   const nameElem: HTMLInputElement = document.querySelector(
74
-    "input[name=name]"
75
-  ) as HTMLInputElement;
74
+    'input[name=name]'
75
+  ) as HTMLInputElement
76 76
   const nicknameElem: HTMLInputElement = document.querySelector(
77
-    "input[name=nickname]"
78
-  ) as HTMLInputElement;
77
+    'input[name=nickname]'
78
+  ) as HTMLInputElement
79 79
   const preferredElem: HTMLHeadingElement = document.querySelector(
80
-    "#preferredName"
81
-  ) as HTMLHeadingElement;
80
+    '#preferredName'
81
+  ) as HTMLHeadingElement
82 82
 
83
-  nameElem.addEventListener("keyup", e => {
83
+  nameElem.addEventListener('keyup', e => {
84 84
     if (!preferNickname()) {
85
-      preferredElem.textContent = nameElem.value;
86
-      nicknameElem.value = usernameify(nameElem.value);
85
+      preferredElem.textContent = nameElem.value
86
+      nicknameElem.value = usernameify(nameElem.value)
87 87
     }
88 88
 
89
-    if (nicknameElem.value === "") {
90
-      nicknameElem.value = usernameify(nameElem.value);
89
+    if (nicknameElem.value === '') {
90
+      nicknameElem.value = usernameify(nameElem.value)
91 91
     }
92 92
 
93
-    updateDid();
94
-  });
93
+    updateDid()
94
+  })
95 95
 
96
-  nicknameElem.addEventListener("keyup", e => {
97
-    nicknameElem.value = usernameify(nicknameElem.value);
96
+  nicknameElem.addEventListener('keyup', e => {
97
+    nicknameElem.value = usernameify(nicknameElem.value)
98 98
 
99 99
     if (preferNickname()) {
100
-      preferredElem.textContent = nicknameElem.value;
100
+      preferredElem.textContent = nicknameElem.value
101 101
     }
102 102
 
103
-    updateDid();
104
-  });
103
+    updateDid()
104
+  })
105 105
 }
106 106
 
107
-function updateDid(): void {
107
+function updateDid (): void {
108 108
   const didElem: HTMLSpanElement = document.querySelector(
109
-    "#did"
110
-  ) as HTMLSpanElement;
109
+    '#did'
110
+  ) as HTMLSpanElement
111 111
   const nicknameElem: HTMLInputElement = document.querySelector(
112
-    "input[name=nickname]"
113
-  ) as HTMLInputElement;
112
+    'input[name=nickname]'
113
+  ) as HTMLInputElement
114 114
 
115
-  didElem.textContent = nicknameElem.value;
115
+  didElem.textContent = nicknameElem.value
116 116
 }
117 117
 
118
-function configureNamePreferenceToggle(): void {
118
+function configureNamePreferenceToggle (): void {
119 119
   const preferredChoiceElem: HTMLInputElement = document.querySelector(
120
-    "input[name=prefer_nickname]"
121
-  ) as HTMLInputElement;
120
+    'input[name=prefer_nickname]'
121
+  ) as HTMLInputElement
122 122
 
123
-  preferredChoiceElem.addEventListener("change", () => {
123
+  preferredChoiceElem.addEventListener('change', () => {
124 124
     if (!preferredChoiceElem.checked) {
125 125
       const nameElem: HTMLInputElement = document.querySelector(
126
-        "input[name=name]"
127
-      ) as HTMLInputElement;
126
+        'input[name=name]'
127
+      ) as HTMLInputElement
128 128
       const nicknameElem: HTMLInputElement = document.querySelector(
129
-        "input[name=nickname]"
130
-      ) as HTMLInputElement;
129
+        'input[name=nickname]'
130
+      ) as HTMLInputElement
131 131
 
132
-      nicknameElem.value = usernameify(nameElem.value);
132
+      nicknameElem.value = usernameify(nameElem.value)
133 133
     }
134 134
 
135
-    updateDid();
136
-  });
135
+    updateDid()
136
+  })
137 137
 }
138 138
 
139
-function renderTotpQrCode(
140
-  imagePath: string = "/~/core/images/default-avatar.png"
139
+function renderTotpQrCode (
140
+  imagePath: string = '/~/core/images/default-avatar.png'
141 141
 ) {
142 142
   const qrTotpUriElem: HTMLInputElement = document.querySelector(
143
-    "#totpUri"
144
-  ) as HTMLInputElement;
145
-  const value: string = qrTotpUriElem.value;
146
-  renderQRCode(document.querySelector("#qrCode"), value, imagePath);
143
+    '#totpUri'
144
+  ) as HTMLInputElement
145
+  const value: string = qrTotpUriElem.value
146
+  renderQRCode(document.querySelector('#qrCode'), value, imagePath)
147 147
 }
148 148
 
149
-function configureAvatarRendering(): void {
149
+function configureAvatarRendering (): void {
150 150
   const avatarInputElem: HTMLInputElement = document.querySelector(
151
-    "input[name=photo]"
152
-  ) as HTMLInputElement;
151
+    'input[name=photo]'
152
+  ) as HTMLInputElement
153 153
   const avatarRenderer: HTMLImageElement = document.querySelector(
154
-    "img#profileImage"
155
-  ) as HTMLImageElement;
154
+    'img#profileImage'
155
+  ) as HTMLImageElement
156 156
 
157
-  avatarInputElem.addEventListener("change", () => {
157
+  avatarInputElem.addEventListener('change', () => {
158 158
     if (avatarInputElem.files!.length !== 0) {
159
-      const file = avatarInputElem.files!.item(0) as File;
160
-      const fileReader = new FileReader();
161
-      fileReader.readAsDataURL(file);
162
-      fileReader.addEventListener("load", () => {
163
-        const result = fileReader.result as string;
164
-        avatarRenderer.src = result;
165
-      });
159
+      const file = avatarInputElem.files!.item(0) as File
160
+      const fileReader = new FileReader()
161
+      fileReader.readAsDataURL(file)
162
+      fileReader.addEventListener('load', () => {
163
+        const result = fileReader.result as string
164
+        avatarRenderer.src = result
165
+      })
166 166
     } else {
167
-      avatarRenderer.src = "/~/core/images/default-avatar.png";
167
+      avatarRenderer.src = '/~/core/images/default-avatar.png'
168 168
     }
169
-  });
169
+  })
170 170
 }
171 171
 
172
-window.addEventListener("load", function startSetupPage() {
173
-  if (document.querySelector("#regionId")) {
174
-    configureNameFields();
175
-    configureNamePreferenceToggle();
176
-    configureNoteEditor();
177
-    configureAvatarRendering();
178
-  } else if (document.querySelector("#regionAuth")) {
179
-    renderTotpQrCode();
172
+window.addEventListener('load', function startSetupPage () {
173
+  if (document.querySelector('#regionId')) {
174
+    configureNameFields()
175
+    configureNamePreferenceToggle()
176
+    configureNoteEditor()
177
+    configureAvatarRendering()
178
+  } else if (document.querySelector('#regionAuth')) {
179
+    renderTotpQrCode()
180 180
   }
181
-});
181
+})

Loading…
Cancel
Save