mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-10 02:07:57 -06:00
feat: add changelogs, update old changelogs, update build scripts
This commit is contained in:
@@ -5,17 +5,20 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:paperless_mobile/constants.dart';
|
||||
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
||||
import 'package:paperless_mobile/core/global/asset_images.dart';
|
||||
import 'package:paperless_mobile/core/widgets/hint_card.dart';
|
||||
import 'package:paperless_mobile/core/widgets/paperless_logo.dart';
|
||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
|
||||
import 'package:paperless_mobile/features/sharing/cubit/receive_share_cubit.dart';
|
||||
import 'package:paperless_mobile/generated/assets.gen.dart';
|
||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||
import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/branches/saved_views_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/branches/upload_queue_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/top_level/changelog_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/top_level/settings_route.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
@@ -95,7 +98,7 @@ class AppDrawer extends StatelessWidget {
|
||||
),
|
||||
actionsAlignment: MainAxisAlignment.spaceBetween,
|
||||
actions: [
|
||||
Text("~ Anton"),
|
||||
const Text("~ Anton"),
|
||||
TextButton(
|
||||
onPressed: Navigator.of(context).pop,
|
||||
child: Text(S.of(context)!.gotIt),
|
||||
@@ -105,6 +108,14 @@ class AppDrawer extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
dense: true,
|
||||
leading: const Icon(Icons.history),
|
||||
title: Text(S.of(context)!.changelog),
|
||||
onTap: () {
|
||||
ChangelogRoute().push(context);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
dense: true,
|
||||
leading: const Icon(Icons.bug_report_outlined),
|
||||
@@ -127,9 +138,11 @@ class AppDrawer extends StatelessWidget {
|
||||
),
|
||||
ListTile(
|
||||
dense: true,
|
||||
leading: SvgPicture.asset(
|
||||
"assets/images/github-mark.svg",
|
||||
color: Theme.of(context).colorScheme.onBackground,
|
||||
leading: Assets.images.githubMark.svg(
|
||||
colorFilter: ColorFilter.mode(
|
||||
Theme.of(context).colorScheme.onBackground,
|
||||
BlendMode.srcIn,
|
||||
),
|
||||
height: 24,
|
||||
width: 24,
|
||||
),
|
||||
@@ -215,7 +228,7 @@ class AppDrawer extends StatelessWidget {
|
||||
const CreateSavedViewRoute(showInSidebar: true)
|
||||
.push(context);
|
||||
},
|
||||
icon: Icon(Icons.add),
|
||||
icon: const Icon(Icons.add),
|
||||
label: Text(S.of(context)!.newView),
|
||||
),
|
||||
],
|
||||
@@ -227,7 +240,7 @@ class AppDrawer extends StatelessWidget {
|
||||
final view = sidebarViews[index];
|
||||
return ListTile(
|
||||
title: Text(view.name),
|
||||
trailing: Icon(Icons.arrow_forward),
|
||||
trailing: const Icon(Icons.arrow_forward),
|
||||
onTap: () {
|
||||
Scaffold.of(context).closeDrawer();
|
||||
context
|
||||
|
||||
118
lib/features/changelogs/view/changelog_dialog.dart
Normal file
118
lib/features/changelogs/view/changelog_dialog.dart
Normal file
@@ -0,0 +1,118 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||
import 'package:paperless_mobile/theme.dart';
|
||||
|
||||
class ChangelogDialog extends StatelessWidget {
|
||||
const ChangelogDialog({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
actionsPadding: const EdgeInsets.all(4),
|
||||
title: Text(S.of(context)!.changelog),
|
||||
content: FutureBuilder<String>(
|
||||
future: _loadChangelog(context),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
).padded(24);
|
||||
}
|
||||
return SizedBox(
|
||||
width: 1000,
|
||||
child: Markdown(
|
||||
data: snapshot.data!,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
child: Text(S.of(context)!.close),
|
||||
onPressed: () {
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<String> _loadChangelog(BuildContext context) async {
|
||||
final languageCode = Localizations.localeOf(context).languageCode;
|
||||
final locale = switch (languageCode) {
|
||||
'de' => 'de-DE',
|
||||
_ => 'en-US',
|
||||
};
|
||||
'en-US';
|
||||
String changelog = await rootBundle.loadString(
|
||||
'assets/changelogs/changelogs_$locale.md',
|
||||
);
|
||||
for (var versionNumber in _versionNumbers.keys) {
|
||||
changelog = changelog.replaceFirst(
|
||||
RegExp('# $versionNumber'),
|
||||
'# v${_versionNumbers[versionNumber]!}',
|
||||
);
|
||||
}
|
||||
return changelog;
|
||||
}
|
||||
}
|
||||
|
||||
const _versionNumbers = {
|
||||
"53": "3.0.6",
|
||||
"52": "3.0.5",
|
||||
"51": "3.0.4",
|
||||
"50": "3.0.3",
|
||||
"49": "3.0.2",
|
||||
"48": "3.0.1",
|
||||
"47": "3.0.0",
|
||||
"46": "2.3.11",
|
||||
"45": "2.3.10",
|
||||
"44": "2.3.9",
|
||||
"43": "2.3.8",
|
||||
"42": "2.3.7",
|
||||
"41": "2.3.6",
|
||||
"40": "2.3.5",
|
||||
"39": "2.3.4",
|
||||
"38": "2.3.3",
|
||||
"37": "2.3.2",
|
||||
"36": "2.3.1",
|
||||
"35": "2.3.0",
|
||||
"34": "2.2.6",
|
||||
"33": "2.2.5",
|
||||
"32": "2.2.4",
|
||||
"31": "2.2.3",
|
||||
"30": "2.2.2",
|
||||
"29": "2.2.1",
|
||||
"28": "2.2.0",
|
||||
"27": "2.1.0",
|
||||
"26": "2.0.9",
|
||||
"25": "2.0.8",
|
||||
"24": "2.0.7",
|
||||
"23": "2.0.6",
|
||||
"22": "2.0.5",
|
||||
"21": "2.0.4",
|
||||
"20": "2.0.3",
|
||||
"19": "2.0.2",
|
||||
"18": "2.0.1",
|
||||
"17": "2.0.0",
|
||||
"16": "1.5.3",
|
||||
"15": "1.5.2",
|
||||
"14": "1.5.1",
|
||||
"13": "1.5.0",
|
||||
"12": "1.4.1",
|
||||
"11": "1.4.0",
|
||||
"10": "1.3.1",
|
||||
"9": "1.3.0",
|
||||
"8": "1.2.2",
|
||||
"7": "1.2.1",
|
||||
"6": "1.2.0",
|
||||
"5": "1.1.0",
|
||||
"3": "1.0.5",
|
||||
"4": "1.0.6",
|
||||
"2": "1.0.4",
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/constants.dart';
|
||||
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
||||
@@ -14,6 +15,14 @@ import 'package:paperless_mobile/routes/typed/branches/documents_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/branches/inbox_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/branches/saved_views_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
|
||||
import 'package:paperless_mobile/routes/typed/top_level/changelog_route.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class Changelog {
|
||||
final int buildNumber;
|
||||
final String? changelog;
|
||||
Changelog(this.buildNumber, this.changelog);
|
||||
}
|
||||
|
||||
class LandingPage extends StatefulWidget {
|
||||
const LandingPage({super.key});
|
||||
@@ -25,6 +34,34 @@ class LandingPage extends StatefulWidget {
|
||||
class _LandingPageState extends State<LandingPage> {
|
||||
final _searchBarHandle = SliverOverlapAbsorberHandle();
|
||||
|
||||
Future<bool> get _shouldShowChangelog async {
|
||||
try {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
final currentBuild = packageInfo.buildNumber;
|
||||
final _existingVersions =
|
||||
sp.getStringList('changelogSeenForBuilds') ?? [];
|
||||
if (_existingVersions.contains(currentBuild)) {
|
||||
return false;
|
||||
} else {
|
||||
_existingVersions.add(currentBuild);
|
||||
await sp.setStringList('changelogSeenForBuilds', _existingVersions);
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
||||
if (await _shouldShowChangelog) {
|
||||
ChangelogRoute().push(context);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final currentUser = context.watch<LocalUserAccount>().paperlessUser;
|
||||
@@ -187,18 +224,19 @@ class _LandingPageState extends State<LandingPage> {
|
||||
titleTextStyle: Theme.of(context).textTheme.labelLarge,
|
||||
title: Text(S.of(context)!.totalCharacters),
|
||||
trailing: Text(
|
||||
stats.totalChars.toString(),
|
||||
(stats.totalChars ?? 0).toString(),
|
||||
style: Theme.of(context).textTheme.labelLarge,
|
||||
),
|
||||
),
|
||||
),
|
||||
AspectRatio(
|
||||
aspectRatio: 1.3,
|
||||
child: SizedBox(
|
||||
width: 300,
|
||||
child: MimeTypesPieChart(statistics: stats),
|
||||
if (stats.fileTypeCounts.isNotEmpty)
|
||||
AspectRatio(
|
||||
aspectRatio: 1.3,
|
||||
child: SizedBox(
|
||||
width: 300,
|
||||
child: MimeTypesPieChart(statistics: stats),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
).padded(16);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user