mirror of
https://github.com/jonasbark/swiftcontrol.git
synced 2026-02-18 00:17:40 +01:00
211 lines
6.6 KiB
Dart
Executable File
211 lines
6.6 KiB
Dart
Executable File
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:in_app_update/in_app_update.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
import 'package:restart_app/restart_app.dart';
|
|
import 'package:shorebird_code_push/shorebird_code_push.dart';
|
|
import 'package:swift_control/main.dart';
|
|
import 'package:swift_control/widgets/small_progress_indicator.dart';
|
|
import 'package:url_launcher/url_launcher_string.dart';
|
|
import 'package:version/version.dart';
|
|
|
|
PackageInfo? packageInfoValue;
|
|
bool? isFromPlayStore;
|
|
Patch? shorebirdPatch;
|
|
|
|
class AppTitle extends StatefulWidget {
|
|
const AppTitle({super.key});
|
|
|
|
@override
|
|
State<AppTitle> createState() => _AppTitleState();
|
|
}
|
|
|
|
class _AppTitleState extends State<AppTitle> {
|
|
final updater = ShorebirdUpdater();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
if (updater.isAvailable) {
|
|
updater.readCurrentPatch().then((patch) {
|
|
setState(() {
|
|
shorebirdPatch = patch;
|
|
});
|
|
});
|
|
}
|
|
|
|
if (packageInfoValue == null) {
|
|
PackageInfo.fromPlatform().then((value) {
|
|
setState(() {
|
|
packageInfoValue = value;
|
|
});
|
|
_checkForUpdate();
|
|
});
|
|
}
|
|
}
|
|
|
|
void _checkForUpdate() async {
|
|
if (screenshotMode) {
|
|
return;
|
|
} else if (updater.isAvailable) {
|
|
final updateStatus = await updater.checkForUpdate();
|
|
if (updateStatus == UpdateStatus.outdated) {
|
|
updater
|
|
.update()
|
|
.then((value) {
|
|
_showShorebirdRestartSnackbar();
|
|
})
|
|
.catchError((e) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text('Failed to update: $e'),
|
|
duration: Duration(seconds: 5),
|
|
),
|
|
);
|
|
});
|
|
} else if (updateStatus == UpdateStatus.restartRequired) {
|
|
_showShorebirdRestartSnackbar();
|
|
}
|
|
}
|
|
|
|
if (kIsWeb) {
|
|
// no-op
|
|
} else if (Platform.isAndroid) {
|
|
try {
|
|
final appUpdateInfo = await InAppUpdate.checkForUpdate();
|
|
if (context.mounted && appUpdateInfo.updateAvailability == UpdateAvailability.updateAvailable) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text('New version available'),
|
|
duration: Duration(seconds: 1337),
|
|
action: SnackBarAction(
|
|
label: 'Update',
|
|
onPressed: () {
|
|
InAppUpdate.performImmediateUpdate();
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
isFromPlayStore = true;
|
|
return null;
|
|
} on Exception catch (e) {
|
|
isFromPlayStore = false;
|
|
print('Failed to check for update: $e');
|
|
}
|
|
setState(() {});
|
|
} else if (Platform.isIOS) {
|
|
final url = Uri.parse('https://itunes.apple.com/lookup?id=6753721284');
|
|
final response = await http.get(url);
|
|
|
|
if (response.statusCode == 200) {
|
|
final data = json.decode(response.body);
|
|
if (data['resultCount'] > 0) {
|
|
final versionString = data['results'][0]['version'] as String;
|
|
_compareVersion(versionString);
|
|
}
|
|
}
|
|
} else if (Platform.isMacOS) {
|
|
final url = Uri.parse('https://apps.apple.com/us/app/swiftcontrol/id6753721284?platform=mac');
|
|
final res = await http.get(url, headers: {'User-Agent': 'Mozilla/5.0'});
|
|
if (res.statusCode != 200) return null;
|
|
|
|
final body = res.body;
|
|
final regex = RegExp(
|
|
r'whats-new__latest__version">Version ([0-9]{1,2}\.[0-9]{1,2}.[0-9]{1,2})</p>',
|
|
dotAll: true,
|
|
);
|
|
final match = regex.firstMatch(body);
|
|
if (match == null) return null;
|
|
final versionString = match.group(1);
|
|
|
|
if (versionString != null) {
|
|
_compareVersion(versionString);
|
|
}
|
|
} else if (Platform.isWindows) {
|
|
final url = Uri.parse(
|
|
'https://raw.githubusercontent.com/jonasbark/swiftcontrol/refs/heads/main/WINDOWS_STORE_VERSION.txt',
|
|
);
|
|
final res = await http.get(url, headers: {'User-Agent': 'Mozilla/5.0'});
|
|
if (res.statusCode != 200) return null;
|
|
|
|
final body = res.body.trim();
|
|
_compareVersion(body);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('SwiftControl', style: TextStyle(fontWeight: FontWeight.bold)),
|
|
if (packageInfoValue != null)
|
|
Text(
|
|
'v${packageInfoValue!.version}${shorebirdPatch != null ? '+${shorebirdPatch!.number}' : ''}${kIsWeb || (Platform.isAndroid && isFromPlayStore == false) ? ' (sideloaded)' : ''}',
|
|
style: screenshotMode
|
|
? TextStyle(fontSize: 12)
|
|
: TextStyle(fontFamily: "monospace", fontFamilyFallback: <String>["Courier"], fontSize: 12),
|
|
)
|
|
else
|
|
SmallProgressIndicator(),
|
|
],
|
|
);
|
|
}
|
|
|
|
void _showShorebirdRestartSnackbar() {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text('Force-close the app to use the new version'),
|
|
duration: Duration(seconds: 10),
|
|
action: SnackBarAction(
|
|
label: 'Restart',
|
|
onPressed: () {
|
|
if (Platform.isIOS) {
|
|
connection.reset();
|
|
Restart.restartApp(delayBeforeRestart: 1000);
|
|
} else {
|
|
connection.reset();
|
|
exit(0);
|
|
}
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _compareVersion(String versionString) {
|
|
final parsed = Version.parse(versionString);
|
|
final current = Version.parse(packageInfoValue!.version);
|
|
if (parsed > current && mounted && !kDebugMode) {
|
|
if (Platform.isAndroid) {
|
|
_showUpdateSnackbar(parsed, 'https://play.google.com/store/apps/details?id=org.jonasbark.swiftcontrol');
|
|
} else if (Platform.isIOS || Platform.isMacOS) {
|
|
_showUpdateSnackbar(parsed, 'https://apps.apple.com/app/id6753721284');
|
|
} else if (Platform.isWindows) {
|
|
_showUpdateSnackbar(parsed, 'ms-windows-store://pdp/?productid=9NP42GS03Z26');
|
|
}
|
|
}
|
|
}
|
|
|
|
void _showUpdateSnackbar(Version newVersion, String url) {
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text('New version available: ${newVersion.toString()}'),
|
|
duration: Duration(seconds: 1337),
|
|
action: SnackBarAction(
|
|
label: 'Download',
|
|
onPressed: () {
|
|
launchUrlString(url);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|