ask permissions
This commit is contained in:
@@ -108,6 +108,8 @@ PODS:
|
||||
- GoogleUtilities/Logger
|
||||
- image_picker (0.0.1):
|
||||
- Flutter
|
||||
- media_gallery (0.0.1):
|
||||
- Flutter
|
||||
- nanopb (1.30906.0):
|
||||
- nanopb/decode (= 1.30906.0)
|
||||
- nanopb/encode (= 1.30906.0)
|
||||
@@ -115,7 +117,7 @@ PODS:
|
||||
- nanopb/encode (1.30906.0)
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- photo_gallery (0.0.1):
|
||||
- "permission_handler (5.0.1+1)":
|
||||
- Flutter
|
||||
- PromisesObjC (1.2.11)
|
||||
- Protobuf (3.13.0)
|
||||
@@ -167,8 +169,9 @@ DEPENDENCIES:
|
||||
- flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
|
||||
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
|
||||
- image_picker (from `.symlinks/plugins/image_picker/ios`)
|
||||
- media_gallery (from `.symlinks/plugins/media_gallery/ios`)
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- photo_gallery (from `.symlinks/plugins/photo_gallery/ios`)
|
||||
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
||||
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`)
|
||||
@@ -220,10 +223,12 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/flutter_secure_storage/ios"
|
||||
image_picker:
|
||||
:path: ".symlinks/plugins/image_picker/ios"
|
||||
media_gallery:
|
||||
:path: ".symlinks/plugins/media_gallery/ios"
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
photo_gallery:
|
||||
:path: ".symlinks/plugins/photo_gallery/ios"
|
||||
permission_handler:
|
||||
:path: ".symlinks/plugins/permission_handler/ios"
|
||||
shared_preferences:
|
||||
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||
sqflite:
|
||||
@@ -259,9 +264,10 @@ SPEC CHECKSUMS:
|
||||
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
|
||||
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
|
||||
image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09
|
||||
media_gallery: 834a04455a476b975c280aa1f24ed2853dfe36de
|
||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
photo_gallery: 9f95e57747cd22c10676ece3660d1ffe6c603ee5
|
||||
permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6
|
||||
PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
|
||||
Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748
|
||||
SDWebImage: b69257f4ab14e9b6a2ef53e910fdf914d8f757c1
|
||||
|
||||
@@ -327,9 +327,9 @@
|
||||
"${BUILT_PRODUCTS_DIR}/flutter_local_notifications/flutter_local_notifications.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/flutter_secure_storage/flutter_secure_storage.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/image_picker/image_picker.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/media_gallery/media_gallery.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/photo_gallery/photo_gallery.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/sqlite3/sqlite3.framework",
|
||||
@@ -358,9 +358,9 @@
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_local_notifications.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_secure_storage.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_picker.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/media_gallery.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/photo_gallery.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqlite3.framework",
|
||||
|
||||
+135
-133
@@ -59,165 +59,167 @@ class ChooseUserPage extends StatelessWidget {
|
||||
(_, value) => value..extraData['image'] = getRandomPicUrl(value));
|
||||
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 34,
|
||||
bottom: 20,
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
'assets/logo.svg',
|
||||
height: 40,
|
||||
body: SafeArea(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 34,
|
||||
bottom: 20,
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
'assets/logo.svg',
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 13.0),
|
||||
child: Text(
|
||||
'Welcome to Stream Chat',
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 13.0),
|
||||
child: Text(
|
||||
'Welcome to Stream Chat',
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Select a user to try the Flutter SDK:',
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontSize: 14.5,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'Select a user to try the Flutter SDK:',
|
||||
style: TextStyle(
|
||||
fontSize: 14.5,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
separatorBuilder: (context, i) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
color: Colors.black12,
|
||||
height: 1,
|
||||
);
|
||||
},
|
||||
itemCount: users.length + 1,
|
||||
itemBuilder: (context, i) {
|
||||
return [
|
||||
...users.entries.map((entry) {
|
||||
final token = entry.key;
|
||||
final user = entry.value;
|
||||
return ListTile(
|
||||
onTap: () async {
|
||||
showDialog(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (context) => Center(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white,
|
||||
),
|
||||
height: 100,
|
||||
width: 100,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
separatorBuilder: (context, i) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
color: Colors.black12,
|
||||
height: 1,
|
||||
);
|
||||
},
|
||||
itemCount: users.length + 1,
|
||||
itemBuilder: (context, i) {
|
||||
return [
|
||||
...users.entries.map((entry) {
|
||||
final token = entry.key;
|
||||
final user = entry.value;
|
||||
return ListTile(
|
||||
onTap: () async {
|
||||
showDialog(
|
||||
barrierDismissible: false,
|
||||
context: context,
|
||||
builder: (context) => Center(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Colors.white,
|
||||
),
|
||||
height: 100,
|
||||
width: 100,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final secureStorage = FlutterSecureStorage();
|
||||
final client = StreamChat.of(context).client;
|
||||
|
||||
await client.setUser(
|
||||
user,
|
||||
token,
|
||||
);
|
||||
|
||||
secureStorage.write(
|
||||
key: kStreamApiKey,
|
||||
value: kDefaultStreamApiKey,
|
||||
);
|
||||
secureStorage.write(
|
||||
key: kStreamUserId,
|
||||
value: user.id,
|
||||
);
|
||||
secureStorage.write(
|
||||
key: kStreamToken,
|
||||
value: token,
|
||||
);
|
||||
|
||||
if (!kIsWeb) {
|
||||
initNotifications(client);
|
||||
}
|
||||
|
||||
Navigator.pop(context);
|
||||
await Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return StreamChat(
|
||||
client: client,
|
||||
child: ChannelListPage(),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: UserAvatar(
|
||||
user: user,
|
||||
constraints: BoxConstraints.tight(
|
||||
Size.fromRadius(20),
|
||||
),
|
||||
);
|
||||
|
||||
final secureStorage = FlutterSecureStorage();
|
||||
final client = StreamChat.of(context).client;
|
||||
|
||||
await client.setUser(
|
||||
user,
|
||||
token,
|
||||
);
|
||||
|
||||
secureStorage.write(
|
||||
key: kStreamApiKey,
|
||||
value: kDefaultStreamApiKey,
|
||||
);
|
||||
secureStorage.write(
|
||||
key: kStreamUserId,
|
||||
value: user.id,
|
||||
);
|
||||
secureStorage.write(
|
||||
key: kStreamToken,
|
||||
value: token,
|
||||
);
|
||||
|
||||
if (!kIsWeb) {
|
||||
initNotifications(client);
|
||||
}
|
||||
|
||||
Navigator.pop(context);
|
||||
await Navigator.pushReplacement(
|
||||
),
|
||||
title: Text(
|
||||
user.name,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: Text('Stream test account'),
|
||||
trailing: SvgPicture.asset(
|
||||
'assets/icon_arrow_right.svg',
|
||||
height: 24,
|
||||
width: 24,
|
||||
),
|
||||
);
|
||||
}),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return StreamChat(
|
||||
client: client,
|
||||
child: ChannelListPage(),
|
||||
);
|
||||
},
|
||||
builder: (context) => AdvancedOptionsPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: UserAvatar(
|
||||
user: user,
|
||||
constraints: BoxConstraints.tight(
|
||||
Size.fromRadius(20),
|
||||
leading: CircleAvatar(
|
||||
child: Icon(
|
||||
StreamIcons.settings,
|
||||
color: Colors.black,
|
||||
),
|
||||
backgroundColor:
|
||||
StreamChatTheme.of(context).secondaryColor,
|
||||
),
|
||||
title: Text(
|
||||
user.name,
|
||||
'Advanced Options',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: Text('Stream test account'),
|
||||
subtitle: Text('Custom settings'),
|
||||
trailing: SvgPicture.asset(
|
||||
'assets/icon_arrow_right.svg',
|
||||
height: 24,
|
||||
width: 24,
|
||||
clipBehavior: Clip.none,
|
||||
),
|
||||
);
|
||||
}),
|
||||
ListTile(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => AdvancedOptionsPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: CircleAvatar(
|
||||
child: Icon(
|
||||
StreamIcons.settings,
|
||||
color: Colors.black,
|
||||
),
|
||||
backgroundColor:
|
||||
StreamChatTheme.of(context).secondaryColor,
|
||||
),
|
||||
title: Text(
|
||||
'Advanced Options',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
subtitle: Text('Custom settings'),
|
||||
trailing: SvgPicture.asset(
|
||||
'assets/icon_arrow_right.svg',
|
||||
height: 24,
|
||||
width: 24,
|
||||
clipBehavior: Clip.none,
|
||||
),
|
||||
),
|
||||
][i];
|
||||
},
|
||||
][i];
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
StreamVersion(),
|
||||
],
|
||||
StreamVersion(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
+66
-64
@@ -64,83 +64,85 @@ class ChannelListPage extends StatelessWidget {
|
||||
final user = StreamChat.of(context).user;
|
||||
return Scaffold(
|
||||
drawer: Drawer(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: MediaQuery.of(context).viewPadding.top + 8,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 20.0,
|
||||
left: 8,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
UserAvatar(
|
||||
user: user,
|
||||
showOnlineStatus: false,
|
||||
constraints: BoxConstraints.tight(Size.fromRadius(20)),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0),
|
||||
child: Text(
|
||||
user.name,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
child: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
top: MediaQuery.of(context).viewPadding.top + 8,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 20.0,
|
||||
left: 8,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
UserAvatar(
|
||||
user: user,
|
||||
showOnlineStatus: false,
|
||||
constraints: BoxConstraints.tight(Size.fromRadius(20)),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0),
|
||||
child: Text(
|
||||
user.name,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(StreamIcons.edit),
|
||||
title: Text(
|
||||
'New direct message',
|
||||
style: TextStyle(
|
||||
fontSize: 14.5,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(StreamIcons.edit),
|
||||
title: Text(
|
||||
'New direct message',
|
||||
style: TextStyle(
|
||||
fontSize: 14.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: Icon(StreamIcons.group),
|
||||
title: Text(
|
||||
'New group',
|
||||
style: TextStyle(
|
||||
fontSize: 14.5,
|
||||
ListTile(
|
||||
leading: Icon(StreamIcons.group),
|
||||
title: Text(
|
||||
'New group',
|
||||
style: TextStyle(
|
||||
fontSize: 14.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: ListTile(
|
||||
onTap: () async {
|
||||
await StreamChat.of(context).client.disconnect();
|
||||
Expanded(
|
||||
child: Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: ListTile(
|
||||
onTap: () async {
|
||||
await StreamChat.of(context).client.disconnect();
|
||||
|
||||
final secureStorage = FlutterSecureStorage();
|
||||
await secureStorage.deleteAll();
|
||||
Navigator.pop(context);
|
||||
await Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ChooseUserPage(),
|
||||
final secureStorage = FlutterSecureStorage();
|
||||
await secureStorage.deleteAll();
|
||||
Navigator.pop(context);
|
||||
await Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ChooseUserPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: Icon(StreamIcons.user),
|
||||
title: Text(
|
||||
'Sign out',
|
||||
style: TextStyle(
|
||||
fontSize: 14.5,
|
||||
),
|
||||
);
|
||||
},
|
||||
leading: Icon(StreamIcons.user),
|
||||
title: Text(
|
||||
'Sign out',
|
||||
style: TextStyle(
|
||||
fontSize: 14.5,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: example
|
||||
description: A new Flutter project.
|
||||
version: 1.0.58+60
|
||||
version: 1.0.59+61
|
||||
|
||||
environment:
|
||||
sdk: ">=2.2.2 <3.0.0"
|
||||
|
||||
+84
-18
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:emojis/emoji.dart';
|
||||
@@ -659,7 +660,7 @@ class MessageInputState extends State<MessageInput> {
|
||||
setState(() {
|
||||
_animateContainer = false;
|
||||
_filePickerSize = (_filePickerSize - update.delta.dy).clamp(
|
||||
100,
|
||||
240.0,
|
||||
MediaQuery.of(context).size.height / 1.7,
|
||||
);
|
||||
});
|
||||
@@ -709,17 +710,80 @@ class MessageInputState extends State<MessageInput> {
|
||||
Widget _buildPickerSection() {
|
||||
switch (_filePickerIndex) {
|
||||
case 0:
|
||||
return MediaListView(
|
||||
selectedIds: _attachments.map((e) => e.id).toList(),
|
||||
onSelect: (media) {
|
||||
if (!_attachments.any((element) => element.id == media.id)) {
|
||||
_addAttachment(media);
|
||||
} else {
|
||||
_attachments.removeWhere((element) => element.id == media.id);
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
);
|
||||
return FutureBuilder<PermissionStatus>(
|
||||
future: Platform.isAndroid
|
||||
? Permission.storage.status
|
||||
: Permission.photos.status,
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
if (snapshot.data.isGranted) {
|
||||
return MediaListView(
|
||||
selectedIds: _attachments.map((e) => e.id).toList(),
|
||||
onSelect: (media) {
|
||||
if (!_attachments
|
||||
.any((element) => element.id == media.id)) {
|
||||
_addAttachment(media);
|
||||
} else {
|
||||
_attachments
|
||||
.removeWhere((element) => element.id == media.id);
|
||||
setState(() {});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
var status = await (Platform.isAndroid
|
||||
? Permission.storage.status
|
||||
: Permission.photos.status);
|
||||
print('status: ${status}');
|
||||
if (status.isPermanentlyDenied || status.isDenied) {
|
||||
if (await openAppSettings()) {
|
||||
setState(() {});
|
||||
}
|
||||
} else {
|
||||
status = await (Platform.isAndroid
|
||||
? Permission.storage
|
||||
: Permission.photos)
|
||||
.request();
|
||||
if (status.isGranted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
color: Color(0xFFF2F2F2),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
'svgs/icon_picture_empty_state.svg',
|
||||
package: 'stream_chat_flutter',
|
||||
height: 140,
|
||||
color: StreamChatTheme.of(context).accentColor,
|
||||
),
|
||||
Center(
|
||||
child: Text(
|
||||
'Allow access to your gallery',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: StreamChatTheme.of(context).accentColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
@@ -1235,12 +1299,14 @@ class MessageInputState extends State<MessageInput> {
|
||||
_filePickerSize = 250.0;
|
||||
});
|
||||
} else {
|
||||
final status = await Permission.storage.request();
|
||||
if (status.isDenied || status.isPermanentlyDenied) {
|
||||
final res = await openAppSettings();
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
final status = await (Platform.isAndroid
|
||||
? Permission.storage.status
|
||||
: Permission.photos.status);
|
||||
if (status.isUndetermined) {
|
||||
await (Platform.isAndroid
|
||||
? Permission.storage
|
||||
: Permission.photos)
|
||||
.request();
|
||||
}
|
||||
showAttachmentModal();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg width="136" height="136" viewBox="0 0 136 136" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3333 45.3333C11.3333 35.9445 18.9444 28.3333 28.3333 28.3333H107.667C117.055 28.3333 124.667 35.9445 124.667 45.3333V90.6667C124.667 100.055 117.055 107.667 107.667 107.667H28.3333C18.9444 107.667 11.3333 100.055 11.3333 90.6667V45.3333ZM28.3333 39.6666C25.2036 39.6666 22.6666 42.2037 22.6666 45.3333V90.6666C22.6666 93.7963 25.2036 96.3333 28.3333 96.3333H107.667C110.796 96.3333 113.333 93.7963 113.333 90.6666V45.3333C113.333 42.2037 110.796 39.6666 107.667 39.6666H28.3333Z" fill="#D6D6D6"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M90.61 51.0003C92.3115 50.9833 93.9306 51.7318 95.0199 53.039L123.353 87.039C125.357 89.4432 125.032 93.0164 122.628 95.0199C120.223 97.0234 116.65 96.6986 114.647 94.2944L90.7563 65.6258L72.4249 88.5399C70.5129 90.9299 67.0486 91.3698 64.6 89.5333L45.8651 75.4821L26.6736 94.6736C24.4606 96.8866 20.8727 96.8866 18.6597 94.6736C16.4468 92.4606 16.4468 88.8727 18.6597 86.6597L41.3264 63.9931C43.3204 61.999 46.4773 61.7747 48.7333 63.4667L67.0061 77.1713L86.2417 53.1267C87.3047 51.798 88.9085 51.0173 90.61 51.0003Z" fill="#D6D6D6"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
Reference in New Issue
Block a user