@capytale/meta-player 0.8.3 → 0.9.0
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/.prettierrc.json +4 -4
- package/LICENSE +674 -674
- package/README.md +12 -12
- package/eslint.config.js +28 -28
- package/index.html +15 -15
- package/package.json +60 -60
- package/public/themes/lara-dark-blue/theme.css +7015 -7015
- package/public/themes/lara-light-blue/theme.css +7005 -7005
- package/src/App.tsx +140 -139
- package/src/AppRedux.css +39 -39
- package/src/MetaPlayer.tsx +170 -170
- package/src/activityJs.ts +7 -7
- package/src/app/createAppSlice.ts +6 -6
- package/src/app/hooks.ts +12 -12
- package/src/app/store.ts +52 -52
- package/src/app.module.scss +80 -80
- package/src/demo.tsx +87 -87
- package/src/external/prime.ts +5 -5
- package/src/features/activityData/ExitWarning.ts +28 -28
- package/src/features/activityData/IsAntiCheatExitDetectionDisabledSetter.tsx +19 -19
- package/src/features/activityData/IsDirtySetter.tsx +17 -17
- package/src/features/activityData/MetaPlayerOptionsSetter.tsx +41 -41
- package/src/features/activityData/activityDataSlice.ts +252 -256
- package/src/features/activityData/activityJsData.ts +82 -82
- package/src/features/activityData/hooks.ts +34 -34
- package/src/features/activityData/metaPlayerOptions.ts +23 -23
- package/src/features/activityData/uiState.ts +20 -20
- package/src/features/activityJS/ActivityJSProvider.tsx +339 -339
- package/src/features/activityJS/AfterResetAction.tsx +23 -23
- package/src/features/activityJS/AfterSaveAction.tsx +23 -23
- package/src/features/activityJS/BeforeResetAction.tsx +23 -23
- package/src/features/activityJS/BeforeSaveAction.tsx +23 -23
- package/src/features/activityJS/Saver.tsx +167 -167
- package/src/features/activityJS/hooks.ts +85 -85
- package/src/features/activityJS/internal-hooks.ts +96 -96
- package/src/features/activityJS/saverSlice.ts +96 -96
- package/src/features/activitySettings/ActivitySettingsSetter.tsx +21 -21
- package/src/features/activitySettings/hooks.ts +12 -12
- package/src/features/activitySettings/index.tsx +43 -43
- package/src/features/activitySettings/store.ts +108 -108
- package/src/features/activitySettings/style.module.scss +8 -8
- package/src/features/activitySettings/types.ts +140 -140
- package/src/features/activitySettings/ui.tsx +299 -299
- package/src/features/functionalities/AttachedFilesFunctionality.ts +23 -23
- package/src/features/functionalities/PreviewDialog.tsx +83 -83
- package/src/features/functionalities/functionalitiesSlice.ts +98 -98
- package/src/features/functionalities/hooks.ts +70 -70
- package/src/features/layout/hooks.ts +7 -7
- package/src/features/layout/layoutSlice.ts +93 -90
- package/src/features/navbar/activity-info/index.tsx +54 -54
- package/src/features/navbar/activity-info/style.module.scss +38 -38
- package/src/features/navbar/activity-menu/ActivityQuickActions.tsx +57 -57
- package/src/features/navbar/activity-menu/index.tsx +154 -154
- package/src/features/navbar/activity-menu/style.module.scss +7 -7
- package/src/features/navbar/capytale-menu/CloneDialog.tsx +75 -75
- package/src/features/navbar/capytale-menu/Countdown.tsx +312 -312
- package/src/features/navbar/capytale-menu/CountdownAndSaveButton.tsx +115 -115
- package/src/features/navbar/capytale-menu/index.tsx +260 -260
- package/src/features/navbar/capytale-menu/style.module.scss +8 -8
- package/src/features/navbar/index.tsx +39 -39
- package/src/features/navbar/navbarSlice.ts +79 -79
- package/src/features/navbar/review-navbar/GradingNav.tsx +128 -128
- package/src/features/navbar/review-navbar/index.tsx +18 -18
- package/src/features/navbar/review-navbar/style.module.scss +22 -22
- package/src/features/navbar/sidebars/ActivitySidebarActions.tsx +57 -57
- package/src/features/navbar/sidebars/AttachedFilesSidebarContent.module.scss +43 -43
- package/src/features/navbar/sidebars/AttachedFilesSidebarContent.tsx +181 -181
- package/src/features/navbar/sidebars/SettingsSidebarContent.tsx +192 -192
- package/src/features/navbar/sidebars/style.module.scss +15 -15
- package/src/features/navbar/student-utils.ts +11 -11
- package/src/features/navbar/style.module.scss +65 -65
- package/src/features/pedago/InstructionsEditor.tsx +102 -102
- package/src/features/pedago/PdfEditor.tsx +91 -91
- package/src/features/pedago/PedagoCommands.tsx +353 -353
- package/src/features/pedago/SharedNotesEditor.tsx +144 -144
- package/src/features/pedago/hooks.ts +99 -0
- package/src/features/pedago/index.tsx +197 -207
- package/src/features/pedago/style.module.scss +233 -233
- package/src/features/theming/ThemeSwitcher.tsx +51 -51
- package/src/features/theming/hooks.ts +6 -6
- package/src/features/theming/themingSlice.ts +93 -93
- package/src/features/toast.tsx +38 -38
- package/src/hooks/index.ts +16 -16
- package/src/index.css +132 -132
- package/src/index.ts +90 -90
- package/src/logo.svg +1 -1
- package/src/my_json_data.js +4146 -4146
- package/src/settings.ts +6 -6
- package/src/types.ts +9 -9
- package/src/utils/ButtonDoubleIcon.tsx +35 -35
- package/src/utils/CardSelector.tsx +41 -41
- package/src/utils/ErrorBoundary.tsx +41 -41
- package/src/utils/PopupButton.tsx +134 -134
- package/src/utils/activity.ts +8 -8
- package/src/utils/breakpoints.ts +4 -4
- package/src/utils/capytale.ts +10 -10
- package/src/utils/clipboard.ts +11 -11
- package/src/utils/download.ts +7 -7
- package/src/utils/equality.ts +32 -32
- package/src/utils/server-clock.ts +42 -42
- package/src/utils/style.module.scss +45 -45
- package/src/utils/useFullscreen.ts +65 -65
- package/src/vite-env.d.ts +1 -1
- package/tsconfig.json +28 -28
- package/tsconfig.node.json +9 -9
- package/vite.config.ts +11 -11
package/src/MetaPlayer.tsx
CHANGED
|
@@ -1,170 +1,170 @@
|
|
|
1
|
-
import React, { FC, PropsWithChildren, useCallback, useMemo } from "react";
|
|
2
|
-
|
|
3
|
-
import { Provider } from "react-redux";
|
|
4
|
-
|
|
5
|
-
import { APIOptions, PrimeReactProvider } from "primereact/api";
|
|
6
|
-
import "primeicons/primeicons.css";
|
|
7
|
-
|
|
8
|
-
import App from "./App";
|
|
9
|
-
import { makeStore } from "./app/store";
|
|
10
|
-
import "./index.css";
|
|
11
|
-
import ThemeSwitcher from "./features/theming/ThemeSwitcher";
|
|
12
|
-
import {
|
|
13
|
-
ActivityJSProvider,
|
|
14
|
-
useActivityJS,
|
|
15
|
-
} from "./features/activityJS/ActivityJSProvider";
|
|
16
|
-
import { LoadOptions } from "./features/activityJS/internal-hooks";
|
|
17
|
-
import { ErrorBoundary } from "./utils/ErrorBoundary";
|
|
18
|
-
import Saver from "./features/activityJS/Saver";
|
|
19
|
-
import {
|
|
20
|
-
CapytaleAntiCheat,
|
|
21
|
-
ContentHidingMethod,
|
|
22
|
-
ExitDetectionMethod,
|
|
23
|
-
} from "@capytale/capytale-anti-triche";
|
|
24
|
-
import { useAppSelector } from "./app/hooks";
|
|
25
|
-
import {
|
|
26
|
-
selectActivityInfo,
|
|
27
|
-
selectAntiCheat,
|
|
28
|
-
selectHasAntiCheat,
|
|
29
|
-
selectIsAntiCheatExitDetectionDisabled,
|
|
30
|
-
selectIsDirty,
|
|
31
|
-
selectReturnUrl,
|
|
32
|
-
} from "./features/activityData/activityDataSlice";
|
|
33
|
-
|
|
34
|
-
import { initialState as layoutInitialState } from "./features/layout/layoutSlice";
|
|
35
|
-
import ExitWarning from "./features/activityData/ExitWarning";
|
|
36
|
-
import type { AntiCheatOptions, UIOptions } from "./types";
|
|
37
|
-
import { ToastProvider } from "./features/toast";
|
|
38
|
-
|
|
39
|
-
type MetaPlayerProps = PropsWithChildren<{
|
|
40
|
-
activityJSOptions?: LoadOptions;
|
|
41
|
-
antiCheatOptions?: Partial<AntiCheatOptions>;
|
|
42
|
-
uiOptions?: Partial<UIOptions>;
|
|
43
|
-
}>;
|
|
44
|
-
|
|
45
|
-
const MetaPlayer: FC<MetaPlayerProps> = (props) => {
|
|
46
|
-
const primeSettings: Partial<APIOptions> = {
|
|
47
|
-
ripple: true,
|
|
48
|
-
};
|
|
49
|
-
const antiCheatOptions: AntiCheatOptions = useMemo(
|
|
50
|
-
() => ({
|
|
51
|
-
preserveDom: true,
|
|
52
|
-
hasIframes: false,
|
|
53
|
-
...props.antiCheatOptions,
|
|
54
|
-
}),
|
|
55
|
-
[props.antiCheatOptions],
|
|
56
|
-
);
|
|
57
|
-
const uiOptions: UIOptions = {
|
|
58
|
-
closePedagoByDefault: false,
|
|
59
|
-
noWorkflow: false,
|
|
60
|
-
noSaveForStudents: false,
|
|
61
|
-
...props.uiOptions,
|
|
62
|
-
};
|
|
63
|
-
const store = useMemo(
|
|
64
|
-
() =>
|
|
65
|
-
makeStore({
|
|
66
|
-
layout: {
|
|
67
|
-
...layoutInitialState,
|
|
68
|
-
isPedagoVisible: !uiOptions.closePedagoByDefault,
|
|
69
|
-
showWorkflow: !uiOptions.noWorkflow,
|
|
70
|
-
showSaveForStudents: !uiOptions.noSaveForStudents,
|
|
71
|
-
},
|
|
72
|
-
}),
|
|
73
|
-
[],
|
|
74
|
-
);
|
|
75
|
-
return (
|
|
76
|
-
<PrimeReactProvider value={primeSettings}>
|
|
77
|
-
<ToastProvider>
|
|
78
|
-
<Provider store={store}>
|
|
79
|
-
<ThemeSwitcher />
|
|
80
|
-
<ExitWarning />
|
|
81
|
-
<ErrorBoundary fallback={<div>Une erreur est survenue</div>}>
|
|
82
|
-
<ActivityJSProvider
|
|
83
|
-
options={props.activityJSOptions}
|
|
84
|
-
loadingFallback={<div>Chargement de l'activité...</div>}
|
|
85
|
-
errorFallback={({ children }) => (
|
|
86
|
-
<div style={{ marginLeft: "1rem", marginRight: "1rem" }}>
|
|
87
|
-
<p>Erreur lors du chargement de l'activité : {children}</p>
|
|
88
|
-
<p>
|
|
89
|
-
Êtes-vous bien connecté(e) à Capytale ? Avez-vous bien le
|
|
90
|
-
droit d'accéder à cette ressource ?
|
|
91
|
-
</p>
|
|
92
|
-
<p>
|
|
93
|
-
<a href="/">Retour à l'accueil</a>
|
|
94
|
-
</p>
|
|
95
|
-
</div>
|
|
96
|
-
)}
|
|
97
|
-
>
|
|
98
|
-
<Saver />
|
|
99
|
-
<MetaPlayerContent antiCheatOptions={antiCheatOptions}>
|
|
100
|
-
<App>{props.children}</App>
|
|
101
|
-
</MetaPlayerContent>
|
|
102
|
-
</ActivityJSProvider>
|
|
103
|
-
</ErrorBoundary>
|
|
104
|
-
</Provider>
|
|
105
|
-
</ToastProvider>
|
|
106
|
-
</PrimeReactProvider>
|
|
107
|
-
);
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
type MetaPlayerContentProps = {
|
|
111
|
-
antiCheatOptions: AntiCheatOptions;
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const MetaPlayerContent: React.FC<PropsWithChildren<MetaPlayerContentProps>> = (
|
|
115
|
-
props,
|
|
116
|
-
) => {
|
|
117
|
-
const isDirty = useAppSelector(selectIsDirty);
|
|
118
|
-
const antiCheat = useAppSelector(selectAntiCheat);
|
|
119
|
-
const hasAntiCheat = useAppSelector(selectHasAntiCheat);
|
|
120
|
-
const activityInfo = useAppSelector(selectActivityInfo);
|
|
121
|
-
const returnUrl = useAppSelector(selectReturnUrl);
|
|
122
|
-
const isAntiCheatExitDetectionDisabled = useAppSelector(
|
|
123
|
-
selectIsAntiCheatExitDetectionDisabled,
|
|
124
|
-
);
|
|
125
|
-
const studentName = activityInfo.studentInfo
|
|
126
|
-
? `${activityInfo.studentInfo.firstName} ${activityInfo.studentInfo.lastName}`
|
|
127
|
-
: "";
|
|
128
|
-
const activityJS = useActivityJS();
|
|
129
|
-
|
|
130
|
-
const touch = useCallback(() => {
|
|
131
|
-
if (
|
|
132
|
-
activityJS.activitySession == null ||
|
|
133
|
-
activityJS.activitySession.activityBunch.assignmentNode == null
|
|
134
|
-
) {
|
|
135
|
-
console.error("ActivityJS data not loaded or touch not available");
|
|
136
|
-
return Promise.resolve();
|
|
137
|
-
} else {
|
|
138
|
-
return activityJS.activitySession.activityBunch.assignmentNode.touch();
|
|
139
|
-
}
|
|
140
|
-
}, [activityJS.activitySession]);
|
|
141
|
-
|
|
142
|
-
return (
|
|
143
|
-
<CapytaleAntiCheat
|
|
144
|
-
enabled={hasAntiCheat}
|
|
145
|
-
hashedPassword={antiCheat?.passwordHash || null}
|
|
146
|
-
startLocked={antiCheat?.startLocked || null}
|
|
147
|
-
activityTitle={activityInfo.title}
|
|
148
|
-
studentName={studentName}
|
|
149
|
-
isDirty={isDirty}
|
|
150
|
-
returnUrl={returnUrl}
|
|
151
|
-
dbTouchFunction={touch}
|
|
152
|
-
disableExitDetection={isAntiCheatExitDetectionDisabled}
|
|
153
|
-
contentClassName="anti-cheat-content"
|
|
154
|
-
exitDetectionMethod={
|
|
155
|
-
props.antiCheatOptions.hasIframes
|
|
156
|
-
? ExitDetectionMethod.VISIBILITY_CHANGE
|
|
157
|
-
: ExitDetectionMethod.BLUR
|
|
158
|
-
}
|
|
159
|
-
contentHidingMethod={
|
|
160
|
-
props.antiCheatOptions.preserveDom
|
|
161
|
-
? ContentHidingMethod.DISPLAY_NONE
|
|
162
|
-
: ContentHidingMethod.REMOVE_FROM_DOM
|
|
163
|
-
}
|
|
164
|
-
>
|
|
165
|
-
{props.children}
|
|
166
|
-
</CapytaleAntiCheat>
|
|
167
|
-
);
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
export default MetaPlayer;
|
|
1
|
+
import React, { FC, PropsWithChildren, useCallback, useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
import { Provider } from "react-redux";
|
|
4
|
+
|
|
5
|
+
import { APIOptions, PrimeReactProvider } from "primereact/api";
|
|
6
|
+
import "primeicons/primeicons.css";
|
|
7
|
+
|
|
8
|
+
import App from "./App";
|
|
9
|
+
import { makeStore } from "./app/store";
|
|
10
|
+
import "./index.css";
|
|
11
|
+
import ThemeSwitcher from "./features/theming/ThemeSwitcher";
|
|
12
|
+
import {
|
|
13
|
+
ActivityJSProvider,
|
|
14
|
+
useActivityJS,
|
|
15
|
+
} from "./features/activityJS/ActivityJSProvider";
|
|
16
|
+
import { LoadOptions } from "./features/activityJS/internal-hooks";
|
|
17
|
+
import { ErrorBoundary } from "./utils/ErrorBoundary";
|
|
18
|
+
import Saver from "./features/activityJS/Saver";
|
|
19
|
+
import {
|
|
20
|
+
CapytaleAntiCheat,
|
|
21
|
+
ContentHidingMethod,
|
|
22
|
+
ExitDetectionMethod,
|
|
23
|
+
} from "@capytale/capytale-anti-triche";
|
|
24
|
+
import { useAppSelector } from "./app/hooks";
|
|
25
|
+
import {
|
|
26
|
+
selectActivityInfo,
|
|
27
|
+
selectAntiCheat,
|
|
28
|
+
selectHasAntiCheat,
|
|
29
|
+
selectIsAntiCheatExitDetectionDisabled,
|
|
30
|
+
selectIsDirty,
|
|
31
|
+
selectReturnUrl,
|
|
32
|
+
} from "./features/activityData/activityDataSlice";
|
|
33
|
+
|
|
34
|
+
import { initialState as layoutInitialState } from "./features/layout/layoutSlice";
|
|
35
|
+
import ExitWarning from "./features/activityData/ExitWarning";
|
|
36
|
+
import type { AntiCheatOptions, UIOptions } from "./types";
|
|
37
|
+
import { ToastProvider } from "./features/toast";
|
|
38
|
+
|
|
39
|
+
type MetaPlayerProps = PropsWithChildren<{
|
|
40
|
+
activityJSOptions?: LoadOptions;
|
|
41
|
+
antiCheatOptions?: Partial<AntiCheatOptions>;
|
|
42
|
+
uiOptions?: Partial<UIOptions>;
|
|
43
|
+
}>;
|
|
44
|
+
|
|
45
|
+
const MetaPlayer: FC<MetaPlayerProps> = (props) => {
|
|
46
|
+
const primeSettings: Partial<APIOptions> = {
|
|
47
|
+
ripple: true,
|
|
48
|
+
};
|
|
49
|
+
const antiCheatOptions: AntiCheatOptions = useMemo(
|
|
50
|
+
() => ({
|
|
51
|
+
preserveDom: true,
|
|
52
|
+
hasIframes: false,
|
|
53
|
+
...props.antiCheatOptions,
|
|
54
|
+
}),
|
|
55
|
+
[props.antiCheatOptions],
|
|
56
|
+
);
|
|
57
|
+
const uiOptions: UIOptions = {
|
|
58
|
+
closePedagoByDefault: false,
|
|
59
|
+
noWorkflow: false,
|
|
60
|
+
noSaveForStudents: false,
|
|
61
|
+
...props.uiOptions,
|
|
62
|
+
};
|
|
63
|
+
const store = useMemo(
|
|
64
|
+
() =>
|
|
65
|
+
makeStore({
|
|
66
|
+
layout: {
|
|
67
|
+
...layoutInitialState,
|
|
68
|
+
isPedagoVisible: !uiOptions.closePedagoByDefault,
|
|
69
|
+
showWorkflow: !uiOptions.noWorkflow,
|
|
70
|
+
showSaveForStudents: !uiOptions.noSaveForStudents,
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
|
+
[],
|
|
74
|
+
);
|
|
75
|
+
return (
|
|
76
|
+
<PrimeReactProvider value={primeSettings}>
|
|
77
|
+
<ToastProvider>
|
|
78
|
+
<Provider store={store}>
|
|
79
|
+
<ThemeSwitcher />
|
|
80
|
+
<ExitWarning />
|
|
81
|
+
<ErrorBoundary fallback={<div>Une erreur est survenue</div>}>
|
|
82
|
+
<ActivityJSProvider
|
|
83
|
+
options={props.activityJSOptions}
|
|
84
|
+
loadingFallback={<div>Chargement de l'activité...</div>}
|
|
85
|
+
errorFallback={({ children }) => (
|
|
86
|
+
<div style={{ marginLeft: "1rem", marginRight: "1rem" }}>
|
|
87
|
+
<p>Erreur lors du chargement de l'activité : {children}</p>
|
|
88
|
+
<p>
|
|
89
|
+
Êtes-vous bien connecté(e) à Capytale ? Avez-vous bien le
|
|
90
|
+
droit d'accéder à cette ressource ?
|
|
91
|
+
</p>
|
|
92
|
+
<p>
|
|
93
|
+
<a href="/">Retour à l'accueil</a>
|
|
94
|
+
</p>
|
|
95
|
+
</div>
|
|
96
|
+
)}
|
|
97
|
+
>
|
|
98
|
+
<Saver />
|
|
99
|
+
<MetaPlayerContent antiCheatOptions={antiCheatOptions}>
|
|
100
|
+
<App>{props.children}</App>
|
|
101
|
+
</MetaPlayerContent>
|
|
102
|
+
</ActivityJSProvider>
|
|
103
|
+
</ErrorBoundary>
|
|
104
|
+
</Provider>
|
|
105
|
+
</ToastProvider>
|
|
106
|
+
</PrimeReactProvider>
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
type MetaPlayerContentProps = {
|
|
111
|
+
antiCheatOptions: AntiCheatOptions;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const MetaPlayerContent: React.FC<PropsWithChildren<MetaPlayerContentProps>> = (
|
|
115
|
+
props,
|
|
116
|
+
) => {
|
|
117
|
+
const isDirty = useAppSelector(selectIsDirty);
|
|
118
|
+
const antiCheat = useAppSelector(selectAntiCheat);
|
|
119
|
+
const hasAntiCheat = useAppSelector(selectHasAntiCheat);
|
|
120
|
+
const activityInfo = useAppSelector(selectActivityInfo);
|
|
121
|
+
const returnUrl = useAppSelector(selectReturnUrl);
|
|
122
|
+
const isAntiCheatExitDetectionDisabled = useAppSelector(
|
|
123
|
+
selectIsAntiCheatExitDetectionDisabled,
|
|
124
|
+
);
|
|
125
|
+
const studentName = activityInfo.studentInfo
|
|
126
|
+
? `${activityInfo.studentInfo.firstName} ${activityInfo.studentInfo.lastName}`
|
|
127
|
+
: "";
|
|
128
|
+
const activityJS = useActivityJS();
|
|
129
|
+
|
|
130
|
+
const touch = useCallback(() => {
|
|
131
|
+
if (
|
|
132
|
+
activityJS.activitySession == null ||
|
|
133
|
+
activityJS.activitySession.activityBunch.assignmentNode == null
|
|
134
|
+
) {
|
|
135
|
+
console.error("ActivityJS data not loaded or touch not available");
|
|
136
|
+
return Promise.resolve();
|
|
137
|
+
} else {
|
|
138
|
+
return activityJS.activitySession.activityBunch.assignmentNode.touch();
|
|
139
|
+
}
|
|
140
|
+
}, [activityJS.activitySession]);
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<CapytaleAntiCheat
|
|
144
|
+
enabled={hasAntiCheat}
|
|
145
|
+
hashedPassword={antiCheat?.passwordHash || null}
|
|
146
|
+
startLocked={antiCheat?.startLocked || null}
|
|
147
|
+
activityTitle={activityInfo.title}
|
|
148
|
+
studentName={studentName}
|
|
149
|
+
isDirty={isDirty}
|
|
150
|
+
returnUrl={returnUrl}
|
|
151
|
+
dbTouchFunction={touch}
|
|
152
|
+
disableExitDetection={isAntiCheatExitDetectionDisabled}
|
|
153
|
+
contentClassName="anti-cheat-content"
|
|
154
|
+
exitDetectionMethod={
|
|
155
|
+
props.antiCheatOptions.hasIframes
|
|
156
|
+
? ExitDetectionMethod.VISIBILITY_CHANGE
|
|
157
|
+
: ExitDetectionMethod.BLUR
|
|
158
|
+
}
|
|
159
|
+
contentHidingMethod={
|
|
160
|
+
props.antiCheatOptions.preserveDom
|
|
161
|
+
? ContentHidingMethod.DISPLAY_NONE
|
|
162
|
+
: ContentHidingMethod.REMOVE_FROM_DOM
|
|
163
|
+
}
|
|
164
|
+
>
|
|
165
|
+
{props.children}
|
|
166
|
+
</CapytaleAntiCheat>
|
|
167
|
+
);
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
export default MetaPlayer;
|
package/src/activityJs.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import evaluationApi from "@capytale/activity.js/backend/capytale/evaluation";
|
|
2
|
-
import type { ActivityMode } from "@capytale/activity.js/activity/activitySession";
|
|
3
|
-
import type { Evaluation } from "@capytale/activity.js/activity/evaluation/evaluation";
|
|
4
|
-
import devconf from "@capytale/activity.js/util/devconf";
|
|
5
|
-
|
|
6
|
-
export { evaluationApi, devconf };
|
|
7
|
-
export type { Evaluation, ActivityMode };
|
|
1
|
+
import evaluationApi from "@capytale/activity.js/backend/capytale/evaluation";
|
|
2
|
+
import type { ActivityMode } from "@capytale/activity.js/activity/activitySession";
|
|
3
|
+
import type { Evaluation } from "@capytale/activity.js/activity/evaluation/evaluation";
|
|
4
|
+
import devconf from "@capytale/activity.js/util/devconf";
|
|
5
|
+
|
|
6
|
+
export { evaluationApi, devconf };
|
|
7
|
+
export type { Evaluation, ActivityMode };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { asyncThunkCreator, buildCreateSlice } from "@reduxjs/toolkit"
|
|
2
|
-
|
|
3
|
-
// `buildCreateSlice` allows us to create a slice with async thunks.
|
|
4
|
-
export const createAppSlice = buildCreateSlice({
|
|
5
|
-
creators: { asyncThunk: asyncThunkCreator },
|
|
6
|
-
})
|
|
1
|
+
import { asyncThunkCreator, buildCreateSlice } from "@reduxjs/toolkit"
|
|
2
|
+
|
|
3
|
+
// `buildCreateSlice` allows us to create a slice with async thunks.
|
|
4
|
+
export const createAppSlice = buildCreateSlice({
|
|
5
|
+
creators: { asyncThunk: asyncThunkCreator },
|
|
6
|
+
})
|
package/src/app/hooks.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// This file serves as a central hub for re-exporting pre-typed Redux hooks.
|
|
2
|
-
// These imports are restricted elsewhere to ensure consistent
|
|
3
|
-
// usage of typed hooks throughout the application.
|
|
4
|
-
// We disable the ESLint rule here because this is the designated place
|
|
5
|
-
// for importing and re-exporting the typed versions of hooks.
|
|
6
|
-
/* eslint-disable @typescript-eslint/no-restricted-imports */
|
|
7
|
-
import { useDispatch, useSelector } from "react-redux"
|
|
8
|
-
import type { AppDispatch, RootState } from "./store"
|
|
9
|
-
|
|
10
|
-
// Use throughout your app instead of plain `useDispatch` and `useSelector`
|
|
11
|
-
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
|
|
12
|
-
export const useAppSelector = useSelector.withTypes<RootState>()
|
|
1
|
+
// This file serves as a central hub for re-exporting pre-typed Redux hooks.
|
|
2
|
+
// These imports are restricted elsewhere to ensure consistent
|
|
3
|
+
// usage of typed hooks throughout the application.
|
|
4
|
+
// We disable the ESLint rule here because this is the designated place
|
|
5
|
+
// for importing and re-exporting the typed versions of hooks.
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-restricted-imports */
|
|
7
|
+
import { useDispatch, useSelector } from "react-redux"
|
|
8
|
+
import type { AppDispatch, RootState } from "./store"
|
|
9
|
+
|
|
10
|
+
// Use throughout your app instead of plain `useDispatch` and `useSelector`
|
|
11
|
+
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
|
|
12
|
+
export const useAppSelector = useSelector.withTypes<RootState>()
|
package/src/app/store.ts
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import type { Action, ThunkAction } from "@reduxjs/toolkit";
|
|
2
|
-
import { combineSlices, configureStore } from "@reduxjs/toolkit";
|
|
3
|
-
import { setupListeners } from "@reduxjs/toolkit/query";
|
|
4
|
-
import { themingSlice } from "../features/theming/themingSlice";
|
|
5
|
-
import { layoutSlice } from "../features/layout/layoutSlice";
|
|
6
|
-
import { activityDataSlice } from "../features/activityData/activityDataSlice";
|
|
7
|
-
import { navbarSlice } from "../features/navbar/navbarSlice";
|
|
8
|
-
import { saverSlice } from "../features/activityJS/saverSlice";
|
|
9
|
-
import { functionalitiesSlice } from "../features/functionalities/functionalitiesSlice";
|
|
10
|
-
|
|
11
|
-
// `combineSlices` automatically combines the reducers using
|
|
12
|
-
// their `reducerPath`s, therefore we no longer need to call `combineReducers`.
|
|
13
|
-
const rootReducer = combineSlices(
|
|
14
|
-
activityDataSlice,
|
|
15
|
-
themingSlice,
|
|
16
|
-
layoutSlice,
|
|
17
|
-
navbarSlice,
|
|
18
|
-
saverSlice,
|
|
19
|
-
functionalitiesSlice,
|
|
20
|
-
);
|
|
21
|
-
// Infer the `RootState` type from the root reducer
|
|
22
|
-
export type RootState = ReturnType<typeof rootReducer>;
|
|
23
|
-
|
|
24
|
-
// The store setup is wrapped in `makeStore` to allow reuse
|
|
25
|
-
// when setting up tests that need the same store config
|
|
26
|
-
export const makeStore = (preloadedState?: Partial<RootState>) => {
|
|
27
|
-
const store = configureStore({
|
|
28
|
-
reducer: rootReducer,
|
|
29
|
-
preloadedState,
|
|
30
|
-
middleware: (getDefaultMiddleware) =>
|
|
31
|
-
getDefaultMiddleware({
|
|
32
|
-
serializableCheck: false
|
|
33
|
-
}),
|
|
34
|
-
});
|
|
35
|
-
// configure listeners using the provided defaults
|
|
36
|
-
// optional, but required for `refetchOnFocus`/`refetchOnReconnect` behaviors
|
|
37
|
-
setupListeners(store.dispatch);
|
|
38
|
-
return store;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export const store = makeStore();
|
|
42
|
-
|
|
43
|
-
// Infer the type of `store`
|
|
44
|
-
export type AppStore = typeof store;
|
|
45
|
-
// Infer the `AppDispatch` type from the store itself
|
|
46
|
-
export type AppDispatch = AppStore["dispatch"];
|
|
47
|
-
export type AppThunk<ThunkReturnType = void> = ThunkAction<
|
|
48
|
-
ThunkReturnType,
|
|
49
|
-
RootState,
|
|
50
|
-
unknown,
|
|
51
|
-
Action
|
|
52
|
-
>;
|
|
1
|
+
import type { Action, ThunkAction } from "@reduxjs/toolkit";
|
|
2
|
+
import { combineSlices, configureStore } from "@reduxjs/toolkit";
|
|
3
|
+
import { setupListeners } from "@reduxjs/toolkit/query";
|
|
4
|
+
import { themingSlice } from "../features/theming/themingSlice";
|
|
5
|
+
import { layoutSlice } from "../features/layout/layoutSlice";
|
|
6
|
+
import { activityDataSlice } from "../features/activityData/activityDataSlice";
|
|
7
|
+
import { navbarSlice } from "../features/navbar/navbarSlice";
|
|
8
|
+
import { saverSlice } from "../features/activityJS/saverSlice";
|
|
9
|
+
import { functionalitiesSlice } from "../features/functionalities/functionalitiesSlice";
|
|
10
|
+
|
|
11
|
+
// `combineSlices` automatically combines the reducers using
|
|
12
|
+
// their `reducerPath`s, therefore we no longer need to call `combineReducers`.
|
|
13
|
+
const rootReducer = combineSlices(
|
|
14
|
+
activityDataSlice,
|
|
15
|
+
themingSlice,
|
|
16
|
+
layoutSlice,
|
|
17
|
+
navbarSlice,
|
|
18
|
+
saverSlice,
|
|
19
|
+
functionalitiesSlice,
|
|
20
|
+
);
|
|
21
|
+
// Infer the `RootState` type from the root reducer
|
|
22
|
+
export type RootState = ReturnType<typeof rootReducer>;
|
|
23
|
+
|
|
24
|
+
// The store setup is wrapped in `makeStore` to allow reuse
|
|
25
|
+
// when setting up tests that need the same store config
|
|
26
|
+
export const makeStore = (preloadedState?: Partial<RootState>) => {
|
|
27
|
+
const store = configureStore({
|
|
28
|
+
reducer: rootReducer,
|
|
29
|
+
preloadedState,
|
|
30
|
+
middleware: (getDefaultMiddleware) =>
|
|
31
|
+
getDefaultMiddleware({
|
|
32
|
+
serializableCheck: false
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
// configure listeners using the provided defaults
|
|
36
|
+
// optional, but required for `refetchOnFocus`/`refetchOnReconnect` behaviors
|
|
37
|
+
setupListeners(store.dispatch);
|
|
38
|
+
return store;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const store = makeStore();
|
|
42
|
+
|
|
43
|
+
// Infer the type of `store`
|
|
44
|
+
export type AppStore = typeof store;
|
|
45
|
+
// Infer the `AppDispatch` type from the store itself
|
|
46
|
+
export type AppDispatch = AppStore["dispatch"];
|
|
47
|
+
export type AppThunk<ThunkReturnType = void> = ThunkAction<
|
|
48
|
+
ThunkReturnType,
|
|
49
|
+
RootState,
|
|
50
|
+
unknown,
|
|
51
|
+
Action
|
|
52
|
+
>;
|
package/src/app.module.scss
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
.app {
|
|
2
|
-
height: 100%;
|
|
3
|
-
height: 100dvh;
|
|
4
|
-
display: grid;
|
|
5
|
-
grid-template-rows: auto 1fr;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.navbarContainer {
|
|
9
|
-
min-width: 0;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.appPedagoSplitter {
|
|
13
|
-
height: 100%;
|
|
14
|
-
border: none;
|
|
15
|
-
border-radius: 0;
|
|
16
|
-
overflow-y: hidden;
|
|
17
|
-
& > * {
|
|
18
|
-
overflow-y: hidden;
|
|
19
|
-
}
|
|
20
|
-
.pedagoContainer[data-show-pedago="false"] & {
|
|
21
|
-
& > :first-child {
|
|
22
|
-
display: none;
|
|
23
|
-
}
|
|
24
|
-
& > :nth-child(2) {
|
|
25
|
-
display: none;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.pedagoPanel {
|
|
31
|
-
width: 100%;
|
|
32
|
-
height: 100%;
|
|
33
|
-
overflow-y: hidden;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.contentPanel {
|
|
37
|
-
height: 100%;
|
|
38
|
-
background-color: var(--surface-a);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.pedagoContainer {
|
|
42
|
-
overflow-y: hidden;
|
|
43
|
-
display: grid;
|
|
44
|
-
:global(.layout-horizontal) & {
|
|
45
|
-
grid-template-columns: 1fr;
|
|
46
|
-
grid-template-rows: 1.2rem 1fr;
|
|
47
|
-
}
|
|
48
|
-
:global(.layout-vertical) & {
|
|
49
|
-
grid-template-rows: 1fr;
|
|
50
|
-
grid-template-columns: 1.2rem 1fr;
|
|
51
|
-
}
|
|
52
|
-
&[data-show-pedago="true"] {
|
|
53
|
-
display: block;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
.hiddenPedago {
|
|
58
|
-
background-color: var(--surface-200);
|
|
59
|
-
.pedagoContainer[data-show-pedago="true"] & {
|
|
60
|
-
display: none;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.hiddenPedagoButton {
|
|
65
|
-
width: 100%;
|
|
66
|
-
height: 100%;
|
|
67
|
-
display: flex;
|
|
68
|
-
justify-content: center;
|
|
69
|
-
align-items: center;
|
|
70
|
-
cursor: pointer;
|
|
71
|
-
& > i {
|
|
72
|
-
font-size: 1rem;
|
|
73
|
-
}
|
|
74
|
-
&:hover {
|
|
75
|
-
background-color: rgba(128, 128, 128, 0.05);
|
|
76
|
-
}
|
|
77
|
-
&:active {
|
|
78
|
-
background-color: rgba(128, 128, 128, 0.2);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
1
|
+
.app {
|
|
2
|
+
height: 100%;
|
|
3
|
+
height: 100dvh;
|
|
4
|
+
display: grid;
|
|
5
|
+
grid-template-rows: auto 1fr;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.navbarContainer {
|
|
9
|
+
min-width: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.appPedagoSplitter {
|
|
13
|
+
height: 100%;
|
|
14
|
+
border: none;
|
|
15
|
+
border-radius: 0;
|
|
16
|
+
overflow-y: hidden;
|
|
17
|
+
& > * {
|
|
18
|
+
overflow-y: hidden;
|
|
19
|
+
}
|
|
20
|
+
.pedagoContainer[data-show-pedago="false"] & {
|
|
21
|
+
& > :first-child {
|
|
22
|
+
display: none;
|
|
23
|
+
}
|
|
24
|
+
& > :nth-child(2) {
|
|
25
|
+
display: none;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.pedagoPanel {
|
|
31
|
+
width: 100%;
|
|
32
|
+
height: 100%;
|
|
33
|
+
overflow-y: hidden;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.contentPanel {
|
|
37
|
+
height: 100%;
|
|
38
|
+
background-color: var(--surface-a);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.pedagoContainer {
|
|
42
|
+
overflow-y: hidden;
|
|
43
|
+
display: grid;
|
|
44
|
+
:global(.layout-horizontal) & {
|
|
45
|
+
grid-template-columns: 1fr;
|
|
46
|
+
grid-template-rows: 1.2rem 1fr;
|
|
47
|
+
}
|
|
48
|
+
:global(.layout-vertical) & {
|
|
49
|
+
grid-template-rows: 1fr;
|
|
50
|
+
grid-template-columns: 1.2rem 1fr;
|
|
51
|
+
}
|
|
52
|
+
&[data-show-pedago="true"] {
|
|
53
|
+
display: block;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.hiddenPedago {
|
|
58
|
+
background-color: var(--surface-200);
|
|
59
|
+
.pedagoContainer[data-show-pedago="true"] & {
|
|
60
|
+
display: none;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.hiddenPedagoButton {
|
|
65
|
+
width: 100%;
|
|
66
|
+
height: 100%;
|
|
67
|
+
display: flex;
|
|
68
|
+
justify-content: center;
|
|
69
|
+
align-items: center;
|
|
70
|
+
cursor: pointer;
|
|
71
|
+
& > i {
|
|
72
|
+
font-size: 1rem;
|
|
73
|
+
}
|
|
74
|
+
&:hover {
|
|
75
|
+
background-color: rgba(128, 128, 128, 0.05);
|
|
76
|
+
}
|
|
77
|
+
&:active {
|
|
78
|
+
background-color: rgba(128, 128, 128, 0.2);
|
|
79
|
+
}
|
|
80
|
+
}
|