added about page with OSS licenses

This commit is contained in:
Thibault Deckers 2020-05-22 13:51:34 +09:00
parent b4bc950fb8
commit 6b68004806
7 changed files with 468 additions and 34 deletions

View file

@ -27,4 +27,189 @@ class Constants {
static const svgBackground = Colors.white;
static const svgColorFilter = ColorFilter.mode(svgBackground, BlendMode.dstOver);
static const List<Dependency> packages = [
Dependency(
name: 'Flutter',
license: 'BSD 3-Clause',
licenseUrl: 'https://github.com/flutter/flutter/blob/master/LICENSE',
sourceUrl: 'https://github.com/flutter/flutter',
),
Dependency(
name: 'Charts',
license: 'Apache 2.0',
licenseUrl: 'https://github.com/google/charts/blob/master/LICENSE',
sourceUrl: 'https://github.com/google/charts',
),
Dependency(
name: 'Collection',
license: 'BSD 3-Clause',
licenseUrl: 'https://github.com/dart-lang/collection/blob/master/LICENSE',
sourceUrl: 'https://github.com/dart-lang/collection',
),
Dependency(
name: 'Draggable Scrollbar',
license: 'MIT',
licenseUrl: 'https://github.com/fluttercommunity/flutter-draggable-scrollbar/blob/master/LICENSE',
sourceUrl: 'https://github.com/fluttercommunity/flutter-draggable-scrollbar',
),
Dependency(
name: 'Event Bus',
license: 'MIT',
licenseUrl: 'https://github.com/marcojakob/dart-event-bus/blob/master/LICENSE',
sourceUrl: 'https://github.com/marcojakob/dart-event-bus',
),
Dependency(
name: 'Expansion Tile Card',
license: 'BSD 3-Clause',
licenseUrl: 'https://github.com/Skylled/expansion_tile_card/blob/master/LICENSE',
sourceUrl: 'https://github.com/Skylled/expansion_tile_card',
),
Dependency(
name: 'Flushbar',
license: 'Apache 2.0',
licenseUrl: 'https://github.com/AndreHaueisen/flushbar/blob/master/LICENSE',
sourceUrl: 'https://github.com/AndreHaueisen/flushbar',
),
Dependency(
name: 'Flutter ijkplayer',
license: 'MIT',
licenseUrl: 'https://github.com/CaiJingLong/flutter_ijkplayer/blob/master/LICENSE',
sourceUrl: 'https://github.com/CaiJingLong/flutter_ijkplayer',
),
Dependency(
name: 'Flutter Native Timezone',
license: 'Apache 2.0',
licenseUrl: 'https://github.com/pinkfish/flutter_native_timezone/blob/master/LICENSE',
sourceUrl: 'https://github.com/pinkfish/flutter_native_timezone',
),
Dependency(
name: 'Flutter SVG',
license: 'MIT',
licenseUrl: 'https://github.com/dnfield/flutter_svg/blob/master/LICENSE',
sourceUrl: 'https://github.com/dnfield/flutter_svg',
),
Dependency(
name: 'Geocoder',
license: 'MIT',
licenseUrl: 'https://github.com/aloisdeniel/flutter_geocoder/blob/master/LICENSE',
sourceUrl: 'https://github.com/aloisdeniel/flutter_geocoder',
),
Dependency(
name: 'Google Maps for Flutter',
license: 'BSD 3-Clause',
licenseUrl: 'https://github.com/flutter/plugins/blob/master/packages/google_maps_flutter/google_maps_flutter/LICENSE',
sourceUrl: 'https://github.com/flutter/plugins/blob/master/packages/google_maps_flutter/google_maps_flutter',
),
Dependency(
name: 'Intl',
license: 'BSD 3-Clause',
licenseUrl: 'https://github.com/dart-lang/intl/blob/master/LICENSE',
sourceUrl: 'https://github.com/dart-lang/intl',
),
Dependency(
name: 'Outline Material Icons',
license: 'Apache 2.0',
licenseUrl: 'https://github.com/lucaslcode/outline_material_icons/blob/master/LICENSE',
sourceUrl: 'https://github.com/lucaslcode/outline_material_icons',
),
Dependency(
name: 'Palette Generator',
license: 'BSD 3-Clause',
licenseUrl: 'https://github.com/flutter/packages/blob/master/packages/palette_generator/LICENSE',
sourceUrl: 'https://github.com/flutter/packages/tree/master/packages/palette_generator',
),
Dependency(
name: 'PDF for Dart and Flutter',
license: 'Apache 2.0',
licenseUrl: 'https://github.com/DavBfr/dart_pdf/blob/master/LICENSE',
sourceUrl: 'https://github.com/DavBfr/dart_pdf',
),
Dependency(
name: 'Pedantic',
license: 'BSD 3-Clause',
licenseUrl: 'https://github.com/dart-lang/pedantic/blob/master/LICENSE',
sourceUrl: 'https://github.com/dart-lang/pedantic',
),
Dependency(
name: 'Percent Indicator',
license: 'BSD 2-Clause',
licenseUrl: 'https://github.com/diegoveloper/flutter_percent_indicator/blob/master/LICENSE',
sourceUrl: 'https://github.com/diegoveloper/flutter_percent_indicator/',
),
Dependency(
name: 'Permission Handler',
license: 'MIT',
licenseUrl: 'https://github.com/Baseflow/flutter-permission-handler/blob/develop/permission_handler/LICENSE',
sourceUrl: 'https://github.com/Baseflow/flutter-permission-handler',
),
Dependency(
name: 'Photo View',
license: 'MIT',
licenseUrl: 'https://github.com/renancaraujo/photo_view/blob/master/LICENSE',
sourceUrl: 'https://github.com/renancaraujo/photo_view',
),
Dependency(
name: 'Printing',
license: 'Apache 2.0',
licenseUrl: 'https://github.com/DavBfr/dart_pdf/blob/master/LICENSE',
sourceUrl: 'https://github.com/DavBfr/dart_pdf',
),
Dependency(
name: 'Provider',
license: 'MIT',
licenseUrl: 'https://github.com/rrousselGit/provider/blob/master/LICENSE',
sourceUrl: 'https://github.com/rrousselGit/provider',
),
Dependency(
name: 'Screen',
license: 'MIT',
licenseUrl: 'https://github.com/clovisnicolas/flutter_screen/blob/master/LICENSE',
sourceUrl: 'https://github.com/clovisnicolas/flutter_screen',
),
Dependency(
name: 'Shared Preferences',
license: 'BSD 3-Clause',
licenseUrl: 'https://github.com/flutter/plugins/blob/master/packages/shared_preferences/shared_preferences/LICENSE',
sourceUrl: 'https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences',
),
Dependency(
name: 'sqflite',
license: 'MIT',
licenseUrl: 'https://github.com/tekartik/sqflite/blob/master/sqflite/LICENSE',
sourceUrl: 'https://github.com/tekartik/sqflite',
),
Dependency(
name: 'Streams Channel',
license: 'Apache 2.0',
licenseUrl: 'https://github.com/loup-v/streams_channel/blob/master/LICENSE',
sourceUrl: 'https://github.com/loup-v/streams_channel',
),
Dependency(
name: 'Tuple',
license: 'BSD 2-Clause',
licenseUrl: 'https://github.com/dart-lang/tuple/blob/master/LICENSE',
sourceUrl: 'https://github.com/dart-lang/tuple',
),
Dependency(
name: 'UUID',
license: 'MIT',
licenseUrl: 'https://github.com/Daegalus/dart-uuid/blob/master/LICENSE',
sourceUrl: 'https://github.com/Daegalus/dart-uuid',
),
];
}
class Dependency {
final String name;
final String license;
final String sourceUrl;
final String licenseUrl;
const Dependency({
@required this.name,
@required this.license,
@required this.licenseUrl,
@required this.sourceUrl,
});
}

