blob: f1cafac2edfce7894e289c578892c2904ec6f864 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:lib.app_driver.dart/module_driver.dart';
import 'package:lib.app.dart/logging.dart';
import 'package:lib.widgets.dart/model.dart';
import 'src/models/link_viewer_model.dart';
const double _kJsonViewerElevation = 1.0;
const double _kJsonViewerBorderRadius = 8.0;
const double _kJsonViewerListViewInset = 16.0;
const double _kJsonViewerEntryIndentPerLevel = 32.0;
const String _kListEntryPrefix = '\u{2022}'; // Unicode bullet point.
/// Main entry point to the link_viewer module.
void main() {
setupLogger();
final driver = ModuleDriver()..start();
final model = LinkViewerModel();
driver.link.watch().listen(
model.onData,
onError: (err, stack) => log.warning(err, stack),
);
runApp(
MaterialApp(
home: ScopedModel<LinkViewerModel>(
model: model,
child: new Center(
child: new PhysicalModel(
color: Colors.black,
elevation: _kJsonViewerElevation,
borderRadius: new BorderRadius.circular(_kJsonViewerBorderRadius),
child: new _JsonViewer(),
),
),
),
),
);
}
class _JsonViewer extends StatelessWidget {
@override
Widget build(BuildContext context) =>
new ScopedModelDescendant<LinkViewerModel>(
builder: (_, __, LinkViewerModel model) {
List<_Entry> entries = <_Entry>[];
_addEntries(0, model.decodedJson, entries);
if (entries.length > 20) {
return new ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(_kJsonViewerListViewInset),
physics: const BouncingScrollPhysics(),
children: entries,
);
} else {
return new SingleChildScrollView(
padding: const EdgeInsets.all(_kJsonViewerListViewInset),
physics: const BouncingScrollPhysics(),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: entries,
),
);
}
},
);
void _addEntries(
int indentLevel,
Object decodedJson,
List<_Entry> entries,
) {
if (decodedJson is List) {
for (int i = 0; i < decodedJson.length; i++) {
if (decodedJson[i] is List || decodedJson[i] is Map) {
entries.add(
new _Entry(indentLevel: indentLevel, prefix: _kListEntryPrefix),
);
_addEntries(indentLevel + 1, decodedJson[i], entries);
} else {
entries.add(
new _Entry(
indentLevel: indentLevel,
prefix: _kListEntryPrefix,
value: ' ${decodedJson[i]}',
),
);
}
}
} else if (decodedJson is Map) {
for (Object key in decodedJson.keys) {
if (decodedJson[key] is List || decodedJson[key] is Map) {
entries.add(
new _Entry(indentLevel: indentLevel, prefix: '$key:'),
);
_addEntries(indentLevel + 1, decodedJson[key], entries);
} else {
entries.add(
new _Entry(
indentLevel: indentLevel,
prefix: '$key:',
value: ' ${decodedJson[key]}',
),
);
}
}
} else {
entries.add(
new _Entry(indentLevel: indentLevel, value: '$decodedJson'),
);
}
}
}
class _Entry extends StatelessWidget {
final int indentLevel;
final String prefix;
final String value;
const _Entry({this.indentLevel, this.prefix = '', this.value = ''});
@override
Widget build(BuildContext context) {
return new Padding(
padding: new EdgeInsets.only(
left: indentLevel * _kJsonViewerEntryIndentPerLevel,
),
child: new Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new Text(prefix, style: const TextStyle(color: Colors.yellow)),
new Flexible(
child: new Text(
value,
style: new TextStyle(color: Colors.grey[100]),
),
),
],
),
);
}
}