Commit 30384e13 authored by Nikhil Jha's avatar Nikhil Jha

add comments

parent 961bc7e3
......@@ -7,3 +7,5 @@
build/
.flutter-plugins
android/key.properties
\ No newline at end of file
......@@ -24,6 +24,10 @@ if (flutterVersionName == null) {
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystorePropertiesFile = rootProject.file("key.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
compileSdkVersion 27
......@@ -33,19 +37,28 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.lobstersapp"
applicationId "com.nikhiljha.lobstersapp"
minSdkVersion 16
targetSdkVersion 27
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
signingConfig signingConfigs.release
}
}
}
......
class LobsterData {
final List<LobsterItem> items;
LobsterData({this.items});
factory LobsterData.fromJson(List<dynamic> parsedJson) {
List<LobsterItem> items = new List<LobsterItem>();
items = parsedJson.map((i) => LobsterItem.fromJson(i)).toList();
return LobsterData(items: items);
}
}
class LobsterItem {
final String short_id;
final String short_id_url;
final String url;
final DateTime created_at;
final String title;
final int score;
LobsterItem({this.score, this.short_id, this.title, this.created_at, this.short_id_url, this.url});
factory LobsterItem.fromJson(Map<String, dynamic> parsedJson) {
return new LobsterItem(
created_at: DateTime.parse(parsedJson['created_at']),
short_id: parsedJson['short_id'],
short_id_url: parsedJson['short_id_url'],
url: parsedJson['url'],
title: parsedJson['title'],
score: parsedJson['score']);
}
}
class LobsterComments {
final List<Comment> items;
LobsterComments({this.items});
factory LobsterComments.fromJson(Map<String, dynamic> parsedJson) {
List<Comment> items = new List<Comment>();
var comments = parsedJson["comments"] as List;
items = comments.map((i) => Comment.fromJson(i)).toList();
return LobsterComments(items: items);
}
}
class Comment {
final String short_id;
final DateTime created_at;
final String comment;
final User commenting_user;
final int indent_level;
final int score;
Comment({this.score, this.short_id, this.created_at, this.comment, this.commenting_user, this.indent_level});
factory Comment.fromJson(Map<String, dynamic> parsedJson) {
return new Comment(
created_at: DateTime.parse(parsedJson['created_at']),
short_id: parsedJson['short_id'],
score: parsedJson['score'],
comment: parsedJson['comment'],
commenting_user: User.fromJson(parsedJson['commenting_user']),
indent_level: parsedJson['indent_level'],
);
}
}
class User {
final String username;
final String avatar_url;
final DateTime created_at;
final bool is_admin;
User({this.username, this.avatar_url, this.created_at, this.is_admin});
factory User.fromJson(Map<String, dynamic> parsedJson) {
return new User(
created_at: DateTime.parse(parsedJson['created_at']),
username: parsedJson['username'],
avatar_url: parsedJson['avatar_url'],
is_admin: parsedJson['is_admin'],
);
}
}
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_html_view/flutter_html_view.dart';
import 'package:lobsters_app/api.dart';
import 'package:http/http.dart' as http;
class CommentView extends StatefulWidget {
final LobsterItem item;
CommentView({@required this.item});
@override
CommentViewState createState() {
return new CommentViewState();
}
}
class CommentViewState extends State<CommentView> {
Future<LobsterComments> data() async {
var response =
await http.get(widget.item.short_id_url + ".json");
if (response.statusCode == 200) {
// Everything is Good.
return LobsterComments.fromJson(json.decode(response.body));
} else {
// TODO: Fix this.
throw Exception('Oops');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.item.title),
),
body: FutureBuilder(
future: data(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.items.length,
itemBuilder: (context, index) {
return new Container(
child: new Card(
child: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Padding(
child: Row(
children: <Widget>[
new Icon(Icons.comment),
new Text(
" ${snapshot.data.items[index].score.toString()} - ${snapshot.data.items[index].commenting_user.username}",
textAlign: TextAlign.right,
textScaleFactor: 1.0,
style: new TextStyle(
color: Colors.black.withOpacity(0.6))),
],
),
padding: const EdgeInsets.only(
left: 16.0, right: 16.0, top: 16.0)),
new Padding(
// TODO: This library is... weird. It prints things to stdout for no reason and it has a low score on dartpub.
// Find a replacement for this soon.
child: new HtmlView(data: snapshot.data.items[index].comment),
padding: const EdgeInsets.only(
left: 16.0,
right: 16.0,
top: 16.0,
bottom: 16.0))
])),
padding: new EdgeInsets.only(
left: 4.0 + snapshot.data.items[index].indent_level * 10,
right: 16.0,
top: snapshot.data.items[index].indent_level == 0 ? 16.0 : 2.0,
bottom: 0.0));
},
);
}
return Center(child: CircularProgressIndicator());
},
),
);
}
}
......@@ -3,11 +3,14 @@ import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:lobsters_app/comments.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:lobsters_app/api.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
void main() => runApp(new MyApp());
void main() => runApp(new LobstersApp());
class MyApp extends StatelessWidget {
class LobstersApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
......@@ -31,7 +34,6 @@ class MyHomePage extends StatefulWidget {
}
class _MyHomePageState extends State<MyHomePage> {
Future<LobsterData> data() async {
var response = await http.get("https://lobste.rs/hottest.json");
if (response.statusCode == 200) {
......@@ -41,21 +43,12 @@ class _MyHomePageState extends State<MyHomePage> {
// TODO: Fix this.
throw Exception('Oops');
}
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return new Scaffold(
appBar: new AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: new Text(widget.title),
),
body: FutureBuilder(
......@@ -65,23 +58,43 @@ class _MyHomePageState extends State<MyHomePage> {
return ListView.builder(
itemCount: snapshot.data.items.length,
itemBuilder: (context, index) {
return new Material(
child: InkWell(
child: new ListTile(
title: Text(snapshot.data.items[index].title),
subtitle: Text(snapshot.data.items[index].created_at.toString()),
leading: new CircleAvatar(
// TODO: Make this colorblind friendly.
child: Text(snapshot.data.items[index].score.toString()),
return new Material(
child: InkWell(
child: Slidable(
delegate: new SlidableDrawerDelegate(),
actionExtentRatio: 0.25,
child: new ListTile(
title: Text(snapshot.data.items[index].title),
subtitle: Text(
snapshot.data.items[index].created_at.toString()),
leading: new CircleAvatar(
child:
Text(snapshot.data.items[index].score.toString()),
),
),
actions: <Widget>[
new IconSlideAction(
caption: "Read Article",
color: Colors.blue,
icon: Icons.link,
onTap: () => launch(snapshot.data.items[index].url),
),
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CommentView(
item: snapshot.data.items[index],
),
));
//launch(snapshot.data.items[index].short_id_url);
},
),
onTap: () {
launch(snapshot.data.items[index].short_id_url);
},
),
);
},
);
);
},
);
} else {
return Center(child: CircularProgressIndicator());
}
......@@ -90,32 +103,3 @@ class _MyHomePageState extends State<MyHomePage> {
);
}
}
class LobsterData {
final List<LobsterItem> items;
LobsterData({this.items});
factory LobsterData.fromJson(List<dynamic> parsedJson){
List<LobsterItem> items = new List<LobsterItem>();
items = parsedJson.map((i)=>LobsterItem.fromJson(i)).toList();
return LobsterData(items: items);
}
}
class LobsterItem {
final String short_id_url;
final DateTime created_at;
final String title;
final int score;
LobsterItem({this.score, this.short_id_url, this.title, this.created_at});
factory LobsterItem.fromJson(Map<String, dynamic> parsedJson) {
return new LobsterItem(
created_at: DateTime.parse(parsedJson['created_at']),
short_id_url: parsedJson['short_id_url'],
title: parsedJson['title'],
score: parsedJson['score']
);
}
}
......@@ -29,6 +29,15 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
cached_network_image:
dependency: transitive
description:
path: "."
ref: HEAD
resolved-ref: "0356381c677df04055caeaf15b70efd3b67a7df1"
url: "https://github.com/jogboms/flutter_cached_network_image.git"
source: git
version: "0.4.1+1"
charcode:
dependency: transitive
description:
......@@ -76,6 +85,36 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_cache_manager:
dependency: transitive
description:
path: "."
ref: HEAD
resolved-ref: be0b184d89b7e0c934cf8e584c0f20d3578c2575
url: "git://github.com/jogboms/flutter_cache_manager"
source: git
version: "0.1.1"
flutter_custom_tabs:
dependency: transitive
description:
name: flutter_custom_tabs
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
flutter_html_view:
dependency: "direct main"
description:
name: flutter_html_view
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.7"
flutter_slidable:
dependency: "direct main"
description:
name: flutter_slidable
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.4"
flutter_test:
dependency: "direct dev"
description: flutter
......@@ -214,6 +253,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.2"
path_provider:
dependency: transitive
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.1"
plugin:
dependency: transitive
description:
......@@ -242,6 +288,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0+1"
shared_preferences:
dependency: transitive
description:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2"
shelf:
dependency: transitive
description:
......@@ -317,6 +370,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
synchronized:
dependency: transitive
description:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.1+1"
term_glyph:
dependency: transitive
description:
......@@ -352,6 +412,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.0+5"
uuid:
dependency: transitive
description:
name: uuid
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
vector_math:
dependency: transitive
description:
......@@ -359,6 +426,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
video_player:
dependency: transitive
description:
name: video_player
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.4"
vm_service_client:
dependency: transitive
description:
......@@ -389,4 +463,4 @@ packages:
version: "2.1.15"
sdks:
dart: ">=2.0.0-dev.68.0 <3.0.0"
flutter: ">=0.1.4 <2.0.0"
flutter: ">=0.2.5 <2.0.0"
......@@ -15,6 +15,8 @@ environment:
dependencies:
http: any
url_launcher: any
flutter_html_view: 0.5.7
flutter_slidable: "^0.4.4"
flutter:
sdk: flutter
......
......@@ -12,7 +12,7 @@ import 'package:lobsters_app/main.dart';
void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(new MyApp());
await tester.pumpWidget(new LobstersApp());
// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment