mirror of
https://github.com/flutter/samples.git
synced 2025-11-10 23:08:59 +00:00
[Gallery] Update desktop Rally for pages that did not have designs before (#314)
* Update desktop Rally for pages that did not have designs before
This commit is contained in:
BIN
gallery/fonts/google_fonts/Eczar-Regular.ttf
Normal file
BIN
gallery/fonts/google_fonts/Eczar-Regular.ttf
Normal file
Binary file not shown.
BIN
gallery/fonts/google_fonts/Eczar-SemiBold.ttf
Normal file
BIN
gallery/fonts/google_fonts/Eczar-SemiBold.ttf
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -171,6 +171,18 @@
|
|||||||
"@rallyAccountDetailDataAccountOwner": {
|
"@rallyAccountDetailDataAccountOwner": {
|
||||||
"description": "Title for an account detail. Below the name of the account owner will be displayed."
|
"description": "Title for an account detail. Below the name of the account owner will be displayed."
|
||||||
},
|
},
|
||||||
|
"rallyBillDetailTotalAmount": "Total Amount",
|
||||||
|
"@rallyBillDetailTotalAmount": {
|
||||||
|
"description": "Title for column where it displays the total dollar amount that the user has in bills."
|
||||||
|
},
|
||||||
|
"rallyBillDetailAmountPaid": "Amount Paid",
|
||||||
|
"@rallyBillDetailAmountPaid": {
|
||||||
|
"description": "Title for column where it displays the amount that the user has paid."
|
||||||
|
},
|
||||||
|
"rallyBillDetailAmountDue": "Amount Due",
|
||||||
|
"@rallyBillDetailAmountDue": {
|
||||||
|
"description": "Title for column where it displays the amount that the user has due."
|
||||||
|
},
|
||||||
"rallyBudgetCategoryCoffeeShops": "Coffee Shops",
|
"rallyBudgetCategoryCoffeeShops": "Coffee Shops",
|
||||||
"@rallyBudgetCategoryCoffeeShops": {
|
"@rallyBudgetCategoryCoffeeShops": {
|
||||||
"description": "Category for budget, to sort expenses / bills in."
|
"description": "Category for budget, to sort expenses / bills in."
|
||||||
@@ -187,6 +199,18 @@
|
|||||||
"@rallyBudgetCategoryClothing": {
|
"@rallyBudgetCategoryClothing": {
|
||||||
"description": "Category for budget, to sort expenses / bills in."
|
"description": "Category for budget, to sort expenses / bills in."
|
||||||
},
|
},
|
||||||
|
"rallyBudgetDetailTotalCap": "Total Cap",
|
||||||
|
"@rallyBudgetDetailTotalCap": {
|
||||||
|
"description": "Title for column where it displays the total dollar cap that the user has for its budget."
|
||||||
|
},
|
||||||
|
"rallyBudgetDetailAmountUsed": "Amount Used",
|
||||||
|
"@rallyBudgetDetailAmountUsed": {
|
||||||
|
"description": "Title for column where it displays the dollar amount that the user has used in its budget."
|
||||||
|
},
|
||||||
|
"rallyBudgetDetailAmountLeft": "Amount Left",
|
||||||
|
"@rallyBudgetDetailAmountLeft": {
|
||||||
|
"description": "Title for column where it displays the dollar amount that the user has left in its budget."
|
||||||
|
},
|
||||||
"rallySettingsManageAccounts": "Manage Accounts",
|
"rallySettingsManageAccounts": "Manage Accounts",
|
||||||
"@rallySettingsManageAccounts": {
|
"@rallySettingsManageAccounts": {
|
||||||
"description": "Link to go to the page 'Manage Accounts."
|
"description": "Link to go to the page 'Manage Accounts."
|
||||||
|
|||||||
@@ -161,6 +161,18 @@
|
|||||||
name="rallyAccountDetailDataAccountOwner"
|
name="rallyAccountDetailDataAccountOwner"
|
||||||
description="Title for an account detail. Below the name of the account owner will be displayed."
|
description="Title for an account detail. Below the name of the account owner will be displayed."
|
||||||
>Account Owner</string>
|
>Account Owner</string>
|
||||||
|
<string
|
||||||
|
name="rallyBillDetailTotalAmount"
|
||||||
|
description="Title for column where it displays the total dollar amount that the user has in bills."
|
||||||
|
>Total Amount</string>
|
||||||
|
<string
|
||||||
|
name="rallyBillDetailAmountPaid"
|
||||||
|
description="Title for column where it displays the amount that the user has paid."
|
||||||
|
>Amount Paid</string>
|
||||||
|
<string
|
||||||
|
name="rallyBillDetailAmountDue"
|
||||||
|
description="Title for column where it displays the amount that the user has due."
|
||||||
|
>Amount Due</string>
|
||||||
<string
|
<string
|
||||||
name="rallyBudgetCategoryCoffeeShops"
|
name="rallyBudgetCategoryCoffeeShops"
|
||||||
description="Category for budget, to sort expenses / bills in."
|
description="Category for budget, to sort expenses / bills in."
|
||||||
@@ -177,6 +189,18 @@
|
|||||||
name="rallyBudgetCategoryClothing"
|
name="rallyBudgetCategoryClothing"
|
||||||
description="Category for budget, to sort expenses / bills in."
|
description="Category for budget, to sort expenses / bills in."
|
||||||
>Clothing</string>
|
>Clothing</string>
|
||||||
|
<string
|
||||||
|
name="rallyBudgetDetailTotalCap"
|
||||||
|
description="Title for column where it displays the total dollar cap that the user has for its budget."
|
||||||
|
>Total Cap</string>
|
||||||
|
<string
|
||||||
|
name="rallyBudgetDetailAmountUsed"
|
||||||
|
description="Title for column where it displays the dollar amount that the user has used in its budget."
|
||||||
|
>Amount Used</string>
|
||||||
|
<string
|
||||||
|
name="rallyBudgetDetailAmountLeft"
|
||||||
|
description="Title for column where it displays the dollar amount that the user has left in its budget."
|
||||||
|
>Amount Left</string>
|
||||||
<string
|
<string
|
||||||
name="rallySettingsManageAccounts"
|
name="rallySettingsManageAccounts"
|
||||||
description="Link to go to the page 'Manage Accounts."
|
description="Link to go to the page 'Manage Accounts."
|
||||||
|
|||||||
@@ -995,6 +995,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
"rallyAlertsMessageSpentOnRestaurants": m24,
|
"rallyAlertsMessageSpentOnRestaurants": m24,
|
||||||
"rallyAlertsMessageUnassignedTransactions": m25,
|
"rallyAlertsMessageUnassignedTransactions": m25,
|
||||||
"rallyBillAmount": m26,
|
"rallyBillAmount": m26,
|
||||||
|
"rallyBillDetailAmountDue":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Amount Due"),
|
||||||
|
"rallyBillDetailAmountPaid":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Amount Paid"),
|
||||||
|
"rallyBillDetailTotalAmount":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Total Amount"),
|
||||||
"rallyBills": MessageLookupByLibrary.simpleMessage("Bills"),
|
"rallyBills": MessageLookupByLibrary.simpleMessage("Bills"),
|
||||||
"rallyBillsDue": MessageLookupByLibrary.simpleMessage("Due"),
|
"rallyBillsDue": MessageLookupByLibrary.simpleMessage("Due"),
|
||||||
"rallyBudgetAmount": m27,
|
"rallyBudgetAmount": m27,
|
||||||
@@ -1006,6 +1012,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||||||
MessageLookupByLibrary.simpleMessage("Groceries"),
|
MessageLookupByLibrary.simpleMessage("Groceries"),
|
||||||
"rallyBudgetCategoryRestaurants":
|
"rallyBudgetCategoryRestaurants":
|
||||||
MessageLookupByLibrary.simpleMessage("Restaurants"),
|
MessageLookupByLibrary.simpleMessage("Restaurants"),
|
||||||
|
"rallyBudgetDetailAmountLeft":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Amount Left"),
|
||||||
|
"rallyBudgetDetailAmountUsed":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Amount Used"),
|
||||||
|
"rallyBudgetDetailTotalCap":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Total Cap"),
|
||||||
"rallyBudgetLeft": MessageLookupByLibrary.simpleMessage("Left"),
|
"rallyBudgetLeft": MessageLookupByLibrary.simpleMessage("Left"),
|
||||||
"rallyBudgets": MessageLookupByLibrary.simpleMessage("Budgets"),
|
"rallyBudgets": MessageLookupByLibrary.simpleMessage("Budgets"),
|
||||||
"rallyDescription":
|
"rallyDescription":
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:flutter/semantics.dart';
|
|||||||
|
|
||||||
import 'package:gallery/data/gallery_options.dart';
|
import 'package:gallery/data/gallery_options.dart';
|
||||||
import 'package:gallery/layout/text_scale.dart';
|
import 'package:gallery/layout/text_scale.dart';
|
||||||
|
import 'package:gallery/layout/adaptive.dart';
|
||||||
import 'package:gallery/studies/rally/colors.dart';
|
import 'package:gallery/studies/rally/colors.dart';
|
||||||
import 'package:gallery/studies/rally/data.dart';
|
import 'package:gallery/studies/rally/data.dart';
|
||||||
import 'package:gallery/studies/rally/formatters.dart';
|
import 'package:gallery/studies/rally/formatters.dart';
|
||||||
@@ -28,6 +29,9 @@ class RallyLineChart extends StatelessWidget {
|
|||||||
labelStyle: Theme.of(context).textTheme.body1,
|
labelStyle: Theme.of(context).textTheme.body1,
|
||||||
textDirection: GalleryOptions.of(context).textDirection(),
|
textDirection: GalleryOptions.of(context).textDirection(),
|
||||||
textScaleFactor: reducedTextScale(context),
|
textScaleFactor: reducedTextScale(context),
|
||||||
|
padding: isDisplayDesktop(context)
|
||||||
|
? EdgeInsets.symmetric(vertical: 22)
|
||||||
|
: EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -41,6 +45,7 @@ class RallyLineChartPainter extends CustomPainter {
|
|||||||
@required this.labelStyle,
|
@required this.labelStyle,
|
||||||
@required this.textDirection,
|
@required this.textDirection,
|
||||||
@required this.textScaleFactor,
|
@required this.textScaleFactor,
|
||||||
|
@required this.padding,
|
||||||
});
|
});
|
||||||
|
|
||||||
// The style for the labels.
|
// The style for the labels.
|
||||||
@@ -52,6 +57,9 @@ class RallyLineChartPainter extends CustomPainter {
|
|||||||
// The text scale factor for the text.
|
// The text scale factor for the text.
|
||||||
final double textScaleFactor;
|
final double textScaleFactor;
|
||||||
|
|
||||||
|
// The padding around the text.
|
||||||
|
final EdgeInsets padding;
|
||||||
|
|
||||||
// The format for the dates.
|
// The format for the dates.
|
||||||
final intl.DateFormat dateFormat;
|
final intl.DateFormat dateFormat;
|
||||||
|
|
||||||
@@ -253,7 +261,8 @@ class RallyLineChartPainter extends CustomPainter {
|
|||||||
textDirection: textDirection,
|
textDirection: textDirection,
|
||||||
);
|
);
|
||||||
leftLabel.layout();
|
leftLabel.layout();
|
||||||
leftLabel.paint(canvas, Offset(rect.left + space / 2, rect.topCenter.dy));
|
leftLabel.paint(canvas,
|
||||||
|
Offset(rect.left + space / 2 + padding.vertical, rect.topCenter.dy));
|
||||||
|
|
||||||
final centerLabel = TextPainter(
|
final centerLabel = TextPainter(
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
@@ -281,7 +290,8 @@ class RallyLineChartPainter extends CustomPainter {
|
|||||||
rightLabel.layout();
|
rightLabel.layout();
|
||||||
rightLabel.paint(
|
rightLabel.paint(
|
||||||
canvas,
|
canvas,
|
||||||
Offset(rect.right - centerLabel.width - space / 2, rect.topCenter.dy),
|
Offset(rect.right - centerLabel.width - space / 2 - padding.vertical,
|
||||||
|
rect.topCenter.dy),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ class RallyColors {
|
|||||||
static const Color cardBackground = Color(0x03FEFEFE);
|
static const Color cardBackground = Color(0x03FEFEFE);
|
||||||
static const Color buttonColor = Color(0xFF09AF79);
|
static const Color buttonColor = Color(0xFF09AF79);
|
||||||
static const Color focusColor = Color(0xCCFFFFFF);
|
static const Color focusColor = Color(0xCCFFFFFF);
|
||||||
|
static const Color dividerColor = Color(0xAA282828);
|
||||||
|
|
||||||
/// Convenience method to get a single account color with position i.
|
/// Convenience method to get a single account color with position i.
|
||||||
static Color accountColor(int i) {
|
static Color accountColor(int i) {
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ double sumAccountDataPrimaryAmount(List<AccountData> items) =>
|
|||||||
double sumBillDataPrimaryAmount(List<BillData> items) =>
|
double sumBillDataPrimaryAmount(List<BillData> items) =>
|
||||||
sumOf<BillData>(items, (item) => item.primaryAmount);
|
sumOf<BillData>(items, (item) => item.primaryAmount);
|
||||||
|
|
||||||
|
/// Calculates the sum of the primary amounts of a list of [BillData].
|
||||||
|
double sumBillDataPaidAmount(List<BillData> items) => sumOf<BillData>(
|
||||||
|
items.where((item) => item.isPaid).toList(),
|
||||||
|
(item) => item.primaryAmount,
|
||||||
|
);
|
||||||
|
|
||||||
/// Calculates the sum of the primary amounts of a list of [BudgetData].
|
/// Calculates the sum of the primary amounts of a list of [BudgetData].
|
||||||
double sumBudgetDataPrimaryAmount(List<BudgetData> items) =>
|
double sumBudgetDataPrimaryAmount(List<BudgetData> items) =>
|
||||||
sumOf<BudgetData>(items, (item) => item.primaryAmount);
|
sumOf<BudgetData>(items, (item) => item.primaryAmount);
|
||||||
@@ -52,7 +58,12 @@ class AccountData {
|
|||||||
///
|
///
|
||||||
/// The [primaryAmount] is the amount due in USD.
|
/// The [primaryAmount] is the amount due in USD.
|
||||||
class BillData {
|
class BillData {
|
||||||
const BillData({this.name, this.primaryAmount, this.dueDate});
|
const BillData({
|
||||||
|
this.name,
|
||||||
|
this.primaryAmount,
|
||||||
|
this.dueDate,
|
||||||
|
this.isPaid = false,
|
||||||
|
});
|
||||||
|
|
||||||
/// The display name of this entity.
|
/// The display name of this entity.
|
||||||
final String name;
|
final String name;
|
||||||
@@ -62,6 +73,9 @@ class BillData {
|
|||||||
|
|
||||||
/// The due date of this bill.
|
/// The due date of this bill.
|
||||||
final String dueDate;
|
final String dueDate;
|
||||||
|
|
||||||
|
/// If this bill has been paid.
|
||||||
|
final bool isPaid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A data model for a budget.
|
/// A data model for a budget.
|
||||||
@@ -103,9 +117,9 @@ class DetailedEventData {
|
|||||||
final double amount;
|
final double amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A data model for account data.
|
/// A data model for data displayed to the user.
|
||||||
class AccountDetailData {
|
class UserDetailData {
|
||||||
AccountDetailData({this.title, this.value});
|
UserDetailData({this.title, this.value});
|
||||||
|
|
||||||
/// The display name of this entity.
|
/// The display name of this entity.
|
||||||
final String title;
|
final String title;
|
||||||
@@ -143,34 +157,34 @@ class DummyDataService {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<AccountDetailData> getAccountDetailList(BuildContext context) {
|
static List<UserDetailData> getAccountDetailList(BuildContext context) {
|
||||||
return <AccountDetailData>[
|
return <UserDetailData>[
|
||||||
AccountDetailData(
|
UserDetailData(
|
||||||
title: GalleryLocalizations.of(context)
|
title: GalleryLocalizations.of(context)
|
||||||
.rallyAccountDetailDataAnnualPercentageYield,
|
.rallyAccountDetailDataAnnualPercentageYield,
|
||||||
value: percentFormat(context).format(0.001),
|
value: percentFormat(context).format(0.001),
|
||||||
),
|
),
|
||||||
AccountDetailData(
|
UserDetailData(
|
||||||
title:
|
title:
|
||||||
GalleryLocalizations.of(context).rallyAccountDetailDataInterestRate,
|
GalleryLocalizations.of(context).rallyAccountDetailDataInterestRate,
|
||||||
value: usdWithSignFormat(context).format(1676.14),
|
value: usdWithSignFormat(context).format(1676.14),
|
||||||
),
|
),
|
||||||
AccountDetailData(
|
UserDetailData(
|
||||||
title:
|
title:
|
||||||
GalleryLocalizations.of(context).rallyAccountDetailDataInterestYtd,
|
GalleryLocalizations.of(context).rallyAccountDetailDataInterestYtd,
|
||||||
value: usdWithSignFormat(context).format(81.45),
|
value: usdWithSignFormat(context).format(81.45),
|
||||||
),
|
),
|
||||||
AccountDetailData(
|
UserDetailData(
|
||||||
title: GalleryLocalizations.of(context)
|
title: GalleryLocalizations.of(context)
|
||||||
.rallyAccountDetailDataInterestPaidLastYear,
|
.rallyAccountDetailDataInterestPaidLastYear,
|
||||||
value: usdWithSignFormat(context).format(987.12),
|
value: usdWithSignFormat(context).format(987.12),
|
||||||
),
|
),
|
||||||
AccountDetailData(
|
UserDetailData(
|
||||||
title: GalleryLocalizations.of(context)
|
title: GalleryLocalizations.of(context)
|
||||||
.rallyAccountDetailDataNextStatement,
|
.rallyAccountDetailDataNextStatement,
|
||||||
value: shortDateFormat(context).format(DateTime.utc(2019, 12, 25)),
|
value: shortDateFormat(context).format(DateTime.utc(2019, 12, 25)),
|
||||||
),
|
),
|
||||||
AccountDetailData(
|
UserDetailData(
|
||||||
title:
|
title:
|
||||||
GalleryLocalizations.of(context).rallyAccountDetailDataAccountOwner,
|
GalleryLocalizations.of(context).rallyAccountDetailDataAccountOwner,
|
||||||
value: 'Philip Cao',
|
value: 'Philip Cao',
|
||||||
@@ -233,6 +247,7 @@ class DummyDataService {
|
|||||||
primaryAmount: 1200,
|
primaryAmount: 1200,
|
||||||
dueDate: dateFormatAbbreviatedMonthDay(context)
|
dueDate: dateFormatAbbreviatedMonthDay(context)
|
||||||
.format(DateTime.utc(2019, 2, 9)),
|
.format(DateTime.utc(2019, 2, 9)),
|
||||||
|
isPaid: true,
|
||||||
),
|
),
|
||||||
BillData(
|
BillData(
|
||||||
name: 'TabFine Credit',
|
name: 'TabFine Credit',
|
||||||
@@ -249,6 +264,24 @@ class DummyDataService {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<UserDetailData> getBillDetailList(BuildContext context,
|
||||||
|
{double dueTotal, double paidTotal}) {
|
||||||
|
return <UserDetailData>[
|
||||||
|
UserDetailData(
|
||||||
|
title: GalleryLocalizations.of(context).rallyBillDetailTotalAmount,
|
||||||
|
value: usdWithSignFormat(context).format(paidTotal + dueTotal),
|
||||||
|
),
|
||||||
|
UserDetailData(
|
||||||
|
title: GalleryLocalizations.of(context).rallyBillDetailAmountPaid,
|
||||||
|
value: usdWithSignFormat(context).format(paidTotal),
|
||||||
|
),
|
||||||
|
UserDetailData(
|
||||||
|
title: GalleryLocalizations.of(context).rallyBillDetailAmountDue,
|
||||||
|
value: usdWithSignFormat(context).format(dueTotal),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
static List<BudgetData> getBudgetDataList(BuildContext context) {
|
static List<BudgetData> getBudgetDataList(BuildContext context) {
|
||||||
return <BudgetData>[
|
return <BudgetData>[
|
||||||
BudgetData(
|
BudgetData(
|
||||||
@@ -274,6 +307,24 @@ class DummyDataService {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<UserDetailData> getBudgetDetailList(BuildContext context,
|
||||||
|
{double capTotal, double usedTotal}) {
|
||||||
|
return <UserDetailData>[
|
||||||
|
UserDetailData(
|
||||||
|
title: GalleryLocalizations.of(context).rallyBudgetDetailTotalCap,
|
||||||
|
value: usdWithSignFormat(context).format(capTotal),
|
||||||
|
),
|
||||||
|
UserDetailData(
|
||||||
|
title: GalleryLocalizations.of(context).rallyBudgetDetailAmountUsed,
|
||||||
|
value: usdWithSignFormat(context).format(usedTotal),
|
||||||
|
),
|
||||||
|
UserDetailData(
|
||||||
|
title: GalleryLocalizations.of(context).rallyBudgetDetailAmountLeft,
|
||||||
|
value: usdWithSignFormat(context).format(capTotal - usedTotal),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
static List<String> getSettingsTitles(BuildContext context) {
|
static List<String> getSettingsTitles(BuildContext context) {
|
||||||
return <String>[
|
return <String>[
|
||||||
GalleryLocalizations.of(context).rallySettingsManageAccounts,
|
GalleryLocalizations.of(context).rallySettingsManageAccounts,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import 'package:flutter/rendering.dart';
|
|||||||
|
|
||||||
import 'package:gallery/data/gallery_options.dart';
|
import 'package:gallery/data/gallery_options.dart';
|
||||||
import 'package:gallery/l10n/gallery_localizations.dart';
|
import 'package:gallery/l10n/gallery_localizations.dart';
|
||||||
|
import 'package:gallery/layout/adaptive.dart';
|
||||||
import 'package:gallery/layout/text_scale.dart';
|
import 'package:gallery/layout/text_scale.dart';
|
||||||
import 'package:gallery/studies/rally/charts/line_chart.dart';
|
import 'package:gallery/studies/rally/charts/line_chart.dart';
|
||||||
import 'package:gallery/studies/rally/charts/pie_chart.dart';
|
import 'package:gallery/studies/rally/charts/pie_chart.dart';
|
||||||
@@ -170,7 +171,7 @@ class FinancialEntityCategoryView extends StatelessWidget {
|
|||||||
height: 1,
|
height: 1,
|
||||||
indent: 16,
|
indent: 16,
|
||||||
endIndent: 16,
|
endIndent: 16,
|
||||||
color: Color(0xAA282828),
|
color: RallyColors.dividerColor,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -309,13 +310,7 @@ class FinancialEntityCategoryDetailsPage extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final List<_DetailedEventCard> cards = items.map((detailedEventData) {
|
final isDesktop = isDisplayDesktop(context);
|
||||||
return _DetailedEventCard(
|
|
||||||
title: detailedEventData.title,
|
|
||||||
date: detailedEventData.date,
|
|
||||||
amount: detailedEventData.amount,
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
return ApplyTextOptions(
|
return ApplyTextOptions(
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
@@ -335,7 +330,20 @@ class FinancialEntityCategoryDetailsPage extends StatelessWidget {
|
|||||||
child: RallyLineChart(events: items),
|
child: RallyLineChart(events: items),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView(shrinkWrap: true, children: cards),
|
child: Padding(
|
||||||
|
padding: isDesktop ? EdgeInsets.all(40) : EdgeInsets.zero,
|
||||||
|
child: ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
children: [
|
||||||
|
for (DetailedEventData detailedEventData in items)
|
||||||
|
_DetailedEventCard(
|
||||||
|
title: detailedEventData.title,
|
||||||
|
date: detailedEventData.date,
|
||||||
|
amount: detailedEventData.amount,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -357,7 +365,7 @@ class _DetailedEventCard extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final isDesktop = isDisplayDesktop(context);
|
||||||
return FlatButton(
|
return FlatButton(
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16),
|
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||||
@@ -366,37 +374,42 @@ class _DetailedEventCard extends StatelessWidget {
|
|||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(vertical: 16),
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Wrap(
|
child: isDesktop
|
||||||
alignment: WrapAlignment.spaceBetween,
|
? Row(
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Expanded(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
flex: 1,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: _EventTitle(title: title),
|
||||||
children: [
|
),
|
||||||
Text(
|
_EventDate(date: date),
|
||||||
title,
|
Expanded(
|
||||||
style: textTheme.body1.copyWith(fontSize: 16),
|
flex: 1,
|
||||||
),
|
child: Align(
|
||||||
Text(
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
shortDateFormat(context).format(date),
|
child: _EventAmount(amount: amount),
|
||||||
semanticsLabel: longDateFormat(context).format(date),
|
),
|
||||||
style:
|
),
|
||||||
textTheme.body1.copyWith(color: RallyColors.gray60),
|
],
|
||||||
),
|
)
|
||||||
],
|
: Wrap(
|
||||||
),
|
alignment: WrapAlignment.spaceBetween,
|
||||||
Text(
|
children: [
|
||||||
usdWithSignFormat(context).format(amount),
|
Column(
|
||||||
style: textTheme.body2
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
.copyWith(fontSize: 20, color: RallyColors.gray),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
),
|
children: [
|
||||||
],
|
_EventTitle(title: title),
|
||||||
),
|
_EventDate(date: date),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
_EventAmount(amount: amount),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 1,
|
height: 1,
|
||||||
child: Container(
|
child: Container(
|
||||||
color: const Color(0xAA282828),
|
color: RallyColors.dividerColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -404,3 +417,49 @@ class _DetailedEventCard extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _EventAmount extends StatelessWidget {
|
||||||
|
const _EventAmount({Key key, @required this.amount}) : super(key: key);
|
||||||
|
|
||||||
|
final double amount;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
return Text(
|
||||||
|
usdWithSignFormat(context).format(amount),
|
||||||
|
style: textTheme.body2.copyWith(fontSize: 20, color: RallyColors.gray),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EventDate extends StatelessWidget {
|
||||||
|
const _EventDate({Key key, @required this.date}) : super(key: key);
|
||||||
|
|
||||||
|
final DateTime date;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
return Text(
|
||||||
|
shortDateFormat(context).format(date),
|
||||||
|
semanticsLabel: longDateFormat(context).format(date),
|
||||||
|
style: textTheme.body1.copyWith(color: RallyColors.gray60),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EventTitle extends StatelessWidget {
|
||||||
|
const _EventTitle({Key key, @required this.title}) : super(key: key);
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
return Text(
|
||||||
|
title,
|
||||||
|
style: textTheme.body1.copyWith(fontSize: 16),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,11 +5,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:gallery/l10n/gallery_localizations.dart';
|
import 'package:gallery/l10n/gallery_localizations.dart';
|
||||||
import 'package:gallery/layout/adaptive.dart';
|
|
||||||
import 'package:gallery/studies/rally/charts/pie_chart.dart';
|
import 'package:gallery/studies/rally/charts/pie_chart.dart';
|
||||||
import 'package:gallery/studies/rally/colors.dart';
|
|
||||||
import 'package:gallery/studies/rally/data.dart';
|
import 'package:gallery/studies/rally/data.dart';
|
||||||
import 'package:gallery/studies/rally/finance.dart';
|
import 'package:gallery/studies/rally/finance.dart';
|
||||||
|
import 'package:gallery/studies/rally/tabs/sidebar.dart';
|
||||||
|
|
||||||
/// A page that shows a summary of accounts.
|
/// A page that shows a summary of accounts.
|
||||||
class AccountsView extends StatelessWidget {
|
class AccountsView extends StatelessWidget {
|
||||||
@@ -18,74 +17,18 @@ class AccountsView extends StatelessWidget {
|
|||||||
final items = DummyDataService.getAccountDataList(context);
|
final items = DummyDataService.getAccountDataList(context);
|
||||||
final detailItems = DummyDataService.getAccountDetailList(context);
|
final detailItems = DummyDataService.getAccountDetailList(context);
|
||||||
final balanceTotal = sumAccountDataPrimaryAmount(items);
|
final balanceTotal = sumAccountDataPrimaryAmount(items);
|
||||||
final view = FinancialEntityView(
|
|
||||||
heroLabel: GalleryLocalizations.of(context).rallyAccountTotal,
|
|
||||||
heroAmount: balanceTotal,
|
|
||||||
segments: buildSegmentsFromAccountItems(items),
|
|
||||||
wholeAmount: balanceTotal,
|
|
||||||
financialEntityCards: buildAccountDataListViews(items, context),
|
|
||||||
);
|
|
||||||
if (isDisplayDesktop(context)) {
|
|
||||||
return Row(
|
|
||||||
children: [
|
|
||||||
Flexible(
|
|
||||||
flex: 2,
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 24),
|
|
||||||
child: view,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
flex: 1,
|
|
||||||
child: Container(
|
|
||||||
color: RallyColors.inputBackground,
|
|
||||||
padding: EdgeInsetsDirectional.only(start: 24),
|
|
||||||
height: double.infinity,
|
|
||||||
alignment: AlignmentDirectional.centerStart,
|
|
||||||
child: ListView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
children: [
|
|
||||||
for (AccountDetailData item in detailItems)
|
|
||||||
_AccountDetail(title: item.title, value: item.value),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return SingleChildScrollView(child: view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AccountDetail extends StatelessWidget {
|
return TabWithSidebar(
|
||||||
const _AccountDetail({Key key, this.value, this.title}) : super(key: key);
|
mainView: FinancialEntityView(
|
||||||
|
heroLabel: GalleryLocalizations.of(context).rallyAccountTotal,
|
||||||
final String value;
|
heroAmount: balanceTotal,
|
||||||
final String title;
|
segments: buildSegmentsFromAccountItems(items),
|
||||||
|
wholeAmount: balanceTotal,
|
||||||
@override
|
financialEntityCards: buildAccountDataListViews(items, context),
|
||||||
Widget build(BuildContext context) {
|
),
|
||||||
final textTheme = Theme.of(context).textTheme;
|
sidebarItems: [
|
||||||
return Column(
|
for (UserDetailData item in detailItems)
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
SidebarItem(title: item.title, value: item.value)
|
||||||
children: [
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style:
|
|
||||||
textTheme.body1.copyWith(fontSize: 16, color: RallyColors.gray60),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Text(
|
|
||||||
value,
|
|
||||||
style: textTheme.body2.copyWith(fontSize: 20),
|
|
||||||
),
|
|
||||||
SizedBox(height: 8),
|
|
||||||
Container(color: RallyColors.primaryBackground, height: 1),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
import 'package:gallery/l10n/gallery_localizations.dart';
|
import 'package:gallery/l10n/gallery_localizations.dart';
|
||||||
import 'package:gallery/layout/adaptive.dart';
|
|
||||||
import 'package:gallery/studies/rally/charts/pie_chart.dart';
|
import 'package:gallery/studies/rally/charts/pie_chart.dart';
|
||||||
import 'package:gallery/studies/rally/data.dart';
|
import 'package:gallery/studies/rally/data.dart';
|
||||||
import 'package:gallery/studies/rally/finance.dart';
|
import 'package:gallery/studies/rally/finance.dart';
|
||||||
|
import 'package:gallery/studies/rally/tabs/sidebar.dart';
|
||||||
|
|
||||||
/// A page that shows a summary of bills.
|
/// A page that shows a summary of bills.
|
||||||
class BillsView extends StatefulWidget {
|
class BillsView extends StatefulWidget {
|
||||||
@@ -22,17 +22,25 @@ class _BillsViewState extends State<BillsView>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<BillData> items = DummyDataService.getBillDataList(context);
|
List<BillData> items = DummyDataService.getBillDataList(context);
|
||||||
final dueTotal = sumBillDataPrimaryAmount(items);
|
final dueTotal = sumBillDataPrimaryAmount(items);
|
||||||
return SingleChildScrollView(
|
final paidTotal = sumBillDataPaidAmount(items);
|
||||||
child: Container(
|
final detailItems = DummyDataService.getBillDetailList(
|
||||||
padding: isDisplayDesktop(context) ? EdgeInsets.only(top: 24) : null,
|
context,
|
||||||
child: FinancialEntityView(
|
dueTotal: dueTotal,
|
||||||
heroLabel: GalleryLocalizations.of(context).rallyBillsDue,
|
paidTotal: paidTotal,
|
||||||
heroAmount: dueTotal,
|
);
|
||||||
segments: buildSegmentsFromBillItems(items),
|
|
||||||
wholeAmount: dueTotal,
|
return TabWithSidebar(
|
||||||
financialEntityCards: buildBillDataListViews(items, context),
|
mainView: FinancialEntityView(
|
||||||
),
|
heroLabel: GalleryLocalizations.of(context).rallyBillsDue,
|
||||||
|
heroAmount: dueTotal,
|
||||||
|
segments: buildSegmentsFromBillItems(items),
|
||||||
|
wholeAmount: dueTotal,
|
||||||
|
financialEntityCards: buildBillDataListViews(items, context),
|
||||||
),
|
),
|
||||||
|
sidebarItems: [
|
||||||
|
for (UserDetailData item in detailItems)
|
||||||
|
SidebarItem(title: item.title, value: item.value)
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
import 'package:gallery/l10n/gallery_localizations.dart';
|
import 'package:gallery/l10n/gallery_localizations.dart';
|
||||||
import 'package:gallery/layout/adaptive.dart';
|
|
||||||
import 'package:gallery/studies/rally/charts/pie_chart.dart';
|
import 'package:gallery/studies/rally/charts/pie_chart.dart';
|
||||||
import 'package:gallery/studies/rally/data.dart';
|
import 'package:gallery/studies/rally/data.dart';
|
||||||
import 'package:gallery/studies/rally/finance.dart';
|
import 'package:gallery/studies/rally/finance.dart';
|
||||||
|
import 'package:gallery/studies/rally/tabs/sidebar.dart';
|
||||||
|
|
||||||
class BudgetsView extends StatefulWidget {
|
class BudgetsView extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
@@ -22,17 +22,24 @@ class _BudgetsViewState extends State<BudgetsView>
|
|||||||
final items = DummyDataService.getBudgetDataList(context);
|
final items = DummyDataService.getBudgetDataList(context);
|
||||||
final capTotal = sumBudgetDataPrimaryAmount(items);
|
final capTotal = sumBudgetDataPrimaryAmount(items);
|
||||||
final usedTotal = sumBudgetDataAmountUsed(items);
|
final usedTotal = sumBudgetDataAmountUsed(items);
|
||||||
return SingleChildScrollView(
|
final detailItems = DummyDataService.getBudgetDetailList(
|
||||||
child: Container(
|
context,
|
||||||
padding: isDisplayDesktop(context) ? EdgeInsets.only(top: 24) : null,
|
capTotal: capTotal,
|
||||||
child: FinancialEntityView(
|
usedTotal: usedTotal,
|
||||||
heroLabel: GalleryLocalizations.of(context).rallyBudgetLeft,
|
);
|
||||||
heroAmount: capTotal - usedTotal,
|
|
||||||
segments: buildSegmentsFromBudgetItems(items),
|
return TabWithSidebar(
|
||||||
wholeAmount: capTotal,
|
mainView: FinancialEntityView(
|
||||||
financialEntityCards: buildBudgetDataListViews(items, context),
|
heroLabel: GalleryLocalizations.of(context).rallyBudgetLeft,
|
||||||
),
|
heroAmount: capTotal - usedTotal,
|
||||||
|
segments: buildSegmentsFromBudgetItems(items),
|
||||||
|
wholeAmount: capTotal,
|
||||||
|
financialEntityCards: buildBudgetDataListViews(items, context),
|
||||||
),
|
),
|
||||||
|
sidebarItems: [
|
||||||
|
for (UserDetailData item in detailItems)
|
||||||
|
SidebarItem(title: item.title, value: item.value)
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:gallery/layout/adaptive.dart';
|
import 'package:gallery/layout/adaptive.dart';
|
||||||
|
import 'package:gallery/studies/rally/colors.dart';
|
||||||
import 'package:gallery/studies/rally/data.dart';
|
import 'package:gallery/studies/rally/data.dart';
|
||||||
import 'package:gallery/studies/rally/login.dart';
|
import 'package:gallery/studies/rally/login.dart';
|
||||||
|
|
||||||
@@ -16,14 +17,19 @@ class SettingsView extends StatefulWidget {
|
|||||||
class _SettingsViewState extends State<SettingsView> {
|
class _SettingsViewState extends State<SettingsView> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final items = DummyDataService.getSettingsTitles(context)
|
|
||||||
.map((title) => _SettingsItem(title))
|
|
||||||
.toList();
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.only(top: isDisplayDesktop(context) ? 24 : 0),
|
padding: EdgeInsets.only(top: isDisplayDesktop(context) ? 24 : 0),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: items,
|
children: [
|
||||||
|
for (String title in DummyDataService.getSettingsTitles(context)) ...[
|
||||||
|
_SettingsItem(title),
|
||||||
|
Divider(
|
||||||
|
color: RallyColors.dividerColor,
|
||||||
|
height: 1,
|
||||||
|
)
|
||||||
|
]
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
87
gallery/lib/studies/rally/tabs/sidebar.dart
Normal file
87
gallery/lib/studies/rally/tabs/sidebar.dart
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// Copyright 2020 The Flutter team. 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:gallery/layout/adaptive.dart';
|
||||||
|
import 'package:gallery/studies/rally/colors.dart';
|
||||||
|
|
||||||
|
class TabWithSidebar extends StatelessWidget {
|
||||||
|
const TabWithSidebar({
|
||||||
|
Key key,
|
||||||
|
@required this.mainView,
|
||||||
|
@required this.sidebarItems,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final Widget mainView;
|
||||||
|
final List<Widget> sidebarItems;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
if (isDisplayDesktop(context)) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
flex: 2,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 24),
|
||||||
|
child: mainView,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
flex: 1,
|
||||||
|
child: Container(
|
||||||
|
color: RallyColors.inputBackground,
|
||||||
|
padding: EdgeInsetsDirectional.only(start: 24),
|
||||||
|
height: double.infinity,
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
child: ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
children: sidebarItems,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return SingleChildScrollView(child: mainView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SidebarItem extends StatelessWidget {
|
||||||
|
const SidebarItem({Key key, this.value, this.title}) : super(key: key);
|
||||||
|
|
||||||
|
final String value;
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: textTheme.body1.copyWith(
|
||||||
|
fontSize: 16,
|
||||||
|
color: RallyColors.gray60,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
value,
|
||||||
|
style: textTheme.body2.copyWith(fontSize: 20),
|
||||||
|
),
|
||||||
|
SizedBox(height: 8),
|
||||||
|
Container(
|
||||||
|
color: RallyColors.primaryBackground,
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user