Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground>
<inset
android:drawable="@drawable/ic_launcher_foreground"
android:inset="16%" />
</foreground>
</adaptive-icon>
Binary file modified android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions android/app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#EE322F</color>
</resources>
16 changes: 16 additions & 0 deletions assets/svg/icons/github.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions lib/core/constants/asset_paths.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ abstract final class AssetPaths {
static const iconUtensils = 'assets/svg/icons/utensils.svg';
static const iconFine = 'assets/svg/icons/circle-dollar-sign.svg';
static const iconHistory = 'assets/svg/icons/history.svg';
static const iconGithub = 'assets/svg/icons/github.svg';
}
3 changes: 3 additions & 0 deletions lib/features/home/home_strings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ abstract final class HomeStrings {
static const restaurantShortcut = 'Central (Meléndez)';
static const comingSoon = 'Muy pronto podrás usar esta función.';
static const allFunctionalitiesTitle = 'Todas las funcionalidades';
static const repositoryLabel = 'code3743/univalle_app';
static const repositoryUrl = 'https://github.com/code3743/univalle_app';
static const cannotOpenRepositoryLink = 'No pudimos abrir el repositorio.';
}
11 changes: 11 additions & 0 deletions lib/features/home/presentation/providers/app_version_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:package_info_plus/package_info_plus.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'app_version_provider.g.dart';

/// App version shown in the Home footer, e.g. "0.1.0".
@riverpod
Future<String> appVersion(Ref ref) async {
final info = await PackageInfo.fromPlatform();
return info.version;
}
3 changes: 3 additions & 0 deletions lib/features/home/presentation/views/home_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import '../../../auth/presentation/viewmodels/auth_view_model.dart';
import '../../../profile/presentation/viewmodels/profile_view_model.dart';
import '../../home_strings.dart';
import '../providers/latest_semester_provider.dart';
import '../widgets/home_footer.dart';
import '../widgets/home_top_bar.dart';
import '../widgets/program_card.dart';
import '../widgets/quick_access_items.dart';
Expand Down Expand Up @@ -145,6 +146,8 @@ class HomeView extends ConsumerWidget {
)
.toList(),
),
const SizedBox(height: AppSpacing.lg),
const HomeFooter(),
],
),
),
Expand Down
60 changes: 60 additions & 0 deletions lib/features/home/presentation/widgets/home_footer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:url_launcher/url_launcher.dart';

import '../../../../core/constants/asset_paths.dart';
import '../../../../core/extensions/snackbar_extension.dart';
import '../../home_strings.dart';
import '../providers/app_version_provider.dart';

class HomeFooter extends ConsumerWidget {
const HomeFooter({super.key});

Future<void> _openRepository(BuildContext context) async {
final uri = Uri.parse(HomeStrings.repositoryUrl);
final launched = await launchUrl(uri, mode: LaunchMode.externalApplication);
if (!launched && context.mounted) {
context.showSnack(HomeStrings.cannotOpenRepositoryLink);
}
}

@override
Widget build(BuildContext context, WidgetRef ref) {
final colorScheme = Theme.of(context).colorScheme;
final mutedStyle = Theme.of(context).textTheme.bodySmall
?.copyWith(color: colorScheme.onSurfaceVariant);
final version = ref.watch(appVersionProvider).value;

return Center(
child: Column(
children: [
InkWell(
borderRadius: BorderRadius.circular(8),
onTap: () => _openRepository(context),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset(
AssetPaths.iconGithub,
width: 15,
height: 15,
colorFilter: ColorFilter.mode(
colorScheme.onSurfaceVariant,
BlendMode.srcIn,
),
),
const SizedBox(width: 6),
Text(HomeStrings.repositoryLabel, style: mutedStyle),
],
),
),
),
if (version != null) Text('v$version', style: mutedStyle),
],
),
);
}
}
34 changes: 33 additions & 1 deletion pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.0"
ffi_leak_tracker:
dependency: transitive
description:
name: ffi_leak_tracker
sha256: "4093d4ef9ca06ffe2786e73bfb25e22aa92112b9bb4ec941f11e3e6b61489a97"
url: "https://pub.dev"
source: hosted
version: "0.1.2"
file:
dependency: transitive
description:
Expand Down Expand Up @@ -589,6 +597,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
package_info_plus:
dependency: "direct main"
description:
name: package_info_plus
sha256: "127e1751e37ffb2ff4658beeaca77bad0c27bf5f932bd3a501c2296926d4b481"
url: "https://pub.dev"
source: hosted
version: "10.2.1"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: db762cb2f4f25ee60fb6359773861b0f199e00b90d237bd85a76a1e806b46ef4
url: "https://pub.dev"
source: hosted
version: "4.1.0"
path:
dependency: transitive
description:
Expand Down Expand Up @@ -963,7 +987,7 @@ packages:
source: hosted
version: "3.2.6"
url_launcher_platform_interface:
dependency: transitive
dependency: "direct dev"
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
Expand Down Expand Up @@ -1098,6 +1122,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.26.1"
win32:
dependency: transitive
description:
name: win32
sha256: a0b93865d5644f11cf6a8c3f6db909f1ec168958b5805f6cc684adea957cd63d
url: "https://pub.dev"
source: hosted
version: "6.4.0"
xdg_directories:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ dependencies:
google_fonts: ^8.2.1
html: ^0.15.7
intl: ^0.20.3
package_info_plus: ^10.2.1
riverpod_annotation: ^4.0.7
shared_preferences: ^2.5.5
url_launcher: ^6.3.1
Expand All @@ -33,6 +34,7 @@ dev_dependencies:
build_runner: ^2.16.1
flutter_native_splash: ^2.4.8
mocktail: ^1.0.4
url_launcher_platform_interface: ^2.3.2

