Skip to content

Commit 66b2b93

Browse files
authored
feat: gprc parser impl (#2)
* chore: init * feat: grpc parser * chore: update README.md * chore: updated readme again * feat: added functionality to protobuf def and parser
1 parent 94cf6c9 commit 66b2b93

30 files changed

+9903
-74
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ migrate_working_dir/
2929
.flutter-plugins
3030
.flutter-plugins-dependencies
3131
build/
32+
bin

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
# Changelog
2+
13
## 0.0.1
24

3-
* TODO: Describe initial release.
5+
### Added
6+
7+
- Basic framework for Server-Driven UI implementation
8+
- Support for rendering UI from server-provided definitions
9+
- gRPC integration with Protocol Buffers
10+
- Core widget support (Text, Column, Row, Container, etc.)
11+
- Example application demonstrating gRPC usage
12+
- Setup scripts for Protocol Buffer compilation

README.md

Lines changed: 291 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,328 @@
22
<a href="https://dscvit.com">
33
<img width="400" src="https://user-images.githubusercontent.com/56252312/159312411-58410727-3933-4224-b43e-4e9b627838a3.png#gh-light-mode-only" alt="GDSC VIT"/>
44
</a>
5-
<h2 align="center"> < Insert Project Title Here > </h2>
6-
<h4 align="center"> < Insert Project Description Here > <h4>
5+
<h2 align="center">Flutter SDUI Package</h2>
6+
<h4 align="center">A Flutter package for implementing Server-Driven UI with both JSON and gRPC support<h4>
77
</p>
88

9-
---
109
[![Join Us](https://img.shields.io/badge/Join%20Us-Developer%20Student%20Clubs-red)](https://dsc.community.dev/vellore-institute-of-technology/)
1110
[![Discord Chat](https://img.shields.io/discord/760928671698649098.svg)](https://discord.gg/498KVdSKWR)
11+
[![DOCS](https://img.shields.io/badge/Documentation-see%20docs-green?style=flat-square&logo=appveyor)](docs/grpc_support.md)
12+
[![UI ](https://img.shields.io/badge/Flutter-SDK-blue?style=flat-square&logo=flutter)](https://flutter.dev)
1213

13-
[![DOCS](https://img.shields.io/badge/Documentation-see%20docs-green?style=flat-square&logo=appveyor)](INSERT_LINK_FOR_DOCS_HERE)
14-
[![UI ](https://img.shields.io/badge/User%20Interface-Link%20to%20UI-orange?style=flat-square&logo=appveyor)](INSERT_UI_LINK_HERE)
14+
A powerful Flutter package for implementing Server-Driven UI (SDUI) with both JSON and gRPC support.
1515

16+
## What is SDUI?
17+
18+
Server-Driven UI is an architectural pattern where the UI layout and content definitions come from a backend server rather than being hardcoded in the client application. This approach enables:
19+
20+
- Dynamic UI updates without app store releases
21+
- A/B testing and feature flagging at the UI level
22+
- Consistent UI across platforms
23+
- Faster iteration cycles for UI changes
1624

1725
## Features
18-
- [ ] < feature >
19-
- [ ] < feature >
20-
- [ ] < feature >
21-
- [ ] < feature >
2226

23-
<br>
27+
- [x] Render UI dynamically from server-provided definitions
28+
- [x] Support for essential Flutter widgets (Text, Column, Row, Container, etc.)
29+
- [x] JSON parsing for server responses
30+
- [x] gRPC support for efficient, type-safe communication
31+
- [x] Protocol Buffers for structured data exchange
32+
- [x] Easy-to-use client API
33+
- [x] Customizable error handling and loading states
2434

25-
## Dependencies
26-
- < dependency >
27-
- < dependency >
35+
## Installation
2836

37+
Add the package to your `pubspec.yaml`:
38+
39+
```yaml
40+
dependencies:
41+
flutter_sdui: ^0.0.1
42+
```
2943
30-
## Running
44+
```yaml
45+
# For devs
46+
dependencies:
47+
flutter_sdui:
48+
path: path/to/flutter_sdui
49+
```
3150
51+
Or use the Flutter CLI:
3252
33-
< directions to install >
3453
```bash
35-
< insert code >
54+
flutter pub add flutter_sdui
55+
```
56+
57+
Import the package in your Dart code:
58+
59+
```dart
60+
import 'package:flutter_sdui/flutter_sdui.dart';
61+
```
62+
63+
## Basic Usage
64+
65+
This package provides two approaches for implementing server-driven UI:
66+
67+
### 1. Using gRPC (Recommended)
68+
69+
For efficient, type-safe server communication:
70+
71+
```dart
72+
// Create a gRPC client
73+
final client = SduiGrpcClient(
74+
host: 'your-server.com',
75+
port: 50051,
76+
);
77+
78+
// Use the SduiGrpcRenderer widget
79+
SduiGrpcRenderer(
80+
client: client,
81+
screenId: 'home_screen',
82+
loadingWidget: CircularProgressIndicator(),
83+
errorBuilder: (context, error) => Text('Error: $error'),
84+
)
85+
```
86+
87+
### 2. Using JSON
88+
89+
For simpler implementation with standard HTTP requests (coming soon).
90+
91+
## Example
92+
93+
Here's a complete example of using the gRPC renderer:
94+
95+
```dart
96+
import 'package:flutter/material.dart';
97+
import 'package:flutter_sdui/flutter_sdui.dart';
98+
99+
void main() {
100+
runApp(const MyApp());
101+
}
102+
103+
class MyApp extends StatelessWidget {
104+
const MyApp({super.key});
105+
106+
@override
107+
Widget build(BuildContext context) {
108+
return MaterialApp(
109+
title: 'SDUI Demo',
110+
theme: ThemeData(
111+
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
112+
useMaterial3: true,
113+
),
114+
home: const SDUIDemo(),
115+
);
116+
}
117+
}
118+
119+
class SDUIDemo extends StatefulWidget {
120+
const SDUIDemo({super.key});
121+
122+
@override
123+
State<SDUIDemo> createState() => _SDUIDemoState();
124+
}
125+
126+
class _SDUIDemoState extends State<SDUIDemo> {
127+
late SduiGrpcClient _grpcClient;
128+
String _screenId = 'home';
129+
130+
@override
131+
void initState() {
132+
super.initState();
133+
_grpcClient = SduiGrpcClient(
134+
host: 'localhost', // Replace with your server address
135+
port: 50051, // Replace with your server port
136+
);
137+
}
138+
139+
@override
140+
void dispose() {
141+
_grpcClient.dispose();
142+
super.dispose();
143+
}
144+
145+
@override
146+
Widget build(BuildContext context) {
147+
return Scaffold(
148+
appBar: AppBar(
149+
title: const Text('Server-Driven UI Demo'),
150+
),
151+
body: SduiGrpcRenderer(
152+
client: _grpcClient,
153+
screenId: _screenId,
154+
loadingWidget: const Center(
155+
child: CircularProgressIndicator(),
156+
),
157+
errorBuilder: (context, error) {
158+
return Center(
159+
child: Column(
160+
mainAxisAlignment: MainAxisAlignment.center,
161+
children: [
162+
Icon(Icons.error, color: Colors.red, size: 48),
163+
SizedBox(height: 16),
164+
Text('Error: $error'),
165+
SizedBox(height: 16),
166+
ElevatedButton(
167+
onPressed: () => setState(() {}),
168+
child: Text('Retry'),
169+
),
170+
],
171+
),
172+
);
173+
},
174+
),
175+
);
176+
}
177+
}
36178
```
37179

38-
< directions to execute >
180+
## Server Implementation
181+
182+
### Setting Up a gRPC Server
183+
184+
Here's a basic example of a Dart server that provides UI definitions via gRPC:
185+
186+
```dart
187+
import 'package:grpc/grpc.dart';
188+
import 'package:flutter_sdui/src/generated/sdui.pb.dart';
189+
import 'package:flutter_sdui/src/generated/sdui.pbgrpc.dart';
190+
191+
Future<void> main() async {
192+
final server = Server.create(
193+
services: [
194+
SduiServiceImpl(),
195+
],
196+
);
197+
198+
await server.serve(port: 50051);
199+
print('Server listening on port 50051...');
200+
}
201+
202+
class SduiServiceImpl extends SduiServiceBase {
203+
@override
204+
Future<SduiWidgetData> getSduiWidget(
205+
ServiceCall call, SduiRequest request) async {
206+
// Return different UI based on the screenId
207+
switch (request.screenId) {
208+
case 'home':
209+
return _createHomeScreen();
210+
default:
211+
return _createErrorScreen();
212+
}
213+
}
214+
215+
SduiWidgetData _createHomeScreen() {
216+
return SduiWidgetData()
217+
..type = WidgetType.SCAFFOLD
218+
..body = (SduiWidgetData()
219+
..type = WidgetType.COLUMN
220+
..children.addAll([
221+
SduiWidgetData()
222+
..type = WidgetType.CONTAINER
223+
..padding = (EdgeInsetsData()..all = 16)
224+
..child = (SduiWidgetData()
225+
..type = WidgetType.TEXT
226+
..stringAttributes['text'] = 'Welcome to Server-Driven UI!'
227+
..textStyle = (TextStyleData()
228+
..fontSize = 22
229+
..fontWeight = 'bold')),
230+
SduiWidgetData()
231+
..type = WidgetType.TEXT
232+
..stringAttributes['text'] = 'This UI is rendered from gRPC data'
233+
]));
234+
}
235+
}
236+
```
237+
238+
## Supported Widgets
239+
240+
The package currently supports these Flutter widgets:
241+
242+
- `Scaffold`
243+
- `Container`
244+
- `Column`
245+
- `Row`
246+
- `Text`
247+
- `Image`
248+
- `SizedBox`
249+
- `Spacer`
250+
- `Icon`
251+
252+
## Advanced Usage
253+
254+
### Protobuf Definitions
255+
256+
The package uses Protocol Buffers to define the data structures for gRPC communication. Here's a simplified version of the main message types:
257+
258+
```protobuf
259+
message SduiWidgetData {
260+
WidgetType type = 1;
261+
map<string, string> string_attributes = 2;
262+
map<string, double> double_attributes = 3;
263+
map<string, bool> bool_attributes = 4;
264+
265+
// Complex nested attributes
266+
TextStyleData text_style = 6;
267+
EdgeInsetsData padding = 7;
268+
269+
// Children widgets
270+
repeated SduiWidgetData children = 12;
271+
SduiWidgetData child = 13;
272+
273+
// Scaffold specific parts
274+
SduiWidgetData app_bar = 14;
275+
SduiWidgetData body = 15;
276+
}
277+
278+
service SduiService {
279+
rpc GetSduiWidget (SduiRequest) returns (SduiWidgetData);
280+
}
281+
```
282+
283+
### Working with Protocol Buffers
284+
285+
If you need to regenerate the Dart files from the proto definitions:
286+
287+
1. Install the Protocol Buffer compiler using the provided scripts:
39288

40289
```bash
41-
< insert code >
290+
# Windows
291+
pwsh ./tool/setup_protoc.ps1
292+
293+
# Generate the Protobuf files
294+
pwsh ./tool/generate_protos.ps1
42295
```
43296

297+
## Roadmap
298+
299+
- [x] Basic widget support
300+
- [x] gRPC implementation
301+
- [ ] JSON implementation
302+
- [ ] Interactive widgets (buttons, forms)
303+
- [ ] More advanced widget support
304+
305+
## Contributing
306+
307+
We welcome contributions! Please see our [contributing guidelines](contributing.md) for details.
308+
309+
## License
310+
311+
This project is licensed under the [LICENSE](LICENSE) file in the repository.
312+
44313
## Contributors
45314

46315
<table>
47316
<tr align="center">
48317
<td>
49-
John Doe
318+
Jothish Kamal
50319
<p align="center">
51-
<img src = "https://dscvit.com/images/dsc-logo-square.svg" width="150" height="150" alt="Your Name Here (Insert Your Image Link In Src">
320+
<img src = "https://avatars.githubusercontent.com/u/74227363?v=4" width="150" height="150" alt="Jothish Kamal">
52321
</p>
53322
<p align="center">
54-
<a href = "https://github.com/person1">
323+
<a href = "https://github.com/JothishKamal">
55324
<img src = "http://www.iconninja.com/files/241/825/211/round-collaboration-social-github-code-circle-network-icon.svg" width="36" height = "36" alt="GitHub"/>
56325
</a>
57-
<a href = "https://www.linkedin.com/in/person1">
326+
<a href = "https://www.linkedin.com/in/jothishkamal">
58327
<img src = "http://www.iconninja.com/files/863/607/751/network-linkedin-social-connection-circular-circle-media-icon.svg" width="36" height="36" alt="LinkedIn"/>
59328
</a>
60329
</p>

build.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
targets:
2+
$default:
3+
builders:
4+
protoc_plugin: # Using the package name as the builder key
5+
enabled: true
6+
options:
7+
grpc: true # Enable gRPC stub generation
8+
output_directory: lib/src/generated # Specify output directory
9+
generate_mixins: true # Generate mixins for classes
10+
generate_kythe_info: false

0 commit comments

Comments
 (0)