Skip to content

Commit

Permalink
Create ChangelogDialog
Browse files Browse the repository at this point in the history
  • Loading branch information
WilliamKarolDiCioccio committed Aug 26, 2024
1 parent 5cc1256 commit af3b540
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 6 deletions.
1 change: 1 addition & 0 deletions app/assets/l10n/intl_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"attachFilesDialogBrowseFilesButton": "Browse files",
"attachFilesDialogDropFilesText": "Drop files here",
"cancelButtonShared": "Cancel",
"changelogButton": "Changelog",
"chatAttachFilesTooltip": "Attach files",
"chatCancelEditButton": "Cancel editing",
"chatCancelGenerationTooltip": "Cancel generation",
Expand Down
24 changes: 24 additions & 0 deletions app/assets/metadata/app_changelog.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"releases": [
{
"version": "1.0.0",
"date": "26/08/2024",
"type": "patch",
"image": "https://github.com/WilliamKarolDiCioccio/open_local_ui/raw/main/.github/images/github_readme_banner.webp",
"changes": [
{
"category": "bugfix",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
},
{
"category": "feature",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
},
{
"category": "improvement",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
}
]
}
]
}
237 changes: 237 additions & 0 deletions app/lib/frontend/dialogs/changelog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
import 'dart:convert';

import 'package:flutter/material.dart';

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:gap/gap.dart';
import 'package:timelines_plus/timelines_plus.dart';
import 'package:unicons/unicons.dart';

class ChangelogDialog extends StatelessWidget {
Widget _buildChangeCategoryChip(String type) {
switch (type) {
case 'bugfix':
return Chip(
avatar: Icon(
UniconsLine.bug,
size: 18,
color: Colors.red,
),
label: Text(
type.toUpperCase(),
style: TextStyle(
fontSize: 12,
),
),
backgroundColor: Colors.red.withOpacity(0.25),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
side: BorderSide(
color: Colors.red,
width: 1,
),
),
);
case 'feature':
return Chip(
avatar: Icon(
UniconsLine.rocket,
size: 18,
color: Colors.green,
),
label: Text(
type.toUpperCase(),
style: TextStyle(
fontSize: 12,
),
),
backgroundColor: Colors.green.withOpacity(0.25),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
side: BorderSide(
color: Colors.green,
width: 1,
),
),
);
case 'improvement':
return Chip(
avatar: Icon(
UniconsLine.chart_bar,
size: 18,
color: Colors.tealAccent,
),
label: Text(
type.toUpperCase(),
style: TextStyle(
fontSize: 12,
),
),
backgroundColor: Colors.tealAccent.withOpacity(0.25),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
side: BorderSide(
color: Colors.tealAccent,
width: 1,
),
),
);
default:
return SizedBox.shrink();
}
}

