In app rating

This commit is contained in:
2024-09-24 22:10:45 +08:00
parent e1ddd22e4e
commit 7a5fd2e468
10 changed files with 123 additions and 9 deletions

View File

@@ -1,8 +1,10 @@
import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:in_app_review/in_app_review.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -42,6 +44,27 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
final Completer _bootCompleter = Completer();
void _requestRating() async {
final prefs = await SharedPreferences.getInstance();
if (prefs.containsKey('first_boot_time')) {
final rawTime = prefs.getString('first_boot_time');
final time = DateTime.tryParse(rawTime ?? '');
if (time != null &&
time.isBefore(DateTime.now().subtract(const Duration(days: 3)))) {
final inAppReview = InAppReview.instance;
if (prefs.getBool('rating_requested') == true) return;
if (await inAppReview.isAvailable()) {
await inAppReview.requestReview();
prefs.setBool('rating_requested', true);
} else {
log('Unable request app review, unavailable');
}
}
} else {
prefs.setString('first_boot_time', DateTime.now().toIso8601String());
}
}
void _updateNow(String localVersionString, String remoteVersionString) {
context
.showConfirmDialog(
@@ -226,6 +249,9 @@ class _BootstrapperShellState extends State<BootstrapperShell> {
super.initState();
_runPeriods();
_checkForUpdate();
_bootCompleter.future.then((_) {
_requestRating();
});
}
@override

View File

@@ -27,6 +27,8 @@ abstract class PlatformInfo {
static bool get canCacheImage => isAndroid || isIOS || isMacOS;
static bool get canRateTheApp => isIOS || isMacOS;
static bool get canRecord => (isMobile || isMacOS);
static bool get canPushNotification => isAndroid || isIOS || isMacOS;
@@ -38,4 +40,4 @@ abstract class PlatformInfo {
} catch (_) {}
return version;
}
}
}

View File

@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:solian/widgets/sized_container.dart';
import 'package:url_launcher/url_launcher_string.dart';
@@ -52,8 +54,8 @@ class AboutScreen extends StatelessWidget {
CenteredContainer(
maxWidth: 280,
child: Wrap(
spacing: 8,
runSpacing: 8,
spacing: 4,
runSpacing: 4,
alignment: WrapAlignment.center,
children: [
TextButton(
@@ -92,6 +94,13 @@ class AboutScreen extends StatelessWidget {
launchUrlString('https://solsynth.dev/terms');
},
),
TextButton(
style: denseButtonStyle,
child: Text('serviceStatus'.tr),
onPressed: () {
launchUrlString('https://status.solsynth.dev');
},
),
],
),
),
@@ -103,6 +112,34 @@ class AboutScreen extends StatelessWidget {
fontSize: 12,
),
),
FutureBuilder(
future: SharedPreferences.getInstance(),
builder: (context, snapshot) {
const textStyle = TextStyle(
fontWeight: FontWeight.w300,
fontSize: 12,
);
if (!snapshot.hasData ||
!snapshot.data!.containsKey('first_boot_time')) {
return Text(
'firstBootTime'.trParams({'time': 'unknown'.tr}),
style: textStyle,
);
} else {
return Text(
'firstBootTime'.trParams({
'time': DateFormat('yyyy-MM-dd').format(
DateTime.tryParse(
snapshot.data!.getString('first_boot_time')!,
)?.toLocal() ??
DateTime.now(),
),
}),
style: textStyle,
);
}
},
),
],
),
),

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:in_app_review/in_app_review.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:solian/exceptions/request.dart';
@@ -205,6 +206,21 @@ class _SettingScreenState extends State<SettingScreen> {
});
},
),
if (PlatformInfo.canRateTheApp)
ListTile(
leading: const Icon(Icons.star),
trailing: const Icon(Icons.chevron_right),
contentPadding: const EdgeInsets.symmetric(horizontal: 22),
title: Text('rateTheApp'.tr),
subtitle: Text('rateTheAppDesc'.tr),
onTap: () {
final inAppReview = InAppReview.instance;
inAppReview.openStoreListing(
appStoreId: '6499032345',
);
},
),
ListTile(
leading: const Icon(Icons.info_outline),
trailing: const Icon(Icons.chevron_right),