Skip to content

Commit 202b8fc

Browse files
Merge pull request #2 from flet-dev/python-sdk
Python SDK migrated in original form
2 parents 1a347c4 + fca2371 commit 202b8fc

File tree

149 files changed

+14302
-486
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+14302
-486
lines changed

.appveyor.yml

Lines changed: 259 additions & 151 deletions
Large diffs are not rendered by default.

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Change Log - Flet client for Python
2+
3+
## [0.1.0](https://pypi.org/project/flet/0.1.0) - Mar 30, 2022

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
[![Build status](https://ci.appveyor.com/api/projects/status/xwablctxslvey576/branch/main?svg=true)](https://ci.appveyor.com/project/flet-dev/flet/branch/main)
2+
13
# Flet
24

35
Flet is a framework that enables you to easily build realtime web, mobile and desktop apps in your favorite language and securely share them with your team. No frontend experience required.

client/lib/actions.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:ui';
2+
13
import 'protocol/append_control_props_request.dart';
24
import 'protocol/clean_control_payload.dart';
35
import 'protocol/page_controls_batch_payload.dart';
@@ -10,6 +12,11 @@ import 'protocol/register_webclient_response.dart';
1012
import 'protocol/session_crashed_payload.dart';
1113
import 'protocol/signout_payload.dart';
1214

15+
class PageSizeChangeAction {
16+
final Size newSize;
17+
PageSizeChangeAction(this.newSize);
18+
}
19+
1320
class RegisterWebClientAction {
1421
final RegisterWebClientResponse payload;
1522
RegisterWebClientAction(this.payload);

client/lib/controls/button.dart

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,25 @@ import '../web_socket_client.dart';
55

66
class ButtonControl extends StatelessWidget {
77
final Control control;
8+
final bool disabled;
89

9-
const ButtonControl({Key? key, required this.control}) : super(key: key);
10+
const ButtonControl({Key? key, required this.control, required this.disabled})
11+
: super(key: key);
1012

1113
@override
1214
Widget build(BuildContext context) {
1315
debugPrint("Button build: ${control.id}");
14-
return ElevatedButton(
15-
onPressed: () {
16-
debugPrint("Button ${control.id} clicked!");
17-
ws.pageEventFromWeb(
18-
eventTarget: control.id,
19-
eventName: "click",
20-
eventData: control.attrs["data"] ?? "");
21-
},
22-
child: Text(control.attrs["text"] ?? ""),
16+
return SizedBox(
17+
child: ElevatedButton(
18+
onPressed: () {
19+
debugPrint("Button ${control.id} clicked!");
20+
ws.pageEventFromWeb(
21+
eventTarget: control.id,
22+
eventName: "click",
23+
eventData: control.attrs["data"] ?? "");
24+
},
25+
child: Text(control.attrs["text"] ?? ""),
26+
),
2327
);
2428
}
2529
}

client/lib/controls/create_control.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter/widgets.dart';
33
import 'package:flutter_redux/flutter_redux.dart';
4-
import 'package:flet_view/controls/dropdown.dart';
5-
import 'package:flet_view/models/control_view_model.dart';
4+
5+
import '../models/control_view_model.dart';
66
import '../models/app_state.dart';
7+
import 'expanded.dart';
8+
import 'row.dart';
79
import 'textfield.dart';
8-
10+
import 'dropdown.dart';
911
import 'button.dart';
1012
import 'page.dart';
1113
import 'stack.dart';
@@ -31,10 +33,16 @@ Widget createControl(String id) {
3133
case "text":
3234
return TextControl(control: controlView.control);
3335
case "button":
34-
return ButtonControl(control: controlView.control);
36+
return ButtonControl(control: controlView.control, disabled: true);
37+
case "expanded":
38+
return ExpandedControl(
39+
control: controlView.control, children: controlView.children);
3540
case "column":
3641
return ColumnControl(
3742
control: controlView.control, children: controlView.children);
43+
case "row":
44+
return RowControl(
45+
control: controlView.control, children: controlView.children);
3846
case "stack":
3947
return StackControl(
4048
control: controlView.control, children: controlView.children);

client/lib/controls/error.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:flutter/material.dart';
2+
3+
class ErrorControl extends StatelessWidget {
4+
final String message;
5+
6+
const ErrorControl(this.message, {Key? key}) : super(key: key);
7+
8+
@override
9+
Widget build(BuildContext context) {
10+
debugPrint("Error build");
11+
return Container(
12+
padding: const EdgeInsets.all(5),
13+
decoration: BoxDecoration(
14+
color: Colors.red, borderRadius: BorderRadius.circular(3)),
15+
child: Text(message, style: const TextStyle(color: Colors.white)),
16+
);
17+
}
18+
}

client/lib/controls/expanded.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import 'package:flet_view/controls/error.dart';
2+
import 'package:flutter/widgets.dart';
3+
import '../models/control.dart';
4+
import 'create_control.dart';
5+
6+
class ExpandedControl extends StatelessWidget {
7+
final Control control;
8+
final List<Control> children;
9+
10+
const ExpandedControl(
11+
{Key? key, required this.control, required this.children})
12+
: super(key: key);
13+
14+
@override
15+
Widget build(BuildContext context) {
16+
debugPrint("Expanded build: ${control.id}");
17+
if (control.childIds.isEmpty) {
18+
return ErrorControl(
19+
'Error drawing Expanded with ID ${control.id}: it doesn\'t contain child control.');
20+
} else {
21+
return Expanded(child: createControl(control.childIds.first));
22+
}
23+
}
24+
}

client/lib/controls/page.dart

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import '../widgets/screen_size.dart';
12
import 'package:flutter/material.dart';
2-
import 'package:flutter/widgets.dart';
33
import 'create_control.dart';
44
import '../models/control.dart';
55

@@ -14,14 +14,12 @@ class PageControl extends StatelessWidget {
1414
Widget build(BuildContext context) {
1515
debugPrint("Page build: ${control.id}");
1616

17-
// MediaQueryData media = MediaQuery.of(context);
18-
// debugPrint("Screen size: ${media.size}");
1917
return MaterialApp(
2018
home: Scaffold(
2119
body: Column(
22-
children: control.childIds
23-
.map((childId) => createControl(childId))
24-
.toList(),
20+
children:
21+
control.childIds.map((childId) => createControl(childId)).toList()
22+
..add(const ScreenSize()),
2523
),
2624
),
2725
);

client/lib/controls/row.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import '../models/page_breakpoint_view_model.dart';
2+
import 'package:flutter/widgets.dart';
3+
import 'package:flutter_redux/flutter_redux.dart';
4+
import '../models/app_state.dart';
5+
import '../models/control.dart';
6+
import 'create_control.dart';
7+
8+
class RowControl extends StatelessWidget {
9+
final Control control;
10+
final List<Control> children;
11+
12+
const RowControl({Key? key, required this.control, required this.children})
13+
: super(key: key);
14+
15+
@override
16+
Widget build(BuildContext context) {
17+
// debugPrint("Row build: ${control.id}");
18+
// return Row(
19+
// mainAxisAlignment: MainAxisAlignment.start,
20+
// children:
21+
// control.childIds.map((childId) => createControl(childId)).toList());
22+
23+
return StoreConnector<AppState, PageBreakpointViewModel>(
24+
distinct: true,
25+
converter: (store) => PageBreakpointViewModel.fromStore(store),
26+
builder: (context, viewModel) {
27+
debugPrint(
28+
"Row build: ${control.id} with breakpoint: ${viewModel.breakpoint}");
29+
30+
return Row(
31+
mainAxisAlignment: MainAxisAlignment.start,
32+
children: control.childIds
33+
.map((childId) => createControl(childId))
34+
.toList(),
35+
);
36+
});
37+
}
38+
}

client/lib/controls/stack.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ class StackControl extends StatelessWidget {
1212
@override
1313
Widget build(BuildContext context) {
1414
debugPrint("Stack build: ${control.id}");
15-
return Column(
16-
mainAxisAlignment: MainAxisAlignment.center,
15+
return Stack(
1716
children:
1817
control.childIds.map((childId) => createControl(childId)).toList(),
1918
);

client/lib/controls/textfield.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class _TextFieldControlState extends State<TextFieldControl> {
5050
return TextFormField(
5151
//initialValue: widget.control.attrs["value"] ?? "",
5252
decoration: InputDecoration(
53-
labelText: widget.control.attrs["label"] ?? ""),
53+
labelText: widget.control.attrs["label"] ?? "",
54+
border: const OutlineInputBorder()),
5455
controller: _controller,
5556
onChanged: (String value) {
5657
debugPrint(value);

client/lib/main.dart

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:developer';
22
import 'dart:io';
33

4+
import 'package:flet_view/widgets/loading_page.dart';
45
import 'package:flutter/foundation.dart';
56
import 'package:window_size/window_size.dart';
67
import 'package:flutter/material.dart';
@@ -13,15 +14,19 @@ import 'utils/uri.dart';
1314
import 'web_socket_client.dart';
1415
import 'controls/create_control.dart';
1516

16-
void main([List<String>? args]) {
17+
import 'session_store/session_store.dart'
18+
if (dart.library.io) "session_store/session_store_io.dart"
19+
if (dart.library.js) "session_store/session_store_js.dart";
20+
21+
void main([List<String>? args]) async {
1722
//setupWindow();
1823

1924
final store = Store<AppState>(appReducer, initialState: AppState.initial());
2025

2126
var pageUri = Uri.base;
2227

2328
if (kDebugMode) {
24-
pageUri = Uri.parse("http://localhost:8550/p/page-1");
29+
pageUri = Uri.parse("http://localhost:8550/p/test1");
2530
}
2631

2732
if (kIsWeb) {
@@ -38,25 +43,32 @@ void main([List<String>? args]) {
3843

3944
debugPrint("Page URL: $pageUri");
4045

46+
String pageName = getWebPageName(pageUri);
47+
String? sessionId = SessionStore.get("sessionId");
48+
4149
// connect WS
4250
ws.connect(serverUrl: getWebSocketEndpoint(pageUri), store: store);
4351

44-
ws.registerWebClient(pageName: getWebPageName(pageUri));
45-
4652
runApp(FletApp(
4753
title: 'Flet',
4854
store: store,
55+
pageName: pageName,
56+
sessionId: sessionId,
4957
));
5058
}
5159

5260
class FletApp extends StatelessWidget {
5361
final Store<AppState> store;
5462
final String title;
63+
final String pageName;
64+
final String? sessionId;
5565

5666
const FletApp({
5767
Key? key,
5868
required this.store,
5969
required this.title,
70+
required this.pageName,
71+
required this.sessionId,
6072
}) : super(key: key);
6173

6274
@override
@@ -68,11 +80,11 @@ class FletApp extends StatelessWidget {
6880
converter: (store) => PageViewModel.fromStore(store),
6981
builder: (context, viewModel) {
7082
if (viewModel.isLoading) {
71-
return MaterialApp(
72-
title: title,
73-
home: const Scaffold(
74-
body: Center(child: CircularProgressIndicator()),
75-
));
83+
return LoadingPage(
84+
title: title,
85+
pageName: pageName,
86+
sessionId: sessionId,
87+
);
7688
} else if (viewModel.error != "") {
7789
return MaterialApp(
7890
title: title,

client/lib/models/app_state.dart

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:ui';
2+
13
import 'package:equatable/equatable.dart';
24
import 'control.dart';
35

@@ -10,26 +12,51 @@ class AppState extends Equatable {
1012
final bool isLoading;
1113
final String error;
1214
final String sessionId;
15+
final Size size;
16+
final String sizeBreakpoint;
17+
final Map<String, double> sizeBreakpoints;
1318
final Map<String, Control> controls;
1419

1520
const AppState(
1621
{required this.isLoading,
1722
required this.error,
1823
required this.sessionId,
24+
required this.size,
25+
required this.sizeBreakpoint,
26+
required this.sizeBreakpoints,
1927
required this.controls});
2028

21-
factory AppState.initial() =>
22-
const AppState(isLoading: true, error: "", sessionId: "", controls: {});
29+
factory AppState.initial() => const AppState(
30+
isLoading: true,
31+
error: "",
32+
sessionId: "",
33+
size: Size(0, 0),
34+
sizeBreakpoint: "",
35+
sizeBreakpoints: {
36+
"xs": 0,
37+
"sm": 576,
38+
"md": 768,
39+
"lg": 992,
40+
"xl": 1200,
41+
"xxl": 1400
42+
},
43+
controls: {});
2344

2445
AppState copyWith(
2546
{bool? isLoading,
2647
String? error,
2748
String? sessionId,
49+
Size? size,
50+
String? sizeBreakpoint,
51+
Map<String, double>? sizeBreakpoints,
2852
Map<String, Control>? controls}) =>
2953
AppState(
3054
isLoading: isLoading ?? this.isLoading,
3155
error: error ?? this.error,
3256
sessionId: sessionId ?? this.sessionId,
57+
size: size ?? this.size,
58+
sizeBreakpoint: sizeBreakpoint ?? this.sizeBreakpoint,
59+
sizeBreakpoints: sizeBreakpoints ?? this.sizeBreakpoints,
3360
controls: controls ?? this.controls);
3461

3562
@override
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'dart:ui';
2+
3+
import 'package:equatable/equatable.dart';
4+
import 'package:redux/redux.dart';
5+
6+
import 'app_state.dart';
7+
8+
class PageBreakpointViewModel extends Equatable {
9+
final String breakpoint;
10+
final Map<String, double> breakpoints;
11+
12+
const PageBreakpointViewModel(
13+
{required this.breakpoint, required this.breakpoints});
14+
15+
static PageBreakpointViewModel fromStore(Store<AppState> store) {
16+
return PageBreakpointViewModel(
17+
breakpoint: store.state.sizeBreakpoint,
18+
breakpoints: store.state.sizeBreakpoints);
19+
}
20+
21+
@override
22+
List<Object?> get props => [breakpoint, breakpoints];
23+
}

0 commit comments

Comments
 (0)