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 0702451  Merge pull request #16892 from [BEAM-13755] [Playground] 
Scroll the opened example to the context line
0702451 is described below

commit 07024513d7775a599c9c90768a6903909a0d1656
Author: Alexander Zhuravlev <alexander.zhurav...@akvelon.com>
AuthorDate: Mon Feb 28 20:50:51 2022 +0400

    Merge pull request #16892 from [BEAM-13755] [Playground] Scroll the opened 
example to the context line
    
    * [BEAM-13755] Added contextLine parameter to examples, reworked text 
scrolling
    
    * [BEAM-13755] Improving text scrolling
    
    * [BEAM-13755] Updated text scrolling in the editor textarea
    
    * [BEAM-13755] Fixed PR Remarks
---
 .../modules/editor/components/editor_textarea.dart | 94 +++++++++++++++-------
 .../lib/modules/examples/models/example_model.dart |  2 +
 .../example_client/grpc_example_client.dart        |  1 +
 3 files changed, 67 insertions(+), 30 deletions(-)

diff --git 
a/playground/frontend/lib/modules/editor/components/editor_textarea.dart 
b/playground/frontend/lib/modules/editor/components/editor_textarea.dart
index 42e505d..cef01cf 100644
--- a/playground/frontend/lib/modules/editor/components/editor_textarea.dart
+++ b/playground/frontend/lib/modules/editor/components/editor_textarea.dart
@@ -31,7 +31,6 @@ import 
'package:playground/modules/examples/models/example_model.dart';
 import 'package:playground/modules/sdk/models/sdk.dart';
 import 'package:provider/provider.dart';
 
-const kNumberOfStringsToSkip = 16;
 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';
 const kGoRegExp = r'[^\S\r\n]+\'
@@ -39,6 +38,7 @@ const kGoRegExp = r'[^\S\r\n]+\'
     r'.*'
     r'"'
     r'\n\)\n\n';
