Resolves #154 UI building refactoring
This commit is contained in:
@ -1,61 +0,0 @@
|
|||||||
part of 'main.dart';
|
|
||||||
|
|
||||||
class CardWidget extends StatelessWidget {
|
|
||||||
|
|
||||||
final List<Entity> entities;
|
|
||||||
final String friendlyName;
|
|
||||||
|
|
||||||
const CardWidget({
|
|
||||||
Key key,
|
|
||||||
this.entities,
|
|
||||||
this.friendlyName
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final entityModel = EntityModel.of(context);
|
|
||||||
if (entityModel != null) {
|
|
||||||
final groupEntity = entityModel.entity;
|
|
||||||
if ((groupEntity!= null) && (groupEntity.isHidden)) {
|
|
||||||
return Container(width: 0.0, height: 0.0,);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<Widget> body = [];
|
|
||||||
body.add(_buildCardHeader());
|
|
||||||
body.addAll(_buildCardBody(context));
|
|
||||||
return Card(
|
|
||||||
child: new Column(mainAxisSize: MainAxisSize.min, children: body)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildCardHeader() {
|
|
||||||
var result;
|
|
||||||
if ((friendlyName != null) && (friendlyName.trim().length > 0)) {
|
|
||||||
result = new ListTile(
|
|
||||||
//leading: const Icon(Icons.device_hub),
|
|
||||||
//subtitle: Text(".."),
|
|
||||||
//trailing: Text("${data["state"]}"),
|
|
||||||
title: Text("$friendlyName",
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 25.0)),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
result = new Container(width: 0.0, height: 0.0);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> _buildCardBody(BuildContext context) {
|
|
||||||
List<Widget> result = [];
|
|
||||||
entities.forEach((Entity entity) {
|
|
||||||
result.add(
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
|
|
||||||
child: entity.buildDefaultWidget(context),
|
|
||||||
));
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
part of '../main.dart';
|
part of 'main.dart';
|
||||||
|
|
||||||
class Entity {
|
class Entity {
|
||||||
static const STATE_ICONS_COLORS = {
|
static const STATE_ICONS_COLORS = {
|
@ -6,13 +6,14 @@ class EntityCollection {
|
|||||||
Map<String, Entity> views;
|
Map<String, Entity> views;
|
||||||
|
|
||||||
bool get isEmpty => _allEntities.isEmpty;
|
bool get isEmpty => _allEntities.isEmpty;
|
||||||
|
List<Entity> get viewEntities => _allEntities.values.where((entity) => entity.isView).toList();
|
||||||
|
|
||||||
EntityCollection() {
|
EntityCollection() {
|
||||||
_allEntities = {};
|
_allEntities = {};
|
||||||
views = {};
|
views = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get hasDefaultView => _allEntities["group.default_view"] != null;
|
bool get hasDefaultView => _allEntities.keys.contains("group.default_view");
|
||||||
|
|
||||||
void parse(List rawData) {
|
void parse(List rawData) {
|
||||||
_allEntities.clear();
|
_allEntities.clear();
|
||||||
@ -114,31 +115,32 @@ class EntityCollection {
|
|||||||
return _allEntities[entityId] != null;
|
return _allEntities[entityId] != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String,List<String>> getDefaultViewTopLevelEntities() {
|
List<Entity> filterEntitiesForDefaultView() {
|
||||||
Map<String,List<String>> result = {"userGroups": [], "notGroupedEntities": []};
|
List<Entity> result = [];
|
||||||
List<String> entities = [];
|
List<Entity> groups = [];
|
||||||
|
List<Entity> nonGroupEntities = [];
|
||||||
_allEntities.forEach((id, entity){
|
_allEntities.forEach((id, entity){
|
||||||
if ((id.indexOf("group.") == 0) && (id.indexOf(".all_") == -1) && (!entity.isView)) {
|
if ((id.indexOf("group.") == 0) && (id.indexOf(".all_") == -1) && (!entity.isView)) {
|
||||||
result["userGroups"].add(id);
|
groups.add(entity);
|
||||||
}
|
}
|
||||||
if (!entity.isGroup) {
|
if (!entity.isGroup) {
|
||||||
entities.add(id);
|
nonGroupEntities.add(entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
entities.forEach((entiyId) {
|
nonGroupEntities.forEach((entity) {
|
||||||
bool foundInGroup = false;
|
bool foundInGroup = false;
|
||||||
result["userGroups"].forEach((userGroupId) {
|
groups.forEach((groupEntity) {
|
||||||
if (_allEntities[userGroupId].childEntityIds.contains(entiyId)) {
|
if (groupEntity.childEntityIds.contains(entity.entityId)) {
|
||||||
foundInGroup = true;
|
foundInGroup = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (!foundInGroup) {
|
if (!foundInGroup) {
|
||||||
result["notGroupedEntities"].add(entiyId);
|
result.add(entity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
result.insertAll(0, groups);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,217 @@
|
|||||||
|
part of 'main.dart';
|
||||||
|
|
||||||
|
class GroupBasedUI {
|
||||||
|
List<HACView> views;
|
||||||
|
|
||||||
|
GroupBasedUI() {
|
||||||
|
views = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TabBarView(
|
||||||
|
children: _buildViews(context)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildViews(BuildContext context) {
|
||||||
|
TheLogger.log("Debug", "Building UI");
|
||||||
|
List<Widget> result = [];
|
||||||
|
views.forEach((view) {
|
||||||
|
result.add(
|
||||||
|
view.build(context)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class HACView {
|
||||||
|
List<HACCard> cards = [];
|
||||||
|
List<Entity> badges = [];
|
||||||
|
Entity linkedEntity;
|
||||||
|
String name;
|
||||||
|
String id;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
HACView({
|
||||||
|
this.name,
|
||||||
|
this.id,
|
||||||
|
this.count
|
||||||
|
});
|
||||||
|
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return NewViewWidget(
|
||||||
|
view: this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewViewWidget extends StatefulWidget {
|
||||||
|
final HACView view;
|
||||||
|
|
||||||
|
const NewViewWidget({
|
||||||
|
Key key,
|
||||||
|
this.view
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() {
|
||||||
|
return NewViewWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewViewWidgetState extends State<NewViewWidget> {
|
||||||
|
|
||||||
|
StreamSubscription _refreshDataSubscription;
|
||||||
|
Completer _refreshCompleter;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_refreshDataSubscription = eventBus.on<RefreshDataFinishedEvent>().listen((event) {
|
||||||
|
if ((_refreshCompleter != null) && (!_refreshCompleter.isCompleted)) {
|
||||||
|
_refreshCompleter.complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
TheLogger.log("Debug", "--Building view ${widget.view.id}");
|
||||||
|
return RefreshIndicator(
|
||||||
|
color: Colors.amber,
|
||||||
|
child: ListView(
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
children: _buildChildren(context),
|
||||||
|
),
|
||||||
|
onRefresh: () => _refreshData(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildChildren(BuildContext context) {
|
||||||
|
List<Widget> result = [];
|
||||||
|
|
||||||
|
if (widget.view.badges.isNotEmpty) {
|
||||||
|
result.insert(0,
|
||||||
|
Wrap(
|
||||||
|
alignment: WrapAlignment.center,
|
||||||
|
spacing: 10.0,
|
||||||
|
runSpacing: 1.0,
|
||||||
|
children: _buildBadges(context),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
widget.view.cards.forEach((HACCard card){
|
||||||
|
result.add(
|
||||||
|
card.build(context)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildBadges(BuildContext context) {
|
||||||
|
List<Widget> result = [];
|
||||||
|
widget.view.badges.forEach((Entity entity) {
|
||||||
|
result.add(entity.buildBadgeWidget(context));
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future _refreshData() {
|
||||||
|
if ((_refreshCompleter != null) && (!_refreshCompleter.isCompleted)) {
|
||||||
|
TheLogger.log("Debug","Previous data refresh is still in progress");
|
||||||
|
} else {
|
||||||
|
_refreshCompleter = Completer();
|
||||||
|
eventBus.fire(RefreshDataEvent());
|
||||||
|
}
|
||||||
|
return _refreshCompleter.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_refreshDataSubscription.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class HACCard {
|
||||||
|
List<Entity> entities = [];
|
||||||
|
Entity linkedEntity;
|
||||||
|
String name;
|
||||||
|
String id;
|
||||||
|
|
||||||
|
HACCard({
|
||||||
|
this.name,
|
||||||
|
this.id,
|
||||||
|
this.linkedEntity
|
||||||
|
});
|
||||||
|
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return NewCardWidget(
|
||||||
|
card: this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class NewCardWidget extends StatelessWidget {
|
||||||
|
|
||||||
|
final HACCard card;
|
||||||
|
|
||||||
|
const NewCardWidget({
|
||||||
|
Key key,
|
||||||
|
this.card
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
TheLogger.log("Debug", "----Building card ${card.id}");
|
||||||
|
if ((card.linkedEntity!= null) && (card.linkedEntity.isHidden)) {
|
||||||
|
return Container(width: 0.0, height: 0.0,);
|
||||||
|
}
|
||||||
|
List<Widget> body = [];
|
||||||
|
body.add(_buildCardHeader());
|
||||||
|
body.addAll(_buildCardBody(context));
|
||||||
|
return Card(
|
||||||
|
child: new Column(mainAxisSize: MainAxisSize.min, children: body)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildCardHeader() {
|
||||||
|
var result;
|
||||||
|
if ((card.name != null) && (card.name.trim().length > 0)) {
|
||||||
|
result = new ListTile(
|
||||||
|
//leading: const Icon(Icons.device_hub),
|
||||||
|
//subtitle: Text(".."),
|
||||||
|
//trailing: Text("${data["state"]}"),
|
||||||
|
title: Text("${card.name}",
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: new TextStyle(fontWeight: FontWeight.bold, fontSize: 25.0)),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
result = new Container(width: 0.0, height: 0.0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Widget> _buildCardBody(BuildContext context) {
|
||||||
|
List<Widget> result = [];
|
||||||
|
card.entities.forEach((Entity entity) {
|
||||||
|
TheLogger.log("Debug", "------entity ${entity.entityId}");
|
||||||
|
result.add(
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
|
||||||
|
child: entity.buildDefaultWidget(context),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,8 +14,8 @@ class HomeAssistant {
|
|||||||
int _subscriptionMessageId = 0;
|
int _subscriptionMessageId = 0;
|
||||||
int _configMessageId = 0;
|
int _configMessageId = 0;
|
||||||
int _userInfoMessageId = 0;
|
int _userInfoMessageId = 0;
|
||||||
EntityCollection _entities;
|
EntityCollection entities;
|
||||||
ViewBuilder _viewBuilder;
|
GroupBasedUI ui;
|
||||||
Map _instanceConfig = {};
|
Map _instanceConfig = {};
|
||||||
String _userName;
|
String _userName;
|
||||||
|
|
||||||
@ -38,12 +38,10 @@ class HomeAssistant {
|
|||||||
String get locationName => _instanceConfig["location_name"] ?? "";
|
String get locationName => _instanceConfig["location_name"] ?? "";
|
||||||
String get userName => _userName ?? locationName;
|
String get userName => _userName ?? locationName;
|
||||||
String get userAvatarText => userName.length > 0 ? userName[0] : "";
|
String get userAvatarText => userName.length > 0 ? userName[0] : "";
|
||||||
int get viewsCount => _entities.views.length ?? 0;
|
int get viewsCount => entities.views.length ?? 0;
|
||||||
|
|
||||||
EntityCollection get entities => _entities;
|
|
||||||
|
|
||||||
HomeAssistant() {
|
HomeAssistant() {
|
||||||
_entities = EntityCollection();
|
entities = EntityCollection();
|
||||||
_messageQueue = SendMessageQueue(messageExpirationTime);
|
_messageQueue = SendMessageQueue(messageExpirationTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +312,7 @@ class HomeAssistant {
|
|||||||
void _handleEntityStateChange(Map eventData) {
|
void _handleEntityStateChange(Map eventData) {
|
||||||
//TheLogger.log("Debug", "New state for ${eventData['entity_id']}");
|
//TheLogger.log("Debug", "New state for ${eventData['entity_id']}");
|
||||||
Map data = Map.from(eventData);
|
Map data = Map.from(eventData);
|
||||||
_entities.updateState(data);
|
entities.updateState(data);
|
||||||
eventBus.fire(new StateChangedEvent(data["entity_id"], null, false));
|
eventBus.fire(new StateChangedEvent(data["entity_id"], null, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,13 +365,65 @@ class HomeAssistant {
|
|||||||
_statesCompleter.completeError({"errorCode": 3, "errorMessage": response["error"]["message"]});
|
_statesCompleter.completeError({"errorCode": 3, "errorMessage": response["error"]["message"]});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_entities.parse(response["result"]);
|
entities.parse(response["result"]);
|
||||||
_viewBuilder = ViewBuilder(entityCollection: _entities);
|
|
||||||
|
|
||||||
|
ui = GroupBasedUI();
|
||||||
|
int viewCounter = 0;
|
||||||
|
//TODO add default_view
|
||||||
|
entities.viewEntities.forEach((viewEntity) {
|
||||||
|
TheLogger.log("Debug","--View: ${viewEntity.entityId}");
|
||||||
|
HACView view = HACView(
|
||||||
|
count: viewCounter,
|
||||||
|
id: viewEntity.entityId,
|
||||||
|
name: viewEntity.displayName
|
||||||
|
);
|
||||||
|
view.linkedEntity = viewEntity;
|
||||||
|
List<HACCard> autoGeneratedCards = [];
|
||||||
|
viewEntity.childEntities.forEach((entity) {
|
||||||
|
if (entity.isBadge) {
|
||||||
|
view.badges.add(entity);
|
||||||
|
TheLogger.log("Debug","----Badge: ${entity.entityId}");
|
||||||
|
} else {
|
||||||
|
if (!entity.isGroup) {
|
||||||
|
String groupIdToAdd = "${entity.domain}.${entity.domain}$viewCounter";
|
||||||
|
if (autoGeneratedCards.every((HACCard card) => card.id != groupIdToAdd )) {
|
||||||
|
HACCard card = HACCard(
|
||||||
|
id: groupIdToAdd,
|
||||||
|
name: entity.domain
|
||||||
|
);
|
||||||
|
TheLogger.log("Debug","----Creating card: $groupIdToAdd");
|
||||||
|
card.entities.add(entity);
|
||||||
|
autoGeneratedCards.add(card);
|
||||||
|
} else {
|
||||||
|
autoGeneratedCards.firstWhere((card) => card.id == groupIdToAdd).entities.add(entity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TheLogger.log("Debug","----Card: ${entity.entityId}");
|
||||||
|
HACCard card = HACCard(
|
||||||
|
name: entity.displayName,
|
||||||
|
id: entity.entityId,
|
||||||
|
linkedEntity: entity
|
||||||
|
);
|
||||||
|
card.entities.addAll(entity.childEntities);
|
||||||
|
view.cards.add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
view.cards.addAll(autoGeneratedCards);
|
||||||
|
ui.views.add(
|
||||||
|
view
|
||||||
|
);
|
||||||
|
viewCounter += 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
_statesCompleter.complete();
|
_statesCompleter.complete();
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildViews(BuildContext context) {
|
Widget buildViews(BuildContext context) {
|
||||||
return _viewBuilder.buildWidget(context);
|
//return _viewBuilder.buildWidget(context);
|
||||||
|
return ui.build(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List> getHistory(String entityId) async {
|
Future<List> getHistory(String entityId) async {
|
||||||
|
@ -14,10 +14,9 @@ import 'package:date_format/date_format.dart';
|
|||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:flutter_colorpicker/material_picker.dart';
|
import 'package:flutter_colorpicker/material_picker.dart';
|
||||||
|
|
||||||
part 'entity_class/entity.class.dart';
|
part 'entity.class.dart';
|
||||||
part 'entity_class/stateless_widgets.dart';
|
part 'widgets/stateless_widgets.dart';
|
||||||
part 'entity_class/stateful_widgets.dart';
|
part 'widgets/stateful_widgets.dart';
|
||||||
|
|
||||||
part 'settings.page.dart';
|
part 'settings.page.dart';
|
||||||
part 'home_assistant.class.dart';
|
part 'home_assistant.class.dart';
|
||||||
part 'log.page.dart';
|
part 'log.page.dart';
|
||||||
@ -25,9 +24,7 @@ part 'entity.page.dart';
|
|||||||
part 'utils.class.dart';
|
part 'utils.class.dart';
|
||||||
part 'mdi.class.dart';
|
part 'mdi.class.dart';
|
||||||
part 'entity_collection.class.dart';
|
part 'entity_collection.class.dart';
|
||||||
part 'view_builder.class.dart';
|
part 'group_based_ui.dart';
|
||||||
part 'view_class.dart';
|
|
||||||
part 'card_class.dart';
|
|
||||||
|
|
||||||
EventBus eventBus = new EventBus();
|
EventBus eventBus = new EventBus();
|
||||||
const String appName = "HA Client";
|
const String appName = "HA Client";
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
part of 'main.dart';
|
|
||||||
|
|
||||||
class ViewBuilder{
|
|
||||||
|
|
||||||
EntityCollection entityCollection;
|
|
||||||
List<View> _views;
|
|
||||||
|
|
||||||
ViewBuilder({
|
|
||||||
Key key,
|
|
||||||
this.entityCollection
|
|
||||||
}) {
|
|
||||||
_compose();
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildWidget(BuildContext context) {
|
|
||||||
return ViewBuilderWidget(
|
|
||||||
entities: _views
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _compose() {
|
|
||||||
TheLogger.log("Debug", "Rebuilding all UI...");
|
|
||||||
_views = [];
|
|
||||||
if (!entityCollection.hasDefaultView) {
|
|
||||||
_views.add(_composeDefaultView());
|
|
||||||
}
|
|
||||||
_views.addAll(_composeViews());
|
|
||||||
}
|
|
||||||
|
|
||||||
View _composeDefaultView() {
|
|
||||||
Map<String, List<String>> userGroupsList = entityCollection.getDefaultViewTopLevelEntities();
|
|
||||||
List<Entity> entitiesForView = [];
|
|
||||||
userGroupsList["userGroups"].forEach((groupId){
|
|
||||||
Entity en = entityCollection.get(groupId);
|
|
||||||
entitiesForView.add(en);
|
|
||||||
});
|
|
||||||
userGroupsList["notGroupedEntities"].forEach((entityId){
|
|
||||||
entitiesForView.add(entityCollection.get(entityId));
|
|
||||||
});
|
|
||||||
return View(
|
|
||||||
entities: entitiesForView,
|
|
||||||
count: 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<View> _composeViews() {
|
|
||||||
List<View> result = [];
|
|
||||||
int counter = 0;
|
|
||||||
entityCollection.views.forEach((viewId, viewGroupEntity) {
|
|
||||||
counter += 1;
|
|
||||||
//try {
|
|
||||||
result.add(View(
|
|
||||||
count: counter,
|
|
||||||
entities: viewGroupEntity.childEntities
|
|
||||||
));
|
|
||||||
/*} catch (error) {
|
|
||||||
TheLogger.log("Error","Error parsing view: $viewId");
|
|
||||||
}*/
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViewBuilderWidget extends StatelessWidget {
|
|
||||||
|
|
||||||
final List<View> entities;
|
|
||||||
|
|
||||||
const ViewBuilderWidget({
|
|
||||||
Key key,
|
|
||||||
this.entities
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return TabBarView(
|
|
||||||
children: _buildChildren(context)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> _buildChildren(BuildContext context) {
|
|
||||||
List<Widget> result = [];
|
|
||||||
entities.forEach((View view){
|
|
||||||
result.add(view.buildWidget(context));
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,168 +0,0 @@
|
|||||||
part of 'main.dart';
|
|
||||||
|
|
||||||
class View {
|
|
||||||
List<Entity> childEntitiesAsBadges;
|
|
||||||
Map<String, CardSkeleton> childEntitiesAsCards;
|
|
||||||
|
|
||||||
int count;
|
|
||||||
List<Entity> entities;
|
|
||||||
|
|
||||||
View({
|
|
||||||
Key key,
|
|
||||||
this.count,
|
|
||||||
this.entities
|
|
||||||
}) {
|
|
||||||
childEntitiesAsBadges = [];
|
|
||||||
childEntitiesAsCards = {};
|
|
||||||
_filterEntities();
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget buildWidget(BuildContext context) {
|
|
||||||
return ViewWidget(
|
|
||||||
badges: childEntitiesAsBadges,
|
|
||||||
cards: childEntitiesAsCards,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _filterEntities() {
|
|
||||||
entities.forEach((Entity entity){
|
|
||||||
if (!entity.isGroup) {
|
|
||||||
if (entity.isBadge) {
|
|
||||||
childEntitiesAsBadges.add(entity);
|
|
||||||
} else {
|
|
||||||
String groupIdToAdd = "${entity.domain}.${entity.domain}$count";
|
|
||||||
if (childEntitiesAsCards[groupIdToAdd] == null) {
|
|
||||||
childEntitiesAsCards[groupIdToAdd] = CardSkeleton(
|
|
||||||
displayName: entity.domain,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
childEntitiesAsCards[groupIdToAdd].childEntities.add(entity);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
childEntitiesAsCards[entity.entityId] = CardSkeleton(
|
|
||||||
displayName: entity.displayName,
|
|
||||||
groupEntity: entity
|
|
||||||
);
|
|
||||||
childEntitiesAsCards[entity.entityId].childEntities = entity.childEntities;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViewWidget extends StatefulWidget {
|
|
||||||
final List<Entity> badges;
|
|
||||||
final Map<String, CardSkeleton> cards;
|
|
||||||
final String displayName;
|
|
||||||
|
|
||||||
const ViewWidget({
|
|
||||||
Key key,
|
|
||||||
this.badges,
|
|
||||||
this.cards,
|
|
||||||
this.displayName
|
|
||||||
}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() {
|
|
||||||
return ViewWidgetState();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViewWidgetState extends State<ViewWidget> {
|
|
||||||
|
|
||||||
StreamSubscription _refreshDataSubscription;
|
|
||||||
Completer _refreshCompleter;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
_refreshDataSubscription = eventBus.on<RefreshDataFinishedEvent>().listen((event) {
|
|
||||||
if ((_refreshCompleter != null) && (!_refreshCompleter.isCompleted)) {
|
|
||||||
_refreshCompleter.complete();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return RefreshIndicator(
|
|
||||||
color: Colors.amber,
|
|
||||||
child: ListView(
|
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
|
||||||
children: _buildChildren(context),
|
|
||||||
),
|
|
||||||
onRefresh: () => _refreshData(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> _buildChildren(BuildContext context) {
|
|
||||||
List<Widget> result = [];
|
|
||||||
|
|
||||||
if (widget.badges.isNotEmpty) {
|
|
||||||
result.insert(0,
|
|
||||||
Wrap(
|
|
||||||
alignment: WrapAlignment.center,
|
|
||||||
spacing: 10.0,
|
|
||||||
runSpacing: 1.0,
|
|
||||||
children: _buildBadges(context, widget.badges),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
widget.cards.forEach((String id, CardSkeleton skeleton){
|
|
||||||
result.add(
|
|
||||||
EntityModel(
|
|
||||||
entity: skeleton.groupEntity,
|
|
||||||
handleTap: false,
|
|
||||||
child: CardWidget(
|
|
||||||
entities: skeleton.childEntities,
|
|
||||||
friendlyName: skeleton.displayName,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Widget> _buildBadges(BuildContext context, List<Entity> badges) {
|
|
||||||
List<Widget> result = [];
|
|
||||||
badges.forEach((Entity entity) {
|
|
||||||
result.add(entity.buildBadgeWidget(context));
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future _refreshData() {
|
|
||||||
if ((_refreshCompleter != null) && (!_refreshCompleter.isCompleted)) {
|
|
||||||
TheLogger.log("Debug","Previous data refresh is still in progress");
|
|
||||||
} else {
|
|
||||||
_refreshCompleter = Completer();
|
|
||||||
eventBus.fire(RefreshDataEvent());
|
|
||||||
}
|
|
||||||
return _refreshCompleter.future;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_refreshDataSubscription.cancel();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class CardSkeleton {
|
|
||||||
String displayName;
|
|
||||||
List<Entity> childEntities;
|
|
||||||
Entity groupEntity;
|
|
||||||
|
|
||||||
CardSkeleton({
|
|
||||||
Key key,
|
|
||||||
this.displayName,
|
|
||||||
this.childEntities,
|
|
||||||
this.groupEntity}) {
|
|
||||||
childEntities = [];
|
|
||||||
}
|
|
||||||
}
|
|
@ -113,7 +113,6 @@ class EntityIcon extends StatelessWidget {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.fromLTRB(
|
padding: EdgeInsets.fromLTRB(
|
||||||
Entity.leftWidgetPadding, 0.0, 12.0, 0.0),
|
Entity.leftWidgetPadding, 0.0, 12.0, 0.0),
|
||||||
//TODO: move createIconWidgetFromEntityData into this widget
|
|
||||||
child: MaterialDesignIcons.createIconWidgetFromEntityData(
|
child: MaterialDesignIcons.createIconWidgetFromEntityData(
|
||||||
entityModel.entity,
|
entityModel.entity,
|
||||||
Entity.iconSize,
|
Entity.iconSize,
|
Reference in New Issue
Block a user