Skip to content

Commit ce63aaa

Browse files
authored
Merge pull request #20 from Tiger-OperatingSystem/beta1.2
feat: install packages native + handlers with button issue url
2 parents 2b54d28 + 6b482fa commit ce63aaa

12 files changed

Lines changed: 308 additions & 75 deletions

lib/main.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ Future<void> main() async {
1919

2020
windowManager.waitUntilReadyToShow(windowOptions, () async {
2121
await windowManager.setTitle('Central de Aplicações');
22-
await windowManager.maximize();
2322
await windowManager.show();
2423
await windowManager.focus();
2524
});

lib/src/handlers/exceptions.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:url_launcher/url_launcher.dart';
3+
4+
class CustomExceptionsWidget implements Exception {
5+
CustomExceptionsWidget(
6+
String message,
7+
BuildContext context,
8+
) {
9+
_showHandler(message, context);
10+
}
11+
12+
Future<void> _showHandler(String message, BuildContext context) async {
13+
String uriReport = "https://github.com/Tiger-OperatingSystem/app_store/issues";
14+
showDialog(context: context, builder: (context) {
15+
return AlertDialog(
16+
title: const Text("Ocorreu um erro."),
17+
content: Text(message),
18+
actions: [
19+
ElevatedButton(onPressed: () async {
20+
await launchUrl(Uri.parse(uriReport));
21+
},
22+
child: const Text("Reportar este problema")),
23+
],
24+
);
25+
});
26+
}
27+
}

lib/src/modules/applications/applications_controller.dart

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
// ignore_for_file: use_build_context_synchronously
2+
13
import 'package:app_store/main.dart';
24
import 'package:app_store/src/core/http.dart';
35
import 'package:app_store/src/core/navigation.dart';
6+
import 'package:app_store/src/handlers/exceptions.dart';
47
import 'package:app_store/src/modules/applications/applications_model.dart';
58
import 'package:app_store/src/modules/applications/widgets/build_applications.dart';
69
import 'package:flutter/material.dart';
@@ -15,21 +18,21 @@ class ApplicationsController extends ChangeNotifier {
1518
BuildApplicationsWidget(endpoint: "search/$search"), context);
1619
notifyListeners();
1720
} catch (e) {
18-
rethrow;
21+
throw CustomExceptionsWidget(e.toString(), context);
1922
}
2023
}
2124

2225
static Future<ApplicationsModel> getByFlatpakAppId(
23-
String flatpakAppId) async {
26+
String flatpakAppId, BuildContext context) async {
2427
try {
2528
final data = await Http.get(flatpakAppId);
2629
return ApplicationsModel.fromJson(data);
2730
} catch (e) {
28-
rethrow;
31+
throw CustomExceptionsWidget(e.toString(), context);
2932
}
3033
}
3134