View file

@ -0,0 +1,45 @@
import 'package:aves/widgets/about/licenses.dart';
import 'package:flutter/material.dart';
class AboutPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('About'),
),
body: SafeArea(
child: CustomScrollView(
slivers: [
SliverPadding(
padding: const EdgeInsets.only(top: 16),
sliver: SliverList(
delegate: SliverChildListDelegate(
[
Center(
child: RichText(
text: TextSpan(
children: [
const TextSpan(text: 'Made with ❤️ and '),
WidgetSpan(
child: FlutterLogo(
size: Theme.of(context).textTheme.bodyText2.fontSize * 1.25,
),
),
],
),
),
),
const SizedBox(height: 8),
const Divider(),
],
),
),
),
Licenses(),
],
),
),
);
}
}

View file

@ -0,0 +1,169 @@
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/icons.dart';
import 'package:aves/widgets/common/menu_row.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class Licenses extends StatefulWidget {
@override
_LicensesState createState() => _LicensesState();
}
class _LicensesState extends State<Licenses> {
LicenseSort _sort = LicenseSort.name;
List<Dependency> _packages;
@override
void initState() {
super.initState();
_packages = List.of(Constants.packages);
_sortPackages();
}
void _sortPackages() {
_packages.sort((a, b) {
switch (_sort) {
case LicenseSort.license:
final c = compareAsciiUpperCase(a.license, b.license);
return c != 0 ? c : compareAsciiUpperCase(a.name, b.name);
case LicenseSort.name:
default:
return compareAsciiUpperCase(a.name, b.name);
}
});
}
@override
Widget build(BuildContext context) {
return SliverPadding(
padding: const EdgeInsets.symmetric(horizontal: 8),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
if (index-- == 0) {
return _buildHeader();
}
return LicenseRow(_packages[index]);
},
childCount: _packages.length + 1,
),
),
);
}
Widget _buildHeader() {
return Column(
children: [
Padding(
padding: const EdgeInsetsDirectional.only(start: 8),
child: Row(
children: [
Text(
'Open-source licenses',
style: Theme.of(context).textTheme.headline6.copyWith(fontFamily: 'Concourse Caps'),
),
const Spacer(),
PopupMenuButton<LicenseSort>(
itemBuilder: (context) => [
PopupMenuItem(
value: LicenseSort.name,
child: MenuRow(text: 'Sort by name', checked: _sort == LicenseSort.name),
),
PopupMenuItem(
value: LicenseSort.license,
child: MenuRow(text: 'Sort by license', checked: _sort == LicenseSort.license),
),
],
onSelected: (newSort) {
_sort = newSort;
_sortPackages();
setState(() {});
},
tooltip: 'Sort',
icon: Icon(AIcons.sort),
),
],
),
),
const SizedBox(height: 8),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 8),
child: Text('The following sets forth attribution notices for third party software that may be contained in this application.'),
),
],
);
}
}
class LicenseRow extends StatelessWidget {
final Dependency package;
const LicenseRow(this.package);
static const borderRadius = BorderRadius.all(Radius.circular(8));
@override
Widget build(BuildContext context) {
final textTheme = Theme.of(context).textTheme;
final bodyTextStyle = textTheme.bodyText2;
final subColor = bodyTextStyle.color.withOpacity(.6);
return Padding(
padding: const EdgeInsets.only(top: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
borderRadius: borderRadius,
onTap: () => launch(package.sourceUrl),
child: Padding(
padding: const EdgeInsets.all(8),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
package.name,
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(width: 8),
Icon(
AIcons.openInNew,
size: bodyTextStyle.fontSize,
)
],
),
),
),
Padding(
padding: const EdgeInsetsDirectional.only(start: 16),
child: InkWell(
borderRadius: borderRadius,
onTap: () => launch(package.licenseUrl),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
package.license,
style: TextStyle(color: subColor),
),
const SizedBox(width: 8),
Icon(
AIcons.openInNew,
size: bodyTextStyle.fontSize,
color: subColor,
)
],
),
),
),
),
],
),
);
}
}
enum LicenseSort { license, name }