+const kAdditionalLinesForScrolling = 4;
 
 class EditorTextArea extends StatefulWidget {
   final SDK sdk;
@@ -65,6 +65,7 @@ class EditorTextArea extends StatefulWidget {
 class _EditorTextAreaState extends State<EditorTextArea> {
   CodeController? _codeController;
   var focusNode = FocusNode();
+  final GlobalKey codeFieldKey = LabeledGlobalKey('CodeFieldKey');
 
   @override
   void initState() {
@@ -86,10 +87,6 @@ class _EditorTextAreaState extends State<EditorTextArea> {
       webSpaceFix: false,
     );
 
-    if (widget.enableScrolling) {
-      _setTextScrolling();
-    }
-
     super.didChangeDependencies();
   }
 
@@ -102,6 +99,8 @@ class _EditorTextAreaState extends State<EditorTextArea> {
 
   @override
   Widget build(BuildContext context) {
+    WidgetsBinding.instance!.addPostFrameCallback((_) => _setTextScrolling());
+
     return Semantics(
       container: true,
       textField: true,
@@ -112,6 +111,7 @@ class _EditorTextAreaState extends State<EditorTextArea> {
       child: FocusScope(
         node: FocusScopeNode(canRequestFocus: widget.isEditable),
         child: CodeField(
+          key: codeFieldKey,
           focusNode: focusNode,
           enabled: widget.enabled,
           controller: _codeController!,
@@ -133,44 +133,78 @@ class _EditorTextAreaState extends State<EditorTextArea> {
     focusNode.requestFocus();
     if (_codeController!.text.isNotEmpty) {
       _codeController!.selection = TextSelection.fromPosition(
-        TextPosition(offset: _findOffset()),
+        TextPosition(
+          offset: _getOffset(),
+        ),
       );
     }
   }
 
-  _findOffset() {
+  int _getOffset() {
+    int contextLine = _getIndexOfContextLine();
+    String pattern = _getPattern(_getQntOfStringsOnScreen());
+
+    if (pattern == '' || pattern == '}') {
+      return _codeController!.text.lastIndexOf(pattern);
+    }
+
     return _codeController!.text.indexOf(
-      _skipStrings(kNumberOfStringsToSkip),
-      _getPositionAfterImportsAndLicenses(widget.sdk),
+      pattern,
+      contextLine,
     );
   }
 
-  String _skipStrings(int qntOfStrings) {
-    List<String> strings = _codeController!.text
-        .substring(_getPositionAfterImportsAndLicenses(widget.sdk))
-        .split('\n');
+  String _getPattern(int qntOfStrings) {
+    int contextLineIndex = _getIndexOfContextLine();
+    List<String> stringsAfterContextLine =
+        _codeController!.text.substring(contextLineIndex).split('\n');
+
     String result =
-        strings.length > qntOfStrings ? strings[qntOfStrings] : strings.last;
-    if (result == '') {
-      return _skipStrings(qntOfStrings - 1);
-    } else {
-      return result;
+        stringsAfterContextLine.length + kAdditionalLinesForScrolling >
+                qntOfStrings
+            ? _getResultSubstring(stringsAfterContextLine, qntOfStrings)
+            : stringsAfterContextLine.last;
+
+    return result;
+  }
+
+  int _getQntOfStringsOnScreen() {
+    RenderBox rBox =
+        codeFieldKey.currentContext?.findRenderObject() as RenderBox;
+    double height = rBox.size.height * .75;
+
+    return height ~/ kCodeFontSize;
+  }
+
+  int _getIndexOfContextLine() {
+    int ctxLineNumber = widget.example!.contextLine;
+    String contextLine = _codeController!.text.split('\n')[ctxLineNumber];
+
+    while (contextLine == '') {
+      ctxLineNumber -= 1;
+      contextLine = _codeController!.text.split('\n')[ctxLineNumber];
     }
+
+    return _codeController!.text.indexOf(contextLine);
   }
 
-  int _getPositionAfterImportsAndLicenses(SDK sdk) {
-    switch (sdk) {
-      case SDK.java:
-        return _codeController!.text.lastIndexOf(RegExp(kJavaRegExp));
-      case SDK.python:
-        return _codeController!.text.lastIndexOf(RegExp(kPythonRegExp));
-      case SDK.go:
-        return _codeController!.text.lastIndexOf(RegExp(kGoRegExp));
-      case SDK.scio:
-        return _codeController!.text.indexOf(
-          _codeController!.text.split('\n')[0],
-        );
+  // This function made for more accuracy in the process of finding an exact 
line.
+  String _getResultSubstring(
+    List<String> stringsAfterContextLine,
+    int qntOfStrings,
+  ) {
+    StringBuffer result = StringBuffer();
+
+    for (int i = qntOfStrings - kAdditionalLinesForScrolling;
+        i < qntOfStrings + kAdditionalLinesForScrolling;
+        i++) {
+      if (i == stringsAfterContextLine.length - 1) {
+        return result.toString();
+      }
+      result.write(stringsAfterContextLine[i] + '\n');
     }
+
+    return result.toString();
   }
 
   _getLanguageFromSdk() {
diff --git a/playground/frontend/lib/modules/examples/models/example_model.dart 
b/playground/frontend/lib/modules/examples/models/example_model.dart
index e6f850a..cd752c2 100644
--- a/playground/frontend/lib/modules/examples/models/example_model.dart
+++ b/playground/frontend/lib/modules/examples/models/example_model.dart
@@ -43,6 +43,7 @@ class ExampleModel with Comparable<ExampleModel> {
   final String name;
   final String path;
   final String description;
+  final int contextLine;
   bool isMultiFile;
   String? link;
   String? source;
@@ -56,6 +57,7 @@ class ExampleModel with Comparable<ExampleModel> {
     required this.path,
     required this.description,
     required this.type,
+    this.contextLine = 1,
     this.isMultiFile = false,
     this.link,
     this.source,
diff --git 
a/playground/frontend/lib/modules/examples/repositories/example_client/grpc_example_client.dart
 
b/playground/frontend/lib/modules/examples/repositories/example_client/grpc_example_client.dart
index 672b2e5..8c9f71e 100644
--- 
a/playground/frontend/lib/modules/examples/repositories/example_client/grpc_example_client.dart
+++ 
b/playground/frontend/lib/modules/examples/repositories/example_client/grpc_example_client.dart
@@ -223,6 +223,7 @@ class GrpcExampleClient implements ExampleClient {
       description: example.description,
       type: _exampleTypeFromString(example.type),
       path: example.cloudPath,
+      contextLine: example.contextLine,
       pipelineOptions: example.pipelineOptions,
       isMultiFile: example.multifile,
       link: example.link,

Reply via email to