Skip to content

Commit 8d69e4d

Browse files
authored
Merge branch 'master' into sayomaki-patch
2 parents 20cc1cc + a5b6f7d commit 8d69e4d

File tree

9 files changed

+159
-132
lines changed

9 files changed

+159
-132
lines changed

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
"@mantine/hooks": "^7.11.2",
3434
"@octokit/rest": "^20.0.0",
3535
"@reduxjs/toolkit": "^1.9.7",
36-
"@sentry/browser": "^7.57.0",
37-
"@sourceacademy/c-slang": "^1.0.20",
36+
"@sentry/browser": "^8.33.0",
37+
"@sourceacademy/c-slang": "^1.0.21",
3838
"@sourceacademy/sharedb-ace": "^2.0.3",
3939
"@sourceacademy/sling-client": "^0.1.0",
4040
"@szhsin/react-menu": "^4.0.0",
@@ -47,6 +47,7 @@
4747
"array-move": "^4.0.0",
4848
"browserfs": "^1.4.3",
4949
"classnames": "^2.3.2",
50+
"dayjs": "^1.11.13",
5051
"dompurify": "^3.1.6",
5152
"flexboxgrid": "^6.3.1",
5253
"flexboxgrid-helpers": "^1.1.3",
@@ -62,7 +63,6 @@
6263
"lz-string": "^1.4.4",
6364
"mdast-util-from-markdown": "^2.0.0",
6465
"mdast-util-to-hast": "^13.0.0",
65-
"moment": "^2.29.4",
6666
"normalize.css": "^8.0.1",
6767
"phaser": "^3.55.2",
6868
"query-string": "^9.0.0",
@@ -108,7 +108,7 @@
108108
"@craco/craco": "^7.1.0",
109109
"@svgr/webpack": "^8.0.0",
110110
"@testing-library/jest-dom": "^6.0.0",
111-
"@testing-library/react": "^14.0.0",
111+
"@testing-library/react": "^15.0.6",
112112
"@testing-library/user-event": "^14.4.3",
113113
"@types/dompurify": "^3.0.5",
114114
"@types/estree": "^1.0.5",

src/commons/achievement/utils/DateHelper.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import moment from 'moment';
1+
import dayjs from 'dayjs';
22

33
const now = new Date();
44

@@ -38,12 +38,12 @@ export const timeFromExpired = (deadline?: Date) =>
3838
export const prettifyDate = (deadline?: Date) => {
3939
if (deadline === undefined) return '';
4040

41-
return moment(deadline).format('D MMMM YYYY HH:mm');
41+
return dayjs(deadline).format('D MMMM YYYY HH:mm');
4242
};
4343

4444
export const prettifyTime = (time?: Date) => {
4545
if (time === undefined) return '';
46-
return moment(time).format('HH:mm');
46+
return dayjs(time).format('HH:mm');
4747
};
4848

4949
// Converts Date to deadline countdown
@@ -54,11 +54,11 @@ export const prettifyDeadline = (deadline?: Date) => {
5454
return 'Expired';
5555
}
5656

57-
const now = moment();
57+
const now = dayjs();
5858

59-
const weeksAway = Math.ceil(moment(deadline).diff(now, 'weeks', true));
60-
const daysAway = Math.ceil(moment(deadline).diff(now, 'days', true));
61-
const hoursAway = Math.ceil(moment(deadline).diff(now, 'hours', true));
59+
const weeksAway = Math.ceil(dayjs(deadline).diff(now, 'weeks', true));
60+
const daysAway = Math.ceil(dayjs(deadline).diff(now, 'days', true));
61+
const hoursAway = Math.ceil(dayjs(deadline).diff(now, 'hours', true));
6262