View file

@ -11,7 +11,7 @@ import 'package:aves/model/filters/tag.dart';
import 'package:aves/model/mime_types.dart';
import 'package:aves/model/settings.dart';
import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/color_utils.dart';
import 'package:aves/widgets/about/about_page.dart';
import 'package:aves/widgets/album/collection_page.dart';
import 'package:aves/widgets/common/aves_logo.dart';
import 'package:aves/widgets/common/icons.dart';
@ -87,6 +87,15 @@ class _AppDrawerState extends State<AppDrawer> {
title: 'Favourites',
filter: FavouriteFilter(),
);
final aboutEntry = SafeArea(
top: false,
bottom: false,
child: ListTile(
leading: const Icon(AIcons.info),
title: const Text('About'),
onTap: () => _goToAbout(context),
),
);
final drawerItems = <Widget>[
header,
@ -97,6 +106,7 @@ class _AppDrawerState extends State<AppDrawer> {
_buildRegularAlbumSection(),
_buildCountrySection(),
_buildTagSection(),
aboutEntry,
if (kDebugMode) ...[
const Divider(),
SafeArea(
@ -150,35 +160,6 @@ class _AppDrawerState extends State<AppDrawer> {
);
}
Widget _buildLocationEntry(LocationLevel level, String location) {
String title;
String flag;
if (level == LocationLevel.country) {
final split = location.split(';');
String countryCode;
if (split.isNotEmpty) title = split[0];
if (split.length > 1) countryCode = split[1];
flag = LocationFilter.countryCodeToFlag(countryCode);
} else {
title = location;
}
return _FilteredCollectionNavTile(
source: source,
leading: flag != null
? Text(
flag,
style: TextStyle(fontSize: IconTheme.of(context).size),
)
: Icon(
AIcons.location,
color: stringToColor(title),
),
title: title,
dense: true,
filter: LocationFilter(level, location),
);
}
Widget _buildSpecialAlbumSection() {
return StreamBuilder(
stream: source.eventBus.on<AlbumsChangedEvent>(),
@ -320,6 +301,16 @@ class _AppDrawerState extends State<AppDrawer> {
);
}
void _goToAbout(BuildContext context) {
Navigator.pop(context);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AboutPage(),
),
);
}
void _goToDebug(BuildContext context) {
Navigator.pop(context);
Navigator.push(

View file

@ -40,6 +40,7 @@ class AIcons {
static const IconData search = OMIcons.search;
static const IconData select = OMIcons.selectAll;
static const IconData share = OMIcons.share;
static const IconData sort = OMIcons.sort;
static const IconData stats = OMIcons.pieChart;
static const IconData zoomIn = OMIcons.add;
static const IconData zoomOut = OMIcons.remove;

View file

@ -303,6 +303,13 @@ packages:
relative: true
source: path
version: "0.9.2"
platform_detect:
dependency: transitive
description:
name: platform_detect
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
plugin_platform_interface:
dependency: transitive
description:
@ -324,6 +331,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.1"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.4"
qr:
dependency: transitive
description:
@ -469,6 +483,34 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "5.4.10"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+7"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.7"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1+6"
utf:
dependency: transitive
description:

View file

@ -47,19 +47,19 @@ dependencies:
path: ../expansion_tile_card
# git:
# url: git://github.com/deckerst/expansion_tile_card.git
flushbar:
flutter_ijkplayer:
path: ../flutter_ijkplayer
# git:
# url: git://github.com/deckerst/flutter_ijkplayer.git
flushbar:
flutter_native_timezone:
flutter_svg:
geocoder:
google_maps_flutter:
intl:
outline_material_icons:
pdf:
palette_generator:
pdf:
pedantic:
percent_indicator:
permission_handler:
@ -76,6 +76,7 @@ dependencies:
sqflite:
streams_channel:
tuple:
url_launcher:
uuid:
dev_dependencies: