✨ Can edit avatar and banner
This commit is contained in:
parent
e742338d92
commit
740c704fb8
@ -20,7 +20,7 @@ pluginManagement {
|
|||||||
plugins {
|
plugins {
|
||||||
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
|
||||||
id "com.android.application" version "7.3.0" apply false
|
id "com.android.application" version "7.3.0" apply false
|
||||||
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
|
id "org.jetbrains.kotlin.android" version "1.9.23" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
include ":app"
|
include ":app"
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
"chatNew": "New Chat",
|
"chatNew": "New Chat",
|
||||||
"chatNewCreate": "Create a channel",
|
"chatNewCreate": "Create a channel",
|
||||||
"chatNewJoin": "Join a exists channel",
|
"chatNewJoin": "Join a exists channel",
|
||||||
"chatManage": "Manage Chat",
|
"chatDetail": "Chat Details",
|
||||||
"chatMember": "Member",
|
"chatMember": "Member",
|
||||||
"chatNotifySetting": "Notify Settings",
|
"chatNotifySetting": "Notify Settings",
|
||||||
"chatChannelUsage": "Channel",
|
"chatChannelUsage": "Channel",
|
||||||
|
@ -73,7 +73,7 @@
|
|||||||
"reactionAdded": "你的反应已被添加。",
|
"reactionAdded": "你的反应已被添加。",
|
||||||
"reactionRemoved": "你的反应已被移除。",
|
"reactionRemoved": "你的反应已被移除。",
|
||||||
"chatNew": "新聊天",
|
"chatNew": "新聊天",
|
||||||
"chatManage": "管理聊天",
|
"chatDetail": "聊天详情",
|
||||||
"chatMember": "成员",
|
"chatMember": "成员",
|
||||||
"chatNotifySetting": "通知设定",
|
"chatNotifySetting": "通知设定",
|
||||||
"chatNewCreate": "新建频道",
|
"chatNewCreate": "新建频道",
|
||||||
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/router.dart';
|
import 'package:solian/router.dart';
|
||||||
|
import 'package:solian/utils/theme.dart';
|
||||||
import 'package:solian/widgets/account/account_avatar.dart';
|
import 'package:solian/widgets/account/account_avatar.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:solian/widgets/scaffold.dart';
|
import 'package:solian/widgets/scaffold.dart';
|
||||||
@ -14,7 +15,7 @@ class AccountScreen extends StatelessWidget {
|
|||||||
return IndentScaffold(
|
return IndentScaffold(
|
||||||
title: AppLocalizations.of(context)!.account,
|
title: AppLocalizations.of(context)!.account,
|
||||||
noSafeArea: true,
|
noSafeArea: true,
|
||||||
fixedAppBarColor: true,
|
fixedAppBarColor: SolianTheme.isLargeScreen(context),
|
||||||
child: AccountScreenWidget(
|
child: AccountScreenWidget(
|
||||||
onSelect: (item) {
|
onSelect: (item) {
|
||||||
SolianRouter.router.pushNamed(item);
|
SolianRouter.router.pushNamed(item);
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
import 'package:solian/utils/service_url.dart';
|
import 'package:solian/utils/service_url.dart';
|
||||||
|
import 'package:solian/widgets/account/account_avatar.dart';
|
||||||
import 'package:solian/widgets/exts.dart';
|
import 'package:solian/widgets/exts.dart';
|
||||||
import 'package:solian/widgets/scaffold.dart';
|
import 'package:solian/widgets/scaffold.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
@ -31,6 +35,8 @@ class PersonalizeScreenWidget extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PersonalizeScreenWidgetState extends State<PersonalizeScreenWidget> {
|
class _PersonalizeScreenWidgetState extends State<PersonalizeScreenWidget> {
|
||||||
|
final _imagePicker = ImagePicker();
|
||||||
|
|
||||||
final _usernameController = TextEditingController();
|
final _usernameController = TextEditingController();
|
||||||
final _nicknameController = TextEditingController();
|
final _nicknameController = TextEditingController();
|
||||||
final _firstNameController = TextEditingController();
|
final _firstNameController = TextEditingController();
|
||||||
@ -38,6 +44,8 @@ class _PersonalizeScreenWidgetState extends State<PersonalizeScreenWidget> {
|
|||||||
final _descriptionController = TextEditingController();
|
final _descriptionController = TextEditingController();
|
||||||
final _birthdayController = TextEditingController();
|
final _birthdayController = TextEditingController();
|
||||||
|
|
||||||
|
String? _avatar;
|
||||||
|
String? _banner;
|
||||||
DateTime? _birthday;
|
DateTime? _birthday;
|
||||||
|
|
||||||
bool _isSubmitting = false;
|
bool _isSubmitting = false;
|
||||||
@ -65,6 +73,12 @@ class _PersonalizeScreenWidgetState extends State<PersonalizeScreenWidget> {
|
|||||||
_descriptionController.text = prof['description'];
|
_descriptionController.text = prof['description'];
|
||||||
_firstNameController.text = prof['profile']['first_name'];
|
_firstNameController.text = prof['profile']['first_name'];
|
||||||
_lastNameController.text = prof['profile']['last_name'];
|
_lastNameController.text = prof['profile']['last_name'];
|
||||||
|
if (prof['avatar'] != null && prof['avatar'].isNotEmpty) {
|
||||||
|
_avatar = getRequestUri('passport', '/api/avatar/${prof['avatar']}').toString();
|
||||||
|
}
|
||||||
|
if (prof['banner'] != null && prof['banner'].isNotEmpty) {
|
||||||
|
_banner = getRequestUri('passport', '/api/avatar/${prof['banner']}').toString();
|
||||||
|
}
|
||||||
if (prof['profile']['birthday'] != null) {
|
if (prof['profile']['birthday'] != null) {
|
||||||
_birthday = DateTime.parse(prof['profile']['birthday']);
|
_birthday = DateTime.parse(prof['profile']['birthday']);
|
||||||
_birthdayController.text = DateFormat('yyyy-MM-dd hh:mm').format(_birthday!);
|
_birthdayController.text = DateFormat('yyyy-MM-dd hh:mm').format(_birthday!);
|
||||||
@ -93,7 +107,9 @@ class _PersonalizeScreenWidgetState extends State<PersonalizeScreenWidget> {
|
|||||||
);
|
);
|
||||||
if (res.statusCode == 200) {
|
if (res.statusCode == 200) {
|
||||||
await auth.fetchProfiles();
|
await auth.fetchProfiles();
|
||||||
resetInputs();
|
setState(() {
|
||||||
|
resetInputs();
|
||||||
|
});
|
||||||
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
content: Text(AppLocalizations.of(context)!.personalizeApplied),
|
content: Text(AppLocalizations.of(context)!.personalizeApplied),
|
||||||
@ -106,20 +122,115 @@ class _PersonalizeScreenWidgetState extends State<PersonalizeScreenWidget> {
|
|||||||
setState(() => _isSubmitting = false);
|
setState(() => _isSubmitting = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> applyAvatar(String position) async {
|
||||||
|
final auth = context.read<AuthProvider>();
|
||||||
|
if (!await auth.isAuthorized()) return;
|
||||||
|
|
||||||
|
final image = await _imagePicker.pickImage(source: ImageSource.gallery);
|
||||||
|
if (image == null) return;
|
||||||
|
|
||||||
|
setState(() => _isSubmitting = true);
|
||||||
|
|
||||||
|
final file = File(image.path);
|
||||||
|
try {
|
||||||
|
final req = MultipartRequest('PUT', getRequestUri('passport', '/api/users/me/$position'));
|
||||||
|
req.files.add(await MultipartFile.fromPath(position, file.path));
|
||||||
|
|
||||||
|
var res = await auth.client!.send(req);
|
||||||
|
if (res.statusCode == 200) {
|
||||||
|
await auth.fetchProfiles();
|
||||||
|
setState(() {
|
||||||
|
resetInputs();
|
||||||
|
});
|
||||||
|
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||||
|
content: Text(AppLocalizations.of(context)!.personalizeApplied),
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
throw Exception(utf8.decode(await res.stream.toBytes()));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
context.showErrorDialog(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() => _isSubmitting = false);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
Future.delayed(Duration.zero, () => resetInputs());
|
Future.delayed(Duration.zero, () {
|
||||||
|
setState(() {
|
||||||
|
resetInputs();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 28, horizontal: 32),
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||||
child: Column(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
_isSubmitting ? const LinearProgressIndicator().animate().scaleX() : Container(),
|
_isSubmitting ? const LinearProgressIndicator().animate().scaleX() : Container(),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
AccountAvatar(source: _avatar ?? '', radius: 40, direct: true),
|
||||||
|
Positioned(
|
||||||
|
bottom: 0,
|
||||||
|
left: 40,
|
||||||
|
child: FloatingActionButton.small(
|
||||||
|
onPressed: () => applyAvatar('avatar'),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.camera,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
ClipRRect(
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||||
|
child: AspectRatio(
|
||||||
|
aspectRatio: 16 / 9,
|
||||||
|
child: Container(
|
||||||
|
color: Theme.of(context).colorScheme.surfaceVariant,
|
||||||
|
child: _banner != null
|
||||||
|
? Image.network(
|
||||||
|
_banner!,
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
|
||||||
|
if (loadingProgress == null) return child;
|
||||||
|
return Center(
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
value: loadingProgress.expectedTotalBytes != null
|
||||||
|
? loadingProgress.cumulativeBytesLoaded / loadingProgress.expectedTotalBytes!
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: 16,
|
||||||
|
right: 16,
|
||||||
|
child: FloatingActionButton(
|
||||||
|
onPressed: () => applyAvatar('banner'),
|
||||||
|
child: const Icon(
|
||||||
|
Icons.camera_alt,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 24),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Flexible(
|
Flexible(
|
||||||
|
@ -63,7 +63,7 @@ class _ChatDetailScreenState extends State<ChatDetailScreen> {
|
|||||||
];
|
];
|
||||||
|
|
||||||
return IndentScaffold(
|
return IndentScaffold(
|
||||||
title: AppLocalizations.of(context)!.chatManage,
|
title: AppLocalizations.of(context)!.chatDetail,
|
||||||
hideDrawer: true,
|
hideDrawer: true,
|
||||||
noSafeArea: true,
|
noSafeArea: true,
|
||||||
child: Column(
|
child: Column(
|
||||||
|
9
lib/utils/file.dart
Normal file
9
lib/utils/file.dart
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:crypto/crypto.dart';
|
||||||
|
|
||||||
|
Future<String> calculateFileSha256(File file) async {
|
||||||
|
final bytes = await file.readAsBytes();
|
||||||
|
final digest = sha256.convert(bytes);
|
||||||
|
return digest.toString();
|
||||||
|
}
|
@ -2,7 +2,6 @@ import 'dart:convert';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import 'package:crypto/crypto.dart';
|
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
@ -11,6 +10,7 @@ import 'package:image_picker/image_picker.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:solian/models/post.dart';
|
import 'package:solian/models/post.dart';
|
||||||
import 'package:solian/providers/auth.dart';
|
import 'package:solian/providers/auth.dart';
|
||||||
|
import 'package:solian/utils/file.dart';
|
||||||
import 'package:solian/utils/service_url.dart';
|
import 'package:solian/utils/service_url.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:solian/widgets/exts.dart';
|
import 'package:solian/widgets/exts.dart';
|
||||||
@ -62,7 +62,7 @@ class _AttachmentEditorState extends State<AttachmentEditor> {
|
|||||||
bool isPopped = false;
|
bool isPopped = false;
|
||||||
for (final media in medias) {
|
for (final media in medias) {
|
||||||
final file = File(media.path);
|
final file = File(media.path);
|
||||||
final hashcode = await calculateSha256(file);
|
final hashcode = await calculateFileSha256(file);
|
||||||
try {
|
try {
|
||||||
await uploadAttachment(file, hashcode);
|
await uploadAttachment(file, hashcode);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -90,7 +90,7 @@ class _AttachmentEditorState extends State<AttachmentEditor> {
|
|||||||
|
|
||||||
bool isPopped = false;
|
bool isPopped = false;
|
||||||
for (final file in files) {
|
for (final file in files) {
|
||||||
final hashcode = await calculateSha256(file);
|
final hashcode = await calculateFileSha256(file);
|
||||||
try {
|
try {
|
||||||
await uploadAttachment(file, hashcode);
|
await uploadAttachment(file, hashcode);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -120,7 +120,7 @@ class _AttachmentEditorState extends State<AttachmentEditor> {
|
|||||||
setState(() => _isSubmitting = true);
|
setState(() => _isSubmitting = true);
|
||||||
|
|
||||||
final file = File(media.path);
|
final file = File(media.path);
|
||||||
final hashcode = await calculateSha256(file);
|
final hashcode = await calculateFileSha256(file);
|
||||||
|
|
||||||
if (Navigator.canPop(context)) {
|
if (Navigator.canPop(context)) {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
@ -171,12 +171,6 @@ class _AttachmentEditorState extends State<AttachmentEditor> {
|
|||||||
setState(() => _isSubmitting = false);
|
setState(() => _isSubmitting = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> calculateSha256(File file) async {
|
|
||||||
final bytes = await file.readAsBytes();
|
|
||||||
final digest = sha256.convert(bytes);
|
|
||||||
return digest.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
String getFileName(Attachment item) {
|
String getFileName(Attachment item) {
|
||||||
return item.filename.replaceAll(RegExp(r'\.[^/.]+$'), '');
|
return item.filename.replaceAll(RegExp(r'\.[^/.]+$'), '');
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@ PODS:
|
|||||||
- connectivity_plus (0.0.1):
|
- connectivity_plus (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- desktop_drop (0.0.1):
|
||||||
|
- FlutterMacOS
|
||||||
- device_info_plus (0.0.1):
|
- device_info_plus (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- file_selector_macos (0.0.1):
|
- file_selector_macos (0.0.1):
|
||||||
@ -30,6 +32,9 @@ PODS:
|
|||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- screen_brightness_macos (0.1.0):
|
- screen_brightness_macos (0.1.0):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
|
- sqflite (0.0.3):
|
||||||
|
- Flutter
|
||||||
|
- FlutterMacOS
|
||||||
- url_launcher_macos (0.0.1):
|
- url_launcher_macos (0.0.1):
|
||||||
- FlutterMacOS
|
- FlutterMacOS
|
||||||
- wakelock_plus (0.0.1):
|
- wakelock_plus (0.0.1):
|
||||||
@ -38,6 +43,7 @@ PODS:
|
|||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin`)
|
- connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin`)
|
||||||
|
- desktop_drop (from `Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos`)
|
||||||
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
|
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
|
||||||
- file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`)
|
- file_selector_macos (from `Flutter/ephemeral/.symlinks/plugins/file_selector_macos/macos`)
|
||||||
- flutter_local_notifications (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos`)
|
- flutter_local_notifications (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_notifications/macos`)
|
||||||
@ -51,6 +57,7 @@ DEPENDENCIES:
|
|||||||
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
||||||
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- screen_brightness_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos`)
|
- screen_brightness_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos`)
|
||||||
|
- sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/darwin`)
|
||||||
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||||
- wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
|
- wakelock_plus (from `Flutter/ephemeral/.symlinks/plugins/wakelock_plus/macos`)
|
||||||
|
|
||||||
@ -61,6 +68,8 @@ SPEC REPOS:
|
|||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
connectivity_plus:
|
connectivity_plus:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin
|
:path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/darwin
|
||||||
|
desktop_drop:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/desktop_drop/macos
|
||||||
device_info_plus:
|
device_info_plus:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
|
||||||
file_selector_macos:
|
file_selector_macos:
|
||||||
@ -87,6 +96,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
|
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
|
||||||
screen_brightness_macos:
|
screen_brightness_macos:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/screen_brightness_macos/macos
|
||||||
|
sqflite:
|
||||||
|
:path: Flutter/ephemeral/.symlinks/plugins/sqflite/darwin
|
||||||
url_launcher_macos:
|
url_launcher_macos:
|
||||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||||
wakelock_plus:
|
wakelock_plus:
|
||||||
@ -94,6 +105,7 @@ EXTERNAL SOURCES:
|
|||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
|
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
|
||||||
|
desktop_drop: 69eeff437544aa619c8db7f4481b3a65f7696898
|
||||||
device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720
|
device_info_plus: ce1b7762849d3ec103d0e0517299f2db7ad60720
|
||||||
file_selector_macos: 468fb6b81fac7c0e88d71317f3eec34c3b008ff9
|
file_selector_macos: 468fb6b81fac7c0e88d71317f3eec34c3b008ff9
|
||||||
flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4
|
flutter_local_notifications: 3805ca215b2fb7f397d78b66db91f6a747af52e4
|
||||||
@ -107,6 +119,7 @@ SPEC CHECKSUMS:
|
|||||||
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
|
package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c
|
||||||
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
|
||||||
screen_brightness_macos: 2d6d3af2165592d9a55ffcd95b7550970e41ebda
|
screen_brightness_macos: 2d6d3af2165592d9a55ffcd95b7550970e41ebda
|
||||||
|
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec
|
||||||
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
|
url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95
|
||||||
wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
|
wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269
|
||||||
WebRTC-SDK: efc3e67e0355b1ee14bfe3c91188cada6000cb94
|
WebRTC-SDK: efc3e67e0355b1ee14bfe3c91188cada6000cb94
|
||||||
|
Loading…
Reference in New Issue
Block a user