Skip to content

Commit 71b1ebc

Browse files
committed
remove old language directory attempt and clean up
1 parent a8ea7c0 commit 71b1ebc

20 files changed

+100
-192
lines changed

src/commons/application/ApplicationTypes.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { PlaybackStatus, RecordingStatus } from '../../features/sourceRecorder/S
99
import type { StoriesEnvState, StoriesState } from '../../features/stories/StoriesTypes';
1010
import { freshSortState } from '../../pages/academy/grading/subcomponents/GradingSubmissionsTable';
1111
import { WORKSPACE_BASE_PATHS } from '../../pages/fileSystem/createInBrowserFileSystem';
12-
import { getSupportedLanguages, ILanguageDefinition } from '../directory/language';
1312
import { defaultFeatureFlags, FeatureFlagsState } from '../featureFlags';
1413
import type { FileSystemState } from '../fileSystem/FileSystemTypes';
1514
import type { SideContentManagerState, SideContentState } from '../sideContent/SideContentTypes';
@@ -372,16 +371,9 @@ const getDefaultLanguageConfig = (): SALanguage => {
372371
};
373372
export const defaultLanguageConfig: SALanguage = getDefaultLanguageConfig();
374373

375-
export const defaultConductorLanguage: ILanguageDefinition = getSupportedLanguages()[0] || {
376-
id: '',
377-
name: '',
378-
evaluators: []
379-
};
380-
381374
export const defaultPlayground: PlaygroundState = {
382375
githubSaveInfo: { repoName: '', filePath: '' },
383-
languageConfig: defaultLanguageConfig,
384-
conductorLanguage: defaultConductorLanguage
376+
languageConfig: defaultLanguageConfig
385377
};
386378