6363
let prettifiedDeadline = '';
6464
if (weeksAway > 1) {

src/commons/achievement/utils/InsertFakeAchievements.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import moment from 'moment';
1+
import dayjs from 'dayjs';
22

33
import {
44
cardBackgroundUrl,
@@ -23,7 +23,7 @@ function insertFakeAchievements(
2323
inferencer: AchievementInferencer
2424
) {
2525
const sortedOverviews = [...assessmentOverviews].sort((overview1, overview2) =>
26-
moment(overview1.closeAt).diff(moment(overview2.closeAt))
26+
dayjs(overview1.closeAt).diff(dayjs(overview2.closeAt))
2727
);
2828
const length = assessmentOverviews.length;
2929

src/commons/application/ApplicationTypes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,10 @@ export function isSchemeLanguage(chapter: Chapter): boolean {
214214
].includes(chapter);
215215
}
216216

217+
export function isCseVariant(variant: Variant): boolean {
218+
return variant == Variant.EXPLICIT_CONTROL;
219+
}
220+
217221
const pySubLanguages: Array<Pick<SALanguage, 'chapter' | 'variant' | 'displayName'>> = [
218222
{ chapter: Chapter.PYTHON_1, variant: Variant.DEFAULT, displayName: 'Python \xa71' }
219223
//{ chapter: Chapter.PYTHON_2, variant: Variant.DEFAULT, displayName: 'Python \xa72' },

src/commons/utils/DateHelper.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import moment from 'moment';
1+
import dayjs from 'dayjs';
2+
import advancedFormat from 'dayjs/plugin/advancedFormat';
3+
import relativeTime from 'dayjs/plugin/relativeTime';
4+
5+
dayjs.extend(advancedFormat);
6+
dayjs.extend(relativeTime);
27

38
/**
49
* Checks if a date is before or at the current time.
@@ -9,8 +14,8 @@ import moment from 'moment';
914
* is before the time of execution of this function.
1015
*/
1116
export const beforeNow = (dateString: string): boolean => {
12-
const date = moment(dateString);
13-
const now = moment();
17+
const date = dayjs(dateString);
18+
const now = dayjs();
1419
return date.isBefore(now);
1520
};
1621

@@ -25,25 +30,25 @@ export const beforeNow = (dateString: string): boolean => {
2530
* e.g 7th June, 20:09
2631
*/
2732
export const getPrettyDate = (dateString: string): string => {
28-
const date = moment(dateString);
33+
const date = dayjs(dateString);
2934
const prettyDate = date.format('Do MMMM, HH:mm');
3035
return prettyDate;
3136
};
3237

3338
export const getStandardDateTime = (dateString: string): string => {
34-
const date = moment(dateString);
39+
const date = dayjs(dateString);
3540
const prettyDate = date.format('MMMM Do YYYY, HH:mm');
3641
return prettyDate;
3742
};
3843

3944
export const getStandardDate = (dateString: string): string => {
40-
const date = moment(dateString);
45+
const date = dayjs(dateString);
4146
const prettyDate = date.format('MMMM Do YYYY');
4247
return prettyDate;
4348
};
4449

4550
export const getPrettyDateAfterHours = (dateString: string, hours: number): string => {
46-
const date = moment(dateString).add(hours, 'hours');
51+
const date = dayjs(dateString).add(hours, 'hours');
4752
const absolutePrettyDate = date.format('Do MMMM, HH:mm');
4853
const relativePrettyDate = date.fromNow();
4954
return `${absolutePrettyDate} (${relativePrettyDate})`;

src/pages/academy/groundControl/subcomponents/GroundControlEditCell.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Dialog, DialogBody, DialogFooter, Intent } from '@blueprintjs/core';
22
import { DateInput3 } from '@blueprintjs/datetime2';
33
import { IconNames } from '@blueprintjs/icons';
4-
import moment from 'moment';
4+
import dayjs from 'dayjs';
55
import React, { useCallback, useState } from 'react';
66

77
import { AssessmentOverview } from '../../../../commons/assessment/AssessmentTypes';
@@ -21,10 +21,10 @@ const EditCell: React.FC<Props> = ({ data, forOpenDate, handleAssessmentChangeDa
2121
const maxDate = new Date(2030, 11, 31);
2222

2323
const currentDateString = forOpenDate ? data.openAt : data.closeAt;
24-
const currentDate = moment(currentDateString, moment.ISO_8601, true);
24+
const currentDate = dayjs(currentDateString, undefined, true);
2525

2626
const [isDialogOpen, setDialogState] = useState(false);
27-
const [newDate, setNewDate] = useState<moment.Moment | null>(currentDate);
27+
const [newDate, setNewDate] = useState<dayjs.Dayjs | null>(currentDate);
2828

2929
const handleOpenDialog = useCallback(() => setDialogState(true), []);
3030
const handleCloseDialog = useCallback(() => setDialogState(false), []);
@@ -46,13 +46,13 @@ const EditCell: React.FC<Props> = ({ data, forOpenDate, handleAssessmentChangeDa
4646
}, [newDate, currentDate, data, handleAssessmentChangeDate, forOpenDate, handleCloseDialog]);
4747

4848
const handleParseDate = (str: string) => {
49-
const date = moment(str, dateDisplayFormat, true);
49+
const date = dayjs(str, dateDisplayFormat, true);
5050
return date.isValid() ? date.toDate() : false;
5151
};
52-
const handleFormatDate = (date: Date) => moment(date).format(dateDisplayFormat);
52+
const handleFormatDate = (date: Date) => dayjs(date).format(dateDisplayFormat);
5353

5454
const handleDateChange = React.useCallback(
55-
(selectedDate: string | null) => setNewDate(moment(selectedDate)),
55+
(selectedDate: string | null) => setNewDate(dayjs(selectedDate)),
5656
[]
5757
);
5858
const handleDateError = React.useCallback(() => {

src/pages/achievement/control/AchievementControl.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,18 @@ const AchievementControl: React.FC = () => {
3535
[dispatch]
3636
);
3737

38-
const inferencer = useTypedSelector(
39-
state => new AchievementInferencer(state.achievement.achievements, state.achievement.goals)
38+
// TODO: This is a hacky fix. By right, we shouldn't need to use an
39+
// inferencer instance since we can encapsulate the logic using hooks
40+
// and component state.
41+
const [initialAchievements, initialGoals] = useTypedSelector(state => [
42+
state.achievement.achievements,
43+
state.achievement.goals
44+
]);
45+
const inferencer = useMemo(
46+
() => new AchievementInferencer(initialAchievements, initialGoals),
47+
// We only want to create the inferencer once
48+
// eslint-disable-next-line react-hooks/exhaustive-deps
49+
[]
4050
);
4151

4252
/**

src/pages/playground/Playground.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
setSessionDetails,
1919
setSharedbConnected
2020
} from 'src/commons/collabEditing/CollabEditingActions';
21+
import { ControlBarExecutionTime } from 'src/commons/controlBar/ControlBarExecutionTime';
2122
import makeCseMachineTabFrom from 'src/commons/sideContent/content/SideContentCseMachine';
2223
import makeDataVisualizerTabFrom from 'src/commons/sideContent/content/SideContentDataVisualizer';
2324
import makeHtmlDisplayTabFrom from 'src/commons/sideContent/content/SideContentHtmlDisplay';
@@ -49,6 +50,7 @@ import {
4950
import {
5051
getDefaultFilePath,
5152
getLanguageConfig,
53+
isCseVariant,
5254
isSourceLanguage,
5355
OverallState,
5456
ResultOutput,
@@ -59,7 +61,6 @@ import { ControlBarAutorunButtons } from '../../commons/controlBar/ControlBarAut
5961
import { ControlBarChapterSelect } from '../../commons/controlBar/ControlBarChapterSelect';
6062
import { ControlBarClearButton } from '../../commons/controlBar/ControlBarClearButton';
6163
import { ControlBarEvalButton } from '../../commons/controlBar/ControlBarEvalButton';
62-
import { ControlBarExecutionTime } from '../../commons/controlBar/ControlBarExecutionTime';
6364
import { ControlBarGoogleDriveButtons } from '../../commons/controlBar/ControlBarGoogleDriveButtons';
6465
import { ControlBarSessionButtons } from '../../commons/controlBar/ControlBarSessionButton';
6566
import { ControlBarShareButton } from '../../commons/controlBar/ControlBarShareButton';
@@ -210,8 +211,8 @@ const Playground: React.FC<PlaygroundProps> = props => {
210211
editorTabs,
211212
editorSessionId,
212213
sessionDetails,
213-
execTime,
214214
stepLimit,
215+
execTime,
215216
isEditorAutorun,
216217
isRunning,
217218
isDebugging,
@@ -977,11 +978,11 @@ const Playground: React.FC<PlaygroundProps> = props => {
977978
languageConfig.supports.multiFile ? toggleFolderModeButton : null,
978979
persistenceButtons,
979980
githubButtons,
980-
usingRemoteExecution || !isSourceLanguage(languageConfig.chapter)
981-
? null
982-
: usingSubst || usingCse
983-
? stepperStepLimit
984-
: executionTime
981+
usingSubst || usingCse || isCseVariant(languageConfig.variant)
982+
? stepperStepLimit
983+
: isSourceLanguage(languageConfig.chapter)
984+
? executionTime
985+
: null
985986
]
986987
},
987988
editorContainerProps: editorContainerProps,

0 commit comments

Comments
 (0)