add install & update MIH Linux

This commit is contained in:
yaso 2026-07-09 14:29:34 +02:00
parent 8c05168c08
commit 8912e77b03
5 changed files with 464 additions and 109 deletions

View file

@ -1,11 +1,9 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:mih_package_toolkit/mih_package_toolkit.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart';
import 'package:url_launcher/url_launcher.dart';
class CallToActionButtons extends StatefulWidget {
const CallToActionButtons({super.key});
@ -15,16 +13,12 @@ class CallToActionButtons extends StatefulWidget {
}
class _CallToActionButtonsState extends State<CallToActionButtons> {
Future<void> launchSocialUrl(Uri linkUrl) async {
if (!await launchUrl(linkUrl)) {
throw Exception('Could not launch $linkUrl');
}
}
Widget getInstallButtonText() {
final isWebAndroid =
kIsWeb && (defaultTargetPlatform == TargetPlatform.android);
final isWebIos = kIsWeb && (defaultTargetPlatform == TargetPlatform.iOS);
final isWebLinux =
kIsWeb && (defaultTargetPlatform == TargetPlatform.linux);
String btnText = "";
FaIconData platformIcon;
if (isWebAndroid) {
@ -33,6 +27,9 @@ class _CallToActionButtonsState extends State<CallToActionButtons> {
} else if (isWebIos) {
btnText = "Install MIH";
platformIcon = FontAwesomeIcons.appStoreIos;
} else if (isWebLinux) {
btnText = "Install MIH";
platformIcon = FontAwesomeIcons.linux;
} else if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Android") {
btnText = "Update MIH";
@ -40,6 +37,10 @@ class _CallToActionButtonsState extends State<CallToActionButtons> {
} else if (MzansiInnovationHub.of(context)!.theme.getPlatform() == "iOS") {
btnText = "Update MIH";
platformIcon = FontAwesomeIcons.appStoreIos;
} else if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Linux") {
btnText = "Update MIH";
platformIcon = FontAwesomeIcons.linux;
} else {
btnText = "Install MIH";
platformIcon = FontAwesomeIcons.globe;
@ -76,95 +77,7 @@ class _CallToActionButtonsState extends State<CallToActionButtons> {
children: [
MihButton(
onPressed: () {
if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Android") {
showDialog(
context: context,
builder: (context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: "Select Option",
onWindowTapClose: () {
context.pop();
},
windowBody: Column(
children: [
Text(
"Please select the platform you want to install/ Update MIH from",
style: TextStyle(
color: MihColors.secondary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 25),
MihButton(
onPressed: () {
launchSocialUrl(
Uri.parse(
"https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih",
),
);
},
buttonColor: MihColors.green(),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FaIcon(
FontAwesomeIcons.googlePlay,
color: MihColors.primary(),
),
const SizedBox(width: 10),
Text(
"Play Store",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
const SizedBox(
height: 10,
),
MihButton(
onPressed: () {
launchSocialUrl(
Uri.parse(
"https://appgallery.huawei.com/app/C113315335?pkgName=za.co.mzansiinnovationhub.mih",
),
);
},
buttonColor: MihColors.green(),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.store,
color: MihColors.primary(),
),
const SizedBox(width: 10),
Text(
"App Gallery",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
);
},
);
} else {
MihInstallServices().installMihTrigger(context);
}
},
buttonColor: MihColors.green(),
width: 300,
@ -172,7 +85,7 @@ class _CallToActionButtonsState extends State<CallToActionButtons> {
),
MihButton(
onPressed: () {
launchSocialUrl(
MihInstallServices().launchSocialUrl(
Uri.parse(
"https://www.youtube.com/playlist?list=PLuT35kJIui0H5kXjxNOZlHoOPZbQLr4qh",
),
@ -201,7 +114,7 @@ class _CallToActionButtonsState extends State<CallToActionButtons> {
),
MihButton(
onPressed: () {
launchSocialUrl(
MihInstallServices().launchSocialUrl(
Uri.parse(
"https://patreon.com/MzansiInnovationHub?utm_medium=unknown&utm_source=join_link&utm_campaign=creatorshare_creator&utm_content=copyLink",
),

View file

@ -0,0 +1,97 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:mih_package_toolkit/mih_package_toolkit.dart';
import 'package:mzansi_innovation_hub/mih_services/mih_install_services.dart';
class MihAndroidStoreOptions extends StatefulWidget {
const MihAndroidStoreOptions({super.key});
@override
State<MihAndroidStoreOptions> createState() => _MihAndroidStoreOptionsState();
}
class _MihAndroidStoreOptionsState extends State<MihAndroidStoreOptions> {
@override
Widget build(BuildContext context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: "Select Option",
onWindowTapClose: () {
context.pop();
},
windowBody: Column(
children: [
Text(
"Please select the platform you want to install/ Update MIH from",
style: TextStyle(
color: MihColors.secondary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 25),
MihButton(
onPressed: () {
MihInstallServices().launchSocialUrl(
Uri.parse(
"https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih",
),
);
},
buttonColor: MihColors.green(),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FaIcon(
FontAwesomeIcons.googlePlay,
color: MihColors.primary(),
),
const SizedBox(width: 10),
Text(
"Play Store",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
const SizedBox(
height: 10,
),
MihButton(
onPressed: () {
MihInstallServices().launchSocialUrl(
Uri.parse(
"https://appgallery.huawei.com/app/C113315335?pkgName=za.co.mzansiinnovationhub.mih",
),
);
},
buttonColor: MihColors.green(),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.store,
color: MihColors.primary(),
),
const SizedBox(width: 10),
Text(
"App Gallery",
style: TextStyle(
color: MihColors.primary(),
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
),
),
],
),
);
}
}

View file

@ -0,0 +1,183 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:mih_package_toolkit/mih_package_toolkit.dart';
class MihLinuxInstallInstructions extends StatefulWidget {
const MihLinuxInstallInstructions({super.key});
@override
State<MihLinuxInstallInstructions> createState() =>
_MihLinuxInstallInstructionsState();
}
class _MihLinuxInstallInstructionsState
extends State<MihLinuxInstallInstructions> {
Widget _buildInstructionStep(BuildContext context,
{required String stepNumber,
required String title,
required String command}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'$stepNumber. $title',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(fontWeight: FontWeight.w500),
),
const SizedBox(height: 6),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[900], // Dark background for terminal look
borderRadius: BorderRadius.circular(6),
),
child: Row(
children: [
Expanded(
child: Text(
command,
style: const TextStyle(
fontFamily: 'Courier', // Monospace font for commands
color: Colors.lightGreenAccent,
fontSize: 13,
),
),
),
IconButton(
icon: const Icon(Icons.copy, color: Colors.grey, size: 18),
onPressed: () {
// Clipboard functionality (Requires: import 'package:flutter/services.dart';)
Clipboard.setData(ClipboardData(text: command));
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text('Command copied to clipboard!'),
),
// const SnackBar(
// content: Text('Command copied to clipboard!')),
);
},
tooltip: 'Copy command',
),
],
),
),
],
);
}
@override
Widget build(BuildContext context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: null,
onWindowTapClose: () {
context.pop();
},
windowBody: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header
Center(
child: FaIcon(
FontAwesomeIcons.linux,
color: MihColors.secondary(),
size: 125,
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Get MIH for Linux',
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 12),
// Description
Text(
'Download the official MIH desktop application for Linux. Distributed as a sandboxed Flatpak package, it ensures seamless integration and automatic updates across any Linux distribution.',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(height: 1.4),
),
const SizedBox(height: 16),
// Prerequisite
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.amber.withOpacity(0.1),
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.amber.withOpacity(0.3)),
),
child: Row(
children: [
const Icon(Icons.warning_amber_rounded,
color: Colors.amber),
const SizedBox(width: 8),
Expanded(
child: Text(
'Prerequisite: Ensure Flatpak is installed on your machine.',
style:
Theme.of(context).textTheme.bodySmall?.copyWith(
fontWeight: FontWeight.w600,
),
),
),
],
),
),
const SizedBox(height: 16),
// Instructions Header
Text(
'Installation Instructions',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
// Command 1
_buildInstructionStep(
context,
stepNumber: '1',
title: 'Add the MIH repository:',
command:
'flatpak remote-add --if-not-exists mih-fphub https://fphub.mzansi-innovation-hub.co.za/mih-fphub.flatpakrepo',
),
const SizedBox(height: 12),
// Command 2
_buildInstructionStep(
context,
stepNumber: '2',
title: 'Install the application:',
command:
'flatpak install mih-fphub za.co.mzansiinnovationhub.mih',
),
],
),
),
],
),
);
}
}

View file

@ -0,0 +1,151 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:mih_package_toolkit/mih_package_toolkit.dart';
class MihLinuxUpdateInstructions extends StatefulWidget {
const MihLinuxUpdateInstructions({super.key});
@override
State<MihLinuxUpdateInstructions> createState() =>
_MihLinuxUpdateInstructionsState();
}
class _MihLinuxUpdateInstructionsState
extends State<MihLinuxUpdateInstructions> {
Widget _buildInstructionStep(BuildContext context,
{required String stepNumber,
required String title,
required String command}) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'$stepNumber $title',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(fontWeight: FontWeight.w500),
),
const SizedBox(height: 6),
Container(
width: double.infinity,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[900], // Dark background for terminal look
borderRadius: BorderRadius.circular(6),
),
child: Row(
children: [
Expanded(
child: Text(
command,
style: const TextStyle(
fontFamily: 'Courier', // Monospace font for commands
color: Colors.lightGreenAccent,
fontSize: 13,
),
),
),
IconButton(
icon: const Icon(Icons.copy, color: Colors.grey, size: 18),
onPressed: () {
// Clipboard functionality (Requires: import 'package:flutter/services.dart';)
Clipboard.setData(ClipboardData(text: command));
ScaffoldMessenger.of(context).showSnackBar(
MihSnackBar(
child: Text('Command copied to clipboard!'),
),
);
},
tooltip: 'Copy command',
),
],
),
),
],
);
}
@override
Widget build(BuildContext context) {
return MihPackageWindow(
fullscreen: false,
windowTitle: null,
onWindowTapClose: () {
context.pop();
},
windowBody: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header
Center(
child: FaIcon(
FontAwesomeIcons.linux,
color: MihColors.secondary(),
size: 125,
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Update MIH for Linux',
style: TextStyle(
fontSize: 35,
fontWeight: FontWeight.bold,
),
),
],
),
const SizedBox(height: 12),
// Description
Text(
'Flatpak apps usually update automatically via your system\'s Software Center. To manually force an update via the terminal, use one of the following commands:',
style: Theme.of(context)
.textTheme
.bodyMedium
?.copyWith(height: 1.4),
),
const SizedBox(height: 16),
Text(
'Update Instructions',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
// Command 1
_buildInstructionStep(
context,
stepNumber: '',
title: 'Update only the MIH app:',
command: 'flatpak update za.co.mzansiinnovationhub.mih',
),
const SizedBox(height: 12),
// Command 2
_buildInstructionStep(
context,
stepNumber: '',
title: 'Update all Flatpak apps on your system:',
command: 'flatpak update',
),
],
),
),
],
),
);
}
}

