This is an automated email from the ASF dual-hosted git repository.
damccorm 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 691899a8466 [Tour of Beam] [Frontend] UI refinement from 01.06.23
(#26964)
691899a8466 is described below
commit 691899a84669c24fd59a659ca5acbaeaf4232b2f
Author: Darkhan Nausharipov <[email protected]>
AuthorDate: Wed Jun 21 21:11:40 2023 +0600
[Tour of Beam] [Frontend] UI refinement from 01.06.23 (#26964)
* default sdk, solution warning, bottom panel alignment
* deleted code
* markdown font sizes
* review
* removed Until we select an SDK the dropdown is not shown
* _checkSdksLoadedCorrectly fix
* _sdk in tour page test
* relaunch ci
* relaunch ci
* deleted import, print exception
* separate google forms url for tob
* relaunch ci
* relaunch ci
* prints in tabbed_snippet_editor for debugging
* reverted TabbedSnippetEditor with todo
---------
Co-authored-by: darkhan.nausharipov <[email protected]>
---
.../frontend/integration_test/tour_page_test.dart | 18 +++++-----
.../integration_test/welcome_page_test.dart | 17 +---------
.../frontend/lib/cache/unit_progress.dart | 18 ++++------
.../frontend/lib/components/footer.dart | 8 ++---
.../tour-of-beam/frontend/lib/components/logo.dart | 4 +--
.../frontend/lib/components/scaffold.dart | 15 ++++-----
.../tour-of-beam/frontend/lib/constants/links.dart | 13 ++------
.../params.dart} | 22 +-----------
.../lib/pages/tour/controllers/content_tree.dart | 8 ++---
.../tour-of-beam/frontend/lib/pages/tour/page.dart | 4 ---
.../frontend/lib/pages/tour/screen.dart | 39 ++++++++++++++--------
.../frontend/lib/pages/tour/state.dart | 23 +++++++------
.../lib/pages/tour/widgets/content_tree.dart | 26 +++++++++++++--
.../pages/tour/widgets/markdown/code_builder.dart | 16 +++++++--
.../lib/pages/tour/widgets/unit_content.dart | 14 ++++++--
.../frontend/lib/pages/welcome/screen.dart | 21 ++++++------
learning/tour-of-beam/frontend/lib/state.dart | 13 +++-----
.../copyright.dart => lib/constants/links.dart} | 13 ++------
.../modules/messages/parsers/messages_parser.dart | 1 +
.../widgets/playground_page_footer.dart | 2 ++
playground/frontend/lib/playground_app.dart | 1 -
.../lib/src/constants/links.dart | 7 ++--
.../playground_components/lib/src/theme/theme.dart | 30 +++++++++++------
.../lib/src/widgets/copyright.dart | 2 +-
.../lib/src/widgets/feedback.dart | 13 +++++---
.../lib/src/widgets/tabbed_snippet_editor.dart | 1 +
26 files changed, 171 insertions(+), 178 deletions(-)
diff --git
a/learning/tour-of-beam/frontend/integration_test/tour_page_test.dart
b/learning/tour-of-beam/frontend/integration_test/tour_page_test.dart
index a683eeff00c..bb6846c28e0 100644
--- a/learning/tour-of-beam/frontend/integration_test/tour_page_test.dart
+++ b/learning/tour-of-beam/frontend/integration_test/tour_page_test.dart
@@ -43,16 +43,15 @@ import 'package:tour_of_beam/state.dart';
import 'common/common.dart';
import 'common/common_finders.dart';
+const _sdk = Sdk.java;
+
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets(
'ToB miscellaneous ui',
(wt) async {
await init(wt);
-
- final sdkCache = GetIt.instance.get<SdkCache>();
- final sdks = sdkCache.getSdks();
- await wt.tapAndSettle(find.text(sdks.first.title));
+ await wt.tapAndSettle(find.outlinedButtonWithText(_sdk.title));
await wt.tapAndSettle(find.startTourButton());
await _checkContentTreeBuildsProperly(wt);
@@ -80,8 +79,7 @@ Future<void> _checkContentTreeBuildsProperly(WidgetTester wt)
async {
List<ModuleModel> _getModules(WidgetTester wt) {
final contentTreeCache = GetIt.instance.get<ContentTreeCache>();
- final controller = getContentTreeController(wt);
- final contentTree = contentTreeCache.getContentTree(controller.sdk);
+ final contentTree = contentTreeCache.getContentTree(_sdk);
return contentTree?.nodes ?? (throw Exception('Cannot load modules'));
}
@@ -123,7 +121,7 @@ Future<void> _checkUnitContentLoadsProperly(
) async {
await wt.tapAndSettle(find.byKey(Key(unit.id)));
- final hasSnippet = _getTourNotifier(wt).isUnitContainsSnippet;
+ final hasSnippet = _getTourNotifier(wt).isPlaygroundShown;
expect(
find.byType(PlaygroundWidget),
@@ -177,7 +175,7 @@ public class MyClass {
}
''';
- await _selectExampleWithSnippet(wt);
+ await _selectUnitWithSnippet(wt);
await wt.pumpAndSettle();
await wt.enterText(find.snippetCodeField(), code);
@@ -222,7 +220,7 @@ Future<void> _checkResizeUnitContent(WidgetTester wt) async
{
expectSimilar(startHandlePosition.dx, movedHandlePosition.dx - 100);
}
-Future<void> _selectExampleWithSnippet(WidgetTester wt) async {
+Future<void> _selectUnitWithSnippet(WidgetTester wt) async {
final tourNotifier = _getTourNotifier(wt);
final modules = _getModules(wt);
@@ -230,7 +228,7 @@ Future<void> _selectExampleWithSnippet(WidgetTester wt)
async {
for (final node in module.nodes) {
if (node is UnitModel) {
await _checkNode(node, wt);
- if (tourNotifier.isUnitContainsSnippet) {
+ if (tourNotifier.isPlaygroundShown) {
return;
}
}
diff --git
a/learning/tour-of-beam/frontend/integration_test/welcome_page_test.dart
b/learning/tour-of-beam/frontend/integration_test/welcome_page_test.dart
index 4af4029991b..6e54d02188c 100644
--- a/learning/tour-of-beam/frontend/integration_test/welcome_page_test.dart
+++ b/learning/tour-of-beam/frontend/integration_test/welcome_page_test.dart
@@ -52,18 +52,7 @@ Future<void> _checkSdksLoadedCorrectly(WidgetTester wt)
async {
);
}
- // Until we select an SDK the dropdown is not shown.
- expect(
- find.sdkDropdown(),
- findsNothing,
- );
-
- var button = wt.widget<ElevatedButton>(find.startTourButton());
- expect(button.onPressed, isNull); // Verify it is disabled.
-
- await wt.tapAndSettle(find.outlinedButtonWithText(sdks[0].title));
-
- button = wt.widget<ElevatedButton>(find.startTourButton());
+ final button = wt.widget<ElevatedButton>(find.startTourButton());
expect(button.onPressed, isNotNull); // Verify it is enabled.
await wt.tapAndSettle(find.sdkDropdown());
@@ -105,10 +94,6 @@ void _checkModulesDisplayed() {
final appNotifier = GetIt.instance.get<AppNotifier>();
final sdkId = appNotifier.sdk;
- if (sdkId == null) {
- throw Exception('sdkId is null');
- }
-
final contentTree = contentTreeCache.getContentTree(sdkId);
if (contentTree == null) {
throw Exception('contentTree is null');
diff --git a/learning/tour-of-beam/frontend/lib/cache/unit_progress.dart
b/learning/tour-of-beam/frontend/lib/cache/unit_progress.dart
index db72d000331..a13f9c4df84 100644
--- a/learning/tour-of-beam/frontend/lib/cache/unit_progress.dart
+++ b/learning/tour-of-beam/frontend/lib/cache/unit_progress.dart
@@ -75,7 +75,7 @@ class UnitProgressCache extends ChangeNotifier {
List<UnitProgressModel> _getUnitProgress() {
if (_future == null) {
- unawaited(loadUnitProgress(GetIt.instance.get<AppNotifier>().sdk!));
+ unawaited(loadUnitProgress(GetIt.instance.get<AppNotifier>().sdk));
}
return _unitProgress;
}
@@ -84,16 +84,14 @@ class UnitProgressCache extends ChangeNotifier {
Future<void> completeUnit(String sdkId, String unitId) async {
try {
- addUpdatingUnitId(unitId);
+ _addUpdatingUnitId(unitId);
await _getUserProgressRepository().completeUnit(sdkId, unitId);
} finally {
- await loadUnitProgress(GetIt.instance.get<AppNotifier>().sdk!);
- clearUpdatingUnitId(unitId);
+ await loadUnitProgress(GetIt.instance.get<AppNotifier>().sdk);
+ _clearUpdatingUnitId(unitId);
}
}
- Set<String> getUpdatingUnitIds() => _updatingUnitIds;
-
Set<String> getCompletedUnits() {
_completedUnitIds.clear();
for (final unitProgress in _getUnitProgress()) {
@@ -104,12 +102,12 @@ class UnitProgressCache extends ChangeNotifier {
return _completedUnitIds;
}
- void addUpdatingUnitId(String unitId) {
+ void _addUpdatingUnitId(String unitId) {
_updatingUnitIds.add(unitId);
notifyListeners();
}
- void clearUpdatingUnitId(String unitId) {
+ void _clearUpdatingUnitId(String unitId) {
_updatingUnitIds.remove(unitId);
notifyListeners();
}
@@ -125,10 +123,6 @@ class UnitProgressCache extends ChangeNotifier {
return getCompletedUnits().contains(unitId);
}
- String? getUnitSavedSnippetId(String? unitId) {
- return _unitProgressByUnitId[unitId]?.userSnippetId;
- }
-
UnitCompletion _getUnitCompletion(String unitId) {
final authNotifier = GetIt.instance.get<AuthNotifier>();
if (!authNotifier.isAuthenticated) {
diff --git a/learning/tour-of-beam/frontend/lib/components/footer.dart
b/learning/tour-of-beam/frontend/lib/components/footer.dart
index daba2dbe6e9..91ebf08f539 100644
--- a/learning/tour-of-beam/frontend/lib/components/footer.dart
+++ b/learning/tour-of-beam/frontend/lib/components/footer.dart
@@ -21,6 +21,7 @@ import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:playground_components/playground_components.dart';
+import '../constants/links.dart';
import '../constants/sizes.dart';
import '../state.dart';
@@ -44,6 +45,7 @@ class Footer extends StatelessWidget {
children: [
FeedbackWidget(
controller: GetIt.instance.get<FeedbackController>(),
+ feedbackFormUrl: tobFeedbackGoogleFormsUrl,
title: 'ui.feedbackTitle'.tr(),
),
ReportIssueButton(playgroundController: playgroundController),
@@ -90,13 +92,9 @@ class _BeamVersion extends StatelessWidget {
const _BeamVersion();
Future<String?> _getBeamSdkVersion() async {
- final sdk = GetIt.instance.get<AppNotifier>().sdk;
- if (sdk == null) {
- return null;
- }
final runnerVersion = await GetIt.instance
.get<BuildMetadataController>()
- .getRunnerVersion(sdk);
+ .getRunnerVersion(GetIt.instance.get<AppNotifier>().sdk);
return runnerVersion.beamSdkVersion;
}
diff --git a/learning/tour-of-beam/frontend/lib/components/logo.dart
b/learning/tour-of-beam/frontend/lib/components/logo.dart
index 913678c76bd..ef3aeef7267 100644
--- a/learning/tour-of-beam/frontend/lib/components/logo.dart
+++ b/learning/tour-of-beam/frontend/lib/components/logo.dart
@@ -24,9 +24,9 @@ class Logo extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Row(
+ return const Row(
mainAxisSize: MainAxisSize.min,
- children: const [
+ children: [
BeamLogo(),
_Text(),
],
diff --git a/learning/tour-of-beam/frontend/lib/components/scaffold.dart
b/learning/tour-of-beam/frontend/lib/components/scaffold.dart
index 6a4df44a171..da41b8cfbfa 100644
--- a/learning/tour-of-beam/frontend/lib/components/scaffold.dart
+++ b/learning/tour-of-beam/frontend/lib/components/scaffold.dart
@@ -126,15 +126,12 @@ class _SdkSelector extends StatelessWidget {
return AnimatedBuilder(
animation: appNotifier,
builder: (context, child) {
- final sdk = appNotifier.sdk;
- return sdk == null
- ? Container()
- : SdkDropdown(
- value: sdk,
- onChanged: (value) {
- appNotifier.sdk = value;
- },
- );
+ return SdkDropdown(
+ value: appNotifier.sdk,
+ onChanged: (value) {
+ appNotifier.sdk = value;
+ },
+ );
},
);
}
diff --git
a/playground/frontend/playground_components/lib/src/widgets/copyright.dart
b/learning/tour-of-beam/frontend/lib/constants/links.dart
similarity index 74%
copy from
playground/frontend/playground_components/lib/src/widgets/copyright.dart
copy to learning/tour-of-beam/frontend/lib/constants/links.dart
index 86b0346f285..de299ca23d4 100644
--- a/playground/frontend/playground_components/lib/src/widgets/copyright.dart
+++ b/learning/tour-of-beam/frontend/lib/constants/links.dart
@@ -16,14 +16,5 @@
* limitations under the License.
*/
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/widgets.dart';
-
-class CopyrightWidget extends StatelessWidget {
- const CopyrightWidget();
-
- @override
- Widget build(BuildContext context) {
- return const Text('ui.copyright').tr();
- }
-}
+const tobFeedbackGoogleFormsUrl =
+
'https://docs.google.com/forms/d/e/1FAIpQLSdI3yTmsCtk_neVPt0zQOPSmxDBlz3uX2AcmUpoNT6iGEwkUQ/viewform?usp=sharing';
diff --git
a/learning/tour-of-beam/frontend/lib/pages/tour/widgets/content_tree_title.dart
b/learning/tour-of-beam/frontend/lib/constants/params.dart
similarity index 59%
rename from
learning/tour-of-beam/frontend/lib/pages/tour/widgets/content_tree_title.dart
rename to learning/tour-of-beam/frontend/lib/constants/params.dart
index d92ff7605d8..306a73fdef3 100644
---
a/learning/tour-of-beam/frontend/lib/pages/tour/widgets/content_tree_title.dart
+++ b/learning/tour-of-beam/frontend/lib/constants/params.dart
@@ -16,26 +16,6 @@
* limitations under the License.
*/
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
import 'package:playground_components/playground_components.dart';
-class ContentTreeTitleWidget extends StatelessWidget {
- const ContentTreeTitleWidget();
-
- @override
- Widget build(BuildContext context) {
- return Padding(
- padding: const EdgeInsets.symmetric(vertical: BeamSizes.size12),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- 'pages.tour.summaryTitle',
- style: Theme.of(context).textTheme.headlineLarge,
- ).tr(),
- ],
- ),
- );
- }
-}
+const defaultSdk = Sdk.java;
diff --git
a/learning/tour-of-beam/frontend/lib/pages/tour/controllers/content_tree.dart
b/learning/tour-of-beam/frontend/lib/pages/tour/controllers/content_tree.dart
index 5f1aa132066..32f76a1a130 100644
---
a/learning/tour-of-beam/frontend/lib/pages/tour/controllers/content_tree.dart
+++
b/learning/tour-of-beam/frontend/lib/pages/tour/controllers/content_tree.dart
@@ -18,7 +18,6 @@
import 'package:flutter/widgets.dart';
import 'package:get_it/get_it.dart';
-import 'package:playground_components/playground_components.dart';
import '../../../cache/content_tree.dart';
@@ -28,7 +27,6 @@ import '../../../models/unit.dart';
import '../../../state.dart';
class ContentTreeController extends ChangeNotifier {
- final Sdk initialSdk;
List<String> _breadcrumbIds;
NodeModel? _currentNode;
final _contentTreeCache = GetIt.instance.get<ContentTreeCache>();
@@ -40,7 +38,6 @@ class ContentTreeController extends ChangeNotifier {
Set<String> get expandedIds => _expandedIds;
ContentTreeController({
- required this.initialSdk,
List<String> initialBreadcrumbIds = const [],
}) : _breadcrumbIds = initialBreadcrumbIds {
_expandedIds.addAll(initialBreadcrumbIds);
@@ -49,7 +46,6 @@ class ContentTreeController extends ChangeNotifier {
_onContentTreeCacheChange();
}
- Sdk get sdk => GetIt.instance.get<AppNotifier>().sdk ?? initialSdk;
List<String> get breadcrumbIds => _breadcrumbIds;
NodeModel? get currentNode => _currentNode;
@@ -109,7 +105,9 @@ class ContentTreeController extends ChangeNotifier {
}
void _onContentTreeCacheChange() {
- final contentTree = _contentTreeCache.getContentTree(sdk);
+ final contentTree = _contentTreeCache.getContentTree(
+ GetIt.instance.get<AppNotifier>().sdk,
+ );
if (contentTree == null) {
return;
}
diff --git a/learning/tour-of-beam/frontend/lib/pages/tour/page.dart
b/learning/tour-of-beam/frontend/lib/pages/tour/page.dart
index 929b280fa79..08a4a6ad839 100644
--- a/learning/tour-of-beam/frontend/lib/pages/tour/page.dart
+++ b/learning/tour-of-beam/frontend/lib/pages/tour/page.dart
@@ -18,7 +18,6 @@
import 'package:app_state/app_state.dart';
import 'package:flutter/widgets.dart';
-import 'package:playground_components/playground_components.dart';
import 'screen.dart';
import 'state.dart';
@@ -28,12 +27,10 @@ class TourPage extends StatefulMaterialPage<void,
TourNotifier> {
/// Called when navigating to the page programmatically.
TourPage({
- required Sdk sdk,
List<String> breadcrumbIds = const [],
}) : super(
key: const ValueKey(classFactoryKey),
state: TourNotifier(
- initialSdk: sdk,
initialBreadcrumbIds: breadcrumbIds,
),
createScreen: TourScreen.new,
@@ -44,7 +41,6 @@ class TourPage extends StatefulMaterialPage<void,
TourNotifier> {
final breadcrumbIds = state['breadcrumbIds'];
return TourPage(
- sdk: Sdk.parseOrCreate(state['sdkId']),
breadcrumbIds:
breadcrumbIds is List ? breadcrumbIds.cast<String>() : const [],
);
diff --git a/learning/tour-of-beam/frontend/lib/pages/tour/screen.dart
b/learning/tour-of-beam/frontend/lib/pages/tour/screen.dart
index 75cc77e6b9c..c9cc88fa3d4 100644
--- a/learning/tour-of-beam/frontend/lib/pages/tour/screen.dart
+++ b/learning/tour-of-beam/frontend/lib/pages/tour/screen.dart
@@ -44,7 +44,7 @@ class TourScreen extends StatelessWidget {
return TobShortcutsManager(
tourNotifier: tourNotifier,
child: TobScaffold(
- playgroundController: tourNotifier.isUnitContainsSnippet
+ playgroundController: tourNotifier.isPlaygroundShown
? tourNotifier.playgroundController
: null,
child:
@@ -87,23 +87,36 @@ class _UnitContentWidget extends StatelessWidget {
return AnimatedBuilder(
animation: tourNotifier,
builder: (context, widget) {
- return !tourNotifier.isUnitContainsSnippet
- ? UnitContentWidget(tourNotifier)
- : SplitView(
- direction: Axis.horizontal,
- dragHandleKey: TourScreen.dragHandleKey,
- first: UnitContentWidget(tourNotifier),
- second: tourNotifier.isSnippetLoading
- ? const Center(child: CircularProgressIndicator())
- : PlaygroundWidget(
- tourNotifier: tourNotifier,
- ),
- );
+ return tourNotifier.isPlaygroundShown
+ ? _UnitContentWithPlaygroundSplitView(tourNotifier)
+ : UnitContentWidget(tourNotifier);
},
);
}
}
+class _UnitContentWithPlaygroundSplitView extends StatelessWidget {
+ final TourNotifier tourNotifier;
+ const _UnitContentWithPlaygroundSplitView(this.tourNotifier);
+
+ @override
+ Widget build(BuildContext context) {
+ final isPlaygroundLoading = tourNotifier.currentUnitContent == null ||
+ tourNotifier.isSnippetLoading;
+
+ return SplitView(
+ direction: Axis.horizontal,
+ dragHandleKey: TourScreen.dragHandleKey,
+ first: UnitContentWidget(tourNotifier),
+ second: isPlaygroundLoading
+ ? const Center(child: CircularProgressIndicator())
+ : PlaygroundWidget(
+ tourNotifier: tourNotifier,
+ ),
+ );
+ }
+}
+
class _NarrowTour extends StatelessWidget {
final TourNotifier tourNotifier;
diff --git a/learning/tour-of-beam/frontend/lib/pages/tour/state.dart
b/learning/tour-of-beam/frontend/lib/pages/tour/state.dart
index c99df29d4c8..8b2a91f1d02 100644
--- a/learning/tour-of-beam/frontend/lib/pages/tour/state.dart
+++ b/learning/tour-of-beam/frontend/lib/pages/tour/state.dart
@@ -50,20 +50,18 @@ class TourNotifier extends ChangeNotifier with
PageStateMixin<void> {
final _unitContentCache = GetIt.instance.get<UnitContentCache>();
final _unitProgressCache = GetIt.instance.get<UnitProgressCache>();
UnitContentModel? _currentUnitContent;
+ bool _isPlaygroundShown = false;
DateTime? _currentUnitOpenedAt;
TobEventContext _tobEventContext = TobEventContext.empty;
TobEventContext get tobEventContext => _tobEventContext;
TourNotifier({
- required Sdk initialSdk,
List<String> initialBreadcrumbIds = const [],
}) : contentTreeController = ContentTreeController(
- initialSdk: initialSdk,
initialBreadcrumbIds: initialBreadcrumbIds,
),
- playgroundController = _createPlaygroundController(initialSdk.id) {
- _appNotifier.sdk ??= initialSdk;
+ playgroundController = _createPlaygroundController() {
contentTreeController.addListener(_onUnitChanged);
_appNotifier.addListener(_onAppNotifierChanged);
_authNotifier.addListener(_onAuthChanged);
@@ -84,17 +82,17 @@ class TourNotifier extends ChangeNotifier with
PageStateMixin<void> {
@override
PagePath get path => TourPath(
- sdkId: contentTreeController.sdk.id,
+ sdkId: GetIt.instance.get<AppNotifier>().sdk.id,
breadcrumbIds: contentTreeController.breadcrumbIds,
);
bool get isAuthenticated => _authNotifier.isAuthenticated;
- Sdk get currentSdk => _appNotifier.sdk!;
+ Sdk get currentSdk => _appNotifier.sdk;
String? get currentUnitId => _currentUnitContent?.id;
UnitContentModel? get currentUnitContent => _currentUnitContent;
- bool get hasSolution => currentUnitContent?.solutionSnippetId != null;
+ bool get hasSolution => _currentUnitContent?.solutionSnippetId != null;
bool get isCodeSaved => _unitProgressCache.hasSavedSnippet(currentUnitId);
SnippetType _snippetType = SnippetType.original;
@@ -109,7 +107,7 @@ class TourNotifier extends ChangeNotifier with
PageStateMixin<void> {
notifyListeners();
}
- bool get isUnitContainsSnippet => currentUnitContent?.taskSnippetId != null;
+ bool get isPlaygroundShown => _isPlaygroundShown;
bool get isSnippetLoading => _isLoadingSnippet;
Future<void> _onAuthChanged() async {
@@ -171,6 +169,9 @@ class TourNotifier extends ChangeNotifier with
PageStateMixin<void> {
_trackUnitClosed();
}
+ if (_currentUnitContent != null) {
+ _isPlaygroundShown = _currentUnitContent!.taskSnippetId != null;
+ }
_currentUnitContent = unitContent;
if (_currentUnitContent != null) {
@@ -358,7 +359,7 @@ class TourNotifier extends ChangeNotifier with
PageStateMixin<void> {
// Playground controller.
- static PlaygroundController _createPlaygroundController(String initialSdkId)
{
+ static PlaygroundController _createPlaygroundController() {
final playgroundController = PlaygroundController(
codeClient: GetIt.instance.get<CodeClient>(),
exampleCache: ExampleCache(
@@ -371,7 +372,9 @@ class TourNotifier extends ChangeNotifier with
PageStateMixin<void> {
playgroundController.examplesLoader.loadIfNew(
ExamplesLoadingDescriptor(
descriptors: [
- EmptyExampleLoadingDescriptor(sdk:
Sdk.parseOrCreate(initialSdkId)),
+ EmptyExampleLoadingDescriptor(
+ sdk: GetIt.instance.get<AppNotifier>().sdk,
+ ),
],
),
),
diff --git
a/learning/tour-of-beam/frontend/lib/pages/tour/widgets/content_tree.dart
b/learning/tour-of-beam/frontend/lib/pages/tour/widgets/content_tree.dart
index 9fd96b5e93b..587dc275696 100644
--- a/learning/tour-of-beam/frontend/lib/pages/tour/widgets/content_tree.dart
+++ b/learning/tour-of-beam/frontend/lib/pages/tour/widgets/content_tree.dart
@@ -16,6 +16,7 @@
* limitations under the License.
*/
+import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:playground_components/playground_components.dart';
@@ -23,7 +24,6 @@ import
'package:playground_components/playground_components.dart';
import '../../../components/builders/content_tree.dart';
import '../../../state.dart';
import '../controllers/content_tree.dart';
-import 'content_tree_title.dart';
import 'module.dart';
// TODO(nausharipov): make it collapsible
@@ -41,7 +41,7 @@ class ContentTreeWidget extends StatelessWidget {
child: AnimatedBuilder(
animation: GetIt.instance.get<AppNotifier>(),
builder: (context, child) => ContentTreeBuilder(
- sdk: controller.sdk,
+ sdk: GetIt.instance.get<AppNotifier>().sdk,
builder: (context, contentTree, child) {
if (contentTree == null) {
return const Center(child: CircularProgressIndicator());
@@ -53,7 +53,7 @@ class ContentTreeWidget extends StatelessWidget {
),
child: Column(
children: [
- const ContentTreeTitleWidget(),
+ const _Title(),
...contentTree.nodes.map(
(module) => ModuleWidget(
module: module,
@@ -70,3 +70,23 @@ class ContentTreeWidget extends StatelessWidget {
);
}
}
+
+class _Title extends StatelessWidget {
+ const _Title();
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.symmetric(vertical: BeamSizes.size12),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ 'pages.tour.summaryTitle',
+ style: Theme.of(context).textTheme.headlineLarge,
+ ).tr(),
+ ],
+ ),
+ );
+ }
+}
diff --git
a/learning/tour-of-beam/frontend/lib/pages/tour/widgets/markdown/code_builder.dart
b/learning/tour-of-beam/frontend/lib/pages/tour/widgets/markdown/code_builder.dart
index b770f777a7e..62e7ab6aab7 100644
---
a/learning/tour-of-beam/frontend/lib/pages/tour/widgets/markdown/code_builder.dart
+++
b/learning/tour-of-beam/frontend/lib/pages/tour/widgets/markdown/code_builder.dart
@@ -50,7 +50,13 @@ class _CodeBlock extends StatelessWidget {
controller: scrollController,
padding: const EdgeInsets.all(BeamSizes.size10),
scrollDirection: Axis.horizontal,
- child: Text(text),
+ child: Text(
+ text,
+ style: Theme.of(context)
+ .extension<BeamThemeExtension>()!
+ .markdownStyle
+ .code,
+ ),
),
),
);
@@ -76,7 +82,13 @@ class _InlineCode extends StatelessWidget {
),
child: Text(
text,
- style: TextStyle(color: Theme.of(context).primaryColor),
+ style: Theme.of(context)
+ .extension<BeamThemeExtension>()!
+ .markdownStyle
+ .p!
+ .copyWith(
+ color: Theme.of(context).primaryColor,
+ ),
),
);
}
diff --git
a/learning/tour-of-beam/frontend/lib/pages/tour/widgets/unit_content.dart
b/learning/tour-of-beam/frontend/lib/pages/tour/widgets/unit_content.dart
index 777ae3011ca..866538c53ee 100644
--- a/learning/tour-of-beam/frontend/lib/pages/tour/widgets/unit_content.dart
+++ b/learning/tour-of-beam/frontend/lib/pages/tour/widgets/unit_content.dart
@@ -128,7 +128,7 @@ class _Title extends StatelessWidget {
),
child: Text(
title,
- style: Theme.of(context).textTheme.headlineLarge,
+ style: Theme.of(context).textTheme.titleLarge,
textAlign: TextAlign.start,
),
);
@@ -196,7 +196,15 @@ class _SnippetTypeSwitcher extends StatelessWidget {
title: 'pages.tour.solution'.tr(),
value: SnippetType.solution,
onChanged: () async {
- await _setSnippetByType(SnippetType.solution);
+ final confirmed = await ConfirmDialog.show(
+ context: context,
+ confirmButtonText: 'pages.tour.showSolution'.tr(),
+ subtitle: 'pages.tour.solveYourself'.tr(),
+ title: 'pages.tour.solution'.tr(),
+ );
+ if (confirmed) {
+ await _setSnippetByType(SnippetType.solution);
+ }
},
),
if (tourNotifier.hasSolution || tourNotifier.isCodeSaved)
@@ -285,7 +293,7 @@ class _ContentFooter extends StatelessWidget {
themeData.extension<BeamThemeExtension>()?.secondaryBackgroundColor,
),
width: double.infinity,
- padding: const EdgeInsets.all(BeamSizes.size20),
+ padding: const EdgeInsets.all(BeamSizes.size10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
diff --git a/learning/tour-of-beam/frontend/lib/pages/welcome/screen.dart
b/learning/tour-of-beam/frontend/lib/pages/welcome/screen.dart
index eab7557ac56..a15b05bbc7c 100644
--- a/learning/tour-of-beam/frontend/lib/pages/welcome/screen.dart
+++ b/learning/tour-of-beam/frontend/lib/pages/welcome/screen.dart
@@ -16,6 +16,8 @@
* limitations under the License.
*/
+import 'dart:async';
+
import 'package:app_state/app_state.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/gestures.dart';
@@ -60,10 +62,10 @@ class _WideWelcome extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return IntrinsicHeight(
+ return const IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
- children: const [
+ children: [
Expanded(
child: _SdkSelection(),
),
@@ -83,8 +85,8 @@ class _NarrowWelcome extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Column(
- children: const [
+ return const Column(
+ children: [
_SdkSelection(),
_TourSummary(),
],
@@ -157,7 +159,7 @@ class _SdkSelection extends StatelessWidget {
if (sdk == null) {
return;
}
- await GetIt.instance.get<PageStack>().push(TourPage(sdk: sdk));
+ await GetIt.instance.get<PageStack>().push(TourPage());
}
}
@@ -171,9 +173,6 @@ class _TourSummary extends StatelessWidget {
animation: appNotifier,
builder: (context, child) {
final sdk = appNotifier.sdk;
- if (sdk == null) {
- return Container();
- }
return Padding(
padding: const EdgeInsets.symmetric(
@@ -259,7 +258,7 @@ class _IntroTextBody extends StatelessWidget {
.copyWith(color: Theme.of(context).primaryColor),
recognizer: TapGestureRecognizer()
..onTap = () {
- _openLoginDialog(context);
+ unawaited(_openLoginDialog(context));
},
),
TextSpan(text: '\n\n${'pages.welcome.selectLanguage'.tr()}'),
@@ -269,8 +268,8 @@ class _IntroTextBody extends StatelessWidget {
);
}
- void _openLoginDialog(BuildContext context) {
- showDialog(
+ Future<void> _openLoginDialog(BuildContext context) async {
+ await showDialog(
context: context,
builder: (context) => Dialog(
child: LoginContent(
diff --git a/learning/tour-of-beam/frontend/lib/state.dart
b/learning/tour-of-beam/frontend/lib/state.dart
index e690e398fae..3209d48a55a 100644
--- a/learning/tour-of-beam/frontend/lib/state.dart
+++ b/learning/tour-of-beam/frontend/lib/state.dart
@@ -22,6 +22,7 @@ import 'package:flutter/material.dart';
import 'package:playground_components/playground_components.dart';
import 'package:shared_preferences/shared_preferences.dart';
+import 'constants/params.dart';
import 'constants/storage_keys.dart';
class AppNotifier extends ChangeNotifier {
@@ -31,21 +32,17 @@ class AppNotifier extends ChangeNotifier {
unawaited(_readSdk());
}
- Sdk? get sdk => _sdk;
+ Sdk get sdk => _sdk ?? defaultSdk;
- set sdk(Sdk? newValue) {
+ set sdk(Sdk newValue) {
_sdk = newValue;
unawaited(_writeSdk(newValue));
notifyListeners();
}
- Future<void> _writeSdk(Sdk? value) async {
+ Future<void> _writeSdk(Sdk value) async {
final preferences = await SharedPreferences.getInstance();
- if (value != null) {
- await preferences.setString(StorageKeys.sdkId, value.id);
- } else {
- await preferences.remove(StorageKeys.sdkId);
- }
+ await preferences.setString(StorageKeys.sdkId, value.id);
}
Future<void> _readSdk() async {
diff --git
a/playground/frontend/playground_components/lib/src/widgets/copyright.dart
b/playground/frontend/lib/constants/links.dart
similarity index 74%
copy from
playground/frontend/playground_components/lib/src/widgets/copyright.dart
copy to playground/frontend/lib/constants/links.dart
index 86b0346f285..5307c4dd18f 100644
--- a/playground/frontend/playground_components/lib/src/widgets/copyright.dart
+++ b/playground/frontend/lib/constants/links.dart
@@ -16,14 +16,5 @@
* limitations under the License.
*/
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/widgets.dart';
-
-class CopyrightWidget extends StatelessWidget {
- const CopyrightWidget();
-
- @override
- Widget build(BuildContext context) {
- return const Text('ui.copyright').tr();
- }
-}
+const playgroundFeedbackGoogleFormsUrl =
+
'https://docs.google.com/forms/d/e/1FAIpQLSd5_5XeOwwW2yjEVHUXmiBad8Lxk-4OtNcgG45pbyAZzd4EbA/viewform?usp=pp_url';
diff --git
a/playground/frontend/lib/modules/messages/parsers/messages_parser.dart
b/playground/frontend/lib/modules/messages/parsers/messages_parser.dart
index 34e1b5b653c..b2e98bf42d1 100644
--- a/playground/frontend/lib/modules/messages/parsers/messages_parser.dart
+++ b/playground/frontend/lib/modules/messages/parsers/messages_parser.dart
@@ -45,6 +45,7 @@ class MessagesParser {
}
} on FormatException catch (ex) {
// TODO: Log
+ print('_tryParseIfJson FormatException: $ex');
}
}
diff --git
a/playground/frontend/lib/pages/standalone_playground/widgets/playground_page_footer.dart
b/playground/frontend/lib/pages/standalone_playground/widgets/playground_page_footer.dart
index 8af1ab6eca3..22bbb71aaf6 100644
---
a/playground/frontend/lib/pages/standalone_playground/widgets/playground_page_footer.dart
+++
b/playground/frontend/lib/pages/standalone_playground/widgets/playground_page_footer.dart
@@ -23,6 +23,7 @@ import
'package:playground_components/playground_components.dart';
import 'package:provider/provider.dart';
import '../../../constants/sizes.dart';
+import '../../../constants/links.dart';
class PlaygroundPageFooter extends StatelessWidget {
const PlaygroundPageFooter({Key? key}) : super(key: key);
@@ -46,6 +47,7 @@ class PlaygroundPageFooter extends StatelessWidget {
children: [
FeedbackWidget(
controller: GetIt.instance.get<FeedbackController>(),
+ feedbackFormUrl: playgroundFeedbackGoogleFormsUrl,
title: 'ui.feedbackTitle'.tr(),
),
ReportIssueButton(playgroundController: playgroundController),
diff --git a/playground/frontend/lib/playground_app.dart
b/playground/frontend/lib/playground_app.dart
index d1777896758..001cd4c07f0 100644
--- a/playground/frontend/lib/playground_app.dart
+++ b/playground/frontend/lib/playground_app.dart
@@ -16,7 +16,6 @@
* limitations under the License.
*/
-import 'package:app_state/app_state.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
diff --git
a/playground/frontend/playground_components/lib/src/constants/links.dart
b/playground/frontend/playground_components/lib/src/constants/links.dart
index 9a29bf72983..c5addcfcc26 100644
--- a/playground/frontend/playground_components/lib/src/constants/links.dart
+++ b/playground/frontend/playground_components/lib/src/constants/links.dart
@@ -24,15 +24,12 @@ class BeamLinks {
// GitHub
static const github = 'https://github.com/apache/beam';
- static const newExample =
'https://github.com/apache/beam/blob/master/playground/load_your_code.md';
+ static const newExample =
+
'https://github.com/apache/beam/blob/master/playground/load_your_code.md';
static const reportIssue = 'https://github.com/apache/beam/issues';
// Projects
static const playgroundGitHub =
'https://github.com/apache/beam/tree/master/playground';
static const scioGitHub = 'https://github.com/spotify/scio';
-
- // Forms
- static const feedbackGoogleForms =
-
'https://docs.google.com/forms/d/e/1FAIpQLSd5_5XeOwwW2yjEVHUXmiBad8Lxk-4OtNcgG45pbyAZzd4EbA/viewform?usp=pp_url';
}
diff --git a/playground/frontend/playground_components/lib/src/theme/theme.dart
b/playground/frontend/playground_components/lib/src/theme/theme.dart
index 25db8d562dd..28efa7f3a25 100644
--- a/playground/frontend/playground_components/lib/src/theme/theme.dart
+++ b/playground/frontend/playground_components/lib/src/theme/theme.dart
@@ -442,32 +442,40 @@ RoundedRectangleBorder _getButtonBorder(double radius) {
MarkdownStyleSheet _getMarkdownStyle(Brightness brightness) {
final Color primaryColor;
final Color codeblockBackgroundColor;
- final Color textColor;
if (brightness == Brightness.light) {
primaryColor = BeamLightThemeColors.primary;
codeblockBackgroundColor = BeamLightThemeColors.codeBackground;
- textColor = BeamLightThemeColors.text;
} else {
primaryColor = BeamDarkThemeColors.primary;
codeblockBackgroundColor = BeamDarkThemeColors.codeBackground;
- textColor = BeamDarkThemeColors.text;
}
- final textTheme = _getTextTheme(textColor);
return MarkdownStyleSheet(
- p: textTheme.bodyMedium,
- pPadding: EdgeInsets.only(top: BeamSizes.size2),
- h1: textTheme.headlineMedium,
- h3: textTheme.headlineSmall,
- h3Padding: EdgeInsets.only(top: BeamSizes.size4),
+ p: const TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w400,
+ ),
+ pPadding: const EdgeInsets.only(top: BeamSizes.size2),
+ h1: const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ ),
+ h2: const TextStyle(
+ fontSize: 17,
+ fontWeight: FontWeight.w600,
+ ),
+ h3: const TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w600,
+ ),
+ h3Padding: const EdgeInsets.only(top: BeamSizes.size4),
blockquoteDecoration: BoxDecoration(
color: codeblockBackgroundColor,
borderRadius: BorderRadius.circular(BeamSizes.size6),
),
code: GoogleFonts.sourceCodePro(
- color: textColor,
backgroundColor: BeamColors.transparent,
- fontSize: BeamSizes.size12,
+ fontSize: 14,
),
codeblockDecoration: BoxDecoration(
color: codeblockBackgroundColor,
diff --git
a/playground/frontend/playground_components/lib/src/widgets/copyright.dart
b/playground/frontend/playground_components/lib/src/widgets/copyright.dart
index 86b0346f285..e0f3a92e8b2 100644
--- a/playground/frontend/playground_components/lib/src/widgets/copyright.dart
+++ b/playground/frontend/playground_components/lib/src/widgets/copyright.dart
@@ -17,7 +17,7 @@
*/
import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/widgets.dart';
+import 'package:flutter/material.dart';
class CopyrightWidget extends StatelessWidget {
const CopyrightWidget();
diff --git
a/playground/frontend/playground_components/lib/src/widgets/feedback.dart
b/playground/frontend/playground_components/lib/src/widgets/feedback.dart
index e42f17dae7e..62fd515dfad 100644
--- a/playground/frontend/playground_components/lib/src/widgets/feedback.dart
+++ b/playground/frontend/playground_components/lib/src/widgets/feedback.dart
@@ -29,10 +29,12 @@ class FeedbackWidget extends StatelessWidget {
static const negativeRatingButtonKey = Key('negative');
final FeedbackController controller;
+ final String feedbackFormUrl;
final String title;
const FeedbackWidget({
required this.controller,
+ required this.feedbackFormUrl,
required this.title,
});
@@ -58,6 +60,7 @@ class FeedbackWidget extends StatelessWidget {
child: FeedbackDropdown(
close: closeNotifier.notifyPublic,
controller: controller,
+ feedbackFormUrl: feedbackFormUrl,
rating: rating,
title: 'widgets.feedback.title'.tr(),
subtitle: 'widgets.feedback.hint'.tr(),
@@ -143,17 +146,19 @@ class FeedbackDropdown extends StatelessWidget {
static const sendButtonKey = Key('sendFeedbackButtonKey');
static const textFieldKey = Key('feedbackTextFieldKey');
- final FeedbackController controller;
final VoidCallback close;
+ final FeedbackController controller;
+ final String feedbackFormUrl;
final FeedbackRating rating;
final String title;
final String subtitle;
const FeedbackDropdown({
+ required this.close,
required this.controller,
+ required this.feedbackFormUrl,
required this.title,
required this.rating,
- required this.close,
required this.subtitle,
});
@@ -181,9 +186,9 @@ class FeedbackDropdown extends StatelessWidget {
textAlign: TextAlign.center,
),
const SizedBox(height: BeamSizes.size16),
- const Expanded(
+ Expanded(
child: IFrameWidget(
- url: BeamLinks.feedbackGoogleForms,
+ url: feedbackFormUrl,
viewType: 'feedbackGoogleForms',
),
),
diff --git
a/playground/frontend/playground_components/lib/src/widgets/tabbed_snippet_editor.dart
b/playground/frontend/playground_components/lib/src/widgets/tabbed_snippet_editor.dart
index 0c1222cfded..4b78b3277e9 100644
---
a/playground/frontend/playground_components/lib/src/widgets/tabbed_snippet_editor.dart
+++
b/playground/frontend/playground_components/lib/src/widgets/tabbed_snippet_editor.dart
@@ -47,6 +47,7 @@ class TabbedSnippetEditor extends StatelessWidget {
final keys = files.map((f) => f.name).toList(growable: false);
final initialKey = files.firstWhereOrNull((f) => f.isMain)?.name;
+ // TODO(nausharipov): fork keyed_collection_widgets and put prints.
return DefaultKeyedTabController<String>.fromKeys(
animationDuration: Duration.zero,
initialKey: initialKey,