✨ Drag to upload
This commit is contained in:
parent
85bba21285
commit
e336d2372a
@ -30,6 +30,13 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<provider
|
||||
android:name="com.superlist.super_native_extensions.DataProvider"
|
||||
android:authorities="dev.solsynth.solian.SuperClipboardDataProvider"
|
||||
android:exported="true"
|
||||
android:grantUriPermissions="true" >
|
||||
</provider>
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
|
@ -33,7 +33,9 @@ void main() async {
|
||||
appRunner: () async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
await protocolHandler.register('solink');
|
||||
if (!PlatformInfo.isWeb) {
|
||||
await protocolHandler.register('solink');
|
||||
}
|
||||
|
||||
await Firebase.initializeApp(
|
||||
options: DefaultFirebaseOptions.currentPlatform,
|
||||
|
@ -179,7 +179,7 @@ class AccountProvider extends GetxController {
|
||||
|
||||
Future<void> registerPushNotifications() async {
|
||||
final AuthProvider auth = Get.find();
|
||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||
if (!await auth.isAuthorized) return;
|
||||
|
||||
late final String? token;
|
||||
late final String provider;
|
||||
|
@ -1,21 +1,40 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:path/path.dart';
|
||||
import 'package:solian/platform.dart';
|
||||
import 'package:solian/providers/auth.dart';
|
||||
import 'package:solian/services.dart';
|
||||
import 'package:image/image.dart' as img;
|
||||
|
||||
Future<String> calculateFileSha256(File file) async {
|
||||
final bytes = await Isolate.run(() => file.readAsBytesSync());
|
||||
final digest = await Isolate.run(() => sha256.convert(bytes));
|
||||
Future<String> calculateBytesSha256(Uint8List data) async {
|
||||
Digest digest;
|
||||
if (PlatformInfo.isWeb) {
|
||||
digest = sha256.convert(data);
|
||||
} else {
|
||||
digest = await Isolate.run(() => sha256.convert(data));
|
||||
}
|
||||
return digest.toString();
|
||||
}
|
||||
|
||||
Future<String> calculateFileSha256(File file) async {
|
||||
Uint8List bytes;
|
||||
if (PlatformInfo.isWeb) {
|
||||
bytes = await file.readAsBytes();
|
||||
} else {
|
||||
bytes = await Isolate.run(() => file.readAsBytesSync());
|
||||
}
|
||||
return await calculateBytesSha256(bytes);
|
||||
}
|
||||
|
||||
Future<double> calculateFileAspectRatio(File file) async {
|
||||
if (PlatformInfo.isWeb) {
|
||||
return 1;
|
||||
}
|
||||
final bytes = await Isolate.run(() => file.readAsBytesSync());
|
||||
final decoder = await Isolate.run(() => img.findDecoderForData(bytes));
|
||||
if (decoder == null) return 1;
|
||||
@ -25,7 +44,10 @@ Future<double> calculateFileAspectRatio(File file) async {
|
||||
}
|
||||
|
||||
class AttachmentProvider extends GetConnect {
|
||||
static Map<String, String> mimetypeOverrides = {'mov': 'video/quicktime'};
|
||||
static Map<String, String> mimetypeOverrides = {
|
||||
'mov': 'video/quicktime',
|
||||
'mp4': 'video/mp4'
|
||||
};
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
@ -45,7 +67,8 @@ class AttachmentProvider extends GetConnect {
|
||||
return resp;
|
||||
}
|
||||
|
||||
Future<Response> createAttachment(File file, String hash, String usage,
|
||||
Future<Response> createAttachment(
|
||||
Uint8List data, String path, String hash, String usage,
|
||||
{double? ratio}) async {
|
||||
final AuthProvider auth = Get.find();
|
||||
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
||||
@ -55,13 +78,12 @@ class AttachmentProvider extends GetConnect {
|
||||
timeout: const Duration(minutes: 3),
|
||||
);
|
||||
|
||||
final filePayload =
|
||||
MultipartFile(await file.readAsBytes(), filename: basename(file.path));
|
||||
final fileAlt = basename(file.path).contains('.')
|
||||
? basename(file.path).substring(0, basename(file.path).lastIndexOf('.'))
|
||||
: basename(file.path);
|
||||
final fileExt = basename(file.path)
|
||||
.substring(basename(file.path).lastIndexOf('.') + 1)
|
||||
final filePayload = MultipartFile(data, filename: basename(path));
|
||||
final fileAlt = basename(path).contains('.')
|
||||
? basename(path).substring(0, basename(path).lastIndexOf('.'))
|
||||
: basename(path);
|
||||
final fileExt = basename(path)
|
||||
.substring(basename(path).lastIndexOf('.') + 1)
|
||||
.toLowerCase();
|
||||
|
||||
// Override for some files cannot be detected mimetype by server-side
|
||||
|
@ -88,7 +88,8 @@ class _PersonalizeScreenState extends State<PersonalizeScreen> {
|
||||
final file = File(image.path);
|
||||
final hash = await calculateFileSha256(file);
|
||||
attachResp = await provider.createAttachment(
|
||||
file,
|
||||
await file.readAsBytes(),
|
||||
file.path,
|
||||
hash,
|
||||
'p.$position',
|
||||
ratio: await calculateFileAspectRatio(file),
|
||||
|
@ -178,12 +178,6 @@ class _AttachmentListState extends State<AttachmentList> {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getMetadataList();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.attachmentsId.isEmpty) {
|
||||
@ -236,7 +230,8 @@ class _AttachmentListState extends State<AttachmentList> {
|
||||
const radius = BorderRadius.all(Radius.circular(16));
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Theme.of(context).dividerColor, width: 1),
|
||||
border:
|
||||
Border.all(color: Theme.of(context).dividerColor, width: 1),
|
||||
borderRadius: radius,
|
||||
),
|
||||
child: ClipRRect(
|
||||
|
@ -1,6 +1,10 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:isolate';
|
||||
import 'dart:math' as math;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_animate/flutter_animate.dart';
|
||||
@ -10,6 +14,7 @@ import 'package:solian/exts.dart';
|
||||
import 'package:solian/models/attachment.dart';
|
||||
import 'package:solian/providers/auth.dart';
|
||||
import 'package:solian/providers/content/attachment.dart';
|
||||
import 'package:super_drag_and_drop/super_drag_and_drop.dart';
|
||||
|
||||
class AttachmentPublishPopup extends StatefulWidget {
|
||||
final String usage;
|
||||
@ -24,8 +29,7 @@ class AttachmentPublishPopup extends StatefulWidget {
|
||||
});
|
||||
|
||||
@override
|
||||
State<AttachmentPublishPopup> createState() =>
|
||||
_AttachmentPublishPopupState();
|
||||
State<AttachmentPublishPopup> createState() => _AttachmentPublishPopupState();
|
||||
}
|
||||
|
||||
class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
||||
@ -51,7 +55,8 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
||||
|
||||
try {
|
||||
await uploadAttachment(
|
||||
file,
|
||||
await file.readAsBytes(),
|
||||
file.path,
|
||||
hash,
|
||||
ratio: await calculateFileAspectRatio(file),
|
||||
);
|
||||
@ -77,7 +82,8 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
||||
const ratio = 16 / 9;
|
||||
|
||||
try {
|
||||
await uploadAttachment(file, hash, ratio: ratio);
|
||||
await uploadAttachment(await file.readAsBytes(), file.path, hash,
|
||||
ratio: ratio);
|
||||
} catch (err) {
|
||||
context.showErrorDialog(err);
|
||||
}
|
||||
@ -100,7 +106,7 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
||||
for (final file in files) {
|
||||
final hash = await calculateFileSha256(file);
|
||||
try {
|
||||
await uploadAttachment(file, hash);
|
||||
await uploadAttachment(await file.readAsBytes(), file.path, hash);
|
||||
} catch (err) {
|
||||
context.showErrorDialog(err);
|
||||
}
|
||||
@ -134,7 +140,12 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
||||
}
|
||||
|
||||
try {
|
||||
await uploadAttachment(file, hash, ratio: ratio);
|
||||
await uploadAttachment(
|
||||
await file.readAsBytes(),
|
||||
file.path,
|
||||
hash,
|
||||
ratio: ratio,
|
||||
);
|
||||
} catch (err) {
|
||||
context.showErrorDialog(err);
|
||||
}
|
||||
@ -142,11 +153,13 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
||||
setState(() => _isBusy = false);
|
||||
}
|
||||
|
||||
Future<void> uploadAttachment(File file, String hash, {double? ratio}) async {
|
||||
Future<void> uploadAttachment(Uint8List data, String path, String hash,
|
||||
{double? ratio}) async {
|
||||
final AttachmentProvider provider = Get.find();
|
||||
try {
|
||||
final resp = await provider.createAttachment(
|
||||
file,
|
||||
data,
|
||||
path,
|
||||
hash,
|
||||
widget.usage,
|
||||
ratio: ratio,
|
||||
@ -208,10 +221,14 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
revertMetadataList();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const density = VisualDensity(horizontal: 0, vertical: 0);
|
||||
@ -219,134 +236,165 @@ class _AttachmentPublishPopupState extends State<AttachmentPublishPopup> {
|
||||
return SafeArea(
|
||||
child: SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.85,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'attachmentAdd'.tr,
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
).paddingOnly(left: 24, right: 24, top: 32, bottom: 16),
|
||||
if (_isBusy) const LinearProgressIndicator().animate().scaleX(),
|
||||
Expanded(
|
||||
child: Builder(builder: (context) {
|
||||
if (_isFirstTimeBusy && _isBusy) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
itemCount: _attachments.length,
|
||||
itemBuilder: (context, index) {
|
||||
final element = _attachments[index];
|
||||
var fileType = element!.mimetype.split('/').firstOrNull;
|
||||
fileType ??= 'unknown';
|
||||
return Container(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 16, right: 8, bottom: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
element.alt,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
'${fileType[0].toUpperCase()}${fileType.substring(1)} · ${formatBytes(element.size)}',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
style: TextButton.styleFrom(
|
||||
shape: const CircleBorder(),
|
||||
foregroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
icon: const Icon(Icons.more_horiz),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AttachmentEditorDialog(
|
||||
item: element,
|
||||
onDelete: () {
|
||||
setState(
|
||||
() => _attachments.removeAt(index));
|
||||
widget.onUpdate(_attachments
|
||||
.map((e) => e!.id)
|
||||
.toList());
|
||||
},
|
||||
onUpdate: (item) {
|
||||
setState(
|
||||
() => _attachments[index] = item);
|
||||
widget.onUpdate(_attachments
|
||||
.map((e) => e!.id)
|
||||
.toList());
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
child: DropRegion(
|
||||
formats: Formats.standardFormats,
|
||||
hitTestBehavior: HitTestBehavior.opaque,
|
||||
onDropOver: (event) {
|
||||
if (event.session.allowedOperations.contains(DropOperation.copy)) {
|
||||
return DropOperation.copy;
|
||||
} else {
|
||||
return DropOperation.none;
|
||||
}
|
||||
},
|
||||
onPerformDrop: (event) async {
|
||||
for (final item in event.session.items) {
|
||||
final reader = item.dataReader!;
|
||||
for (final format
|
||||
in Formats.standardFormats.whereType<FileFormat>()) {
|
||||
if (reader.canProvide(format)) {
|
||||
reader.getFile(format, (file) async {
|
||||
final data = await file.readAll();
|
||||
await uploadAttachment(
|
||||
data,
|
||||
file.fileName ?? 'attachment',
|
||||
await calculateBytesSha256(data),
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
const Divider(thickness: 0.3, height: 0.3),
|
||||
SizedBox(
|
||||
height: 64,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 0,
|
||||
alignment: WrapAlignment.center,
|
||||
runAlignment: WrapAlignment.center,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.add_photo_alternate),
|
||||
label: Text('attachmentAddGalleryPhoto'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => pickPhotoToUpload(),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.add_road),
|
||||
label: Text('attachmentAddGalleryVideo'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => pickVideoToUpload(),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.photo_camera_back),
|
||||
label: Text('attachmentAddCameraPhoto'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => takeMediaToUpload(false),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.video_camera_back_outlined),
|
||||
label: Text('attachmentAddCameraVideo'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => takeMediaToUpload(true),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.file_present_rounded),
|
||||
label: Text('attachmentAddFile'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => pickFileToUpload(),
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(horizontal: 12),
|
||||
}, onError: (error) {
|
||||
print('Error reading value $error');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'attachmentAdd'.tr,
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
).paddingOnly(left: 24, right: 24, top: 32, bottom: 16),
|
||||
if (_isBusy) const LinearProgressIndicator().animate().scaleX(),
|
||||
Expanded(
|
||||
child: Builder(builder: (context) {
|
||||
if (_isFirstTimeBusy && _isBusy) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
itemCount: _attachments.length,
|
||||
itemBuilder: (context, index) {
|
||||
final element = _attachments[index];
|
||||
var fileType = element!.mimetype.split('/').firstOrNull;
|
||||
fileType ??= 'unknown';
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 16, right: 8, bottom: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
element.alt,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
'${fileType[0].toUpperCase()}${fileType.substring(1)} · ${formatBytes(element.size)}',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
style: TextButton.styleFrom(
|
||||
shape: const CircleBorder(),
|
||||
foregroundColor: Theme.of(context).primaryColor,
|
||||
),
|
||||
icon: const Icon(Icons.more_horiz),
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AttachmentEditorDialog(
|
||||
item: element,
|
||||
onDelete: () {
|
||||
setState(
|
||||
() => _attachments.removeAt(index));
|
||||
widget.onUpdate(_attachments
|
||||
.map((e) => e!.id)
|
||||
.toList());
|
||||
},
|
||||
onUpdate: (item) {
|
||||
setState(
|
||||
() => _attachments[index] = item);
|
||||
widget.onUpdate(_attachments
|
||||
.map((e) => e!.id)
|
||||
.toList());
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
)
|
||||
],
|
||||
const Divider(thickness: 0.3, height: 0.3),
|
||||
SizedBox(
|
||||
height: 64,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 0,
|
||||
alignment: WrapAlignment.center,
|
||||
runAlignment: WrapAlignment.center,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.add_photo_alternate),
|
||||
label: Text('attachmentAddGalleryPhoto'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => pickPhotoToUpload(),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.add_road),
|
||||
label: Text('attachmentAddGalleryVideo'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => pickVideoToUpload(),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.photo_camera_back),
|
||||
label: Text('attachmentAddCameraPhoto'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => takeMediaToUpload(false),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.video_camera_back_outlined),
|
||||
label: Text('attachmentAddCameraVideo'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => takeMediaToUpload(true),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.file_present_rounded),
|
||||
label: Text('attachmentAddFile'.tr),
|
||||
style: const ButtonStyle(visualDensity: density),
|
||||
onPressed: () => pickFileToUpload(),
|
||||
),
|
||||
],
|
||||
).paddingSymmetric(horizontal: 12),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -365,8 +413,7 @@ class AttachmentEditorDialog extends StatefulWidget {
|
||||
required this.onUpdate});
|
||||
|
||||
@override
|
||||
State<AttachmentEditorDialog> createState() =>
|
||||
_AttachmentEditorDialogState();
|
||||
State<AttachmentEditorDialog> createState() => _AttachmentEditorDialogState();
|
||||
}
|
||||
|
||||
class _AttachmentEditorDialogState extends State<AttachmentEditorDialog> {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_animate/flutter_animate.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:solian/controllers/chat_events_controller.dart';
|
||||
|
@ -10,7 +10,9 @@
|
||||
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
||||
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
||||
#include <flutter_webrtc/flutter_web_r_t_c_plugin.h>
|
||||
#include <irondash_engine_context/irondash_engine_context_plugin.h>
|
||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||
#include <super_native_extensions/super_native_extensions_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
@ -26,9 +28,15 @@ void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) flutter_webrtc_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterWebRTCPlugin");
|
||||
flutter_web_r_t_c_plugin_register_with_registrar(flutter_webrtc_registrar);
|
||||
g_autoptr(FlPluginRegistrar) irondash_engine_context_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "IrondashEngineContextPlugin");
|
||||
irondash_engine_context_plugin_register_with_registrar(irondash_engine_context_registrar);
|
||||
g_autoptr(FlPluginRegistrar) sentry_flutter_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin");
|
||||
sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar);
|
||||
g_autoptr(FlPluginRegistrar) super_native_extensions_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "SuperNativeExtensionsPlugin");
|
||||
super_native_extensions_plugin_register_with_registrar(super_native_extensions_registrar);
|
||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
|
@ -7,7 +7,9 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||
flutter_acrylic
|
||||
flutter_secure_storage_linux
|
||||
flutter_webrtc
|
||||
irondash_engine_context
|
||||
sentry_flutter
|
||||
super_native_extensions
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
|
@ -13,6 +13,7 @@ import firebase_messaging
|
||||
import flutter_local_notifications
|
||||
import flutter_secure_storage_macos
|
||||
import flutter_webrtc
|
||||
import irondash_engine_context
|
||||
import livekit_client
|
||||
import macos_window_utils
|
||||
import package_info_plus
|
||||
@ -21,6 +22,7 @@ import protocol_handler_macos
|
||||
import sentry_flutter
|
||||
import shared_preferences_foundation
|
||||
import sqflite
|
||||
import super_native_extensions
|
||||
import url_launcher_macos
|
||||
import video_player_avfoundation
|
||||
import wakelock_plus
|
||||
@ -34,6 +36,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||
FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin"))
|
||||
IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin"))
|
||||
LiveKitPlugin.register(with: registry.registrar(forPlugin: "LiveKitPlugin"))
|
||||
MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
@ -42,6 +45,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
|
||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||
|
48
pubspec.lock
48
pubspec.lock
@ -824,6 +824,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
irondash_engine_context:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: irondash_engine_context
|
||||
sha256: cd7b769db11a2b5243b037c8a9b1ecaef02e1ae27a2d909ffa78c1dad747bb10
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.4"
|
||||
irondash_message_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: irondash_message_channel
|
||||
sha256: b4101669776509c76133b8917ab8cfc704d3ad92a8c450b92934dd8884a2f060
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.0"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1104,6 +1120,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.2"
|
||||
pixel_snap:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pixel_snap
|
||||
sha256: "677410ea37b07cd37ecb6d5e6c0d8d7615a7cf3bd92ba406fd1ac57e937d1fb0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1453,6 +1477,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
super_clipboard:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: super_clipboard
|
||||
sha256: cdab725bac26655ebd189f4d202d694a8cbc1c21e0f0478ccd7829c71716f09b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.17"
|
||||
super_drag_and_drop:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: super_drag_and_drop
|
||||
sha256: "8e00c6082646076f80b972b39d9c27b5311082ea1e8add5fa370ce11c410f7de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.17"
|
||||
super_native_extensions:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: super_native_extensions
|
||||
sha256: fa55d452d34b7112453afbb9fa4d13c0527ff201630d10d86546497179030544
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.17"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -51,6 +51,7 @@ dependencies:
|
||||
sqflite: ^2.3.3+1
|
||||
protocol_handler: ^0.2.0
|
||||
markdown: ^7.2.2
|
||||
super_drag_and_drop: ^0.8.17
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -12,10 +12,12 @@
|
||||
#include <flutter_acrylic/flutter_acrylic_plugin.h>
|
||||
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||
#include <flutter_webrtc/flutter_web_r_t_c_plugin.h>
|
||||
#include <irondash_engine_context/irondash_engine_context_plugin_c_api.h>
|
||||
#include <livekit_client/live_kit_plugin.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <protocol_handler_windows/protocol_handler_windows_plugin_c_api.h>
|
||||
#include <sentry_flutter/sentry_flutter_plugin.h>
|
||||
#include <super_native_extensions/super_native_extensions_plugin_c_api.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
#include <video_player_win/video_player_win_plugin_c_api.h>
|
||||
|
||||
@ -32,6 +34,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
|
||||
FlutterWebRTCPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FlutterWebRTCPlugin"));
|
||||
IrondashEngineContextPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("IrondashEngineContextPluginCApi"));
|
||||
LiveKitPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("LiveKitPlugin"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
@ -40,6 +44,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("ProtocolHandlerWindowsPluginCApi"));
|
||||
SentryFlutterPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("SentryFlutterPlugin"));
|
||||
SuperNativeExtensionsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("SuperNativeExtensionsPluginCApi"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
VideoPlayerWinPluginCApiRegisterWithRegistrar(
|
||||
|
@ -9,10 +9,12 @@ list(APPEND FLUTTER_PLUGIN_LIST
|
||||
flutter_acrylic
|
||||
flutter_secure_storage_windows
|
||||
flutter_webrtc
|
||||
irondash_engine_context
|
||||
livekit_client
|
||||
permission_handler_windows
|
||||
protocol_handler_windows
|
||||
sentry_flutter
|
||||
super_native_extensions
|
||||
url_launcher_windows
|
||||
video_player_win
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user