View file

@ -1,6 +1,9 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:mzansi_innovation_hub/main.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/components/mih_android_store_options.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/components/mih_linux_install_instructions.dart';
import 'package:mzansi_innovation_hub/mih_packages/about_mih/components/mih_linux_update_instructions.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:mzansi_innovation_hub/mih_helpers/mih_install_stub.dart'
if (dart.library.js_interop) 'package:mzansi_innovation_hub/mih_helpers/mih_install_web.dart';
@ -18,11 +21,12 @@ class MihInstallServices {
final isWebAndroid =
kIsWeb && (defaultTargetPlatform == TargetPlatform.android);
final isWebIos = kIsWeb && (defaultTargetPlatform == TargetPlatform.iOS);
final isWebLinux =
kIsWeb && (defaultTargetPlatform == TargetPlatform.linux);
if (isWebAndroid) {
launchSocialUrl(
Uri.parse(
"https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih",
),
showDialog(
context: context,
builder: (context) => MihAndroidStoreOptions(),
);
} else if (isWebIos) {
//Show pop up for IOS
@ -33,11 +37,9 @@ class MihInstallServices {
);
} else if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Android") {
//Installed Android App
launchSocialUrl(
Uri.parse(
"https://play.google.com/store/apps/details?id=za.co.mzansiinnovationhub.mih",
),
showDialog(
context: context,
builder: (context) => MihAndroidStoreOptions(),
);
} else if (MzansiInnovationHub.of(context)!.theme.getPlatform() == "iOS") {
launchSocialUrl(
@ -45,8 +47,17 @@ class MihInstallServices {
"https://apps.apple.com/za/app/mzansi-innovation-hub/id6743310890",
),
);
} else if (isWebLinux) {
showDialog(
context: context,
builder: (context) => MihLinuxInstallInstructions(),
);
} else if (MzansiInnovationHub.of(context)!.theme.getPlatform() ==
"Linux") {
showDialog(
context: context,
builder: (context) => MihLinuxUpdateInstructions(),
);
} else {
//Web
triggerWebInstall();