387379
export const defaultEditorValue = '// Type your program in here!';
@@ -626,7 +618,8 @@ export const defaultVscode: VscodeState = {
626618
export const defaultLanguageDirectory: LanguageDirectoryState = {
627619
selectedLanguageId: null,
628620
selectedEvaluatorId: null,
629-
languages: []
621+
languages: [],
622+
languageMap: {}
630623
};
631624

632625
export const defaultState: OverallState = {

src/commons/controlBar/ControlBarChapterSelect.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { Button, Menu, MenuItem } from '@blueprintjs/core';
22
import { IconNames } from '@blueprintjs/icons';
33
import { ItemListRenderer, ItemRenderer, Select } from '@blueprintjs/select';
44
import { Chapter, Variant } from 'js-slang/dist/types';
5+
import { IEvaluatorDefinition } from 'language-directory/dist/types';
56
import React, { useEffect } from 'react';
67
import { useDispatch } from 'react-redux';
78

89
import { flagDirectoryLanguageEnable } from '../../features/directory/flagDirectoryLanguageEnable';
910
import LanguageDirectoryActions from '../../features/directory/LanguageDirectoryActions';
10-
import type { IEvaluatorDefinition } from '../../features/directory/LanguageDirectoryTypes';
1111
import { SALanguage } from '../application/ApplicationTypes';
1212
import { useFeature } from '../featureFlags/useFeature';
1313
import { useTypedSelector } from '../utils/Hooks';

src/commons/directory/flagLangDirUrl.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/commons/directory/language.ts

Lines changed: 0 additions & 29 deletions
This file was deleted.

src/commons/featureFlags/FeatureFlag.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { SagaIterator } from 'redux-saga';
2+
13
export class FeatureFlag<T> {
24
private readonly _flagName: string;
35
private readonly _defaultValue: T;
46
private readonly _flagDesc?: string;
5-
private readonly _callback?: Function;
7+
private readonly _callback?: (newValue: any) => SagaIterator; // using any as the action wipes out type-param
68

79
get flagName(): string {
810
return this._flagName;
@@ -21,12 +23,11 @@ export class FeatureFlag<T> {
2123
flagName: string,
2224
defaultValue: T,
2325
flagDesc?: string,
24-
callback?: (newValue: T) => void
26+
callback?: (newValue: T) => SagaIterator
2527
) {
2628
this._flagName = flagName;
2729
this._defaultValue = defaultValue;
2830
this._flagDesc = flagDesc;
2931
this._callback = callback;
30-
this.onChange(defaultValue);
3132
}
3233
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { OverallState } from '../application/ApplicationTypes';
22
import { FeatureFlag } from './FeatureFlag';
33

4-
export const featureSelector = (featureFlag: FeatureFlag<any>) => (state: OverallState) =>
5-
state.featureFlags.modifiedFlags[featureFlag.flagName];
4+
export function featureSelector<T>(featureFlag: FeatureFlag<T>) {
5+
return (state: OverallState) => state.featureFlags.modifiedFlags[featureFlag.flagName] as T;
6+
}

src/commons/featureFlags/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createSlice } from '@reduxjs/toolkit';
2+
import { SagaIterator } from 'redux-saga';
23

34
import { FeatureFlag } from './FeatureFlag';
45

@@ -19,11 +20,9 @@ const featureFlagsSlice = createSlice({
1920
action: { payload: { featureFlag: FeatureFlag<T>; value: T } }
2021
) {
2122
state.modifiedFlags[action.payload.featureFlag.flagName] = action.payload.value;
22-
action.payload.featureFlag.onChange(action.payload.value);
2323
},
2424
resetFlag<T>(state: FeatureFlagsState, action: { payload: { featureFlag: FeatureFlag<T> } }) {
2525
delete state.modifiedFlags[action.payload.featureFlag.flagName];
26-
action.payload.featureFlag.onChange(action.payload.featureFlag.defaultValue);
2726
}
2827
}
2928
});
@@ -36,7 +35,7 @@ export function createFeatureFlag<T>(
3635
flagName: string,
3736
defaultValue: T,
3837
flagDesc?: string,
39-
callback?: (newValue: T) => void
38+
callback?: (newValue: T) => SagaIterator
4039
): FeatureFlag<T> {
4140
return new FeatureFlag<T>(flagName, defaultValue, flagDesc, callback);
4241
}

src/commons/navigationBar/subcomponents/NavigationBarLangSelectButton.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Position } from '@blueprintjs/core';
2-
import { useEffect, useState } from 'react';
2+
import { useState } from 'react';
33
import { useDispatch } from 'react-redux';
44
import { useFeature } from 'src/commons/featureFlags/useFeature';
55
import SimpleDropdown from 'src/commons/SimpleDropdown';
@@ -21,12 +21,6 @@ const NavigationBarLangSelectButton = () => {
2121

2222
const dispatch = useDispatch();
2323
const dirOptions = useDirectoryOptions();
24-
const languagesLoaded = useTypedSelector(s => s.languageDirectory.languages.length > 0);
25-
useEffect(() => {
26-
if (!languagesLoaded) {
27-
dispatch(LanguageDirectoryActions.fetchLanguages());
28-
}
29-
}, [languagesLoaded, dispatch]);
3024

3125
const directoryEnabled = useFeature(flagDirectoryLanguageEnable);
3226
if (!directoryEnabled) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { call } from 'redux-saga/effects';
2+
3+
import { FeatureFlagsActions } from '../featureFlags';
4+
import { combineSagaHandlers } from '../redux/utils';
5+
6+
const FeatureFlagSaga = combineSagaHandlers({
7+
[FeatureFlagsActions.setFlag.type]: function* ({ payload: { featureFlag, value } }) {
8+
yield call([featureFlag, 'onChange'], value);
9+
},
10+
[FeatureFlagsActions.resetFlag.type]: function* ({ payload: { featureFlag } }) {
11+
yield call([featureFlag, 'onChange'], featureFlag.defaultValue);
12+
}
13+
});
14+
15+
export default FeatureFlagSaga;
Lines changed: 45 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,59 @@
1-
import { call, put, select } from 'redux-saga/effects';
2-
import type { OverallState } from 'src/commons/application/ApplicationTypes';
3-
import { flagConductorEnable } from 'src/features/conductor/flagConductorEnable';
4-
import { flagConductorEvaluatorUrl } from 'src/features/conductor/flagConductorEvaluatorUrl';
5-
import { staticLanguageDirectoryProvider } from 'src/features/directory/LanguageDirectoryTypes';
1+
import { ILanguageDefinition } from 'language-directory/dist/types';
2+
import { getEvaluatorDefinition } from 'language-directory/dist/util';
3+
import { call, fork, put, select } from 'redux-saga/effects';
4+
import { selectDirectoryLanguageUrl } from 'src/features/directory/flagDirectoryLanguageUrl';
65

76
import LanguageDirectoryActions from '../../features/directory/LanguageDirectoryActions';
7+
import { LanguageDirectoryState } from '../../features/directory/LanguageDirectoryTypes';
8+
import type { OverallState } from '../application/ApplicationTypes';
89
import { combineSagaHandlers } from '../redux/utils';
9-
import { actions } from '../utils/ActionsHelper';
1010

11-
const LanguageDirectorySaga = combineSagaHandlers({
11+
export function* getLanguageDefinitionSaga() {
12+
const directory: LanguageDirectoryState = yield select(
13+
(state: OverallState) => state.languageDirectory
14+
);
15+
if (!directory.selectedLanguageId) return undefined;
16+
return directory.languageMap[directory.selectedLanguageId];
17+
}
18+
19+
export function* getEvaluatorDefinitionSaga() {
20+
const directory: LanguageDirectoryState = yield select(
21+
(state: OverallState) => state.languageDirectory
22+
);
23+
if (!directory.selectedEvaluatorId) return undefined;
24+
const language: ILanguageDefinition = yield call(getLanguageDefinitionSaga);
25+
if (!language) return undefined;
26+
return getEvaluatorDefinition(language, directory.selectedEvaluatorId);
27+
}
28+
29+
const languageDirectoryHandlers = combineSagaHandlers({
1230
[LanguageDirectoryActions.setLanguages.type]: function* () {
13-
const state = yield select((s: OverallState) => s.languageDirectory);
14-
if (state.selectedLanguageId === null && state.languages.length > 0) {
15-
yield put(actions.setSelectedLanguage(state.languages[0].id));
16-
}
17-
if (state.selectedEvaluatorId === null && state.languages.length > 0) {
18-
yield put(actions.setSelectedEvaluator(state.languages[0].evaluators[0].id));
31+
const directory = yield select((state: OverallState) => state.languageDirectory);
32+
if (directory.languages.length > 0) {
33+
yield put(LanguageDirectoryActions.setSelectedLanguage(directory.languages[0].id));
1934
}
2035
},
2136
[LanguageDirectoryActions.fetchLanguages.type]: function* () {
22-
const langs = yield call(
23-
staticLanguageDirectoryProvider.getLanguages.bind(staticLanguageDirectoryProvider)
24-
);
25-
yield put(actions.setLanguages(langs));
37+
const url = yield select(selectDirectoryLanguageUrl);
38+
const response = yield call(fetch, url);
39+
if (!response.ok) {
40+
throw new Error(`Can't retrieve language directory: ${response.status}`);
41+
}
42+
const result: ILanguageDefinition[] = yield call([response, 'json']);
43+
yield put(LanguageDirectoryActions.setLanguages(result));
2644
},
27-
[LanguageDirectoryActions.setSelectedLanguage.type]: function* (action) {
28-
const {
29-
payload: { languageId, evaluatorId }
30-
} = action;
31-
if (evaluatorId) return; // already explicitly set
32-
const language = yield call(
33-
staticLanguageDirectoryProvider.getLanguageById.bind(staticLanguageDirectoryProvider),
34-
languageId
35-
);
45+
[LanguageDirectoryActions.setSelectedLanguage.type]: function* () {
46+
const language = yield call(getLanguageDefinitionSaga);
3647
if (!language) return;
37-
const defaultEvaluatorId: string | null =
38-
language.evaluators.length > 0 ? language.evaluators[0].id : null;
39-
if (!defaultEvaluatorId) return;
40-
// If state still matches the same language, set evaluator
41-
const currentLanguageId: string | null = yield select(
42-
(s: OverallState) => s.languageDirectory.selectedLanguageId
43-
);
44-
if (currentLanguageId !== languageId) return;
45-
yield put(actions.setSelectedEvaluator(defaultEvaluatorId));
46-
},
47-
[LanguageDirectoryActions.setSelectedEvaluator.type]: function* (action) {
48-
const {
49-
payload: { evaluatorId }
50-
} = action;
51-
const selectedLanguageId: string | null = yield select(
52-
(s: OverallState) => s.languageDirectory.selectedLanguageId
53-
);
54-
if (!selectedLanguageId) return;
55-
const evaluator = yield call(
56-
staticLanguageDirectoryProvider.getEvaluatorDefinition.bind(staticLanguageDirectoryProvider),
57-
selectedLanguageId,
58-
evaluatorId
59-
);
60-
if (!evaluator) return;
61-
yield put(actions.setFlag({ featureFlag: flagConductorEnable, value: true }));
62-
yield put(actions.setFlag({ featureFlag: flagConductorEvaluatorUrl, value: evaluator.path }));
48+
if (language.evaluators.length > 0) {
49+
yield put(LanguageDirectoryActions.setSelectedEvaluator(language.evaluators[0].id));
50+
}
6351
}
6452
});
6553

54+
function* LanguageDirectorySaga() {
55+
yield fork(languageDirectoryHandlers);
56+
yield put(LanguageDirectoryActions.fetchLanguages());
57+
}
58+
6659
export default LanguageDirectorySaga;

0 commit comments

Comments
 (0)