about: bug reporting instructions
This commit is contained in:
parent
f16645dd34
commit
cbba70d069
12 changed files with 295 additions and 33 deletions
|
@ -14,4 +14,4 @@ __We collect anonymous data to improve the app.__ We use Google Firebase for Cra
|
||||||
## Links
|
## Links
|
||||||
[Sources](https://github.com/deckerst/aves)
|
[Sources](https://github.com/deckerst/aves)
|
||||||
|
|
||||||
[License](https://github.com/deckerst/aves/blob/master/LICENSE)
|
[License](https://github.com/deckerst/aves/blob/main/LICENSE)
|
||||||
|
|
|
@ -363,8 +363,11 @@
|
||||||
|
|
||||||
"aboutPageTitle": "About",
|
"aboutPageTitle": "About",
|
||||||
"@aboutPageTitle": {},
|
"@aboutPageTitle": {},
|
||||||
"aboutFlutter": "Flutter",
|
"aboutLinkSources": "Sources",
|
||||||
"@aboutFlutter": {},
|
"@aboutLinkSources": {},
|
||||||
|
"aboutLinkLicense": "License",
|
||||||
|
"@aboutLinkLicense": {},
|
||||||
|
|
||||||
"aboutUpdate": "New Version Available",
|
"aboutUpdate": "New Version Available",
|
||||||
"@aboutUpdate": {},
|
"@aboutUpdate": {},
|
||||||
"aboutUpdateLinks1": "A new version of Aves is available on",
|
"aboutUpdateLinks1": "A new version of Aves is available on",
|
||||||
|
@ -377,12 +380,29 @@
|
||||||
"@aboutUpdateGitHub": {},
|
"@aboutUpdateGitHub": {},
|
||||||
"aboutUpdateGooglePlay": "Google Play",
|
"aboutUpdateGooglePlay": "Google Play",
|
||||||
"@aboutUpdateGooglePlay": {},
|
"@aboutUpdateGooglePlay": {},
|
||||||
|
|
||||||
|
"aboutBug": "Bug Report",
|
||||||
|
"@aboutBug": {},
|
||||||
|
"aboutBugSaveLogInstruction": "Save app logs to a file",
|
||||||
|
"@aboutBugSaveLogInstruction": {},
|
||||||
|
"aboutBugSaveLogButton": "Save",
|
||||||
|
"@aboutBugSaveLogButton": {},
|
||||||
|
"aboutBugCopyInfoInstruction": "Copy system information",
|
||||||
|
"@aboutBugCopyInfoInstruction": {},
|
||||||
|
"aboutBugCopyInfoButton": "Copy",
|
||||||
|
"@aboutBugCopyInfoButton": {},
|
||||||
|
"aboutBugReportInstruction": "Report on GitHub with the logs and system information",
|
||||||
|
"@aboutBugReportInstruction": {},
|
||||||
|
"aboutBugReportButton": "Report",
|
||||||
|
"@aboutBugReportButton": {},
|
||||||
|
|
||||||
"aboutCredits": "Credits",
|
"aboutCredits": "Credits",
|
||||||
"@aboutCredits": {},
|
"@aboutCredits": {},
|
||||||
"aboutCreditsWorldAtlas1": "This app uses a TopoJSON file from",
|
"aboutCreditsWorldAtlas1": "This app uses a TopoJSON file from",
|
||||||
"@aboutCreditsWorldAtlas1": {},
|
"@aboutCreditsWorldAtlas1": {},
|
||||||
"aboutCreditsWorldAtlas2": "under ISC License.",
|
"aboutCreditsWorldAtlas2": "under ISC License.",
|
||||||
"@aboutCreditsWorldAtlas2": {},
|
"@aboutCreditsWorldAtlas2": {},
|
||||||
|
|
||||||
"aboutLicenses": "Open-Source Licenses",
|
"aboutLicenses": "Open-Source Licenses",
|
||||||
"@aboutLicenses": {},
|
"@aboutLicenses": {},
|
||||||
"aboutLicensesBanner": "This app uses the following open-source packages and libraries.",
|
"aboutLicensesBanner": "This app uses the following open-source packages and libraries.",
|
||||||
|
@ -714,7 +734,7 @@
|
||||||
|
|
||||||
"settingsSectionPrivacy": "Privacy",
|
"settingsSectionPrivacy": "Privacy",
|
||||||
"@settingsSectionPrivacy": {},
|
"@settingsSectionPrivacy": {},
|
||||||
"settingsEnableCrashReport": "Allow anonymous crash reporting",
|
"settingsEnableCrashReport": "Allow anonymous error reporting",
|
||||||
"@settingsEnableCrashReport": {},
|
"@settingsEnableCrashReport": {},
|
||||||
"settingsSaveSearchHistory": "Save search history",
|
"settingsSaveSearchHistory": "Save search history",
|
||||||
"@settingsSaveSearchHistory": {},
|
"@settingsSaveSearchHistory": {},
|
||||||
|
|
|
@ -170,16 +170,28 @@
|
||||||
"menuActionStats": "통계",
|
"menuActionStats": "통계",
|
||||||
|
|
||||||
"aboutPageTitle": "앱 정보",
|
"aboutPageTitle": "앱 정보",
|
||||||
"aboutFlutter": "플러터",
|
"aboutLinkSources": "소스 코드",
|
||||||
|
"aboutLinkLicense": "라이선스",
|
||||||
|
|
||||||
"aboutUpdate": "업데이트 사용 가능",
|
"aboutUpdate": "업데이트 사용 가능",
|
||||||
"aboutUpdateLinks1": "앱의 최신 버전을",
|
"aboutUpdateLinks1": "앱의 최신 버전을",
|
||||||
"aboutUpdateLinks2": "와",
|
"aboutUpdateLinks2": "와",
|
||||||
"aboutUpdateLinks3": "에서 다운로드 사용 가능합니다.",
|
"aboutUpdateLinks3": "에서 다운로드 사용 가능합니다.",
|
||||||
"aboutUpdateGitHub": "깃허브",
|
"aboutUpdateGitHub": "깃허브",
|
||||||
"aboutUpdateGooglePlay": "구글 플레이",
|
"aboutUpdateGooglePlay": "구글 플레이",
|
||||||
|
|
||||||
|
"aboutBug": "버그 보고",
|
||||||
|
"aboutBugSaveLogInstruction": "앱 로그를 파일에 저장하기",
|
||||||
|
"aboutBugSaveLogButton": "저장",
|
||||||
|
"aboutBugCopyInfoInstruction": "시스템 정보를 복사하기",
|
||||||
|
"aboutBugCopyInfoButton": "복사",
|
||||||
|
"aboutBugReportInstruction": "로그와 시스템 정보를 첨부하여 깃허브에서 이슈를 제툴하기",
|
||||||
|
"aboutBugReportButton": "제출",
|
||||||
|
|
||||||
"aboutCredits": "크레딧",
|
"aboutCredits": "크레딧",
|
||||||
"aboutCreditsWorldAtlas1": "이 앱은",
|
"aboutCreditsWorldAtlas1": "이 앱은",
|
||||||
"aboutCreditsWorldAtlas2": "의 TopoJSON 파일(ISC 라이선스)을 이용합니다.",
|
"aboutCreditsWorldAtlas2": "의 TopoJSON 파일(ISC 라이선스)을 이용합니다.",
|
||||||
|
|
||||||
"aboutLicenses": "오픈 소스 라이선스",
|
"aboutLicenses": "오픈 소스 라이선스",
|
||||||
"aboutLicensesBanner": "이 앱은 다음의 오픈 소스 패키지와 라이브러리를 이용합니다.",
|
"aboutLicensesBanner": "이 앱은 다음의 오픈 소스 패키지와 라이브러리를 이용합니다.",
|
||||||
"aboutLicensesAndroidLibraries": "안드로이드 라이브러리",
|
"aboutLicensesAndroidLibraries": "안드로이드 라이브러리",
|
||||||
|
|
|
@ -50,6 +50,7 @@ class MimeTypes {
|
||||||
static const webm = 'video/webm';
|
static const webm = 'video/webm';
|
||||||
|
|
||||||
static const json = 'application/json';
|
static const json = 'application/json';
|
||||||
|
static const plainText = 'text/plain';
|
||||||
|
|
||||||
// groups
|
// groups
|
||||||
|
|
||||||
|
|
|
@ -102,4 +102,7 @@ class AIcons {
|
||||||
static const IconData threeSixty = Icons.threesixty_outlined;
|
static const IconData threeSixty = Icons.threesixty_outlined;
|
||||||
static const IconData selected = Icons.check_circle_outline;
|
static const IconData selected = Icons.check_circle_outline;
|
||||||
static const IconData unselected = Icons.radio_button_unchecked;
|
static const IconData unselected = Icons.radio_button_unchecked;
|
||||||
|
|
||||||
|
static const IconData github = MdiIcons.github;
|
||||||
|
static const IconData legal = MdiIcons.scaleBalance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,8 @@ class Constants {
|
||||||
|
|
||||||
static const int infoGroupMaxValueLength = 140;
|
static const int infoGroupMaxValueLength = 140;
|
||||||
|
|
||||||
|
static const String avesGithub = 'https://github.com/deckerst/aves';
|
||||||
|
|
||||||
static const List<Dependency> androidDependencies = [
|
static const List<Dependency> androidDependencies = [
|
||||||
Dependency(
|
Dependency(
|
||||||
name: 'AndroidX Core-KTX',
|
name: 'AndroidX Core-KTX',
|
||||||
|
@ -91,6 +93,12 @@ class Constants {
|
||||||
licenseUrl: 'https://github.com/fluttercommunity/plus_plugins/blob/main/packages/connectivity_plus/connectivity_plus/LICENSE',
|
licenseUrl: 'https://github.com/fluttercommunity/plus_plugins/blob/main/packages/connectivity_plus/connectivity_plus/LICENSE',
|
||||||
sourceUrl: 'https://github.com/fluttercommunity/plus_plugins/tree/main/packages/connectivity_plus',
|
sourceUrl: 'https://github.com/fluttercommunity/plus_plugins/tree/main/packages/connectivity_plus',
|
||||||
),
|
),
|
||||||
|
Dependency(
|
||||||
|
name: 'Device Info Plus',
|
||||||
|
license: 'BSD 3-Clause',
|
||||||
|
licenseUrl: 'https://github.com/fluttercommunity/plus_plugins/blob/main/packages/device_info_plus/device_info_plus/LICENSE',
|
||||||
|
sourceUrl: 'https://github.com/fluttercommunity/plus_plugins/tree/main/packages/device_info_plus',
|
||||||
|
),
|
||||||
Dependency(
|
Dependency(
|
||||||
name: 'FlutterFire (Core, Crashlytics)',
|
name: 'FlutterFire (Core, Crashlytics)',
|
||||||
license: 'BSD 3-Clause',
|
license: 'BSD 3-Clause',
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:aves/widgets/about/app_ref.dart';
|
import 'package:aves/widgets/about/app_ref.dart';
|
||||||
|
import 'package:aves/widgets/about/bug_report.dart';
|
||||||
import 'package:aves/widgets/about/credits.dart';
|
import 'package:aves/widgets/about/credits.dart';
|
||||||
import 'package:aves/widgets/about/licenses.dart';
|
import 'package:aves/widgets/about/licenses.dart';
|
||||||
import 'package:aves/widgets/about/update.dart';
|
import 'package:aves/widgets/about/update.dart';
|
||||||
|
@ -27,6 +28,8 @@ class AboutPage extends StatelessWidget {
|
||||||
AppReference(),
|
AppReference(),
|
||||||
Divider(),
|
Divider(),
|
||||||
AboutUpdate(),
|
AboutUpdate(),
|
||||||
|
BugReport(),
|
||||||
|
Divider(),
|
||||||
AboutCredits(),
|
AboutCredits(),
|
||||||
Divider(),
|
Divider(),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:aves/flutter_version.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
|
import 'package:aves/utils/constants.dart';
|
||||||
import 'package:aves/widgets/common/basic/link_chip.dart';
|
import 'package:aves/widgets/common/basic/link_chip.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
import 'package:aves/widgets/common/identity/aves_logo.dart';
|
import 'package:aves/widgets/common/identity/aves_logo.dart';
|
||||||
|
@ -29,8 +30,8 @@ class _AppReferenceState extends State<AppReference> {
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
_buildAvesLine(),
|
_buildAvesLine(),
|
||||||
_buildFlutterLine(),
|
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
_buildLinks(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -47,37 +48,45 @@ class _AppReferenceState extends State<AppReference> {
|
||||||
return FutureBuilder<PackageInfo>(
|
return FutureBuilder<PackageInfo>(
|
||||||
future: _packageInfoLoader,
|
future: _packageInfoLoader,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
return LinkChip(
|
return Row(
|
||||||
leading: AvesLogo(
|
mainAxisSize: MainAxisSize.min,
|
||||||
size: style.fontSize! * MediaQuery.textScaleFactorOf(context) * 1.25,
|
children: [
|
||||||
),
|
AvesLogo(
|
||||||
text: '${context.l10n.appName} ${snapshot.data?.version}',
|
size: style.fontSize! * MediaQuery.textScaleFactorOf(context) * 1.25,
|
||||||
url: 'https://github.com/deckerst/aves',
|
),
|
||||||
textStyle: style,
|
const SizedBox(width: 8),
|
||||||
|
Text(
|
||||||
|
'${context.l10n.appName} ${snapshot.data?.version}',
|
||||||
|
style: style,
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFlutterLine() {
|
Widget _buildLinks() {
|
||||||
final style = DefaultTextStyle.of(context).style;
|
return Wrap(
|
||||||
final subColor = style.color!.withOpacity(.6);
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
spacing: 16,
|
||||||
return Text.rich(
|
children: [
|
||||||
TextSpan(
|
LinkChip(
|
||||||
children: [
|
leading: const Icon(
|
||||||
WidgetSpan(
|
AIcons.github,
|
||||||
child: Padding(
|
size: 24,
|
||||||
padding: const EdgeInsetsDirectional.only(end: 4),
|
|
||||||
child: FlutterLogo(
|
|
||||||
size: style.fontSize! * 1.25,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
TextSpan(text: '${context.l10n.aboutFlutter} ${version['frameworkVersion']}'),
|
text: context.l10n.aboutLinkSources,
|
||||||
],
|
url: Constants.avesGithub,
|
||||||
),
|
),
|
||||||
style: TextStyle(color: subColor),
|
LinkChip(
|
||||||
|
leading: const Icon(
|
||||||
|
AIcons.legal,
|
||||||
|
size: 22,
|
||||||
|
),
|
||||||
|
text: context.l10n.aboutLinkLicense,
|
||||||
|
url: '${Constants.avesGithub}/blob/main/LICENSE',
|
||||||
|
),
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
163
lib/widgets/about/bug_report.dart
Normal file
163
lib/widgets/about/bug_report.dart
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:aves/flutter_version.dart';
|
||||||
|
import 'package:aves/ref/mime_types.dart';
|
||||||
|
import 'package:aves/services/services.dart';
|
||||||
|
import 'package:aves/utils/constants.dart';
|
||||||
|
import 'package:aves/widgets/common/action_mixins/feedback.dart';
|
||||||
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
|
||||||
|
import 'package:device_info_plus/device_info_plus.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class BugReport extends StatefulWidget {
|
||||||
|
const BugReport({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_BugReportState createState() => _BugReportState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BugReportState extends State<BugReport> with FeedbackMixin {
|
||||||
|
late Future<String> _infoLoader;
|
||||||
|
bool _showInstructions = false;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_infoLoader = _getInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final l10n = context.l10n;
|
||||||
|
return ExpansionPanelList(
|
||||||
|
expansionCallback: (index, isExpanded) {
|
||||||
|
setState(() => _showInstructions = !isExpanded);
|
||||||
|
},
|
||||||
|
expandedHeaderPadding: EdgeInsets.zero,
|
||||||
|
elevation: 0,
|
||||||
|
children: [
|
||||||
|
ExpansionPanel(
|
||||||
|
headerBuilder: (context, isExpanded) => ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(minHeight: 48),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
alignment: AlignmentDirectional.centerStart,
|
||||||
|
child: Text(l10n.aboutBug, style: Constants.titleTextStyle),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
_buildStep(1, l10n.aboutBugSaveLogInstruction, l10n.aboutBugSaveLogButton, _saveLogs),
|
||||||
|
_buildStep(2, l10n.aboutBugCopyInfoInstruction, l10n.aboutBugCopyInfoButton, _copySystemInfo),
|
||||||
|
FutureBuilder<String>(
|
||||||
|
future: _infoLoader,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final info = snapshot.data;
|
||||||
|
if (info == null) return const SizedBox();
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.grey.shade800,
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
|
),
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 8),
|
||||||
|
child: SelectableText(info));
|
||||||
|
},
|
||||||
|
),
|
||||||
|
_buildStep(3, l10n.aboutBugReportInstruction, l10n.aboutBugReportButton, _goToGithub),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
isExpanded: _showInstructions,
|
||||||
|
canTapOnHeader: true,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildStep(int step, String text, String buttonText, VoidCallback onPressed) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.all(12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.fromBorderSide(BorderSide(
|
||||||
|
color: Theme.of(context).accentColor,
|
||||||
|
width: AvesFilterChip.outlineWidth,
|
||||||
|
)),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
child: Text('$step'),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Expanded(child: Text(text)),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
OutlinedButton(
|
||||||
|
onPressed: onPressed,
|
||||||
|
style: ButtonStyle(
|
||||||
|
side: MaterialStateProperty.all<BorderSide>(BorderSide(color: Theme.of(context).accentColor)),
|
||||||
|
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
|
||||||
|
),
|
||||||
|
child: Text(buttonText),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> _getInfo() async {
|
||||||
|
final packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||||
|
final hasPlayServices = await availability.hasPlayServices;
|
||||||
|
return [
|
||||||
|
'Aves version: ${packageInfo.version} (Build ${packageInfo.buildNumber})',
|
||||||
|
'Flutter version: ${version['frameworkVersion']} (Channel ${version['channel']})',
|
||||||
|
'Android version: ${androidInfo.version.release} (SDK ${androidInfo.version.sdkInt})',
|
||||||
|
'Device: ${androidInfo.manufacturer} ${androidInfo.model}',
|
||||||
|
'Google Play services: ${hasPlayServices ? 'ready' : 'not available'}',
|
||||||
|
].join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _saveLogs() async {
|
||||||
|
final result = await Process.run('logcat', ['-d']);
|
||||||
|
final logs = result.stdout;
|
||||||
|
final success = await storageService.createFile(
|
||||||
|
'aves-logs-${DateFormat('yyyyMMdd_HHmmss').format(DateTime.now())}.txt',
|
||||||
|
MimeTypes.plainText,
|
||||||
|
Uint8List.fromList(utf8.encode(logs)),
|
||||||
|
);
|
||||||
|
if (success != null) {
|
||||||
|
if (success) {
|
||||||
|
showFeedback(context, context.l10n.genericSuccessFeedback);
|
||||||
|
} else {
|
||||||
|
showFeedback(context, context.l10n.genericFailureFeedback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _copySystemInfo() async {
|
||||||
|
await Clipboard.setData(ClipboardData(text: await _infoLoader));
|
||||||
|
showFeedback(context, context.l10n.genericSuccessFeedback);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _goToGithub() async {
|
||||||
|
await launch('${Constants.avesGithub}/issues/new');
|
||||||
|
}
|
||||||
|
}
|
|
@ -62,7 +62,7 @@ class _AboutUpdateState extends State<AboutUpdate> {
|
||||||
WidgetSpan(
|
WidgetSpan(
|
||||||
child: LinkChip(
|
child: LinkChip(
|
||||||
text: context.l10n.aboutUpdateGitHub,
|
text: context.l10n.aboutUpdateGitHub,
|
||||||
url: 'https://github.com/deckerst/aves/releases',
|
url: '${Constants.avesGithub}/releases',
|
||||||
textStyle: const TextStyle(fontWeight: FontWeight.bold),
|
textStyle: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
alignment: PlaceholderAlignment.middle,
|
alignment: PlaceholderAlignment.middle,
|
||||||
|
|
42
pubspec.lock
42
pubspec.lock
|
@ -190,6 +190,48 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.1"
|
version: "1.2.1"
|
||||||
|
device_info_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: device_info_plus
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
device_info_plus_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_linux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
device_info_plus_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_macos
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
device_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
device_info_plus_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
|
device_info_plus_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: device_info_plus_windows
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
equatable:
|
equatable:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -19,6 +19,7 @@ dependencies:
|
||||||
# TODO TLAD as of 2021/08/04, null safe version is pre-release
|
# TODO TLAD as of 2021/08/04, null safe version is pre-release
|
||||||
custom_rounded_rectangle_border: '>=0.2.0-nullsafety.0'
|
custom_rounded_rectangle_border: '>=0.2.0-nullsafety.0'
|
||||||
decorated_icon:
|
decorated_icon:
|
||||||
|
device_info_plus:
|
||||||
equatable:
|
equatable:
|
||||||
event_bus:
|
event_bus:
|
||||||
expansion_tile_card:
|
expansion_tile_card:
|
||||||
|
|
Loading…
Reference in a new issue