364 lines
12 KiB
Dart
364 lines
12 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:app_review/app_review.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
void main() {
|
|
runApp(const MyApp());
|
|
}
|
|
|
|
class MyApp extends StatelessWidget {
|
|
const MyApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
debugShowCheckedModeBanner: false,
|
|
theme: ThemeData(
|
|
useMaterial3: true,
|
|
colorSchemeSeed: Colors.blueAccent,
|
|
brightness: Brightness.light,
|
|
),
|
|
darkTheme: ThemeData(
|
|
useMaterial3: true,
|
|
colorSchemeSeed: Colors.blueAccent,
|
|
brightness: Brightness.dark,
|
|
),
|
|
home: const HomePage(),
|
|
);
|
|
}
|
|
}
|
|
|
|
class HomePage extends StatefulWidget {
|
|
const HomePage({super.key});
|
|
|
|
@override
|
|
State<HomePage> createState() => _HomePageState();
|
|
}
|
|
|
|
class _HomePageState extends State<HomePage> {
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
AppReview.getAppId().then((onValue) {
|
|
setState(() {
|
|
appID = onValue ?? '';
|
|
});
|
|
log(onValue);
|
|
});
|
|
}
|
|
|
|
String appID = "";
|
|
final List<String> _logs = [];
|
|
bool _useAndroidTestMode = true;
|
|
|
|
final testAppId = () {
|
|
if (Platform.isAndroid) return 'com.google.android.googlequicksearchbox';
|
|
if (Platform.isIOS || Platform.isMacOS) return '640199958';
|
|
return null;
|
|
}();
|
|
|
|
void log(String? message) {
|
|
if (message != null) {
|
|
debugPrint(message);
|
|
setState(() {
|
|
_logs.insert(0, message);
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: CustomScrollView(
|
|
slivers: [
|
|
SliverAppBar.large(
|
|
title: const Text('App Review'),
|
|
centerTitle: true,
|
|
),
|
|
SliverToBoxAdapter(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
if (Platform.isAndroid)
|
|
SwitchListTile(
|
|
title: const Text('Use Android Test Mode'),
|
|
subtitle: const Text('Uses FakeReviewManager'),
|
|
value: _useAndroidTestMode,
|
|
onChanged: (value) {
|
|
setState(() {
|
|
_useAndroidTestMode = value;
|
|
});
|
|
},
|
|
),
|
|
_buildInfoCard(
|
|
context,
|
|
title: 'App ID',
|
|
subtitle: appID.isEmpty ? 'Loading...' : appID,
|
|
icon: Icons.info_outline,
|
|
onTap: () {
|
|
AppReview.getAppId().then(log);
|
|
},
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
'Actions',
|
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
|
color: Theme.of(context).colorScheme.primary,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
_buildActionCard(
|
|
context,
|
|
title: 'View Store Page',
|
|
subtitle: 'Open the app store listing for this app',
|
|
icon: Icons.storefront,
|
|
color: Colors.orange,
|
|
onTap: () async {
|
|
try {
|
|
await AppReview.storeListing(
|
|
appStoreId: (Platform.isIOS || Platform.isMacOS)
|
|
? testAppId
|
|
: null,
|
|
playStoreId: Platform.isAndroid ? testAppId : null,
|
|
);
|
|
log('Opened Store Listing');
|
|
} catch (e) {
|
|
log('Failed to open store listing: $e');
|
|
}
|
|
},
|
|
),
|
|
const SizedBox(height: 12),
|
|
_buildActionCard(
|
|
context,
|
|
title: 'Request Review',
|
|
subtitle: 'Ask the user to rate the app',
|
|
icon: Icons.star_rate_rounded,
|
|
color: Colors.amber,
|
|
onTap: () async {
|
|
try {
|
|
await AppReview.requestReview(
|
|
useAndroidTestMode: _useAndroidTestMode,
|
|
);
|
|
log('Requested Review');
|
|
} catch (e) {
|
|
log('Request Review failed: $e');
|
|
}
|
|
},
|
|
),
|
|
const SizedBox(height: 12),
|
|
_buildActionCard(
|
|
context,
|
|
title: 'Write a New Review',
|
|
subtitle: 'Navigate to the review page',
|
|
icon: Icons.rate_review_outlined,
|
|
color: Colors.green,
|
|
onTap: () async {
|
|
try {
|
|
await AppReview.writeReview(
|
|
appStoreId: (Platform.isIOS || Platform.isMacOS)
|
|
? testAppId
|
|
: null,
|
|
playStoreId: Platform.isAndroid ? testAppId : null,
|
|
useAndroidTestMode: _useAndroidTestMode,
|
|
);
|
|
log('Opened Write Review');
|
|
} catch (e) {
|
|
log('Write Review failed: $e');
|
|
}
|
|
},
|
|
),
|
|
const SizedBox(height: 24),
|
|
Text(
|
|
'Log Output',
|
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
|
color: Theme.of(context).colorScheme.primary,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Container(
|
|
height: 200,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(
|
|
color: Theme.of(context).colorScheme.outlineVariant,
|
|
),
|
|
),
|
|
child: _logs.isEmpty
|
|
? Center(
|
|
child: Text(
|
|
'No logs yet',
|
|
style: TextStyle(
|
|
color: Theme.of(context).colorScheme.onSurface,
|
|
),
|
|
),
|
|
)
|
|
: ListView.separated(
|
|
padding: const EdgeInsets.all(8),
|
|
itemCount: _logs.length,
|
|
separatorBuilder: (context, index) =>
|
|
const Divider(height: 1),
|
|
itemBuilder: (context, index) {
|
|
return ListTile(
|
|
dense: true,
|
|
title: Text(
|
|
_logs[index],
|
|
style: TextStyle(
|
|
fontFamily: 'monospace',
|
|
fontSize: 12,
|
|
color:
|
|
Theme.of(context).colorScheme.onSurface,
|
|
),
|
|
),
|
|
leading: const Icon(Icons.code, size: 16),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildInfoCard(
|
|
BuildContext context, {
|
|
required String title,
|
|
required String subtitle,
|
|
required IconData icon,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
return Card(
|
|
elevation: 0,
|
|
color: Theme.of(context).colorScheme.secondaryContainer,
|
|
child: InkWell(
|
|
onTap: onTap,
|
|
borderRadius: BorderRadius.circular(12),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Row(
|
|
children: [
|
|
Icon(
|
|
icon,
|
|
color: Theme.of(context).colorScheme.onSecondaryContainer,
|
|
size: 28,
|
|
),
|
|
const SizedBox(width: 16),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.onSecondaryContainer
|
|
.withValues(alpha: 0.8),
|
|
),
|
|
),
|
|
const SizedBox(height: 4),
|
|
Text(
|
|
subtitle,
|
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.onSecondaryContainer,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Icon(
|
|
Icons.copy,
|
|
size: 18,
|
|
color: Theme.of(context)
|
|
.colorScheme
|
|
.onSecondaryContainer
|
|
.withValues(alpha: 0.5),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildActionCard(
|
|
BuildContext context, {
|
|
required String title,
|
|
required String subtitle,
|
|
required IconData icon,
|
|
required Color color,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
return Card(
|
|
elevation: 2,
|
|
shadowColor: Colors.transparent,
|
|
shape: RoundedRectangleBorder(
|
|
side: BorderSide(
|
|
color: Theme.of(context).colorScheme.outlineVariant,
|
|
),
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: InkWell(
|
|
onTap: onTap,
|
|
borderRadius: BorderRadius.circular(12),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Row(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: color.withValues(alpha: 0.1),
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: Icon(
|
|
icon,
|
|
color: color,
|
|
size: 24,
|
|
),
|
|
),
|
|
const SizedBox(width: 16),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
|
fontWeight: FontWeight.bold,
|
|
color: Theme.of(context).colorScheme.outline,
|
|
),
|
|
),
|
|
const SizedBox(height: 2),
|
|
Text(
|
|
subtitle,
|
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
|
color: Theme.of(context).colorScheme.outline,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Icon(
|
|
Icons.chevron_right,
|
|
color: Theme.of(context).colorScheme.outline,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|