fix ios and recreate examples
This commit is contained in:
@@ -1,100 +1,277 @@
|
||||
import 'package:app_review/app_review.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'dart:io' show Platform;
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
// The existing imports
|
||||
// !! Keep your existing impots here !!
|
||||
|
||||
/// main is entry point of Flutter application
|
||||
void main() {
|
||||
// Desktop platforms aren't a valid platform.
|
||||
if (!kIsWeb) _setTargetPlatformForDesktop();
|
||||
return runApp(MyApp());
|
||||
runApp(const MyApp());
|
||||
}
|
||||
|
||||
/// If the current platform is desktop, override the default platform to
|
||||
/// a supported platform (iOS for macOS, Android for Linux and Windows).
|
||||
/// Otherwise, do nothing.
|
||||
void _setTargetPlatformForDesktop() {
|
||||
TargetPlatform? targetPlatform;
|
||||
if (Platform.isMacOS) {
|
||||
targetPlatform = TargetPlatform.iOS;
|
||||
} else if (Platform.isLinux || Platform.isWindows) {
|
||||
targetPlatform = TargetPlatform.android;
|
||||
}
|
||||
if (targetPlatform != null) {
|
||||
debugDefaultTargetPlatformOverride = targetPlatform;
|
||||
}
|
||||
}
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
@override
|
||||
_MyAppState createState() => new _MyAppState();
|
||||
}
|
||||
|
||||
class _MyAppState extends State<MyApp> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
AppReview.getAppID.then(log);
|
||||
}
|
||||
|
||||
String appID = "";
|
||||
String output = "";
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new MaterialApp(
|
||||
home: new Scaffold(
|
||||
appBar: new AppBar(title: const Text('App Review')),
|
||||
body: new SingleChildScrollView(
|
||||
child: new ListBody(
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
height: 40.0,
|
||||
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 = [];
|
||||
|
||||
void log(String? message) {
|
||||
if (message != null) {
|
||||
setState(() {
|
||||
_logs.insert(0, message);
|
||||
});
|
||||
debugPrint(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: [
|
||||
_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 {
|
||||
final id = await AppReview.getIosAppId();
|
||||
if (id == null || id.isEmpty) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'App not found in store. Using Apple Developer App for testing.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
// Use Apple Developer App ID for testing
|
||||
// https://apps.apple.com/us/app/apple-developer/id640199958
|
||||
AppReview.openAppStore(
|
||||
fallbackUrl:
|
||||
'https://apps.apple.com/us/app/apple-developer/id640199958',
|
||||
).then(log);
|
||||
} else {
|
||||
AppReview.storeListing.then(log);
|
||||
}
|
||||
},
|
||||
),
|
||||
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: () {
|
||||
AppReview.requestReview.then(log);
|
||||
},
|
||||
),
|
||||
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 {
|
||||
final id = await AppReview.getIosAppId();
|
||||
if (id == null || id.isEmpty) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'App not found in store. Using Apple Developer App for testing.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
// Use Apple Developer App ID for testing
|
||||
AppReview.openIosReview(
|
||||
appId: '640199958',
|
||||
compose: true,
|
||||
).then(log);
|
||||
} else {
|
||||
AppReview.writeReview.then(log);
|
||||
}
|
||||
},
|
||||
),
|
||||
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),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
new ListTile(
|
||||
leading: const Icon(Icons.info),
|
||||
title: const Text('App ID'),
|
||||
subtitle: new Text(appID),
|
||||
onTap: () {
|
||||
AppReview.getAppID.then(log);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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 Divider(height: 20.0),
|
||||
new ListTile(
|
||||
leading: const Icon(
|
||||
Icons.shop,
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
title: const Text('View Store Page'),
|
||||
onTap: () {
|
||||
AppReview.storeListing.then(log);
|
||||
},
|
||||
),
|
||||
const Divider(height: 20.0),
|
||||
new ListTile(
|
||||
leading: const Icon(
|
||||
Icons.star,
|
||||
),
|
||||
title: const Text('Request Review'),
|
||||
onTap: () {
|
||||
AppReview.requestReview.then(log);
|
||||
},
|
||||
Icon(
|
||||
Icons.copy,
|
||||
size: 18,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSecondaryContainer
|
||||
.withValues(alpha: 0.5),
|
||||
),
|
||||
const Divider(height: 20.0),
|
||||
new ListTile(
|
||||
leading: const Icon(
|
||||
Icons.note_add,
|
||||
),
|
||||
title: const Text('Write a New Review'),
|
||||
onTap: () {
|
||||
AppReview.writeReview.then(log);
|
||||
},
|
||||
),
|
||||
const Divider(height: 20.0),
|
||||
new ListTile(title: new Text(output)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -102,12 +279,72 @@ class _MyAppState extends State<MyApp> {
|
||||
);
|
||||
}
|
||||
|
||||
void log(String? message) {
|
||||
if (message != null) {
|
||||
setState(() {
|
||||
output = message;
|
||||
});
|
||||
print(message);
|
||||
}
|
||||
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,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user