32-
Future<bool> hasInstalledFlatpak(ApplicationsModel applicationsModel) async {
35+
Future<bool> hasInstalledFlatpak(ApplicationsModel applicationsModel, BuildContext context) async {
3336
try {
3437
late bool hasInstalled;
3538
final result = await shell.run('''ls /var/lib/flatpak/app/''');
@@ -42,31 +45,88 @@ class ApplicationsController extends ChangeNotifier {
4245

4346
return hasInstalled;
4447
} catch (e) {
45-
rethrow;
48+
throw CustomExceptionsWidget(e.toString(), context);
4649
}
4750
}
4851

49-
Future<void> installFlatpak(ApplicationsModel applicationsModel) async {
52+
Future<void> installFlatpak(ApplicationsModel applicationsModel, BuildContext context) async {
5053
try {
5154
final result = await shell.run(
5255
'''flatpak-install-gui --override-appname="${applicationsModel.name}" ${applicationsModel.flatpakAppId}''',
5356
);
5457
result;
5558
notifyListeners();
5659
} catch (e) {
57-
rethrow;
60+
throw CustomExceptionsWidget(e.toString(), context);
5861
}
5962
}
6063

61-
Future<void> removeFlatpak(ApplicationsModel applicationsModel) async {
64+
Future<void> removeFlatpak(ApplicationsModel applicationsModel, BuildContext context) async {
6265
try {
6366
final result = await shell.run(
6467
'''flatpak-install-gui --override-appname="${applicationsModel.name}" --remove ${applicationsModel.flatpakAppId}''',
6568
);
6669
result;
6770
notifyListeners();
6871
} catch (e) {
69-
rethrow;
72+
throw CustomExceptionsWidget(e.toString(), context);
73+
}
74+
}
75+
76+
Future<bool> hasInstalledDebian(ApplicationsModel applicationsModel, BuildContext context) async {
77+
try {
78+
79+
final name = applicationsModel.name!.replaceAll(RegExp(r' '), "-").toLowerCase();
80+
final data = await shell.run("apt list --installed $name");
81+
82+
for(var element in data.outLines) {
83+
if(element.contains(name)) {
84+
return true;
85+
}
86+
}
87+
88+
return false;
89+
} catch (e) {
90+
throw CustomExceptionsWidget(e.toString(), context);
7091
}
7192
}
93+
94+
Future<bool> isDebianPackage(ApplicationsModel applicationsModel, BuildContext context) async {
95+
try {
96+
final name = applicationsModel.name!.replaceAll(RegExp(r' '), "-").toLowerCase();
97+
final data = await shell.run("apt list $name");
98+
99+
for(var element in data.outLines) {
100+
if(element.contains(name)) {
101+
return true;
102+
}
103+
}
104+
105+
return false;
106+
} catch (e) {
107+
throw CustomExceptionsWidget(e.toString(), context);
108+
}
109+
}
110+
111+
Future<void> installDebianPackage(ApplicationsModel applicationsModel, BuildContext context) async {
112+
try {
113+
final name = applicationsModel.name!.replaceAll(RegExp(r' '), "-").toLowerCase();
114+
final result = await shell.run("pkexec apt-get install $name -y");
115+
result;
116+
notifyListeners();
117+
} catch (e) {
118+
throw CustomExceptionsWidget(e.toString(), context);
119+
}
120+
}
121+
122+
Future<void> removeDebianPackage(ApplicationsModel applicationsModel, BuildContext context) async {
123+
try {
124+
final name = applicationsModel.name!.replaceAll(RegExp(r' '), "-").toLowerCase();
125+
final result = await shell.run("pkexec apt-get remove $name -y");
126+
result;
127+
notifyListeners();
128+
} catch (e) {
129+
throw CustomExceptionsWidget(e.toString(), context);
130+
}
131+
}
72132
}

lib/src/modules/applications/applications_details_view.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class ApplicationsDetailsView extends StatelessWidget {
1818
// Build app details
1919
body: FutureBuilder(
2020
future: ApplicationsController.getByFlatpakAppId(
21-
applicationsModel.flatpakAppId!),
21+
applicationsModel.flatpakAppId!, context),
2222
builder: (context, snapshot) {
2323
if (!snapshot.hasData) {
2424
return const Center(
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import 'package:app_store/src/modules/applications/applications_controller.dart';
2+
import 'package:app_store/src/modules/applications/applications_model.dart';
3+
import 'package:flutter/material.dart';
4+
import 'package:provider/provider.dart';
5+
6+
class ButtonInstallWidget extends StatelessWidget {
7+
final ApplicationsModel applicationModel;
8+
const ButtonInstallWidget({super.key, required this.applicationModel});
9+
10+
@override
11+
Widget build(BuildContext context) {
12+
final applicationsController = context.read<ApplicationsController>();
13+
return ListenableBuilder(
14+
listenable: context.watch<ApplicationsController>(),
15+
builder: (context, child) {
16+
return FutureBuilder(
17+
future: Future.wait([applicationsController
18+
.hasInstalledFlatpak(applicationModel, context),
19+
applicationsController
20+
.hasInstalledDebian(applicationModel, context),
21+
applicationsController
22+
.isDebianPackage(applicationModel, context)]),
23+
builder: (context, snapshot) {
24+
if (snapshot.connectionState == ConnectionState.waiting) {
25+
return const Center(child: CircularProgressIndicator());
26+
}
27+
28+
final hasInstalledFlatpak = snapshot.data![0];
29+
final hasInstalledDebian = snapshot.data![1];
30+
final isDebianPackage = snapshot.data![2];
31+
32+
return Row(
33+
mainAxisSize: MainAxisSize.max,
34+
children: [
35+
36+
Visibility(
37+
visible: isDebianPackage ? true : false,
38+
child: SizedBox(
39+
height: 80,
40+
child: ElevatedButton.icon(
41+
icon: !hasInstalledDebian
42+
? const Icon(Icons.download)
43+
: const Icon(Icons.delete),
44+
onPressed: () => _installOrRemoveDebianPackage(
45+
applicationModel,
46+
hasInstalledFlatpak,
47+
applicationsController,
48+
context,
49+
),
50+
label: Text(!hasInstalledDebian ? "Installar nativo" : "Desinstalar nativo",
51+
style: Theme.of(context).textTheme.titleMedium,
52+
),
53+
),
54+
),
55+
),
56+
57+
const SizedBox(width: 15),
58+
59+
SizedBox(
60+
height: 80,
61+
child: ElevatedButton.icon(
62+
icon: !hasInstalledFlatpak
63+
? const Icon(Icons.download)
64+
: const Icon(Icons.delete),
65+
onPressed: () => _installOrRemoveFlatpak(
66+
applicationModel,
67+
hasInstalledFlatpak,
68+
applicationsController,
69+
context,
70+
),
71+
label: Text(!hasInstalledFlatpak ? "Installar flatpak" : "Desinstalar flatpak",
72+
style: Theme.of(context).textTheme.titleMedium,
73+
),
74+
),
75+
),
76+
]
77+
);
78+
},
79+
);
80+
},
81+
);
82+
}
83+
}
84+
85+
void _installOrRemoveFlatpak(ApplicationsModel applicationsModel, bool hasInstalled,
86+
ApplicationsController applicationsController, BuildContext context) {
87+
try {
88+
if (!hasInstalled) {
89+
applicationsController.installFlatpak(applicationsModel, context);
90+
} else {
91+
applicationsController.removeFlatpak(applicationsModel, context);
92+
}
93+
} catch (e) {
94+
rethrow;
95+
}
96+
}
97+
98+
void _installOrRemoveDebianPackage(ApplicationsModel applicationsModel, bool hasInstalled,
99+
ApplicationsController applicationsController, BuildContext context) {
100+
try {
101+
if (!hasInstalled) {
102+
applicationsController.installDebianPackage(applicationsModel, context);
103+
} else {
104+
applicationsController.removeDebianPackage(applicationsModel, context);
105+
}
106+
} catch (e) {
107+
rethrow;
108+
}
109+
}
Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import 'package:app_store/src/modules/applications/applications_controller.dart';
21
import 'package:app_store/src/modules/applications/applications_model.dart';
2+
import 'package:app_store/src/modules/applications/widgets/button_install.dart';
33
import 'package:flutter/material.dart';
4-
import 'package:provider/provider.dart';
54

65
class HeaderApplicationDetailWidget extends StatelessWidget {
76
final ApplicationsModel applicationModel;
@@ -12,7 +11,6 @@ class HeaderApplicationDetailWidget extends StatelessWidget {
1211

1312
@override
1413
Widget build(BuildContext context) {
15-
final applicationsController = context.read<ApplicationsController>();
1614
return Container(
1715
padding: const EdgeInsets.all(22),
1816
child: Row(
@@ -41,58 +39,12 @@ class HeaderApplicationDetailWidget extends StatelessWidget {
4139
// Space
4240
const Expanded(child: SizedBox.shrink()),
4341
SizedBox(
44-
height: 80,
45-
width: 220,
46-
child: ListenableBuilder(
47-
listenable: context.watch<ApplicationsController>(),
48-
builder: (context, child) {
49-
return FutureBuilder(
50-
future: applicationsController
51-
.hasInstalledFlatpak(applicationModel),
52-
builder: (context, snapshot) {
53-
if (snapshot.connectionState == ConnectionState.waiting) {
54-
return const Center(child: CircularProgressIndicator());
55-
}
56-
57-
final hasInstalled = snapshot.data!;
58-
59-
return ElevatedButton.icon(
60-
icon: !hasInstalled
61-
? const Icon(Icons.download)
62-
: const Icon(Icons.delete),
63-
onPressed: () => _installOrRemove(
64-
applicationModel,
65-
hasInstalled,
66-
applicationsController,
67-
),
68-
label: Text(
69-
!hasInstalled ? "Instalar" : "Remover",
70-
style: Theme.of(context).textTheme.titleMedium,
71-
),
72-
);
73-
},
74-
);
75-
},
76-
),
42+
child: ButtonInstallWidget(applicationModel: applicationModel),
7743
),
78-
7944
// Space
8045
const Expanded(child: SizedBox.shrink()),
8146
],
8247
),
8348
);
8449
}
8550
}
86-
87-
void _installOrRemove(ApplicationsModel applicationsModel, bool hasInstalled,
88-
ApplicationsController applicationsController) {
89-
try {
90-
if (!hasInstalled) {
91-
applicationsController.installFlatpak(applicationsModel);
92-
} else {
93-
applicationsController.removeFlatpak(applicationsModel);
94-
}
95-
} catch (e) {
96-
rethrow;
97-
}
98-
}

0 commit comments

Comments
 (0)