You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by pa...@apache.org on 2022/07/07 20:58:33 UTC
[beam] branch master updated: Declarative theming, Remove duplicate PlaygroundState for embedded page, Do not re-create CodeController on language change (#22147)
This is an automated email from the ASF dual-hosted git repository.
pabloem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new 4c2236d2bf5 Declarative theming, Remove duplicate PlaygroundState for embedded page, Do not re-create CodeController on language change (#22147)
new ad25b8774b5 Merge pull request #22158 from Declarative theming, Remove duplicate PlaygroundState for embedded page, Do not re-create CodeController on language change (#22147)
4c2236d2bf5 is described below
commit 4c2236d2bf5712197783aa8d248a9f0e87bed269
Author: Alexey Inkin <al...@akvelon.com>
AuthorDate: Mon Jul 4 12:50:22 2022 +0400
Declarative theming, Remove duplicate PlaygroundState for embedded page, Do not re-create CodeController on language change (#22147)
---
.../modules/editor/components/editor_textarea.dart | 68 +++----------
.../modules/editor/components/editor_themes.dart | 9 +-
.../lib/modules/output/components/output.dart | 18 +++-
.../frontend/lib/modules/sdk/models/sdk.dart | 20 ++++
.../components/embedded_editor.dart | 2 +-
.../embedded_page_providers.dart | 106 ---------------------
.../embedded_playground_page.dart | 3 +-
.../components/editor_textarea_wrapper.dart | 29 +-----
.../components/playground_page_body.dart | 3 +-
.../components/playground_page_providers.dart | 99 +++++++++++++++----
.../pages/playground/states/examples_state.dart | 17 +++-
.../pages/playground/states/playground_state.dart | 47 ++++-----
playground/frontend/lib/pages/routes.dart | 20 ++--
playground/frontend/lib/playground_app.dart | 10 +-
playground/frontend/pubspec.lock | 10 +-
playground/frontend/pubspec.yaml | 5 +-
16 files changed, 210 insertions(+), 256 deletions(-)
diff --git a/playground/frontend/lib/modules/editor/components/editor_textarea.dart b/playground/frontend/lib/modules/editor/components/editor_textarea.dart
index dfaf0eb0943..d3e7d3b6bda 100644
--- a/playground/frontend/lib/modules/editor/components/editor_textarea.dart
+++ b/playground/frontend/lib/modules/editor/components/editor_textarea.dart
@@ -19,17 +19,11 @@
import 'package:code_text_field/code_text_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-import 'package:highlight/languages/go.dart';
-import 'package:highlight/languages/java.dart';
-import 'package:highlight/languages/python.dart';
-import 'package:highlight/languages/scala.dart';
import 'package:playground/config/theme.dart';
import 'package:playground/constants/fonts.dart';
import 'package:playground/constants/sizes.dart';
-import 'package:playground/modules/editor/components/editor_themes.dart';
import 'package:playground/modules/examples/models/example_model.dart';
import 'package:playground/modules/sdk/models/sdk.dart';
-import 'package:provider/provider.dart';
const kJavaRegExp = r'import\s[A-z.0-9]*\;\n\n[(\/\*\*)|(public)|(class)]';
const kPythonRegExp = r'[^\S\r\n](import|as)[^\S\r\n][A-z]*\n\n';
@@ -41,18 +35,18 @@ const kGoRegExp = r'[^\S\r\n]+\'
const kAdditionalLinesForScrolling = 4;
class EditorTextArea extends StatefulWidget {
+ final CodeController codeController;
final SDK sdk;
final ExampleModel? example;
final bool enabled;
- final void Function(String)? onSourceChange;
final bool isEditable;
final bool isEmbedded;
const EditorTextArea({
Key? key,
+ required this.codeController,
required this.sdk,
this.example,
- this.onSourceChange,
required this.enabled,
required this.isEditable,
this.isEmbedded = false,
@@ -63,37 +57,12 @@ class EditorTextArea extends StatefulWidget {
}
class _EditorTextAreaState extends State<EditorTextArea> {
- CodeController? _codeController;
var focusNode = FocusNode();
final GlobalKey codeFieldKey = LabeledGlobalKey('CodeFieldKey');
- @override
- void initState() {
- super.initState();
- }
-
- @override
- void didChangeDependencies() {
- final themeProvider = Provider.of<ThemeProvider>(context, listen: true);
- _codeController = CodeController(
- text: _codeController?.text ?? widget.example?.source ?? '',
- language: _getLanguageFromSdk(),
- theme: themeProvider.isDarkMode ? kDarkCodeTheme : kLightCodeTheme,
- onChange: (newSource) {
- if (widget.onSourceChange != null) {
- widget.onSourceChange!(newSource);
- }
- },
- webSpaceFix: false,
- );
-
- super.didChangeDependencies();
- }
-
@override
void dispose() {
super.dispose();
- _codeController?.dispose();
focusNode.dispose();
}
@@ -116,7 +85,7 @@ class _EditorTextAreaState extends State<EditorTextArea> {
key: codeFieldKey,
focusNode: focusNode,
enabled: widget.enabled,
- controller: _codeController!,
+ controller: widget.codeController,
textStyle: getCodeFontStyle(
textStyle: const TextStyle(fontSize: kCodeFontSize),
),
@@ -131,10 +100,10 @@ class _EditorTextAreaState extends State<EditorTextArea> {
);
}
- _setTextScrolling() {
+ void _setTextScrolling() {
focusNode.requestFocus();
- if (_codeController!.text.isNotEmpty) {
- _codeController!.selection = TextSelection.fromPosition(
+ if (widget.codeController.text.isNotEmpty) {
+ widget.codeController.selection = TextSelection.fromPosition(
TextPosition(
offset: _getOffset(),
),
@@ -146,10 +115,10 @@ class _EditorTextAreaState extends State<EditorTextArea> {
int contextLine = _getIndexOfContextLine();
String pattern = _getPattern(_getQntOfStringsOnScreen());
if (pattern == '' || pattern == '}') {
- return _codeController!.text.lastIndexOf(pattern);
+ return widget.codeController.text.lastIndexOf(pattern);
}
- return _codeController!.text.indexOf(
+ return widget.codeController.text.indexOf(
pattern,
contextLine,
);
@@ -158,7 +127,7 @@ class _EditorTextAreaState extends State<EditorTextArea> {
String _getPattern(int qntOfStrings) {
int contextLineIndex = _getIndexOfContextLine();
List<String> stringsAfterContextLine =
- _codeController!.text.substring(contextLineIndex).split('\n');
+ widget.codeController.text.substring(contextLineIndex).split('\n');
String result =
stringsAfterContextLine.length + kAdditionalLinesForScrolling >
@@ -179,14 +148,14 @@ class _EditorTextAreaState extends State<EditorTextArea> {
int _getIndexOfContextLine() {
int ctxLineNumber = widget.example!.contextLine;
- String contextLine = _codeController!.text.split('\n')[ctxLineNumber];
+ String contextLine = widget.codeController.text.split('\n')[ctxLineNumber];
while (contextLine == '') {
ctxLineNumber -= 1;
- contextLine = _codeController!.text.split('\n')[ctxLineNumber];
+ contextLine = widget.codeController.text.split('\n')[ctxLineNumber];
}
- return _codeController!.text.indexOf(contextLine);
+ return widget.codeController.text.indexOf(contextLine);
}
// This function made for more accuracy in the process of finding an exact line.
@@ -207,17 +176,4 @@ class _EditorTextAreaState extends State<EditorTextArea> {
return result.toString();
}
-
- _getLanguageFromSdk() {
- switch (widget.sdk) {
- case SDK.java:
- return java;
- case SDK.go:
- return go;
- case SDK.python:
- return python;
- case SDK.scio:
- return scala;
- }
- }
}
diff --git a/playground/frontend/lib/modules/editor/components/editor_themes.dart b/playground/frontend/lib/modules/editor/components/editor_themes.dart
index c26df0636d1..e29f1d6bfe4 100644
--- a/playground/frontend/lib/modules/editor/components/editor_themes.dart
+++ b/playground/frontend/lib/modules/editor/components/editor_themes.dart
@@ -16,10 +16,17 @@
* limitations under the License.
*/
+import 'package:code_text_field/code_text_field.dart';
import 'package:flutter/material.dart';
import 'package:playground/config/theme.dart';
-Map<String, TextStyle> createTheme(ThemeColors colors) {
+CodeThemeData createTheme(ThemeColors colors) {
+ return CodeThemeData(
+ styles: _createThemeStyles(colors),
+ );
+}
+
+Map<String, TextStyle> _createThemeStyles(ThemeColors colors) {
return {
'root': TextStyle(
backgroundColor: colors.primaryBackground,
diff --git a/playground/frontend/lib/modules/output/components/output.dart b/playground/frontend/lib/modules/output/components/output.dart
index 887a5da3a89..1f6dac63837 100644
--- a/playground/frontend/lib/modules/output/components/output.dart
+++ b/playground/frontend/lib/modules/output/components/output.dart
@@ -19,6 +19,7 @@
import 'package:flutter/material.dart';
import 'package:playground/modules/output/components/output_area.dart';
import 'package:playground/modules/output/components/output_header/output_header.dart';
+import 'package:playground/pages/playground/states/playground_state.dart';
const kTabsCount = 2;
@@ -26,8 +27,15 @@ class Output extends StatefulWidget {
final bool isEmbedded;
final bool showGraph;
- const Output({Key? key, required this.isEmbedded, required this.showGraph})
- : super(key: key);
+ Output({
+ required this.isEmbedded,
+ required PlaygroundState playgroundState,
+ }) : showGraph = playgroundState.graphAvailable,
+ super(
+ key: ValueKey(
+ '${playgroundState.sdk}_${playgroundState.selectedExample?.path}',
+ ),
+ );
@override
State<Output> createState() => _OutputState();
@@ -41,18 +49,18 @@ class _OutputState extends State<Output> with SingleTickerProviderStateMixin {
void initState() {
final tabsCount = widget.showGraph ? kTabsCount : kTabsCount - 1;
tabController = TabController(vsync: this, length: tabsCount);
- tabController.addListener(onTabChange);
+ tabController.addListener(_onTabChange);
super.initState();
}
@override
void dispose() {
- tabController.removeListener(onTabChange);
+ tabController.removeListener(_onTabChange);
tabController.dispose();
super.dispose();
}
- onTabChange() {
+ void _onTabChange() {
setState(() {
selectedTab = tabController.index;
});
diff --git a/playground/frontend/lib/modules/sdk/models/sdk.dart b/playground/frontend/lib/modules/sdk/models/sdk.dart
index 392fb07d988..17283fcb0b1 100644
--- a/playground/frontend/lib/modules/sdk/models/sdk.dart
+++ b/playground/frontend/lib/modules/sdk/models/sdk.dart
@@ -16,6 +16,11 @@
* limitations under the License.
*/
+import 'package:highlight/highlight.dart';
+import 'package:highlight/languages/go.dart';
+import 'package:highlight/languages/java.dart';
+import 'package:highlight/languages/python.dart';
+import 'package:highlight/languages/scala.dart';
import 'package:playground/config.g.dart';
enum SDK {
@@ -56,3 +61,18 @@ extension SdkToRoute on SDK {
}
}
}
+
+extension SdkToHighlightMode on SDK {
+ Mode get highlightMode {
+ switch (this) {
+ case SDK.java:
+ return java;
+ case SDK.go:
+ return go;
+ case SDK.python:
+ return python;
+ case SDK.scio:
+ return scala;
+ }
+ }
+}
diff --git a/playground/frontend/lib/pages/embedded_playground/components/embedded_editor.dart b/playground/frontend/lib/pages/embedded_playground/components/embedded_editor.dart
index 094a12fe618..fdaa8679f7c 100644
--- a/playground/frontend/lib/pages/embedded_playground/components/embedded_editor.dart
+++ b/playground/frontend/lib/pages/embedded_playground/components/embedded_editor.dart
@@ -30,11 +30,11 @@ class EmbeddedEditor extends StatelessWidget {
Widget build(BuildContext context) {
final state = Provider.of<PlaygroundState>(context);
return EditorTextArea(
+ codeController: state.codeController,
key: ValueKey(state.selectedExample),
enabled: true,
sdk: state.sdk,
example: state.selectedExample,
- onSourceChange: state.setSource,
isEditable: isEditable,
isEmbedded: true,
);
diff --git a/playground/frontend/lib/pages/embedded_playground/embedded_page_providers.dart b/playground/frontend/lib/pages/embedded_playground/embedded_page_providers.dart
deleted file mode 100644
index dbf497632e5..00000000000
--- a/playground/frontend/lib/pages/embedded_playground/embedded_page_providers.dart
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import 'package:flutter/material.dart';
-import 'package:playground/constants/params.dart';
-import 'package:playground/modules/examples/models/example_model.dart';
-import 'package:playground/modules/output/models/output_placement_state.dart';
-import 'package:playground/pages/embedded_playground/embedded_playground_page.dart';
-import 'package:playground/pages/playground/components/playground_page_providers.dart';
-import 'package:playground/pages/playground/states/examples_state.dart';
-import 'package:playground/pages/playground/states/playground_state.dart';
-import 'package:provider/provider.dart';
-
-class EmbeddedPageProviders extends StatelessWidget {
- const EmbeddedPageProviders({Key? key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- return MultiProvider(
- providers: [
- ChangeNotifierProvider<ExampleState>(
- create: (context) => ExampleState(kExampleRepository),
- ),
- ChangeNotifierProxyProvider<ExampleState, PlaygroundState>(
- create: (context) => PlaygroundState(codeRepository: kCodeRepository),
- update: (context, exampleState, playground) {
- if (playground == null) {
- return PlaygroundState(codeRepository: kCodeRepository);
- }
-
- if (playground.selectedExample == null) {
- final example = _getEmbeddedExample();
- _loadExampleData(
- example,
- exampleState,
- playground,
- );
- }
- return playground;
- },
- ),
- ChangeNotifierProvider<OutputPlacementState>(
- create: (context) => OutputPlacementState(),
- ),
- ],
- child: EmbeddedPlaygroundPage(
- isEditable: _isEditableToBool(),
- ),
- );
- }
-
- bool _isEditableToBool() {
- final isEditableString = Uri.base.queryParameters[kIsEditable];
- return isEditableString == 'true';
- }
-
- ExampleModel _getEmbeddedExample() {
- final examplePath = Uri.base.queryParameters[kExampleParam];
-
- return ExampleModel(
- name: 'Embedded_Example',
- path: examplePath ?? '',
- description: '',
- type: ExampleType.example,
- );
- }
-
- _loadExampleData(
- ExampleModel? example,
- ExampleState exampleState,
- PlaygroundState playground,
- ) {
- if (example == null) {
- return;
- }
-
- if (example.path.isEmpty) {
- String source = Uri.base.queryParameters[kSourceCode] ?? '';
- example.setSource(source);
- playground.setExample(example);
- } else {
- exampleState
- .getExample(example.path, playground.sdk)
- .then((example) => exampleState.loadExampleInfo(
- example,
- playground.sdk,
- ))
- .then((exampleWithInfo) => playground.setExample(exampleWithInfo));
- }
- }
-}
diff --git a/playground/frontend/lib/pages/embedded_playground/embedded_playground_page.dart b/playground/frontend/lib/pages/embedded_playground/embedded_playground_page.dart
index c2223cd16f8..8d4c41454f3 100644
--- a/playground/frontend/lib/pages/embedded_playground/embedded_playground_page.dart
+++ b/playground/frontend/lib/pages/embedded_playground/embedded_playground_page.dart
@@ -51,8 +51,7 @@ class EmbeddedPlaygroundPage extends StatelessWidget {
color: Theme.of(context).backgroundColor,
child: Output(
isEmbedded: true,
- showGraph: state.graphAvailable,
- key: ValueKey(state.selectedExample?.path ?? state.sdk.toString())
+ playgroundState: state,
),
),
),
diff --git a/playground/frontend/lib/pages/playground/components/editor_textarea_wrapper.dart b/playground/frontend/lib/pages/playground/components/editor_textarea_wrapper.dart
index 95a02e5940c..a5c2115fed0 100644
--- a/playground/frontend/lib/pages/playground/components/editor_textarea_wrapper.dart
+++ b/playground/frontend/lib/pages/playground/components/editor_textarea_wrapper.dart
@@ -24,9 +24,7 @@ import 'package:playground/modules/editor/components/editor_textarea.dart';
import 'package:playground/modules/editor/components/run_button.dart';
import 'package:playground/modules/examples/components/description_popover/description_popover_button.dart';
import 'package:playground/modules/examples/components/multifile_popover/multifile_popover_button.dart';
-import 'package:playground/modules/examples/models/example_model.dart';
import 'package:playground/modules/notifications/components/notification.dart';
-import 'package:playground/modules/sdk/models/sdk.dart';
import 'package:playground/pages/playground/states/playground_state.dart';
import 'package:playground/utils/analytics_utils.dart';
import 'package:provider/provider.dart';
@@ -43,21 +41,16 @@ class CodeTextAreaWrapper extends StatelessWidget {
});
}
return Column(
- key: ValueKey(EditorKeyObject(
- state.sdk,
- state.selectedExample,
- state.resetKey,
- )),
children: [
Expanded(
child: Stack(
children: [
Positioned.fill(
child: EditorTextArea(
+ codeController: state.codeController,
enabled: !(state.selectedExample?.isMultiFile ?? false),
example: state.selectedExample,
sdk: state.sdk,
- onSourceChange: state.setSource,
isEditable: true,
),
),
@@ -141,23 +134,3 @@ class CodeTextAreaWrapper extends StatelessWidget {
state.resetError();
}
}
-
-class EditorKeyObject {
- final SDK sdk;
- final ExampleModel? example;
- final DateTime? resetKey;
-
- const EditorKeyObject(this.sdk, this.example, this.resetKey);
-
- @override
- bool operator ==(Object other) =>
- identical(this, other) ||
- other is EditorKeyObject &&
- runtimeType == other.runtimeType &&
- sdk == other.sdk &&
- example == other.example &&
- resetKey == other.resetKey;
-
- @override
- int get hashCode => hashValues(sdk, example, resetKey);
-}
diff --git a/playground/frontend/lib/pages/playground/components/playground_page_body.dart b/playground/frontend/lib/pages/playground/components/playground_page_body.dart
index f7237fc9432..3b005d2a979 100644
--- a/playground/frontend/lib/pages/playground/components/playground_page_body.dart
+++ b/playground/frontend/lib/pages/playground/components/playground_page_body.dart
@@ -65,8 +65,7 @@ class PlaygroundPageBody extends StatelessWidget {
Widget createOutput(PlaygroundState state) => Output(
isEmbedded: false,
- showGraph: state.graphAvailable,
- key: ValueKey(state.selectedExample?.path ?? state.sdk.toString()),
+ playgroundState: state,
);
Widget getVerticalSeparator(BuildContext context) => Container(
diff --git a/playground/frontend/lib/pages/playground/components/playground_page_providers.dart b/playground/frontend/lib/pages/playground/components/playground_page_providers.dart
index b0a2bea1a97..beeb95e184b 100644
--- a/playground/frontend/lib/pages/playground/components/playground_page_providers.dart
+++ b/playground/frontend/lib/pages/playground/components/playground_page_providers.dart
@@ -58,19 +58,7 @@ class PlaygroundPageProviders extends StatelessWidget {
return PlaygroundState(codeRepository: kCodeRepository);
}
- if (playground.selectedExample == null &&
- !Uri.base.toString().contains(kIsEmbedded)) {
- final example = _getExample(exampleState, playground);
- if (example != null) {
- exampleState
- .loadExampleInfo(
- example,
- playground.sdk,
- )
- .then((exampleWithInfo) =>
- playground.setExample(exampleWithInfo));
- }
- }
+ _onExampleStateChanged(exampleState, playground);
return playground;
},
),
@@ -85,16 +73,93 @@ class PlaygroundPageProviders extends StatelessWidget {
);
}
- ExampleModel? _getExample(
+ void _onExampleStateChanged(
ExampleState exampleState,
- PlaygroundState playground,
+ PlaygroundState playgroundState,
) {
+ // This property currently doubles as a flag of initialization
+ // because it is initialized when an example is ready
+ // and is filled with a null-object if not showing any example.
+ //
+ // TODO: Add a dedicated flag of initialization or make
+ // PlaygroundState listen for examples and init itself.
+ if (playgroundState.selectedExample != null) {
+ return; // Already initialized.
+ }
+
+ if (_isEmbedded()) {
+ _initEmbedded(exampleState, playgroundState);
+ } else {
+ _initNonEmbedded(exampleState, playgroundState);
+ }
+ }
+
+ bool _isEmbedded() {
+ return Uri.base.toString().contains(kIsEmbedded);
+ }
+
+ Future<void> _initEmbedded(
+ ExampleState exampleState,
+ PlaygroundState playgroundState,
+ ) async {
+ final example = _getEmbeddedExample();
+
+ if (example.path.isEmpty) {
+ String source = Uri.base.queryParameters[kSourceCode] ?? '';
+ example.setSource(source);
+ playgroundState.setExample(example);
+ } else {
+ final loadedExample = await exampleState.getExample(
+ example.path,
+ playgroundState.sdk,
+ );
+
+ final exampleWithInfo = await exampleState.loadExampleInfo(
+ loadedExample,
+ playgroundState.sdk,
+ );
+
+ playgroundState.setExample(exampleWithInfo);
+ }
+ }
+
+ ExampleModel _getEmbeddedExample() {
final examplePath = Uri.base.queryParameters[kExampleParam];
- if (exampleState.defaultExamplesMap.isEmpty) {
- exampleState.loadDefaultExamples();
+ return ExampleModel(
+ name: 'Embedded_Example',
+ path: examplePath ?? '',
+ description: '',
+ type: ExampleType.example,
+ );
+ }
+
+ Future<void> _initNonEmbedded(
+ ExampleState exampleState,
+ PlaygroundState playgroundState,
+ ) async {
+ await exampleState.loadDefaultExamplesIfNot();
+
+ final example = await _getExample(exampleState, playgroundState);
+
+ if (example == null) {
+ return;
}
+ final exampleWithInfo = await exampleState.loadExampleInfo(
+ example,
+ playgroundState.sdk,
+ );
+
+ playgroundState.setExample(exampleWithInfo);
+ }
+
+ Future<ExampleModel?> _getExample(
+ ExampleState exampleState,
+ PlaygroundState playground,
+ ) async {
+ final examplePath = Uri.base.queryParameters[kExampleParam];
+
if (examplePath?.isEmpty ?? true) {
return exampleState.defaultExamplesMap[playground.sdk];
}
diff --git a/playground/frontend/lib/pages/playground/states/examples_state.dart b/playground/frontend/lib/pages/playground/states/examples_state.dart
index 256224ad54b..b080e361566 100644
--- a/playground/frontend/lib/pages/playground/states/examples_state.dart
+++ b/playground/frontend/lib/pages/playground/states/examples_state.dart
@@ -124,7 +124,7 @@ class ExampleState with ChangeNotifier {
notifyListeners();
}
- loadDefaultExamples() async {
+ Future<void> loadDefaultExamples() async {
if (defaultExamplesMap.isNotEmpty) {
return;
}
@@ -144,10 +144,23 @@ class ExampleState with ChangeNotifier {
}
defaultExamplesMap.addEntries(defaultExamples);
+ final futures = <Future<void>>[];
+
for (var entry in defaultExamplesMap.entries) {
- loadExampleInfo(entry.value, entry.key)
+ final exampleFuture = loadExampleInfo(entry.value, entry.key)
.then((value) => defaultExamplesMap[entry.key] = value);
+ futures.add(exampleFuture);
}
notifyListeners();
+
+ await Future.wait(futures);
+ }
+
+ Future<void> loadDefaultExamplesIfNot() async {
+ if (defaultExamplesMap.isNotEmpty) {
+ return;
+ }
+
+ await loadDefaultExamples();
}
}
diff --git a/playground/frontend/lib/pages/playground/states/playground_state.dart b/playground/frontend/lib/pages/playground/states/playground_state.dart
index 4923c756d4c..2340de7b8f8 100644
--- a/playground/frontend/lib/pages/playground/states/playground_state.dart
+++ b/playground/frontend/lib/pages/playground/states/playground_state.dart
@@ -19,6 +19,7 @@
import 'dart:async';
import 'dart:math';
+import 'package:code_text_field/code_text_field.dart';
import 'package:flutter/material.dart';
import 'package:playground/modules/editor/parsers/run_options_parser.dart';
import 'package:playground/modules/editor/repository/code_repository/code_repository.dart';
@@ -39,14 +40,13 @@ const kCachedResultsLog =
'The results of this example are taken from the Apache Beam Playground cache.\n';
class PlaygroundState with ChangeNotifier {
- late SDK _sdk;
+ final CodeController codeController;
+ SDK _sdk;
CodeRepository? _codeRepository;
ExampleModel? _selectedExample;
- String _source = '';
RunCodeResult? _result;
StreamSubscription<RunCodeResult>? _runSubscription;
String _pipelineOptions = '';
- DateTime? resetKey;
StreamController<int>? _executionTime;
OutputType? selectedOutputFilterType;
String? outputResult;
@@ -55,11 +55,14 @@ class PlaygroundState with ChangeNotifier {
SDK sdk = SDK.java,
ExampleModel? selectedExample,
CodeRepository? codeRepository,
- }) {
+ }) : _sdk = sdk,
+ codeController = CodeController(
+ language: sdk.highlightMode,
+ webSpaceFix: false,
+ ) {
_selectedExample = selectedExample;
_pipelineOptions = selectedExample?.pipelineOptions ?? '';
- _sdk = sdk;
- _source = _selectedExample?.source ?? '';
+ codeController.text = _selectedExample?.source ?? '';
_codeRepository = codeRepository;
selectedOutputFilterType = OutputType.all;
outputResult = '';
@@ -74,7 +77,7 @@ class PlaygroundState with ChangeNotifier {
SDK get sdk => _sdk;
- String get source => _source;
+ String get source => codeController.rawText;
bool get isCodeRunning => !(result?.isFinished ?? true);
@@ -96,50 +99,50 @@ class PlaygroundState with ChangeNotifier {
selectedExample?.type != ExampleType.test &&
[SDK.java, SDK.python].contains(sdk);
- setExample(ExampleModel example) {
+ void setExample(ExampleModel example) {
_selectedExample = example;
_pipelineOptions = example.pipelineOptions ?? '';
- _source = example.source ?? '';
+ codeController.text = example.source ?? '';
_result = null;
_executionTime = null;
setOutputResult('');
notifyListeners();
}
- setSdk(SDK sdk) {
+ void setSdk(SDK sdk) {
_sdk = sdk;
+ codeController.language = sdk.highlightMode;
notifyListeners();
}
- setSource(String source) {
- _source = source;
+ void setSource(String source) {
+ codeController.text = source;
}
- setSelectedOutputFilterType(OutputType type) {
+ void setSelectedOutputFilterType(OutputType type) {
selectedOutputFilterType = type;
notifyListeners();
}
- setOutputResult(String outputs) {
+ void setOutputResult(String outputs) {
outputResult = outputs;
notifyListeners();
}
- clearOutput() {
+ void clearOutput() {
_result = null;
notifyListeners();
}
- reset() {
- _source = _selectedExample?.source ?? '';
+ void reset() {
+ codeController.text = _selectedExample?.source ?? '';
_pipelineOptions = selectedExample?.pipelineOptions ?? '';
- resetKey = DateTime.now();
_executionTime = null;
setOutputResult('');
notifyListeners();
}
- resetError() {
+ void resetError() {
if (result == null) {
return;
}
@@ -147,7 +150,7 @@ class PlaygroundState with ChangeNotifier {
notifyListeners();
}
- setPipelineOptions(String options) {
+ void setPipelineOptions(String options) {
_pipelineOptions = options;
notifyListeners();
}
@@ -207,7 +210,7 @@ class PlaygroundState with ChangeNotifier {
notifyListeners();
}
- _showPrecompiledResult() async {
+ Future<void> _showPrecompiledResult() async {
_result = RunCodeResult(
status: RunCodeStatus.preparation,
);
@@ -254,7 +257,7 @@ class PlaygroundState with ChangeNotifier {
return streamController;
}
- filterOutput(OutputType type) {
+ void filterOutput(OutputType type) {
var output = result?.output ?? '';
var log = result?.log ?? '';
diff --git a/playground/frontend/lib/pages/routes.dart b/playground/frontend/lib/pages/routes.dart
index 34c59a66ea1..274368b7a8c 100644
--- a/playground/frontend/lib/pages/routes.dart
+++ b/playground/frontend/lib/pages/routes.dart
@@ -17,11 +17,11 @@
*/
import 'package:flutter/material.dart';
-import 'package:playground/pages/embedded_playground/embedded_page_providers.dart';
+import 'package:playground/constants/params.dart';
+import 'package:playground/pages/embedded_playground/embedded_playground_page.dart';
import 'package:playground/pages/playground/playground_page.dart';
class Routes {
- static const String playground = '/';
static const String embedded = '/embedded';
static Route<dynamic> generateRoute(RouteSettings settings) {
@@ -29,17 +29,23 @@ class Routes {
final queryIndex = name.indexOf('?');
final routePath =
name.substring(0, queryIndex < 0 ? name.length : queryIndex);
+
switch (routePath) {
- case Routes.playground:
- return Routes.renderRoute(const PlaygroundPage());
case Routes.embedded:
- return Routes.renderRoute(const EmbeddedPageProviders());
+ final isEditable = Uri.base.queryParameters[kIsEditable] == 'true';
+
+ return _renderRoute(
+ EmbeddedPlaygroundPage(
+ isEditable: isEditable,
+ ),
+ );
+
default:
- return Routes.renderRoute(const PlaygroundPage());
+ return _renderRoute(const PlaygroundPage());
}
}
- static renderRoute(Widget widget) {
+ static _renderRoute(Widget widget) {
return MaterialPageRoute(builder: (context) => widget);
}
}
diff --git a/playground/frontend/lib/playground_app.dart b/playground/frontend/lib/playground_app.dart
index 7a7ce8e3b9d..4fbde3ff576 100644
--- a/playground/frontend/lib/playground_app.dart
+++ b/playground/frontend/lib/playground_app.dart
@@ -16,12 +16,14 @@
* limitations under the License.
*/
+import 'package:code_text_field/code_text_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:playground/config/locale.dart';
import 'package:playground/config/theme.dart';
import 'package:playground/l10n/l10n.dart';
+import 'package:playground/modules/editor/components/editor_themes.dart';
import 'package:playground/pages/playground/components/playground_page_providers.dart';
import 'package:playground/pages/playground/playground_page.dart';
import 'package:playground/pages/routes.dart';
@@ -36,7 +38,9 @@ class PlaygroundApp extends StatelessWidget {
create: (context) => ThemeProvider()..init(),
builder: (context, _) {
final themeProvider = Provider.of<ThemeProvider>(context);
- return ChangeNotifierProvider<LocaleProvider>(
+ return CodeTheme(
+ data: themeProvider.isDarkMode ? kDarkCodeTheme : kLightCodeTheme,
+ child: ChangeNotifierProvider<LocaleProvider>(
create: (context) => LocaleProvider(),
builder: (context, state) {
final localeProvider = Provider.of<LocaleProvider>(context);
@@ -58,7 +62,9 @@ class PlaygroundApp extends StatelessWidget {
],
),
);
- });
+ },
+ ),
+ );
},
);
}
diff --git a/playground/frontend/pubspec.lock b/playground/frontend/pubspec.lock
index 5c6ec414b16..48bf1b10966 100644
--- a/playground/frontend/pubspec.lock
+++ b/playground/frontend/pubspec.lock
@@ -144,10 +144,12 @@ packages:
code_text_field:
dependency: "direct main"
description:
- name: code_text_field
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.2"
+ path: "."
+ ref: "9e2c9fe52a69481f038f4b6609e8a0a776429437"
+ resolved-ref: "9e2c9fe52a69481f038f4b6609e8a0a776429437"
+ url: "https://github.com/BertrandBev/code_field.git"
+ source: git
+ version: "1.0.3"
collection:
dependency: "direct main"
description:
diff --git a/playground/frontend/pubspec.yaml b/playground/frontend/pubspec.yaml
index b3f304f28ce..758f0f0d100 100644
--- a/playground/frontend/pubspec.yaml
+++ b/playground/frontend/pubspec.yaml
@@ -45,7 +45,10 @@ environment:
# versions available, run `flutter pub outdated`.
dependencies:
aligned_dialog: ^0.0.6
- code_text_field: ^1.0.0
+ code_text_field:
+ git:
+ url: https://github.com/BertrandBev/code_field.git
+ ref: 9e2c9fe52a69481f038f4b6609e8a0a776429437
collection: ^1.15.0
expansion_widget: ^0.0.2
flutter: