Skip to content

Python SDK migrated in original form #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Apr 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
2db4cb9
Python SDK added
FeodorFitsner Mar 29, 2022
41efdde
Run Python tests
FeodorFitsner Mar 29, 2022
c567ea8
Fix matrix
FeodorFitsner Mar 29, 2022
f2f63e2
Move python stack line
FeodorFitsner Mar 29, 2022
7c2a1fa
Test multi-jobs
FeodorFitsner Mar 29, 2022
cbd3876
Try python_version
FeodorFitsner Mar 29, 2022
3e8e049
cd sdk/python
FeodorFitsner Mar 29, 2022
20c183e
cd sdk/python for tests
FeodorFitsner Mar 29, 2022
be4c053
Skip some Python tests
FeodorFitsner Mar 29, 2022
c0f58fa
Build and collect all Server binaries
FeodorFitsner Mar 29, 2022
1ffdd4d
Fix build_server job
FeodorFitsner Mar 29, 2022
e0e4d28
Collect Flet executables
FeodorFitsner Mar 29, 2022
e074b31
Fix building wheels
FeodorFitsner Mar 30, 2022
f5c1f51
Display API URL
FeodorFitsner Mar 30, 2022
621deba
Build wheels only
FeodorFitsner Mar 30, 2022
a1a8a1f
Fixed download URLs
FeodorFitsner Mar 30, 2022
08a3a1a
Handle index page in all layers
FeodorFitsner Mar 30, 2022
9fa6fc5
Generate random port
FeodorFitsner Mar 30, 2022
cbc202f
Run local server on start
FeodorFitsner Mar 31, 2022
3b14f25
Exit on parent process exit
FeodorFitsner Mar 31, 2022
e8ffbf6
popen tests
FeodorFitsner Mar 31, 2022
4c2b15f
get free TCP port
FeodorFitsner Mar 31, 2022
4c8598a
Run child process from Python
FeodorFitsner Mar 31, 2022
a4f57d2
Some more controls
FeodorFitsner Apr 1, 2022
45130df
Store sessionId in browser's sessionstorage
FeodorFitsner Apr 3, 2022
477daa6
Fix python tests
FeodorFitsner Apr 3, 2022
1a319dd
Send page size on web register
FeodorFitsner Apr 4, 2022
b97a8d0
A new logo design
FeodorFitsner Apr 5, 2022
8ee2aed
Track page size in app state.
FeodorFitsner Apr 5, 2022
81c9d53
Page size breakpoints
FeodorFitsner Apr 6, 2022
7da09c9
Roadmap created
FeodorFitsner Apr 7, 2022
fca2371
Merge branch 'main' into python-sdk
FeodorFitsner Apr 7, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
410 changes: 259 additions & 151 deletions .appveyor.yml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Change Log - Flet client for Python

## [0.1.0](https://pypi.org/project/flet/0.1.0) - Mar 30, 2022
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![Build status](https://ci.appveyor.com/api/projects/status/xwablctxslvey576/branch/main?svg=true)](https://ci.appveyor.com/project/flet-dev/flet/branch/main)

# Flet

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.
Expand Down
7 changes: 7 additions & 0 deletions client/lib/actions.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:ui';

import 'protocol/append_control_props_request.dart';
import 'protocol/clean_control_payload.dart';
import 'protocol/page_controls_batch_payload.dart';
Expand All @@ -10,6 +12,11 @@ import 'protocol/register_webclient_response.dart';
import 'protocol/session_crashed_payload.dart';
import 'protocol/signout_payload.dart';

class PageSizeChangeAction {
final Size newSize;
PageSizeChangeAction(this.newSize);
}

class RegisterWebClientAction {
final RegisterWebClientResponse payload;
RegisterWebClientAction(this.payload);
Expand Down
24 changes: 14 additions & 10 deletions client/lib/controls/button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@ import '../web_socket_client.dart';

class ButtonControl extends StatelessWidget {
final Control control;
final bool disabled;

const ButtonControl({Key? key, required this.control}) : super(key: key);
const ButtonControl({Key? key, required this.control, required this.disabled})
: super(key: key);

@override
Widget build(BuildContext context) {
debugPrint("Button build: ${control.id}");
return ElevatedButton(
onPressed: () {
debugPrint("Button ${control.id} clicked!");
ws.pageEventFromWeb(
eventTarget: control.id,
eventName: "click",
eventData: control.attrs["data"] ?? "");
},
child: Text(control.attrs["text"] ?? ""),
return SizedBox(
child: ElevatedButton(
onPressed: () {
debugPrint("Button ${control.id} clicked!");
ws.pageEventFromWeb(
eventTarget: control.id,
eventName: "click",
eventData: control.attrs["data"] ?? "");
},
child: Text(control.attrs["text"] ?? ""),
),
);
}
}
16 changes: 12 additions & 4 deletions client/lib/controls/create_control.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:flet_view/controls/dropdown.dart';
import 'package:flet_view/models/control_view_model.dart';

import '../models/control_view_model.dart';
import '../models/app_state.dart';
import 'expanded.dart';
import 'row.dart';
import 'textfield.dart';

import 'dropdown.dart';
import 'button.dart';
import 'page.dart';
import 'stack.dart';
Expand All @@ -31,10 +33,16 @@ Widget createControl(String id) {
case "text":
return TextControl(control: controlView.control);
case "button":
return ButtonControl(control: controlView.control);
return ButtonControl(control: controlView.control, disabled: true);
case "expanded":
return ExpandedControl(
control: controlView.control, children: controlView.children);
case "column":
return ColumnControl(
control: controlView.control, children: controlView.children);
case "row":
return RowControl(
control: controlView.control, children: controlView.children);
case "stack":
return StackControl(
control: controlView.control, children: controlView.children);
Expand Down
18 changes: 18 additions & 0 deletions client/lib/controls/error.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';

class ErrorControl extends StatelessWidget {
final String message;

const ErrorControl(this.message, {Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
debugPrint("Error build");
return Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(3)),
child: Text(message, style: const TextStyle(color: Colors.white)),
);
}
}
24 changes: 24 additions & 0 deletions client/lib/controls/expanded.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:flet_view/controls/error.dart';
import 'package:flutter/widgets.dart';
import '../models/control.dart';
import 'create_control.dart';

class ExpandedControl extends StatelessWidget {
final Control control;
final List<Control> children;

const ExpandedControl(
{Key? key, required this.control, required this.children})
: super(key: key);

@override
Widget build(BuildContext context) {
debugPrint("Expanded build: ${control.id}");
if (control.childIds.isEmpty) {
return ErrorControl(
'Error drawing Expanded with ID ${control.id}: it doesn\'t contain child control.');
} else {
return Expanded(child: createControl(control.childIds.first));
}
}
}
10 changes: 4 additions & 6 deletions client/lib/controls/page.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '../widgets/screen_size.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'create_control.dart';
import '../models/control.dart';

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

// MediaQueryData media = MediaQuery.of(context);
// debugPrint("Screen size: ${media.size}");
return MaterialApp(
home: Scaffold(
body: Column(
children: control.childIds
.map((childId) => createControl(childId))
.toList(),
children:
control.childIds.map((childId) => createControl(childId)).toList()
..add(const ScreenSize()),
),
),
);
Expand Down
38 changes: 38 additions & 0 deletions client/lib/controls/row.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import '../models/page_breakpoint_view_model.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_redux/flutter_redux.dart';
import '../models/app_state.dart';
import '../models/control.dart';
import 'create_control.dart';

class RowControl extends StatelessWidget {
final Control control;
final List<Control> children;

const RowControl({Key? key, required this.control, required this.children})
: super(key: key);

@override
Widget build(BuildContext context) {
// debugPrint("Row build: ${control.id}");
// return Row(
// mainAxisAlignment: MainAxisAlignment.start,
// children:
// control.childIds.map((childId) => createControl(childId)).toList());

return StoreConnector<AppState, PageBreakpointViewModel>(
distinct: true,
converter: (store) => PageBreakpointViewModel.fromStore(store),
builder: (context, viewModel) {
debugPrint(
"Row build: ${control.id} with breakpoint: ${viewModel.breakpoint}");

return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: control.childIds
.map((childId) => createControl(childId))
.toList(),
);
});
}
}
3 changes: 1 addition & 2 deletions client/lib/controls/stack.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ class StackControl extends StatelessWidget {
@override
Widget build(BuildContext context) {
debugPrint("Stack build: ${control.id}");
return Column(
mainAxisAlignment: MainAxisAlignment.center,
return Stack(
children:
control.childIds.map((childId) => createControl(childId)).toList(),
);
Expand Down
3 changes: 2 additions & 1 deletion client/lib/controls/textfield.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ class _TextFieldControlState extends State<TextFieldControl> {
return TextFormField(
//initialValue: widget.control.attrs["value"] ?? "",
decoration: InputDecoration(
labelText: widget.control.attrs["label"] ?? ""),
labelText: widget.control.attrs["label"] ?? "",
border: const OutlineInputBorder()),
controller: _controller,
onChanged: (String value) {
debugPrint(value);
Expand Down
30 changes: 21 additions & 9 deletions client/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:developer';
import 'dart:io';

import 'package:flet_view/widgets/loading_page.dart';
import 'package:flutter/foundation.dart';
import 'package:window_size/window_size.dart';
import 'package:flutter/material.dart';
Expand All @@ -13,15 +14,19 @@ import 'utils/uri.dart';
import 'web_socket_client.dart';
import 'controls/create_control.dart';

void main([List<String>? args]) {
import 'session_store/session_store.dart'
if (dart.library.io) "session_store/session_store_io.dart"
if (dart.library.js) "session_store/session_store_js.dart";

void main([List<String>? args]) async {
//setupWindow();

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

var pageUri = Uri.base;

if (kDebugMode) {
pageUri = Uri.parse("http://localhost:8550/p/page-1");
pageUri = Uri.parse("http://localhost:8550/p/test1");
}

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

debugPrint("Page URL: $pageUri");

String pageName = getWebPageName(pageUri);
String? sessionId = SessionStore.get("sessionId");

// connect WS
ws.connect(serverUrl: getWebSocketEndpoint(pageUri), store: store);

ws.registerWebClient(pageName: getWebPageName(pageUri));

runApp(FletApp(
title: 'Flet',
store: store,
pageName: pageName,
sessionId: sessionId,
));
}

class FletApp extends StatelessWidget {
final Store<AppState> store;
final String title;
final String pageName;
final String? sessionId;

const FletApp({
Key? key,
required this.store,
required this.title,
required this.pageName,
required this.sessionId,
}) : super(key: key);

@override
Expand All @@ -68,11 +80,11 @@ class FletApp extends StatelessWidget {
converter: (store) => PageViewModel.fromStore(store),
builder: (context, viewModel) {
if (viewModel.isLoading) {
return MaterialApp(
title: title,
home: const Scaffold(
body: Center(child: CircularProgressIndicator()),
));
return LoadingPage(
title: title,
pageName: pageName,
sessionId: sessionId,
);
} else if (viewModel.error != "") {
return MaterialApp(
title: title,
Expand Down
31 changes: 29 additions & 2 deletions client/lib/models/app_state.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:ui';

import 'package:equatable/equatable.dart';
import 'control.dart';

Expand All @@ -10,26 +12,51 @@ class AppState extends Equatable {
final bool isLoading;
final String error;
final String sessionId;
final Size size;
final String sizeBreakpoint;
final Map<String, double> sizeBreakpoints;
final Map<String, Control> controls;

const AppState(
{required this.isLoading,
required this.error,
required this.sessionId,
required this.size,
required this.sizeBreakpoint,
required this.sizeBreakpoints,
required this.controls});

factory AppState.initial() =>
const AppState(isLoading: true, error: "", sessionId: "", controls: {});
factory AppState.initial() => const AppState(
isLoading: true,
error: "",
sessionId: "",
size: Size(0, 0),
sizeBreakpoint: "",
sizeBreakpoints: {
"xs": 0,
"sm": 576,
"md": 768,
"lg": 992,
"xl": 1200,
"xxl": 1400
},
controls: {});

AppState copyWith(
{bool? isLoading,
String? error,
String? sessionId,
Size? size,
String? sizeBreakpoint,
Map<String, double>? sizeBreakpoints,
Map<String, Control>? controls}) =>
AppState(
isLoading: isLoading ?? this.isLoading,
error: error ?? this.error,
sessionId: sessionId ?? this.sessionId,
size: size ?? this.size,
sizeBreakpoint: sizeBreakpoint ?? this.sizeBreakpoint,
sizeBreakpoints: sizeBreakpoints ?? this.sizeBreakpoints,
controls: controls ?? this.controls);

@override
Expand Down
23 changes: 23 additions & 0 deletions client/lib/models/page_breakpoint_view_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'dart:ui';

import 'package:equatable/equatable.dart';
import 'package:redux/redux.dart';

import 'app_state.dart';

class PageBreakpointViewModel extends Equatable {
final String breakpoint;
final Map<String, double> breakpoints;

const PageBreakpointViewModel(
{required this.breakpoint, required this.breakpoints});

static PageBreakpointViewModel fromStore(Store<AppState> store) {
return PageBreakpointViewModel(
breakpoint: store.state.sizeBreakpoint,
breakpoints: store.state.sizeBreakpoints);
}

@override
List<Object?> get props => [breakpoint, breakpoints];
}
Loading