feat: cupertino dark mode

This commit is contained in:
Rongjian Zhang 2019-11-05 21:22:41 +08:00
parent bfc41cd79b
commit 1b7578f4b4
18 changed files with 300 additions and 240 deletions

View File

@ -131,40 +131,41 @@ class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
var settings = Provider.of<AuthModel>(context);
var themData = ThemeData(
final authModel = Provider.of<AuthModel>(context);
final themeModel = Provider.of<ThemeModel>(context);
final themData = ThemeData(
brightness: themeModel.brightness,
primaryColor: PrimerColors.white,
accentColor: PrimerColors.blue500,
);
// TODO:
if (!settings.ready || !Provider.of<ThemeModel>(context).ready) {
if (!authModel.ready || !Provider.of<ThemeModel>(context).ready) {
return MaterialApp(theme: themData, home: Scaffold(body: Text('a')));
}
// Fimber.d(settings.activeLogin);
if (settings.activeAccount == null) {
if (authModel.activeAccount == null) {
return MaterialApp(theme: themData, home: LoginScreen());
}
switch (Provider.of<ThemeModel>(context).theme) {
switch (themeModel.theme) {
case AppThemeType.cupertino:
return CupertinoApp(
home: CupertinoTheme(
data: CupertinoThemeData(
primaryColor: PrimerColors.blue500,
),
child: CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: _navigationItems,
// backgroundColor: PrimerColors.gray000, // TODO:
),
tabBuilder: (context, index) {
return CupertinoTabView(builder: (context) {
theme: CupertinoThemeData(
brightness: themeModel.brightness,
primaryColor: PrimerColors.blue500,
),
home: CupertinoTabScaffold(
tabBar: CupertinoTabBar(items: _navigationItems),
tabBuilder: (context, index) {
return CupertinoTabView(
builder: (context) {
return _buildScreen(index);
});
},
),
},
);
},
),
);
default:

View File

@ -4,6 +4,7 @@ import 'package:fimber/fimber.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:git_touch/widgets/action_button.dart';
import 'package:primer/primer.dart';
import 'package:shared_preferences/shared_preferences.dart';
class DialogOption<T> {
@ -63,6 +64,24 @@ class StaticRoute extends PageRouteBuilder {
);
}
class Palette {
Color primary;
Color text;
Color secondaryText;
Color tertiaryText;
Color background;
Color border;
Palette({
this.primary,
this.text,
this.secondaryText,
this.tertiaryText,
this.background,
this.border,
});
}
class ThemeModel with ChangeNotifier {
static const storageKey = 'theme';
@ -70,6 +89,39 @@ class ThemeModel with ChangeNotifier {
int get theme => _theme;
bool get ready => _theme != null;
Brightness _brightness = Brightness.dark;
Brightness get brightness => _brightness;
Future<void> setBrightness(Brightness v) async {
// TODO: Save
_brightness = v;
notifyListeners();
}
Palette get palette {
switch (brightness) {
case Brightness.light:
return Palette(
primary: PrimerColors.blue500,
text: PrimerColors.gray900,
secondaryText: PrimerColors.gray700,
tertiaryText: PrimerColors.gray500,
background: PrimerColors.white,
border: PrimerColors.gray100,
);
case Brightness.dark:
return Palette(
primary: PrimerColors.blue500,
text: PrimerColors.gray400,
secondaryText: PrimerColors.gray500,
tertiaryText: PrimerColors.gray600,
background: PrimerColors.black,
border: PrimerColors.gray900,
);
default:
return null;
}
}
Future<void> init() async {
var prefs = await SharedPreferences.getInstance();

View File

@ -1,7 +1,6 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:git_touch/models/theme.dart';
import 'package:primer/primer.dart';
import 'package:provider/provider.dart';
class CommonScaffold extends StatelessWidget {
@ -9,14 +8,12 @@ class CommonScaffold extends StatelessWidget {
final Widget body;
final Widget action;
final PreferredSizeWidget bottom;
final Color backgroundColor;
CommonScaffold({
@required this.title,
@required this.body,
this.action,
this.bottom,
this.backgroundColor = Colors.white,
});
@override
@ -24,18 +21,14 @@ class CommonScaffold extends StatelessWidget {
switch (Provider.of<ThemeModel>(context).theme) {
case AppThemeType.cupertino:
return CupertinoPageScaffold(
backgroundColor: backgroundColor,
navigationBar: CupertinoNavigationBar(
middle: title,
trailing: action,
backgroundColor: PrimerColors.gray000,
// border: Border(),
),
child: SafeArea(child: body),
);
default:
return Scaffold(
backgroundColor: backgroundColor,
appBar: AppBar(
title: title,
actions: [

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:git_touch/scaffolds/common.dart';
import 'package:git_touch/scaffolds/utils.dart';
import 'package:primer/primer.dart';
class RefreshStatefulScaffold<T> extends StatefulWidget {
final Widget title;
@ -64,7 +63,6 @@ class _RefreshStatefulScaffoldState<T>
@override
Widget build(BuildContext context) {
return CommonScaffold(
backgroundColor: _data == null ? Colors.white : PrimerColors.gray100,
title: widget.title,
body: RefreshWrapper(
onRefresh: _refresh,

View File

@ -5,13 +5,11 @@ class SingleScaffold extends StatelessWidget {
final Widget title;
final Widget body;
final Widget action;
final Color backgroundColor;
SingleScaffold({
@required this.title,
@required this.body,
this.action,
this.backgroundColor,
});
@override
@ -20,7 +18,6 @@ class SingleScaffold extends StatelessWidget {
title: title,
body: Scrollbar(child: SingleChildScrollView(child: body)),
action: action,
backgroundColor: backgroundColor,
);
}
}

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:git_touch/models/theme.dart';
import 'package:git_touch/scaffolds/common.dart';
import 'package:photo_view/photo_view.dart';
import 'package:provider/provider.dart';
class ImageViewScreen extends StatelessWidget {
final String url;
@ -10,11 +12,13 @@ class ImageViewScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Provider.of<ThemeModel>(context);
return CommonScaffold(
title: title,
body: PhotoView(
imageProvider: NetworkImage(url),
backgroundDecoration: BoxDecoration(color: Colors.white),
backgroundDecoration: BoxDecoration(color: theme.palette.background),
),
);
}

View File

@ -211,15 +211,17 @@ class RepositoryScreen extends StatelessWidget {
child: SizedBox(
height: 10,
child: Row(
children: join(
SizedBox(width: 1),
(repo['languages']['edges'] as List)
.map((lang) => Container(
color: convertColor(lang['node']['color']),
width: langWidth *
lang['size'] /
repo['languages']['totalSize']))
.toList())),
children: join(
SizedBox(width: 1),
(repo['languages']['edges'] as List)
.map((lang) => Container(
color: convertColor(lang['node']['color']),
width: langWidth *
lang['size'] /
repo['languages']['totalSize']))
.toList(),
),
),
),
),
),

View File

@ -7,7 +7,6 @@ import 'package:git_touch/screens/issue_form.dart';
import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/app_bar_title.dart';
import 'package:primer/primer.dart';
import 'package:provider/provider.dart';
import 'package:launch_review/launch_review.dart';
import '../widgets/table_view.dart';
@ -25,7 +24,6 @@ class SettingsScreen extends StatelessWidget {
return SingleScaffold(
title: AppBarTitle('Settings'),
backgroundColor: PrimerColors.gray000,
body: Column(
children: <Widget>[
CommonStyle.verticalGap,

View File

@ -25,7 +25,7 @@ class StorageKeys {
class CommonStyle {
static const padding = EdgeInsets.all(12);
static const border = BorderView();
static final border = BorderView();
static const verticalGap = SizedBox(height: 18);
static final monospace = Platform.isIOS ? 'Menlo' : 'monospace'; // FIXME:
}
@ -87,7 +87,7 @@ Tuple2<String, String> parseRepositoryFullName(String fullName) {
return Tuple2(ls[0], ls[1]);
}
class Palette {
class GithubPalette {
static const green = Color(0xff2cbe4e);
}

View File

@ -1,28 +1,19 @@
import 'package:flutter/material.dart';
import 'package:primer/primer.dart';
import 'package:git_touch/models/theme.dart';
import 'package:provider/provider.dart';
class BorderView extends StatelessWidget {
final double height;
final Color color;
final double leftPadding;
const BorderView({
BorderView({
this.height = 1,
this.color = PrimerColors.gray100,
this.leftPadding = 0,
});
@override
Widget build(BuildContext context) {
final b = SizedBox(
height: height,
child: DecoratedBox(
decoration: BoxDecoration(color: color),
),
);
if (leftPadding == 0) {
return b;
}
final theme = Provider.of<ThemeModel>(context);
return Row(
children: <Widget>[
@ -30,10 +21,17 @@ class BorderView extends StatelessWidget {
width: leftPadding,
height: height,
child: DecoratedBox(
decoration: BoxDecoration(color: PrimerColors.white),
decoration: BoxDecoration(color: theme.palette.background),
),
),
Expanded(
child: SizedBox(
height: height,
child: DecoratedBox(
decoration: BoxDecoration(color: theme.palette.border),
),
),
),
Expanded(child: b),
],
);

View File

@ -1,6 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:git_touch/models/theme.dart';
import 'package:git_touch/utils/utils.dart';
import 'package:primer/primer.dart';
import 'package:provider/provider.dart';
import 'link.dart';
class EntryItem extends StatelessWidget {
@ -13,6 +14,8 @@ class EntryItem extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Provider.of<ThemeModel>(context);
return Expanded(
child: Link(
child: Container(
@ -21,13 +24,17 @@ class EntryItem extends StatelessWidget {
children: <Widget>[
Text(
numberFormat.format(count),
style: TextStyle(fontSize: 17, fontWeight: FontWeight.w600),
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w600,
color: theme.palette.text,
),
),
Text(
text,
style: TextStyle(
fontSize: 12,
color: PrimerColors.gray700,
color: theme.palette.secondaryText,
fontWeight: FontWeight.w500,
),
)

View File

@ -5,7 +5,6 @@ import 'package:git_touch/screens/repository.dart';
import 'package:git_touch/widgets/action_button.dart';
import 'package:provider/provider.dart';
import 'package:timeago/timeago.dart' as timeago;
import 'package:primer/primer.dart';
import '../screens/issue.dart';
import '../screens/user.dart';
import 'avatar.dart';
@ -42,16 +41,18 @@ class EventItem extends StatelessWidget {
EventItem(this.event);
static const linkStyle = TextStyle(
color: PrimerColors.blue500,
fontWeight: FontWeight.w600,
);
TextSpan _buildLinkSpan(ThemeModel theme, String text) {
return TextSpan(
text: text,
style: TextStyle(
color: theme.palette.primary,
fontWeight: FontWeight.w600,
),
);
}
TextSpan _buildRepo() =>
TextSpan(text: '${event.repoOwner}/${event.repoName}', style: linkStyle);
TextSpan _buildIssue(int number) =>
TextSpan(text: '#$number', style: linkStyle);
TextSpan _buildRepo(ThemeModel theme) =>
_buildLinkSpan(theme, '${event.repoOwner}/${event.repoName}');
Iterable<ActionItem> _getUserActions(List<String> users) {
// Remove duplicates
@ -70,6 +71,8 @@ class EventItem extends StatelessWidget {
String url,
List<ActionItem> actionItems,
}) {
final theme = Provider.of<ThemeModel>(context);
if (detailWidget == null && detail != null) {
detailWidget =
Text(detail.trim(), overflow: TextOverflow.ellipsis, maxLines: 5);
@ -105,11 +108,11 @@ class EventItem extends StatelessWidget {
text: TextSpan(
style: TextStyle(
fontSize: 16,
color: PrimerColors.gray900,
color: theme.palette.text,
fontWeight: FontWeight.w500,
),
children: [
TextSpan(text: event.actorLogin, style: linkStyle),
_buildLinkSpan(theme, event.actorLogin),
...spans,
],
),
@ -117,18 +120,19 @@ class EventItem extends StatelessWidget {
if (detailWidget != null)
DefaultTextStyle(
style: TextStyle(
color: PrimerColors.gray900, fontSize: 14),
color: theme.palette.text, fontSize: 14),
child: detailWidget,
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(iconData, color: PrimerColors.gray500, size: 14),
Icon(iconData,
color: theme.palette.tertiaryText, size: 14),
SizedBox(width: 4),
Text(timeago.format(event.createdAt),
style: TextStyle(
fontSize: 13,
color: PrimerColors.gray500,
color: theme.palette.tertiaryText,
))
],
),
@ -145,12 +149,14 @@ class EventItem extends StatelessWidget {
@override
build(BuildContext context) {
final theme = Provider.of<ThemeModel>(context);
var defaultItem = _buildItem(
context: context,
spans: [
TextSpan(
text: ' ' + event.type,
style: TextStyle(color: PrimerColors.blue500),
style: TextStyle(color: theme.palette.primary),
)
],
iconData: Octicons.octoface,
@ -179,9 +185,9 @@ class EventItem extends StatelessWidget {
context: context,
spans: [
TextSpan(text: ' forked '),
TextSpan(text: '$forkeeOwner/$forkeeName', style: linkStyle),
_buildLinkSpan(theme, '$forkeeOwner/$forkeeName'),
TextSpan(text: ' from '),
_buildRepo(),
_buildRepo(theme),
],
iconData: Octicons.repo_forked,
screenBuilder: (_) => RepositoryScreen(forkeeOwner, forkeeName),
@ -208,9 +214,9 @@ class EventItem extends StatelessWidget {
context: context,
spans: [
TextSpan(text: ' commented on $resource '),
_buildIssue(number),
_buildLinkSpan(theme, '#$number'),
TextSpan(text: ' at '),
_buildRepo(),
_buildRepo(theme),
// TextSpan(text: event.payload['comment']['body'])
],
detail: event.payload['comment']['body'],
@ -235,9 +241,9 @@ class EventItem extends StatelessWidget {
context: context,
spans: [
TextSpan(text: ' $action issue '),
_buildIssue(number),
_buildLinkSpan(theme, '#$number'),
TextSpan(text: ' at '),
_buildRepo(),
_buildRepo(theme),
],
iconData: Octicons.issue_opened,
detail: event.payload['issue']['title'],
@ -271,9 +277,9 @@ class EventItem extends StatelessWidget {
context: context,
spans: [
TextSpan(text: ' $action pull request '),
_buildIssue(number),
_buildLinkSpan(theme, '#$number'),
TextSpan(text: ' at '),
_buildRepo(),
_buildRepo(theme),
],
iconData: Octicons.git_pull_request,
detail: event.payload['pull_request']['title'],
@ -300,9 +306,9 @@ class EventItem extends StatelessWidget {
context: context,
spans: [
TextSpan(text: ' reviewed pull request '),
_buildIssue(number),
_buildLinkSpan(theme, '#$number'),
TextSpan(text: ' at '),
_buildRepo(),
_buildRepo(theme),
],
detail: event.payload['comment']['body'],
screenBuilder: (_) => IssueScreen(
@ -330,7 +336,7 @@ class EventItem extends StatelessWidget {
child: PrimerBranchName(ref.replaceFirst('refs/heads/', '')),
),
TextSpan(text: ' at '),
_buildRepo()
_buildRepo(theme)
],
iconData: Octicons.repo_push,
detailWidget: Column(
@ -340,7 +346,7 @@ class EventItem extends StatelessWidget {
Text(
(commit['sha'] as String).substring(0, 7),
style: TextStyle(
color: PrimerColors.blue500,
color: theme.palette.primary,
fontSize: 13,
fontFamily: CommonStyle.monospace,
),
@ -377,7 +383,7 @@ class EventItem extends StatelessWidget {
case 'WatchEvent':
return _buildItem(
context: context,
spans: [TextSpan(text: ' starred '), _buildRepo()],
spans: [TextSpan(text: ' starred '), _buildRepo(theme)],
iconData: Octicons.star,
screenBuilder: (_) =>
RepositoryScreen(event.repoOwner, event.repoName),

View File

@ -62,7 +62,7 @@ class IssueItem extends StatelessWidget {
isPullRequest
? Octicons.git_pull_request
: Octicons.issue_opened,
color: Palette.green,
color: GithubPalette.green,
size: 18),
SizedBox(width: 6),
Expanded(

View File

@ -33,19 +33,17 @@ class Link extends StatelessWidget {
@override
Widget build(BuildContext context) {
final theme = Provider.of<ThemeModel>(context).theme;
return Material(
child: Ink(
color: Colors.white,
color: CupertinoTheme.of(context).scaffoldBackgroundColor,
child: InkWell(
child: child,
// splashColor:
// theme == AppThemeType.cupertino ? Colors.transparent : null,
splashColor:
theme == AppThemeType.cupertino ? Colors.transparent : null,
onTap: () => _onTap(context),
onLongPress: () {
if (onLongPress != null) {
onLongPress();
}
},
onLongPress: onLongPress,
),
),
);

View File

@ -37,7 +37,7 @@ class _NotificationItemState extends State<NotificationItem> {
case 'Issue':
switch (payload.state) {
case 'OPEN':
return _buildIcon(Octicons.issue_opened, Palette.green);
return _buildIcon(Octicons.issue_opened, GithubPalette.green);
case 'CLOSED':
return _buildIcon(Octicons.issue_closed, PrimerColors.red600);
default:
@ -47,7 +47,7 @@ class _NotificationItemState extends State<NotificationItem> {
case 'PullRequest':
switch (payload.state) {
case 'OPEN':
return _buildIcon(Octicons.git_pull_request, Palette.green);
return _buildIcon(Octicons.git_pull_request, GithubPalette.green);
case 'CLOSED':
return _buildIcon(Octicons.git_pull_request, PrimerColors.red600);
case 'MERGED':

View File

@ -89,79 +89,10 @@ class RepositoryItem extends StatelessWidget {
return Octicons.repo;
}
Widget _buildStatus() {
return DefaultTextStyle(
style: TextStyle(
color: PrimerColors.gray800,
fontSize: 13,
fontWeight: FontWeight.w500,
),
child: Row(
children: <Widget>[
Expanded(
child: Row(children: <Widget>[
Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: convertColor(primaryLanguageColor),
shape: BoxShape.circle,
),
),
SizedBox(width: 4),
Text(primaryLanguageName ?? 'Unknown'),
]),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(Octicons.star, size: 14, color: PrimerColors.gray600),
Text(numberFormat.format(starCount)),
],
),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(Octicons.repo_forked,
size: 14, color: PrimerColors.gray600),
Text(numberFormat.format(forkCount)),
],
),
),
],
),
);
}
Widget _buildTopics() {
// TODO: link
return Wrap(
spacing: 4,
runSpacing: 4,
children: topics.map((node) {
return Container(
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
decoration: BoxDecoration(
color: PrimerColors.blue000,
borderRadius: BorderRadius.all(Radius.circular(4)),
),
child: Text(
node['topic']['name'],
style: TextStyle(
fontSize: 12,
color: PrimerColors.blue500,
),
),
);
}).toList(),
);
}
@override
Widget build(BuildContext context) {
final theme = Provider.of<ThemeModel>(context);
// TODO: text style
return Link(
screenBuilder: inRepoScreen ? null : screenBuilder,
@ -189,7 +120,7 @@ class RepositoryItem extends StatelessWidget {
owner + ' / ',
style: TextStyle(
fontSize: inRepoScreen ? 18 : 16,
color: PrimerColors.blue500,
color: theme.palette.primary,
fontWeight: FontWeight.w500,
),
),
@ -197,22 +128,91 @@ class RepositoryItem extends StatelessWidget {
name,
style: TextStyle(
fontSize: inRepoScreen ? 18 : 16,
color: PrimerColors.blue500,
color: theme.palette.primary,
fontWeight: FontWeight.w600,
),
),
Expanded(child: Container()),
Icon(iconData, size: 18, color: PrimerColors.gray600),
Icon(iconData,
size: 18, color: theme.palette.tertiaryText),
],
),
if (description != null && description.isNotEmpty)
Text(
description,
style: TextStyle(
color: PrimerColors.gray700,
color: theme.palette.secondaryText,
fontSize: inRepoScreen ? 15 : 14),
),
if (inRepoScreen) _buildTopics() else _buildStatus(),
if (inRepoScreen)
// TODO: link
Wrap(
spacing: 4,
runSpacing: 4,
children: topics.map((node) {
return Container(
padding:
EdgeInsets.symmetric(vertical: 4, horizontal: 8),
decoration: BoxDecoration(
color: PrimerColors.blue000,
borderRadius: BorderRadius.all(Radius.circular(4)),
),
child: Text(
node['topic']['name'],
style: TextStyle(
fontSize: 12,
color: theme.palette.primary,
),
),
);
}).toList(),
)
else
DefaultTextStyle(
style: TextStyle(
color: theme.palette.text,
fontSize: 13,
fontWeight: FontWeight.w500,
),
child: Row(
children: <Widget>[
Expanded(
child: Row(children: <Widget>[
Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: convertColor(primaryLanguageColor),
shape: BoxShape.circle,
),
),
SizedBox(width: 4),
Text(primaryLanguageName ?? 'Unknown'),
]),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(Octicons.star,
size: 14, color: theme.palette.text),
Text(numberFormat.format(starCount)),
],
),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Icon(Octicons.repo_forked,
size: 14, color: theme.palette.text),
Text(numberFormat.format(forkCount)),
],
),
),
],
),
),
]),
),
),

View File

@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:git_touch/models/theme.dart';
import 'package:git_touch/utils/utils.dart';
import 'package:git_touch/widgets/border_view.dart';
import 'package:primer/primer.dart';
import 'package:provider/provider.dart';
import 'link.dart';
class TableViewHeader extends StatelessWidget {
@ -53,72 +55,76 @@ class TableView extends StatelessWidget {
TableView({this.headerText, @required this.items, this.hasIcon = false});
Widget _buildItem(TableViewItem item) {
if (item == null) return null;
var leftWidget = item.leftWidget;
if (leftWidget == null && hasIcon) {
leftWidget = Icon(
item.leftIconData,
color: PrimerColors.blue500,
size: 18,
);
}
// Container(
// width: 24,
// height: 24,
// // decoration: BoxDecoration(
// // borderRadius: BorderRadius.circular(4), color: PrimerColors.blue400),
// child: Icon(iconData, size: 24, color: PrimerColors.gray600),
// )
var widget = DefaultTextStyle(
style: TextStyle(fontSize: 16, color: PrimerColors.gray900),
overflow: TextOverflow.ellipsis,
child: Container(
height: 44,
child: Row(
children: [
SizedBox(width: _leftPadding, child: leftWidget),
Expanded(child: item.text),
if (item.rightWidget != null) ...[
DefaultTextStyle(
style: TextStyle(fontSize: 16, color: PrimerColors.gray500),
child: item.rightWidget,
),
SizedBox(width: 6)
],
if ((item.onTap != null ||
item.screenBuilder != null ||
item.url != null) &&
!item.hideRightChevron)
Icon(CupertinoIcons.right_chevron,
size: 20, color: PrimerColors.gray300)
else
SizedBox(width: 2),
SizedBox(width: 8),
],
),
),
);
return Link(
onTap: item.onTap,
screenBuilder: item.screenBuilder,
url: item.url,
child: widget,
);
}
@override
Widget build(BuildContext context) {
final themeModel = Provider.of<ThemeModel>(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
if (headerText != null) TableViewHeader(headerText),
CommonStyle.border,
...join(BorderView(leftPadding: _leftPadding),
items.map(_buildItem).toList()),
...join(
BorderView(leftPadding: _leftPadding),
items.map((item) {
if (item == null) return null;
var leftWidget = item.leftWidget;
if (leftWidget == null && hasIcon) {
leftWidget = Icon(
item.leftIconData,
color: themeModel.palette.primary,
size: 18,
);
}
// Container(
// width: 24,
// height: 24,
// // decoration: BoxDecoration(
// // borderRadius: BorderRadius.circular(4), color: PrimerColors.blue400),
// child: Icon(iconData, size: 24, color: PrimerColors.gray600),
// )
var widget = DefaultTextStyle(
style: TextStyle(fontSize: 16, color: themeModel.palette.text),
overflow: TextOverflow.ellipsis,
child: Container(
height: 44,
child: Row(
children: [
SizedBox(width: _leftPadding, child: leftWidget),
Expanded(child: item.text),
if (item.rightWidget != null) ...[
DefaultTextStyle(
style: TextStyle(
fontSize: 16,
color: themeModel.palette.tertiaryText,
),
child: item.rightWidget,
),
SizedBox(width: 6)
],
if ((item.onTap != null ||
item.screenBuilder != null ||
item.url != null) &&
!item.hideRightChevron)
Icon(CupertinoIcons.right_chevron,
size: 20, color: themeModel.palette.tertiaryText)
else
SizedBox(width: 2),
SizedBox(width: 8),
],
),
),
);
return Link(
onTap: item.onTap,
screenBuilder: item.screenBuilder,
url: item.url,
child: widget,
);
}).toList()),
CommonStyle.border,
],
);

View File

@ -107,7 +107,7 @@ class TimelineItem extends StatelessWidget {
return TimelineEventItem(
actor: payload['actor']['login'],
iconData: Octicons.primitive_dot,
iconColor: Palette.green,
iconColor: GithubPalette.green,
textSpan: TextSpan(
text: ' referenced this on #' +
payload['source']['number'].toString()),
@ -126,7 +126,7 @@ class TimelineItem extends StatelessWidget {
return TimelineEventItem(
actor: payload['actor']['login'],
iconData: Octicons.primitive_dot,
iconColor: Palette.green,
iconColor: GithubPalette.green,
textSpan: TextSpan(text: ' reopened this '),
item: payload,
);