1110 check app version and prompt user to update (#1215)
* initial work for checking app version * fix error in version endpoint url * show dialog on new version available --------- Co-authored-by: wcjord <32568597+wcjord@users.noreply.github.com>pull/1544/head
parent
07f56a7ff6
commit
e38c1a08ee
@ -1,16 +0,0 @@
|
||||
BASE_API='https://api.staging.pangea.chat/api/v1'
|
||||
CHOREO_API = "http://localhost:8000/choreo"
|
||||
FRONTEND_URL='https://app.pangea.chat'
|
||||
|
||||
SYNAPSE_URL = 'matrix.staging.pangea.chat'
|
||||
CHOREO_API_KEY = 'e6fa9fa97031ba0c852efe78457922f278a2fbc109752fe18e465337699e9873'
|
||||
|
||||
RC_PROJECT = 'a499dc21'
|
||||
RC_KEY = 'sk_eVGBdPyInaOfJrKlPBgFVnRynqKJB'
|
||||
|
||||
RC_GOOGLE_KEY = 'goog_paQMrzFKGzuWZvcMTPkkvIsifJe'
|
||||
RC_IOS_KEY = 'appl_DUPqnxuLjkBLzhBPTWeDjqNENuv'
|
||||
RC_STRIPE_KEY = 'strp_YWZxWUeEfvagiefDNoofinaRCOl'
|
||||
RC_OFFERING_NAME = 'test'
|
||||
|
||||
STRIPE_MANAGEMENT_LINK = 'https://billing.stripe.com/p/login/test_9AQaI8d3O9lmaXe5kk'
|
||||
@ -0,0 +1,175 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pangea/config/environment.dart';
|
||||
import 'package:fluffychat/pangea/constants/local.key.dart';
|
||||
import 'package:fluffychat/pangea/constants/model_keys.dart';
|
||||
import 'package:fluffychat/pangea/network/requests.dart';
|
||||
import 'package:fluffychat/pangea/network/urls.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:url_launcher/url_launcher_string.dart';
|
||||
|
||||
class AppVersionController {
|
||||
static Future<AppVersionResponse> _getAppVersion(
|
||||
String accessToken,
|
||||
) async {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final currentVersion = packageInfo.version;
|
||||
final currentBuildNumber = packageInfo.buildNumber;
|
||||
|
||||
final Requests request = Requests(
|
||||
choreoApiKey: Environment.choreoApiKey,
|
||||
accessToken: accessToken,
|
||||
);
|
||||
|
||||
Map<String, dynamic> json = {};
|
||||
final Response res = await request.post(
|
||||
url: PApiUrls.appVersion,
|
||||
body: {
|
||||
"current_version": currentVersion,
|
||||
"current_build_number": currentBuildNumber,
|
||||
},
|
||||
);
|
||||
|
||||
json = jsonDecode(res.body);
|
||||
return AppVersionResponse.fromJson(json);
|
||||
}
|
||||
|
||||
static Future<void> showAppVersionDialog(BuildContext context) async {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final currentVersion = packageInfo.version;
|
||||
final currentBuildNumber = packageInfo.buildNumber;
|
||||
|
||||
final accessToken = MatrixState.pangeaController.userController.accessToken;
|
||||
final AppVersionResponse resp = await _getAppVersion(accessToken);
|
||||
|
||||
final remoteVersion = resp.latestVersion;
|
||||
final remoteBuildNumber = resp.latestBuildNumber;
|
||||
final mandatoryUpdate = resp.mandatoryUpdate;
|
||||
|
||||
if (currentVersion == remoteVersion &&
|
||||
currentBuildNumber == remoteBuildNumber) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mandatoryUpdate &&
|
||||
showedUpdateDialog != null &&
|
||||
DateTime.now().difference(showedUpdateDialog!) <
|
||||
const Duration(days: 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final OkCancelResult dialogResponse =
|
||||
await _showDialog(context, mandatoryUpdate);
|
||||
|
||||
if (!mandatoryUpdate && dialogResponse != OkCancelResult.ok) {
|
||||
await MatrixState.pangeaController.pStoreService.save(
|
||||
PLocalKey.showedUpdateDialog,
|
||||
DateTime.now().toIso8601String(),
|
||||
);
|
||||
}
|
||||
|
||||
if (dialogResponse == OkCancelResult.ok) {
|
||||
_launchUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
static Future<OkCancelResult> _showDialog(
|
||||
BuildContext context,
|
||||
bool mandatoryUpdate,
|
||||
) async {
|
||||
final title = mandatoryUpdate
|
||||
? L10n.of(context).mandatoryUpdateRequired
|
||||
: L10n.of(context).updateAvailable;
|
||||
final message = mandatoryUpdate
|
||||
? L10n.of(context).mandatoryUpdateRequiredDesc
|
||||
: L10n.of(context).updateAvailableDesc;
|
||||
return mandatoryUpdate
|
||||
? showOkAlertDialog(
|
||||
context: context,
|
||||
title: title,
|
||||
message: message,
|
||||
canPop: false,
|
||||
barrierDismissible: false,
|
||||
okLabel: L10n.of(context).updateNow,
|
||||
)
|
||||
: showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: title,
|
||||
message: message,
|
||||
canPop: false,
|
||||
barrierDismissible: false,
|
||||
okLabel: L10n.of(context).updateNow,
|
||||
cancelLabel: L10n.of(context).updateLater,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<void> _launchUpdate() async {
|
||||
if (kIsWeb) {
|
||||
html.window.location.reload();
|
||||
return;
|
||||
}
|
||||
|
||||
final String url = PlatformInfos.isIOS
|
||||
? AppConfig.iosUpdateURL
|
||||
: AppConfig.androidUpdateURL;
|
||||
await launchUrlString(url);
|
||||
}
|
||||
|
||||
static DateTime? get showedUpdateDialog {
|
||||
final entry = MatrixState.pangeaController.pStoreService
|
||||
.read(PLocalKey.showedUpdateDialog);
|
||||
if (entry == null) return null;
|
||||
try {
|
||||
return DateTime.parse(entry);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AppVersionResponse {
|
||||
final String latestVersion;
|
||||
final String latestBuildNumber;
|
||||
final bool mandatoryUpdate;
|
||||
|
||||
AppVersionResponse({
|
||||
required this.latestVersion,
|
||||
required this.latestBuildNumber,
|
||||
required this.mandatoryUpdate,
|
||||
});
|
||||
|
||||
factory AppVersionResponse.fromJson(Map<String, dynamic> json) {
|
||||
if (json[ModelKey.mandatoryUpdate] is! bool) {
|
||||
throw Exception("mandatory_update is not a boolean");
|
||||
}
|
||||
if (json[ModelKey.latestVersion] is! String) {
|
||||
throw Exception("latest_version is not a string");
|
||||
}
|
||||
if (json[ModelKey.latestBuildNumber] is! String) {
|
||||
throw Exception("latest_build_number is not a string");
|
||||
}
|
||||
|
||||
return AppVersionResponse(
|
||||
latestVersion: json[ModelKey.latestVersion],
|
||||
latestBuildNumber: json[ModelKey.latestBuildNumber],
|
||||
mandatoryUpdate: json[ModelKey.mandatoryUpdate],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
ModelKey.latestVersion: latestVersion,
|
||||
ModelKey.latestBuildNumber: latestBuildNumber,
|
||||
ModelKey.mandatoryUpdate: mandatoryUpdate,
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue