underpost 3.2.4 → 3.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.cd.yml +1 -2
- package/CHANGELOG.md +268 -1
- package/CLI-HELP.md +26 -13
- package/Dockerfile +0 -4
- package/README.md +3 -3
- package/bin/build.js +13 -3
- package/bin/deploy.js +570 -1
- package/bin/file.js +5 -0
- package/conf.js +11 -2
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +2 -3
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +2 -3
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +136 -66
- package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
- package/package.json +20 -11
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.service.js +36 -36
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +3 -20
- package/src/cli/deploy.js +33 -30
- package/src/cli/fs.js +62 -5
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +5 -1
- package/src/cli/release.js +58 -2
- package/src/cli/repository.js +35 -3
- package/src/cli/run.js +304 -38
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/client/Default.index.js +21 -33
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +1 -1
- package/src/client/components/core/Auth.js +20 -32
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +42 -63
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +60 -59
- package/src/client/components/core/DropDown.js +69 -91
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +102 -234
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +25 -18
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +41 -41
- package/src/client/components/core/LogOut.js +23 -14
- package/src/client/components/core/Modal.js +397 -176
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -50
- package/src/client/components/core/PanelForm.js +25 -125
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +52 -48
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +31 -2
- package/src/client/components/core/SocketIoHandler.js +6 -6
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Worker.js +140 -25
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +6 -4
- package/src/client/components/default/LogOutDefault.js +6 -4
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/services/core/core.service.js +17 -49
- package/src/client/services/default/default.management.js +139 -242
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +79 -0
- package/src/client/services/user/user.management.js +5 -5
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/index.js +1 -1
- package/src/runtime/express/Dockerfile +4 -4
- package/src/runtime/lampp/Dockerfile +8 -7
- package/src/runtime/wp/Dockerfile +11 -17
- package/src/server/backup.js +1 -2
- package/src/server/client-build-docs.js +45 -46
- package/src/server/client-build.js +334 -60
- package/src/server/client-formatted.js +47 -16
- package/src/server/conf.js +29 -13
- package/src/server/cron.js +6 -8
- package/src/server/dns.js +2 -1
- package/src/server/ipfs-client.js +232 -91
- package/src/server/process.js +13 -27
- package/src/server/start.js +6 -3
- package/src/server/valkey.js +134 -235
- package/tsconfig.docs.json +15 -0
- package/typedoc.json +20 -0
- package/jsdoc.json +0 -52
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
|
@@ -7,17 +7,18 @@ import { Modal } from './Modal.js';
|
|
|
7
7
|
import { getId } from './CommonJs.js';
|
|
8
8
|
import { setPath, getProxyPath, getQueryParams, extractUsernameFromPath, RouterEvents } from './Router.js';
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
Data
|
|
12
|
-
|
|
10
|
+
class PublicProfile {
|
|
11
|
+
static Data = {};
|
|
12
|
+
/** @type {string|null} Track the currently displayed username for back/forward navigation */
|
|
13
|
+
static currentUsername = null;
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
static async Update(options = { idModal: '', user: {} }) {
|
|
15
16
|
const { idModal, user } = options;
|
|
16
17
|
const username = user.username || 'Unknown User';
|
|
17
18
|
|
|
18
19
|
// Check if modal exists and is registered in Modal.Data
|
|
19
20
|
if (!Modal.Data[idModal]) {
|
|
20
|
-
return await this.
|
|
21
|
+
return await this.instance(options);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
try {
|
|
@@ -35,7 +36,7 @@ const PublicProfile = {
|
|
|
35
36
|
this._cleanupProfileData({ idModal });
|
|
36
37
|
|
|
37
38
|
// Re-render the profile content with new user
|
|
38
|
-
const newContent = await this.
|
|
39
|
+
const newContent = await this.instance({ ...options, disableUpdate: true });
|
|
39
40
|
|
|
40
41
|
// Update modal content using Modal.writeHTML with smooth transition
|
|
41
42
|
Modal.writeHTML({ idModal, html: newContent });
|
|
@@ -54,9 +55,9 @@ const PublicProfile = {
|
|
|
54
55
|
|
|
55
56
|
throw error;
|
|
56
57
|
}
|
|
57
|
-
}
|
|
58
|
+
}
|
|
58
59
|
|
|
59
|
-
_getLoadingHtml
|
|
60
|
+
static _getLoadingHtml(username) {
|
|
60
61
|
return html`
|
|
61
62
|
<div class="profile-loading-container">
|
|
62
63
|
<div class="profile-loading-spinner"></div>
|
|
@@ -94,9 +95,9 @@ const PublicProfile = {
|
|
|
94
95
|
</style>
|
|
95
96
|
</div>
|
|
96
97
|
`;
|
|
97
|
-
}
|
|
98
|
+
}
|
|
98
99
|
|
|
99
|
-
_addTransitionEffect
|
|
100
|
+
static _addTransitionEffect(idModal) {
|
|
100
101
|
// Add smooth transition effect to modal content
|
|
101
102
|
const modalContent = s(`.html-${idModal}`);
|
|
102
103
|
if (modalContent) {
|
|
@@ -108,9 +109,9 @@ const PublicProfile = {
|
|
|
108
109
|
modalContent.style.opacity = '1';
|
|
109
110
|
}, 50);
|
|
110
111
|
}
|
|
111
|
-
}
|
|
112
|
+
}
|
|
112
113
|
|
|
113
|
-
_getErrorHtml
|
|
114
|
+
static _getErrorHtml(username, errorMessage) {
|
|
114
115
|
return html`
|
|
115
116
|
<div class="profile-error-container">
|
|
116
117
|
<div class="profile-error-icon">
|
|
@@ -169,24 +170,27 @@ const PublicProfile = {
|
|
|
169
170
|
</style>
|
|
170
171
|
</div>
|
|
171
172
|
`;
|
|
172
|
-
}
|
|
173
|
+
}
|
|
173
174
|
|
|
174
|
-
_cleanupProfileData
|
|
175
|
+
static _cleanupProfileData({ idModal }) {
|
|
175
176
|
delete ThemeEvents[`error-state-${idModal}`];
|
|
176
177
|
delete ThemeEvents[`profile-${idModal}`];
|
|
177
178
|
delete this.Data[idModal];
|
|
178
|
-
}
|
|
179
|
+
}
|
|
179
180
|
|
|
180
|
-
_ensureModalState
|
|
181
|
+
static _ensureModalState(idModal) {
|
|
181
182
|
// Ensure modal is in the correct state for content updates
|
|
182
183
|
if (Modal.Data[idModal]) {
|
|
183
184
|
// Reset any modal-specific states that might interfere
|
|
184
185
|
Modal.Data[idModal].updated = true;
|
|
185
186
|
Modal.Data[idModal].lastUpdated = Date.now();
|
|
186
187
|
}
|
|
187
|
-
}
|
|
188
|
+
}
|
|
188
189
|
|
|
189
|
-
|
|
190
|
+
/**
|
|
191
|
+
* @param {{ idModal?: string, user: { _id?: string, username?: string } }} options
|
|
192
|
+
*/
|
|
193
|
+
static async instance(
|
|
190
194
|
options = {
|
|
191
195
|
idModal: '',
|
|
192
196
|
user: {},
|
|
@@ -436,7 +440,7 @@ const PublicProfile = {
|
|
|
436
440
|
onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='0 4px 12px ${colors.buttonShadow}';"
|
|
437
441
|
>
|
|
438
442
|
<i class="fa-solid fa-home"></i>
|
|
439
|
-
${Translate.
|
|
443
|
+
${Translate.instance('go-home')}
|
|
440
444
|
</a>
|
|
441
445
|
<a
|
|
442
446
|
href="javascript:history.back()"
|
|
@@ -459,7 +463,7 @@ const PublicProfile = {
|
|
|
459
463
|
onmouseout="this.style.background='transparent'; this.style.borderColor='${colors.primaryColor}40';"
|
|
460
464
|
>
|
|
461
465
|
<i class="fa-solid fa-arrow-left"></i>
|
|
462
|
-
${Translate.
|
|
466
|
+
${Translate.instance('go-back')}
|
|
463
467
|
</a>
|
|
464
468
|
</div>
|
|
465
469
|
</div>
|
|
@@ -468,7 +472,7 @@ const PublicProfile = {
|
|
|
468
472
|
|
|
469
473
|
if (!userId && !username) {
|
|
470
474
|
return renderErrorState(
|
|
471
|
-
Translate.
|
|
475
|
+
Translate.instance('user-not-found'),
|
|
472
476
|
'fa-user-slash',
|
|
473
477
|
"The user you're looking for could not be found. Please check the username and try again.",
|
|
474
478
|
);
|
|
@@ -503,13 +507,13 @@ const PublicProfile = {
|
|
|
503
507
|
} else {
|
|
504
508
|
if (result.message && result.message.toLowerCase().match('private'))
|
|
505
509
|
return renderErrorState(
|
|
506
|
-
Translate.
|
|
510
|
+
Translate.instance('profile-is-private'),
|
|
507
511
|
'fa-lock',
|
|
508
512
|
'This user has chosen to keep their profile private. Respect their privacy and check back later if they change their settings.',
|
|
509
513
|
);
|
|
510
514
|
else
|
|
511
515
|
return renderErrorState(
|
|
512
|
-
Translate.
|
|
516
|
+
Translate.instance('user-not-found'),
|
|
513
517
|
'fa-user-slash',
|
|
514
518
|
'This user profile does not exist or has been removed. Please verify the username.',
|
|
515
519
|
);
|
|
@@ -517,7 +521,7 @@ const PublicProfile = {
|
|
|
517
521
|
} catch (error) {
|
|
518
522
|
console.error('Error fetching public profile:', error);
|
|
519
523
|
return renderErrorState(
|
|
520
|
-
Translate.
|
|
524
|
+
Translate.instance('error-loading-profile'),
|
|
521
525
|
'fa-circle-exclamation',
|
|
522
526
|
'We encountered an issue loading this profile. Please try again in a moment or contact support if the problem persists.',
|
|
523
527
|
);
|
|
@@ -526,7 +530,7 @@ const PublicProfile = {
|
|
|
526
530
|
// If user doesn't have public profile enabled
|
|
527
531
|
if (!userData.publicProfile) {
|
|
528
532
|
return renderErrorState(
|
|
529
|
-
Translate.
|
|
533
|
+
Translate.instance('profile-is-private'),
|
|
530
534
|
'fa-lock',
|
|
531
535
|
'This user has chosen to keep their profile private. Respect their privacy and check back later if they change their settings.',
|
|
532
536
|
);
|
|
@@ -765,7 +769,7 @@ const PublicProfile = {
|
|
|
765
769
|
transition: color 0.3s ease-in-out;
|
|
766
770
|
"
|
|
767
771
|
>
|
|
768
|
-
${Translate.
|
|
772
|
+
${Translate.instance('no-description')}
|
|
769
773
|
</p>`}
|
|
770
774
|
</div>
|
|
771
775
|
|
|
@@ -792,7 +796,7 @@ const PublicProfile = {
|
|
|
792
796
|
"
|
|
793
797
|
>
|
|
794
798
|
<i class="fa-solid fa-calendar" style="margin-right: 6px;"></i>
|
|
795
|
-
${Translate.
|
|
799
|
+
${Translate.instance('member-since')}: ${new Date(userData.createdAt).toLocaleDateString()}
|
|
796
800
|
</span>
|
|
797
801
|
</div>
|
|
798
802
|
|
|
@@ -817,7 +821,7 @@ const PublicProfile = {
|
|
|
817
821
|
<a
|
|
818
822
|
class="${profileId}-button"
|
|
819
823
|
href="javascript:void(0)"
|
|
820
|
-
title="${Translate.
|
|
824
|
+
title="${Translate.instance('view-profile')}"
|
|
821
825
|
style="
|
|
822
826
|
display: inline-flex;
|
|
823
827
|
align-items: center;
|
|
@@ -850,9 +854,12 @@ const PublicProfile = {
|
|
|
850
854
|
</div>
|
|
851
855
|
</div>
|
|
852
856
|
`;
|
|
853
|
-
}
|
|
857
|
+
}
|
|
854
858
|
|
|
855
|
-
|
|
859
|
+
/**
|
|
860
|
+
* @param {{ idModal?: string }} options
|
|
861
|
+
*/
|
|
862
|
+
static async Router(options = { idModal: '' }) {
|
|
856
863
|
const idModal = options.idModal || 'modal-public-profile';
|
|
857
864
|
// Register RouterEvents listener for back/forward navigation between profiles
|
|
858
865
|
// This ensures the profile updates when the user navigates through browser history
|
|
@@ -882,7 +889,7 @@ const PublicProfile = {
|
|
|
882
889
|
}
|
|
883
890
|
}
|
|
884
891
|
};
|
|
885
|
-
}
|
|
886
|
-
}
|
|
892
|
+
}
|
|
893
|
+
}
|
|
887
894
|
|
|
888
895
|
export { PublicProfile };
|
|
@@ -8,13 +8,25 @@ import { Translate } from './Translate.js';
|
|
|
8
8
|
import { Validator } from './Validator.js';
|
|
9
9
|
import { s } from './VanillaJs.js';
|
|
10
10
|
import { getProxyPath, getQueryParams } from './Router.js';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Event
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
import { RecoverEventType, recoverEvents } from './ClientEvents.js';
|
|
12
|
+
class Recover {
|
|
13
|
+
static Event = {};
|
|
14
|
+
static onTriggered(listener, options = {}) {
|
|
15
|
+
if (options.key) Recover.Event[options.key] = listener;
|
|
16
|
+
return recoverEvents.on(RecoverEventType.triggered, listener, options);
|
|
17
|
+
}
|
|
18
|
+
static offTriggered(key) {
|
|
19
|
+
delete Recover.Event[key];
|
|
20
|
+
return recoverEvents.off(key);
|
|
21
|
+
}
|
|
22
|
+
static hasTriggeredListener(key) {
|
|
23
|
+
return recoverEvents.has(key);
|
|
24
|
+
}
|
|
25
|
+
static async Trigger(options) {
|
|
26
|
+
await recoverEvents.emit(RecoverEventType.triggered, options);
|
|
27
|
+
for (const eventKey of Object.keys(Recover.Event)) await Recover.Event[eventKey](options);
|
|
28
|
+
}
|
|
29
|
+
static async instance(options = { idModal: '', user: {}, bottomRender: async () => '' }) {
|
|
18
30
|
const { idModal, user } = options;
|
|
19
31
|
let mode = 'recover-verify-email';
|
|
20
32
|
const recoverToken = getQueryParams().payload;
|
|
@@ -25,7 +37,7 @@ const Recover = {
|
|
|
25
37
|
rules: [{ type: 'isEmpty' }, { type: 'isLength', options: { min: 2, max: 20 } }],
|
|
26
38
|
show: () => false,
|
|
27
39
|
disable: function () {
|
|
28
|
-
return !
|
|
40
|
+
return !Recover.show();
|
|
29
41
|
},
|
|
30
42
|
},
|
|
31
43
|
'recover-email': {
|
|
@@ -34,7 +46,7 @@ const Recover = {
|
|
|
34
46
|
rules: [{ type: 'isEmpty' }, { type: 'isEmail' }],
|
|
35
47
|
show: () => mode === 'recover-verify-email',
|
|
36
48
|
disable: function () {
|
|
37
|
-
return !
|
|
49
|
+
return !Recover.show();
|
|
38
50
|
},
|
|
39
51
|
},
|
|
40
52
|
'recover-password': {
|
|
@@ -43,7 +55,7 @@ const Recover = {
|
|
|
43
55
|
rules: [{ type: 'isStrongPassword' }],
|
|
44
56
|
show: () => mode === 'change-password',
|
|
45
57
|
disable: function () {
|
|
46
|
-
return !
|
|
58
|
+
return !Recover.show();
|
|
47
59
|
},
|
|
48
60
|
},
|
|
49
61
|
'recover-repeat-password': {
|
|
@@ -51,23 +63,19 @@ const Recover = {
|
|
|
51
63
|
rules: [{ type: 'isEmpty' }, { type: 'passwordMismatch', options: `recover-password` }],
|
|
52
64
|
show: () => mode === 'change-password',
|
|
53
65
|
disable: function () {
|
|
54
|
-
return !
|
|
66
|
+
return !Recover.show();
|
|
55
67
|
},
|
|
56
68
|
},
|
|
57
69
|
};
|
|
58
|
-
|
|
59
70
|
if (recoverToken) {
|
|
60
71
|
mode = 'change-password';
|
|
61
72
|
}
|
|
62
|
-
|
|
63
73
|
setTimeout(async () => {
|
|
64
74
|
if (user && user.email) {
|
|
65
75
|
s(`.recover-email`).value = user.role === 'guest' ? '' : user.email;
|
|
66
76
|
if (user.emailConfirmed) s(`.recover-email`).setAttribute('disabled', '');
|
|
67
77
|
}
|
|
68
|
-
|
|
69
78
|
const validators = await Validator.instance(formData);
|
|
70
|
-
|
|
71
79
|
EventsUI.onClick(`.btn-recover`, async (e) => {
|
|
72
80
|
e.preventDefault();
|
|
73
81
|
s(`.recover-resend-btn-container`).classList.add('hide');
|
|
@@ -86,7 +94,9 @@ const Recover = {
|
|
|
86
94
|
});
|
|
87
95
|
NotificationManager.Push({
|
|
88
96
|
html:
|
|
89
|
-
result.status === 'error'
|
|
97
|
+
result.status === 'error'
|
|
98
|
+
? result.message
|
|
99
|
+
: Translate.instance(`${result.status}-recover-verify-email`),
|
|
90
100
|
status: result.status,
|
|
91
101
|
});
|
|
92
102
|
if (result.status === 'success') {
|
|
@@ -99,7 +109,7 @@ const Recover = {
|
|
|
99
109
|
const result = await UserService.put({ id: `recover/${recoverToken}`, body });
|
|
100
110
|
NotificationManager.Push({
|
|
101
111
|
html:
|
|
102
|
-
typeof result.data === 'string' ? result.data : Translate.
|
|
112
|
+
typeof result.data === 'string' ? result.data : Translate.instance(`${result.status}-recover-password`),
|
|
103
113
|
status: result.status,
|
|
104
114
|
});
|
|
105
115
|
if (result.status === 'success') {
|
|
@@ -112,7 +122,7 @@ const Recover = {
|
|
|
112
122
|
s(`.input-container-recover-repeat-password`).classList.add('hide');
|
|
113
123
|
s(`.btn-recover-log-in`).classList.remove('hide');
|
|
114
124
|
}
|
|
115
|
-
|
|
125
|
+
Recover.Trigger({ user: result.data });
|
|
116
126
|
}
|
|
117
127
|
break;
|
|
118
128
|
}
|
|
@@ -128,80 +138,74 @@ const Recover = {
|
|
|
128
138
|
};
|
|
129
139
|
});
|
|
130
140
|
return html`
|
|
131
|
-
${await BtnIcon.
|
|
141
|
+
${await BtnIcon.instance({
|
|
132
142
|
class: 'in section-mp form-button btn-recover-log-in hide',
|
|
133
|
-
label: Translate.
|
|
143
|
+
label: Translate.instance('log-in'),
|
|
134
144
|
type: 'button',
|
|
135
145
|
})}
|
|
136
146
|
<form class="in">
|
|
137
147
|
<div class="in">
|
|
138
|
-
${await Input.
|
|
148
|
+
${await Input.instance({
|
|
139
149
|
id: `recover-username`,
|
|
140
150
|
type: 'text',
|
|
141
|
-
label: html`<i class="fa-solid fa-pen-to-square"></i> ${Translate.
|
|
142
|
-
containerClass: `inl section-mp width-mini-box input-container ${
|
|
143
|
-
formData[`recover-username`].show() ? '' : 'hide'
|
|
144
|
-
}`,
|
|
151
|
+
label: html`<i class="fa-solid fa-pen-to-square"></i> ${Translate.instance('username')}`,
|
|
152
|
+
containerClass: `inl section-mp width-mini-box input-container ${formData[`recover-username`].show() ? '' : 'hide'}`,
|
|
145
153
|
placeholder: true,
|
|
146
154
|
})}
|
|
147
155
|
</div>
|
|
148
156
|
<div class="in">
|
|
149
|
-
${await Input.
|
|
157
|
+
${await Input.instance({
|
|
150
158
|
id: `recover-email`,
|
|
151
159
|
type: 'email',
|
|
152
|
-
label: html`<i class="fa-solid fa-envelope"></i> ${Translate.
|
|
153
|
-
containerClass: `inl section-mp width-mini-box input-container ${
|
|
154
|
-
formData[`recover-email`].show() ? '' : 'hide'
|
|
155
|
-
}`,
|
|
160
|
+
label: html`<i class="fa-solid fa-envelope"></i> ${Translate.instance('email')}`,
|
|
161
|
+
containerClass: `inl section-mp width-mini-box input-container ${formData[`recover-email`].show() ? '' : 'hide'}`,
|
|
156
162
|
placeholder: true,
|
|
157
163
|
autocomplete: 'email',
|
|
158
164
|
})}
|
|
159
165
|
</div>
|
|
160
166
|
<div class="in">
|
|
161
|
-
${await Input.
|
|
167
|
+
${await Input.instance({
|
|
162
168
|
id: `recover-password`,
|
|
163
169
|
type: 'password',
|
|
164
170
|
autocomplete: 'new-password',
|
|
165
|
-
label: html`<i class="fa-solid fa-lock"></i> ${Translate.
|
|
166
|
-
containerClass: `inl section-mp width-mini-box input-container ${
|
|
167
|
-
formData[`recover-password`].show() ? '' : 'hide'
|
|
168
|
-
}`,
|
|
171
|
+
label: html`<i class="fa-solid fa-lock"></i> ${Translate.instance('password')}`,
|
|
172
|
+
containerClass: `inl section-mp width-mini-box input-container ${formData[`recover-password`].show() ? '' : 'hide'}`,
|
|
169
173
|
placeholder: true,
|
|
170
174
|
})}
|
|
171
175
|
</div>
|
|
172
176
|
<div class="in">
|
|
173
|
-
${await Input.
|
|
177
|
+
${await Input.instance({
|
|
174
178
|
id: `recover-repeat-password`,
|
|
175
179
|
type: 'password',
|
|
176
180
|
autocomplete: 'new-password',
|
|
177
|
-
label: html`<i class="fa-solid fa-lock"></i> ${Translate.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}`,
|
|
181
|
+
label: html`<i class="fa-solid fa-lock"></i> ${Translate.instance('repeat')}
|
|
182
|
+
${Translate.instance('password')}`,
|
|
183
|
+
containerClass: `inl section-mp width-mini-box input-container ${formData[`recover-repeat-password`].show() ? '' : 'hide'}`,
|
|
181
184
|
placeholder: true,
|
|
182
185
|
})}
|
|
183
186
|
</div>
|
|
184
187
|
${options?.bottomRender ? await options.bottomRender() : ``}
|
|
185
188
|
<div class="in recover-send-btn-container">
|
|
186
|
-
${await BtnIcon.
|
|
189
|
+
${await BtnIcon.instance({
|
|
187
190
|
class: 'in section-mp form-button btn-recover',
|
|
188
|
-
label: Translate.
|
|
191
|
+
label: Translate.instance(
|
|
192
|
+
mode === 'recover-verify-email' ? 'send-recover-verify-email' : 'change-password',
|
|
193
|
+
),
|
|
189
194
|
type: 'button',
|
|
190
195
|
})}
|
|
191
196
|
</div>
|
|
192
197
|
<div class="in recover-resend-btn-container hide">
|
|
193
198
|
<div class="in section-mp form-button" style="color: #ed9d0f">
|
|
194
|
-
<i class="fa-solid fa-triangle-exclamation"></i> ${Translate.
|
|
199
|
+
<i class="fa-solid fa-triangle-exclamation"></i> ${Translate.instance('15-min-valid-recover-email')}
|
|
195
200
|
</div>
|
|
196
|
-
${await BtnIcon.
|
|
201
|
+
${await BtnIcon.instance({
|
|
197
202
|
class: 'in section-mp form-button btn-recover-resend',
|
|
198
|
-
label: html`${Translate.
|
|
203
|
+
label: html`${Translate.instance('resend')} ${Translate.instance('recover-verify-email')}`,
|
|
199
204
|
type: 'submit',
|
|
200
205
|
})}
|
|
201
206
|
</div>
|
|
202
207
|
</form>
|
|
203
208
|
`;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
209
|
+
}
|
|
210
|
+
}
|
|
207
211
|
export { Recover };
|
|
@@ -1,35 +1,41 @@
|
|
|
1
1
|
import { newInstance } from './CommonJs.js';
|
|
2
|
+
import {
|
|
3
|
+
ResponsiveEventType,
|
|
4
|
+
responsiveChangeEvents,
|
|
5
|
+
responsiveOrientationEvents,
|
|
6
|
+
responsiveOrientationSettledEvents,
|
|
7
|
+
responsiveSettledEvents,
|
|
8
|
+
} from './ClientEvents.js';
|
|
2
9
|
import { loggerFactory } from './Logger.js';
|
|
3
10
|
import { getResponsiveData } from './VanillaJs.js';
|
|
4
|
-
|
|
5
11
|
const logger = loggerFactory(import.meta);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
getResponsiveDataAmplitude: function (options) {
|
|
12
|
+
class Responsive {
|
|
13
|
+
static Data = {};
|
|
14
|
+
static Event = {};
|
|
15
|
+
static DelayEvent = {};
|
|
16
|
+
static Observer = ResizeObserver;
|
|
17
|
+
static getResponsiveData() {
|
|
18
|
+
return newInstance(Responsive.Data);
|
|
19
|
+
}
|
|
20
|
+
static getResponsiveDataAmplitude(options) {
|
|
16
21
|
const { dimAmplitude } = options;
|
|
17
|
-
const ResponsiveDataAmplitude = newInstance(
|
|
22
|
+
const ResponsiveDataAmplitude = newInstance(Responsive.Data);
|
|
18
23
|
ResponsiveDataAmplitude.minValue = ResponsiveDataAmplitude.minValue * dimAmplitude;
|
|
19
24
|
ResponsiveDataAmplitude.maxValue = ResponsiveDataAmplitude.maxValue * dimAmplitude;
|
|
20
25
|
ResponsiveDataAmplitude.width = ResponsiveDataAmplitude.width * dimAmplitude;
|
|
21
26
|
ResponsiveDataAmplitude.height = ResponsiveDataAmplitude.height * dimAmplitude;
|
|
22
27
|
return ResponsiveDataAmplitude;
|
|
23
|
-
}
|
|
24
|
-
resizeCallback
|
|
28
|
+
}
|
|
29
|
+
static resizeCallback(force) {
|
|
25
30
|
const Data = getResponsiveData();
|
|
26
31
|
if (force === true || Data.minValue !== Responsive.Data.minValue || Data.maxValue !== Responsive.Data.maxValue) {
|
|
27
32
|
Responsive.Data = Data;
|
|
33
|
+
Responsive.emitChanged(Data);
|
|
28
34
|
Responsive.triggerEvents();
|
|
29
35
|
}
|
|
30
|
-
}
|
|
31
|
-
resize
|
|
32
|
-
|
|
36
|
+
}
|
|
37
|
+
static resize = 0;
|
|
38
|
+
static async instance() {
|
|
33
39
|
Responsive.resizeCallback();
|
|
34
40
|
window.onresize = (e, force) => {
|
|
35
41
|
Responsive.resize++;
|
|
@@ -39,6 +45,7 @@ const Responsive = {
|
|
|
39
45
|
if (resize === Responsive.resize) {
|
|
40
46
|
Responsive.resizeCallback(force);
|
|
41
47
|
Responsive.resize = 0;
|
|
48
|
+
Responsive.emitSettled(Responsive.Data);
|
|
42
49
|
for (const event of Object.keys(Responsive.DelayEvent)) Responsive.DelayEvent[event]();
|
|
43
50
|
}
|
|
44
51
|
}, 750);
|
|
@@ -46,7 +53,6 @@ const Responsive = {
|
|
|
46
53
|
// alternative option
|
|
47
54
|
// this.Observer = new ResizeObserver(this.resizeCallback);
|
|
48
55
|
// this.Observer.observe(document.documentElement);
|
|
49
|
-
|
|
50
56
|
// Check if screen.orientation is available before adding event listener
|
|
51
57
|
if (
|
|
52
58
|
typeof screen !== 'undefined' &&
|
|
@@ -62,7 +68,6 @@ const Responsive = {
|
|
|
62
68
|
});
|
|
63
69
|
}
|
|
64
70
|
Responsive.matchMediaOrientationInstance = matchMedia('screen and (orientation:portrait)');
|
|
65
|
-
|
|
66
71
|
Responsive.matchMediaOrientationInstance.onchange = (e) => {
|
|
67
72
|
console.log('orientation change', Responsive.matchMediaOrientationInstance.matches ? 'portrait' : 'landscape');
|
|
68
73
|
// though beware square will be marked as landscape here,
|
|
@@ -71,20 +76,71 @@ const Responsive = {
|
|
|
71
76
|
setTimeout(() => window.onresize({}, true));
|
|
72
77
|
Responsive.triggerEventsOrientation();
|
|
73
78
|
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
}
|
|
80
|
+
static onChanged(listener, options = {}) {
|
|
81
|
+
if (options.key) Responsive.Event[options.key] = listener;
|
|
82
|
+
return responsiveChangeEvents.on(ResponsiveEventType.changed, listener, options);
|
|
83
|
+
}
|
|
84
|
+
static offChanged(key) {
|
|
85
|
+
delete Responsive.Event[key];
|
|
86
|
+
return responsiveChangeEvents.off(key);
|
|
87
|
+
}
|
|
88
|
+
static hasChangedListener(key) {
|
|
89
|
+
return responsiveChangeEvents.has(key) || Boolean(Responsive.Event[key]);
|
|
90
|
+
}
|
|
91
|
+
static onSettled(listener, options = {}) {
|
|
92
|
+
if (options.key) Responsive.DelayEvent[options.key] = listener;
|
|
93
|
+
return responsiveSettledEvents.on(ResponsiveEventType.settled, listener, options);
|
|
94
|
+
}
|
|
95
|
+
static offSettled(key) {
|
|
96
|
+
delete Responsive.DelayEvent[key];
|
|
97
|
+
return responsiveSettledEvents.off(key);
|
|
98
|
+
}
|
|
99
|
+
static onOrientationChanged(listener, options = {}) {
|
|
100
|
+
if (options.key) Responsive.orientationEvent[options.key] = listener;
|
|
101
|
+
return responsiveOrientationEvents.on(ResponsiveEventType.orientationChanged, listener, options);
|
|
102
|
+
}
|
|
103
|
+
static offOrientationChanged(key) {
|
|
104
|
+
delete Responsive.orientationEvent[key];
|
|
105
|
+
return responsiveOrientationEvents.off(key);
|
|
106
|
+
}
|
|
107
|
+
static onOrientationSettled(listener, options = {}) {
|
|
108
|
+
if (options.key) Responsive.orientationDelayEvent[options.key] = listener;
|
|
109
|
+
return responsiveOrientationSettledEvents.on(ResponsiveEventType.orientationSettled, listener, options);
|
|
110
|
+
}
|
|
111
|
+
static offOrientationSettled(key) {
|
|
112
|
+
delete Responsive.orientationDelayEvent[key];
|
|
113
|
+
return responsiveOrientationSettledEvents.off(key);
|
|
114
|
+
}
|
|
115
|
+
static async emitChanged(detail = Responsive.Data) {
|
|
116
|
+
await responsiveChangeEvents.emit(ResponsiveEventType.changed, detail);
|
|
117
|
+
}
|
|
118
|
+
static async emitSettled(detail = Responsive.Data) {
|
|
119
|
+
await responsiveSettledEvents.emit(ResponsiveEventType.settled, detail);
|
|
120
|
+
}
|
|
121
|
+
static async emitOrientationChanged(detail = Responsive.Data) {
|
|
122
|
+
await responsiveOrientationEvents.emit(ResponsiveEventType.orientationChanged, detail);
|
|
123
|
+
}
|
|
124
|
+
static async emitOrientationSettled(detail = Responsive.Data) {
|
|
125
|
+
await responsiveOrientationSettledEvents.emit(ResponsiveEventType.orientationSettled, detail);
|
|
126
|
+
}
|
|
127
|
+
static triggerChanged(keyEvent) {
|
|
128
|
+
return Responsive.triggerEvents(keyEvent);
|
|
129
|
+
}
|
|
130
|
+
static triggerEventsOrientation() {
|
|
131
|
+
Responsive.emitOrientationChanged(Responsive.Data);
|
|
132
|
+
for (const event of Object.keys(Responsive.orientationEvent)) Responsive.orientationEvent[event]();
|
|
77
133
|
setTimeout(() => {
|
|
78
134
|
window.onresize();
|
|
79
|
-
|
|
135
|
+
Responsive.emitOrientationSettled(Responsive.Data);
|
|
136
|
+
for (const event of Object.keys(Responsive.orientationDelayEvent)) Responsive.orientationDelayEvent[event]();
|
|
80
137
|
}, 1500);
|
|
81
|
-
}
|
|
82
|
-
triggerEvents
|
|
83
|
-
if (keyEvent) return
|
|
84
|
-
return Object.keys(
|
|
85
|
-
}
|
|
86
|
-
orientationEvent
|
|
87
|
-
orientationDelayEvent
|
|
88
|
-
}
|
|
89
|
-
|
|
138
|
+
}
|
|
139
|
+
static triggerEvents(keyEvent) {
|
|
140
|
+
if (keyEvent) return Responsive.Event[keyEvent]();
|
|
141
|
+
return Object.keys(Responsive.Event).map((key) => Responsive.Event[key]());
|
|
142
|
+
}
|
|
143
|
+
static orientationEvent = {};
|
|
144
|
+
static orientationDelayEvent = {};
|
|
145
|
+
}
|
|
90
146
|
export { Responsive };
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { getId, newInstance } from './CommonJs.js';
|
|
2
2
|
import { Modal } from './Modal.js';
|
|
3
3
|
import { s } from './VanillaJs.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.Tokens[id] = {};
|
|
4
|
+
class RichText {
|
|
5
|
+
static Tokens = {};
|
|
6
|
+
static async instance(options = { id: '', parentIdModal: '' }) {
|
|
7
|
+
const id = options?.id ? options.id : getId(RichText.Tokens, 'rich-text-');
|
|
8
|
+
RichText.Tokens[id] = {};
|
|
10
9
|
setTimeout(() => {
|
|
11
10
|
const easyMDE = new EasyMDE({
|
|
12
11
|
element: s(`.${id}`),
|
|
@@ -23,20 +22,12 @@ const RichText = {
|
|
|
23
22
|
}
|
|
24
23
|
},
|
|
25
24
|
});
|
|
26
|
-
|
|
25
|
+
RichText.Tokens[id].easyMDE = easyMDE;
|
|
27
26
|
// easyMDE.value();
|
|
28
27
|
// easyMDE.value(val);
|
|
29
28
|
});
|
|
30
|
-
return html` <style>
|
|
31
|
-
.md-container {
|
|
32
|
-
background: white;
|
|
33
|
-
}
|
|
34
|
-
.md-container button {
|
|
35
|
-
color: black;
|
|
36
|
-
}
|
|
37
|
-
</style>
|
|
29
|
+
return html` <style></style>
|
|
38
30
|
<div class="in md-container"><textarea class="${id}"></textarea></div>`;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
31
|
+
}
|
|
32
|
+
}
|
|
42
33
|
export { RichText };
|