From 3f59d5694dd5b6a045b0ad642e5167a9f4e0faf6 Mon Sep 17 00:00:00 2001 From: Rongjian Zhang Date: Fri, 30 Aug 2019 14:23:58 +0800 Subject: [PATCH] feat: show code blob --- lib/screens/object.dart | 127 ++++++++++++++++++++++++++-------------- pubspec.yaml | 2 + 2 files changed, 86 insertions(+), 43 deletions(-) diff --git a/lib/screens/object.dart b/lib/screens/object.dart index d916151..bcee26a 100644 --- a/lib/screens/object.dart +++ b/lib/screens/object.dart @@ -1,4 +1,7 @@ +import 'package:flutter_highlight/themes/github.dart'; +import 'package:path/path.dart' as path; import 'package:flutter/material.dart'; +import 'package:flutter_highlight/flutter_highlight.dart'; import 'package:git_touch/providers/settings.dart'; import 'package:git_touch/scaffolds/refresh.dart'; import 'package:git_touch/utils/utils.dart'; @@ -9,12 +12,14 @@ class ObjectScreen extends StatelessWidget { final String name; final String branch; final List paths; + final String type; ObjectScreen({ @required this.owner, @required this.name, this.branch = 'master', this.paths = const [], + this.type = 'tree', }); get expression => '$branch:' + paths.join('/'); @@ -30,6 +35,75 @@ class ObjectScreen extends StatelessWidget { } } + String get _subQuery { + switch (type) { + case 'tree': + return ''' +... on Tree { + entries { + type + name + } +} +'''; + case 'blob': + default: + return ''' +... on Blob { + text +} +'''; + } + } + + Widget _buildTree(payload) { + return Column( + children: (payload['entries'] as List).map((item) { + return Link( + screenBuilder: (context) { + return ObjectScreen( + name: name, + owner: owner, + branch: branch, + paths: [...paths, item['name']], + type: item['type'], + ); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + border: + Border(bottom: BorderSide(color: Colors.grey.shade100))), + child: Row( + children: [ + Icon(_buildIconData(item), color: Color(0x80032f62), size: 20), + SizedBox(width: 8), + Expanded( + child: Text(item['name'], style: TextStyle(fontSize: 16))) + ], + ), + ), + ); + }).toList(), + ); + } + + Widget _buildBlob(payload) { + // FIXME: + var lang = path.extension(paths.last); + if (lang.isEmpty) { + lang = 'plaintext'; + } else { + lang = lang.substring(1); + } + return Highlight( + payload['text'], + language: lang, + theme: githubTheme, + padding: EdgeInsets.all(10), + ); + } + @override Widget build(BuildContext context) { return RefreshScaffold( @@ -38,54 +112,21 @@ class ObjectScreen extends StatelessWidget { var data = await SettingsProvider.of(context).query('''{ repository(owner: "$owner", name: "$name") { object(expression: "$expression") { - ... on Tree { - entries { - type - name - } - } + $_subQuery } } }'''); - return data['repository']['object']['entries']; + return data['repository']['object']; }, bodyBuilder: (payload) { - return Column( - children: (payload as List).map((item) { - return Link( - screenBuilder: (context) { - switch (item['type']) { - case 'tree': - return ObjectScreen( - name: name, - owner: owner, - branch: branch, - paths: [...paths, item['name']], - ); - case 'blob': // TODO: - default: - return null; - } - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide(color: Colors.grey.shade100))), - child: Row( - children: [ - Icon(_buildIconData(item), - color: Color(0x80032f62), size: 20), - SizedBox(width: 4), - Expanded( - child: - Text(item['name'], style: TextStyle(fontSize: 16))) - ], - ), - ), - ); - }).toList(), - ); + switch (type) { + case 'tree': + return _buildTree(payload); + case 'blob': + return _buildBlob(payload); + default: + return null; + } }, ); } diff --git a/pubspec.yaml b/pubspec.yaml index 2d75183..f7067e8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,9 +30,11 @@ dependencies: github_contributions: ^0.1.1 flutter_svg: ^0.13.0 launch_review: ^2.0.0 + flutter_highlight: ^0.2.1 primer: git: url: git://github.com/pd4d10/primer-flutter + path: primer # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons.