Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion mobile-app/lib/enums/ext_type.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
enum Ext { js, html, css, jsx }
enum Ext {
js('js'),
html('html'),
css('css'),
jsx('jsx');

final String value;
const Ext(this.value);
}

Ext parseExt(String ext) {
switch (ext) {
Expand Down
116 changes: 15 additions & 101 deletions mobile-app/lib/ui/views/learn/challenge/challenge_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -44,43 +44,12 @@ class ChallengeView extends StatelessWidget {

bool onlyJs = challenge.files.every((file) => file.ext.name == 'js');

bool editableRegion = currFile.editableRegionBoundaries.isNotEmpty;
EditorOptions options = EditorOptions(
hasRegion: editableRegion,
fontFamily: 'Hack',
);

Editor editor = Editor(
language: currFile.ext.name.toUpperCase(),
options: options,
);

model.initFile(editor, challenge, currFile, editableRegion);
model.listenToFocusedController(editor);
model.listenToSymbolBarScrollController();
model.initFile(challenge, currFile);

if (model.showPanel) {
FocusManager.instance.primaryFocus?.unfocus();
}

editor.onTextChange.stream.listen((text) {
model.fileService.saveFileInCache(
challenge,
model.currentSelectedFile,
text,
);

model.setEditorText = text;
model.setHasTypedInEditor = true;
model.setCompletedChallenge = false;
});

if (editableRegion) {
editor.editableRegion.stream.listen((region) {
model.setEditableRegionContent = region;
});
}

BoxDecoration decoration = const BoxDecoration(
border: Border(
bottom: BorderSide(
Expand All @@ -90,6 +59,12 @@ class ChallengeView extends StatelessWidget {
),
);

if (!model.mounted) {
return Center(
child: CircularProgressIndicator(),
);
}

return PopScope(
canPop: true,
onPopInvokedWithResult: (bool didPop, dynamic result) {
Expand Down Expand Up @@ -154,12 +129,7 @@ class ChallengeView extends StatelessWidget {
),
if (!model.showPreview && challenge.files.length > 1)
for (ChallengeFile file in challenge.files)
customTabBar(
model,
challenge,
file,
editor,
)
customTabBar(model, challenge, file)
],
),
),
Expand All @@ -179,7 +149,6 @@ class ChallengeView extends StatelessWidget {
model,
keyboard,
challenge,
editor,
context,
),
),
Expand All @@ -193,9 +162,9 @@ class ChallengeView extends StatelessWidget {
panel: model.panelType,
maxChallenges: maxChallenges,
challengesCompleted: challengesCompleted,
editor: editor,
editor: model.editor!,
),
Expanded(child: editor)
Expanded(child: model.editor!)
],
)
: Column(
Expand All @@ -207,7 +176,7 @@ class ChallengeView extends StatelessWidget {
panel: model.panelType,
maxChallenges: maxChallenges,
challengesCompleted: challengesCompleted,
editor: editor,
editor: model.editor!,
),
model.showProjectPreview && !onlyJs
? ProjectPreview(
Expand All @@ -231,7 +200,6 @@ class ChallengeView extends StatelessWidget {
ChallengeViewModel model,
Challenge challenge,
ChallengeFile file,
Editor editor,
) {
return Expanded(
child: Container(
Expand All @@ -251,31 +219,9 @@ class ChallengeView extends StatelessWidget {
),
onPressed: () async {
model.setCurrentSelectedFile = file.name;
model.setMounted = false;
ChallengeFile currFile = model.currentFile(challenge);

String currText = await model.fileService.getExactFileFromCache(
challenge,
currFile,
);
bool hasRegion = currFile.editableRegionBoundaries.isNotEmpty;

editor.fileTextStream.sink.add(
FileIDE(
id: challenge.id + currFile.name,
ext: currFile.ext.name.toUpperCase(),
name: currFile.name,
content: currText == '' ? currFile.contents : currText,
hasRegion: currFile.editableRegionBoundaries.isNotEmpty,
region: EditorRegionOptions(
start:
hasRegion ? currFile.editableRegionBoundaries[0] : null,
end: hasRegion ? currFile.editableRegionBoundaries[1] : null,
),
),
);

model.setEditorText = currText == '' ? currFile.contents : currText;
model.setShowPreview = false;
model.initFile(challenge, currFile);
},
child: Text(
'${file.name}.${file.ext.name}',
Expand All @@ -296,7 +242,6 @@ class ChallengeView extends StatelessWidget {
ChallengeViewModel model,
bool keyboard,
Challenge challenge,
Editor editor,
BuildContext context,
) {
return BottomAppBar(
Expand All @@ -308,7 +253,7 @@ class ChallengeView extends StatelessWidget {
if (keyboard)
SymbolBar(
model: model,
editor: editor,
editor: model.editor!,
),
Row(
children: [
Expand Down Expand Up @@ -398,38 +343,7 @@ class ChallengeView extends StatelessWidget {
onPressed: () async {
ChallengeFile currFile = model.currentFile(challenge);

String currText =
await model.fileService.getExactFileFromCache(
challenge,
currFile,
);

model.setMounted = false;

editor.fileTextStream.sink.add(FileIDE(
id: challenge.id + currFile.name,
ext: currFile.ext.name.toUpperCase(),
name: currFile.name,
content: currText == '' ? currFile.contents : currText,
hasRegion: currFile.editableRegionBoundaries.isNotEmpty,
region: EditorRegionOptions(
start: currFile.editableRegionBoundaries.isNotEmpty
? currFile.editableRegionBoundaries[0]
: null,
end: currFile.editableRegionBoundaries.isNotEmpty
? currFile.editableRegionBoundaries[1]
: null,
),
));
model.setEditorText =
currText == '' ? currFile.contents : currText;
model.setShowPreview = !model.showPreview;

if (!model.showProjectPreview && !model.showConsole) {
model.setShowProjectPreview = true;
}

model.refresh();
model.initFile(challenge, currFile);
},
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
Expand Down
107 changes: 75 additions & 32 deletions mobile-app/lib/ui/views/learn/challenge/challenge_viewmodel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,15 @@ class ChallengeViewModel extends BaseViewModel {
final InAppLocalhostServer _localhostServer =
InAppLocalhostServer(documentRoot: 'assets/test_runner');

Editor? _editor;
Editor? get editor => _editor;

String? _editorText;
String? get editorText => _editorText;

String _editorLanguage = 'html';
String get editorLanguage => _editorLanguage;

String _currentSelectedFile = '';
String get currentSelectedFile => _currentSelectedFile;

Expand Down Expand Up @@ -82,6 +88,7 @@ class ChallengeViewModel extends BaseViewModel {
Syntax get currFileType => _currFileType;

bool _mounted = false;
bool get mounted => _mounted;

// TestRunner? _testRunner;
// TestRunner? get testRunner => _testRunner;
Expand Down Expand Up @@ -228,6 +235,16 @@ class ChallengeViewModel extends BaseViewModel {
notifyListeners();
}

set setEditor(Editor editor) {
_editor = editor;
notifyListeners();
}

set setEditorLanguage(String value) {
_editorLanguage = value;
notifyListeners();
}

void init(
Block block,
Challenge challenge,
Expand All @@ -241,61 +258,87 @@ class ChallengeViewModel extends BaseViewModel {
setBlock = block;
setChallengesCompleted = challengesCompleted;

// _testRunner = TestRunner(
// model: this,
// challenge: challenge,
// builder: TestRunnerBuilder(
// source: '',
// code: Code(contents: ''),
// workerType: getWorkerType(challenge.challengeType),
// ),
// );
listenToSymbolBarScrollController();
}

void shutdownLocalHost() {
_localhostServer.close();
}

void initFile(
Editor editor,
Challenge challenge,
ChallengeFile currFile,
bool hasRegion,
) async {
if (!_mounted) {
await Future.delayed(Duration.zero);
String fileContents = await fileService.getExactFileFromCache(
challenge,
currFile,
);
editor.fileTextStream.sink.add(
FileIDE(
id: challenge.id + currFile.name,
ext: currFile.ext.name,
name: currFile.name,
content: fileContents,
hasRegion: hasRegion,
region: EditorRegionOptions(
start: hasRegion ? currFile.editableRegionBoundaries[0] : null,
end: hasRegion ? currFile.editableRegionBoundaries[1] : null,
condition: completedChallenge,
),
),
);
_mounted = true;

if (currFile.name != currentSelectedFile) {
setCurrentSelectedFile = currFile.name;
setEditorText = fileContents;
}
setCurrentSelectedFile = currFile.name;
setEditorText = fileContents;
setEditorLanguage = currFile.ext.value;
initEditor(challenge, currFile);
setMounted = true;
}
}

void listenToFocusedController(Editor editor) {
void initEditor(Challenge challenge, ChallengeFile file) {
bool editableRegion = file.editableRegionBoundaries.isNotEmpty;

EditorOptions options = EditorOptions(
hasRegion: editableRegion,
regionOptions: editableRegion
? EditorRegionOptions(
start: file.editableRegionBoundaries[0],
end: file.editableRegionBoundaries[1],
)
: null,
fontFamily: 'Hack',
);

Editor editor = Editor(
key: ValueKey(editorText),
defaultLanguage: editorLanguage,
defaultValue: editorText ?? '',
path: '/${challenge.id}/${file.name}',
options: options,
);

setEditor = editor;

initEditorListeners(challenge, file, editor);
}

void initEditorListeners(
Challenge challenge,
ChallengeFile file,
Editor editor,
) {
bool editableRegion = file.editableRegionBoundaries.isNotEmpty;

editor.textfieldData.stream.listen((textfieldData) {
setTextFieldData = textfieldData;
setShowPanel = false;
});

editor.onTextChange.stream.listen((text) {
fileService.saveFileInCache(
challenge,
currentSelectedFile,
text,
);

setEditorText = text;
setHasTypedInEditor = true;
setCompletedChallenge = false;
});

if (editableRegion) {
editor.editableRegion.stream.listen((region) {
setEditableRegionContent = region;
});
}
}

void listenToSymbolBarScrollController() {
Expand Down
7 changes: 3 additions & 4 deletions mobile-app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1300,10 +1300,9 @@ packages:
phone_ide:
dependency: "direct main"
description:
name: phone_ide
sha256: "6c9b69acd1ac46318c0a3a660abce936cf979d41a485109f2baf2697b42cea7e"
url: "https://pub.dev"
source: hosted
path: "../../phoneide"
relative: true
source: path
version: "1.5.1"
photo_view:
dependency: "direct main"
Expand Down
3 changes: 2 additions & 1 deletion mobile-app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ dependencies:
just_audio: 0.10.2
path: 1.9.1
path_provider: 2.1.5
phone_ide: 1.5.1
phone_ide:
path: ../../phoneide
photo_view: 0.15.0
pretty_dio_logger: 1.4.0
quick_actions: 1.1.0
Expand Down
Loading