flutter:
uses-material-design: true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:univalle_app/features/home/presentation/providers/app_version_provider.dart';

import '../../../../helpers/container.dart';

void main() {
setUp(() {
PackageInfo.setMockInitialValues(
appName: 'Univalle App',
packageName: 'co.edu.univalle.univalle_app',
version: '1.2.3',
buildNumber: '7',
buildSignature: '',
);
});

test('reads the version reported by the platform', () async {
final container = createContainer();

final version = await container.read(appVersionProvider.future);

expect(version, '1.2.3');
});
}
73 changes: 73 additions & 0 deletions test/features/home/presentation/widgets/home_footer_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:univalle_app/features/home/home_strings.dart';
import 'package:univalle_app/features/home/presentation/widgets/home_footer.dart';
import 'package:url_launcher_platform_interface/link.dart';
import 'package:url_launcher_platform_interface/url_launcher_platform_interface.dart';

import '../../../../helpers/pump_app.dart';

class _FakeUrlLauncher extends UrlLauncherPlatform {
_FakeUrlLauncher({this.result = true});

final bool result;
String? launchedUrl;

@override
LinkDelegate? get linkDelegate => null;

@override
Future<bool> launchUrl(String url, LaunchOptions options) async {
launchedUrl = url;
return result;
}
}

void main() {
setUp(() {
PackageInfo.setMockInitialValues(
appName: 'Univalle App',
packageName: 'co.edu.univalle.univalle_app',
version: '1.2.3',
buildNumber: '7',
buildSignature: '',
);
});

testWidgets('shows the repository label and the app version', (tester) async {
UrlLauncherPlatform.instance = _FakeUrlLauncher();

await tester.pumpApp(const HomeFooter());
await tester.pumpAndSettle();

expect(find.text(HomeStrings.repositoryLabel), findsOneWidget);
expect(find.text('v1.2.3'), findsOneWidget);
});

testWidgets('opens the repository url when tapped', (tester) async {
final fakeLauncher = _FakeUrlLauncher();
UrlLauncherPlatform.instance = fakeLauncher;

await tester.pumpApp(const HomeFooter());
await tester.pumpAndSettle();

await tester.tap(find.text(HomeStrings.repositoryLabel));
await tester.pumpAndSettle();

expect(fakeLauncher.launchedUrl, HomeStrings.repositoryUrl);
});

testWidgets('shows a snackbar when the link cannot be opened', (
tester,
) async {
UrlLauncherPlatform.instance = _FakeUrlLauncher(result: false);

await tester.pumpApp(const HomeFooter());
await tester.pumpAndSettle();

await tester.tap(find.text(HomeStrings.repositoryLabel));
await tester.pumpAndSettle();

expect(find.text(HomeStrings.cannotOpenRepositoryLink), findsOneWidget);
});
}