@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Changelog'),
content: SizedBox(
width: 900,
child: FutureBuilder(
future: DefaultAssetBundle.of(context).loadString(
'assets/metadata/app_changelog.json',
),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasData) {
final changelogData = jsonDecode(snapshot.data.toString());
final releases = changelogData['releases'] as List<dynamic>;

if (releases.isEmpty) return Text('No changelog data available');

return SingleChildScrollView(
child: FixedTimeline(
theme: TimelineThemeData(
nodePosition: 0.5,
connectorTheme: ConnectorThemeData(
color: Colors.grey,
thickness: 2.0,
),
indicatorTheme: IndicatorThemeData(
size: 20.0,
color: Colors.blue,
),
),
children: releases.map<TimelineTile>((release) {
final version = release['version'];
final date = release['date'];
final changes = release['changes'] as List<dynamic>;

return TimelineTile(
nodePosition: 0.3,
oppositeContents: Container(
margin: EdgeInsets.symmetric(horizontal: 8.0),
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
' $version ',
style: TextStyle(
fontSize: 48.0,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.start,
),
Text(
date,
style: TextStyle(
color: Colors.grey,
),
textAlign: TextAlign.center,
),
const Gap(16.0),
if (release['image'] != null)
CachedNetworkImage(
imageUrl: release['image'],
),
],
),
),
contents: Container(
decoration: BoxDecoration(
border: Border.all(
color: AdaptiveTheme.of(context).theme.dividerColor,
),
borderRadius: BorderRadius.circular(16.0),
),
margin: EdgeInsets.symmetric(
horizontal: 22.0,
vertical: 16.0,
),
padding: const EdgeInsets.all(12.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: changes.map<Widget>((change) {
final changeData =
change as Map<String, dynamic>;

return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
_buildChangeCategoryChip(
changeData['category'],
),
const Gap(8.0),
Text(
changeData['description'],
),
],
),
);
}).toList(),
),
],
),
),
node: TimelineNode(
indicator: OutlinedDotIndicator(
color: AdaptiveTheme.of(context).theme.dividerColor,
),
startConnector: SolidLineConnector(),
endConnector: SolidLineConnector(),
),
);
}).toList(),
),
);
} else if (snapshot.hasError) {
return Text('Failed to load changelog data');
} else {
return CircularProgressIndicator();
}
},
),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(AppLocalizations.of(context).closeButtonShared),
),
],
);
}
}

Future<void> showChangelogDialog(BuildContext context) async {
return showDialog<void>(
context: context,
builder: (context) {
return ChangelogDialog();
},
);
}
17 changes: 11 additions & 6 deletions app/lib/frontend/screens/dashboard.dart
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import 'dart:io';

import 'package:battery_plus/battery_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:adaptive_theme/adaptive_theme.dart';
import 'package:battery_plus/battery_plus.dart';
import 'package:feedback/feedback.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:gap/gap.dart';
import 'package:gpu_info/gpu_info.dart';
import 'package:image/image.dart' as img;
import 'package:open_local_ui/core/github.dart';
import 'package:open_local_ui/core/logger.dart';
import 'package:open_local_ui/core/snackbar.dart';
import 'package:open_local_ui/core/update.dart';
import 'package:open_local_ui/frontend/components/floating_menu.dart';
import 'package:open_local_ui/frontend/components/window_management_bar.dart';
import 'package:open_local_ui/frontend/dialogs/changelog.dart';
import 'package:open_local_ui/frontend/dialogs/update.dart';
import 'package:open_local_ui/core/snackbar.dart';
import 'package:open_local_ui/frontend/pages/dashboard/about.dart';
import 'package:open_local_ui/frontend/pages/dashboard/chat.dart';
import 'package:open_local_ui/frontend/pages/dashboard/models.dart';
import 'package:open_local_ui/frontend/pages/dashboard/sessions.dart';
import 'package:open_local_ui/frontend/pages/dashboard/settings.dart';
import 'package:open_local_ui/frontend/components/window_management_bar.dart';
import 'package:path_provider/path_provider.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:system_info2/system_info2.dart';
Expand Down Expand Up @@ -285,9 +286,13 @@ class _DashboardScreenState extends State<DashboardScreen> {
),
const Gap(8),
TextButton.icon(
onPressed: () {
showLicensePage(context: context);
},
onPressed: () => showChangelogDialog(context),
icon: const Icon(UniconsLine.code_branch),
label: Text(AppLocalizations.of(context).changelogButton),
),
const Gap(8),
TextButton.icon(
onPressed: () => showLicensePage(context: context),
icon: const Icon(UniconsLine.keyhole_circle),
label: Text(AppLocalizations.of(context).licenseButton),
),
Expand Down
2 changes: 2 additions & 0 deletions app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ flutter:
- assets/prompts/sessions_title_generator.txt
# Model Metadata
- assets/metadata/ollama_models.json
# App metadata
- assets/metadata/app_changelog.json
# Logos
- assets/graphics/logos/open_local_ui.svg
- assets/graphics/logos/flutter.svg
Expand Down

0 comments on commit af3b540

Please sign in to comment.