✨ Setting of attachment thumbnail
This commit is contained in:
parent
1210cda998
commit
c5a975b5ed
@ -1,6 +1,4 @@
|
||||
PODS:
|
||||
- audio_session (0.0.1):
|
||||
- Flutter
|
||||
- connectivity_plus (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
@ -223,11 +221,15 @@ PODS:
|
||||
- TOCropViewController (~> 2.7.4)
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- just_audio (0.0.1):
|
||||
- Flutter
|
||||
- livekit_client (2.2.4):
|
||||
- Flutter
|
||||
- WebRTC-SDK (= 125.6422.04)
|
||||
- media_kit_libs_ios_video (1.0.4):
|
||||
- Flutter
|
||||
- media_kit_native_event_loop (1.0.0):
|
||||
- Flutter
|
||||
- media_kit_video (0.0.1):
|
||||
- Flutter
|
||||
- nanopb (3.30910.0):
|
||||
- nanopb/decode (= 3.30910.0)
|
||||
- nanopb/encode (= 3.30910.0)
|
||||
@ -249,6 +251,8 @@ PODS:
|
||||
- PromisesObjC (= 2.4.0)
|
||||
- protocol_handler_ios (0.0.1):
|
||||
- Flutter
|
||||
- screen_brightness_ios (0.1.0):
|
||||
- Flutter
|
||||
- SDWebImage (5.19.7):
|
||||
- SDWebImage/Core (= 5.19.7)
|
||||
- SDWebImage/Core (5.19.7)
|
||||
@ -264,15 +268,13 @@ PODS:
|
||||
- TOCropViewController (2.7.4)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
- video_player_avfoundation (0.0.1):
|
||||
- volume_controller (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- wakelock_plus (0.0.1):
|
||||
- Flutter
|
||||
- WebRTC-SDK (125.6422.04)
|
||||
|
||||
DEPENDENCIES:
|
||||
- audio_session (from `.symlinks/plugins/audio_session/ios`)
|
||||
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/darwin`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||
@ -289,19 +291,22 @@ DEPENDENCIES:
|
||||
- gal (from `.symlinks/plugins/gal/darwin`)
|
||||
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- just_audio (from `.symlinks/plugins/just_audio/ios`)
|
||||
- livekit_client (from `.symlinks/plugins/livekit_client/ios`)
|
||||
- media_kit_libs_ios_video (from `.symlinks/plugins/media_kit_libs_ios_video/ios`)
|
||||
- media_kit_native_event_loop (from `.symlinks/plugins/media_kit_native_event_loop/ios`)
|
||||
- media_kit_video (from `.symlinks/plugins/media_kit_video/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- pasteboard (from `.symlinks/plugins/pasteboard/ios`)
|
||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||
- pointer_interceptor_ios (from `.symlinks/plugins/pointer_interceptor_ios/ios`)
|
||||
- protocol_handler_ios (from `.symlinks/plugins/protocol_handler_ios/ios`)
|
||||
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
|
||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/darwin`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
|
||||
- volume_controller (from `.symlinks/plugins/volume_controller/ios`)
|
||||
- wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
@ -334,8 +339,6 @@ SPEC REPOS:
|
||||
- WebRTC-SDK
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
audio_session:
|
||||
:path: ".symlinks/plugins/audio_session/ios"
|
||||
connectivity_plus:
|
||||
:path: ".symlinks/plugins/connectivity_plus/darwin"
|
||||
device_info_plus:
|
||||
@ -368,10 +371,14 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/image_cropper/ios"
|
||||
image_picker_ios:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
just_audio:
|
||||
:path: ".symlinks/plugins/just_audio/ios"
|
||||
livekit_client:
|
||||
:path: ".symlinks/plugins/livekit_client/ios"
|
||||
media_kit_libs_ios_video:
|
||||
:path: ".symlinks/plugins/media_kit_libs_ios_video/ios"
|
||||
media_kit_native_event_loop:
|
||||
:path: ".symlinks/plugins/media_kit_native_event_loop/ios"
|
||||
media_kit_video:
|
||||
:path: ".symlinks/plugins/media_kit_video/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
pasteboard:
|
||||
@ -384,6 +391,8 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/pointer_interceptor_ios/ios"
|
||||
protocol_handler_ios:
|
||||
:path: ".symlinks/plugins/protocol_handler_ios/ios"
|
||||
screen_brightness_ios:
|
||||
:path: ".symlinks/plugins/screen_brightness_ios/ios"
|
||||
share_plus:
|
||||
:path: ".symlinks/plugins/share_plus/ios"
|
||||
shared_preferences_foundation:
|
||||
@ -392,13 +401,12 @@ EXTERNAL SOURCES:
|
||||
:path: ".symlinks/plugins/sqflite/darwin"
|
||||
url_launcher_ios:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
video_player_avfoundation:
|
||||
:path: ".symlinks/plugins/video_player_avfoundation/darwin"
|
||||
volume_controller:
|
||||
:path: ".symlinks/plugins/volume_controller/ios"
|
||||
wakelock_plus:
|
||||
:path: ".symlinks/plugins/wakelock_plus/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
audio_session: 088d2483ebd1dc43f51d253d4a1c517d9a2e7207
|
||||
connectivity_plus: ddd7f30999e1faaef5967c23d5b6d503d10434db
|
||||
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d
|
||||
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
|
||||
@ -434,8 +442,10 @@ SPEC CHECKSUMS:
|
||||
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
|
||||
image_cropper: 37d40f62177c101ff4c164906d259ea2c3aa70cf
|
||||
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1
|
||||
just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
|
||||
livekit_client: d079c5f040d4bf2b80440ff0ae997725a183e4bc
|
||||
media_kit_libs_ios_video: a5fe24bc7875ccd6378a0978c13185e1344651c1
|
||||
media_kit_native_event_loop: e6b2ab20cf0746eb1c33be961fcf79667304fa2a
|
||||
media_kit_video: 5da63f157170e5bf303bf85453b7ef6971218a2e
|
||||
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
|
||||
package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
|
||||
pasteboard: 982969ebaa7c78af3e6cc7761e8f5e77565d9ce0
|
||||
@ -445,6 +455,7 @@ SPEC CHECKSUMS:
|
||||
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
|
||||
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
|
||||
protocol_handler_ios: a5db8abc38526ee326988b808be621e5fd568990
|
||||
screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625
|
||||
SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3
|
||||
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
|
||||
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
|
||||
@ -452,7 +463,7 @@ SPEC CHECKSUMS:
|
||||
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
|
||||
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
|
||||
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
|
||||
video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
|
||||
volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9
|
||||
wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1
|
||||
WebRTC-SDK: c3d69a87e7185fad3568f6f3cff7c9ac5890acf3
|
||||
|
||||
|
@ -192,6 +192,7 @@ class AttachmentProvider extends GetConnect {
|
||||
Future<Response> updateAttachment(
|
||||
int id,
|
||||
String alt, {
|
||||
required Map<String, dynamic> metadata,
|
||||
bool isMature = false,
|
||||
}) async {
|
||||
final AuthProvider auth = Get.find();
|
||||
@ -201,6 +202,7 @@ class AttachmentProvider extends GetConnect {
|
||||
|
||||
var resp = await client.put('/attachments/$id', {
|
||||
'alt': alt,
|
||||
'metadata': metadata,
|
||||
'is_mature': isMature,
|
||||
});
|
||||
|
||||
|
@ -37,6 +37,7 @@ class _AttachmentAttrEditorDialogState
|
||||
widget.item.id,
|
||||
_altController.value.text,
|
||||
isMature: _isMature,
|
||||
metadata: widget.item.metadata ?? {},
|
||||
);
|
||||
|
||||
Get.find<AttachmentProvider>().clearCache(id: widget.item.rid);
|
||||
|
@ -20,6 +20,7 @@ import 'package:solian/providers/attachment_uploader.dart';
|
||||
import 'package:solian/providers/auth.dart';
|
||||
import 'package:solian/providers/content/attachment.dart';
|
||||
import 'package:solian/widgets/attachments/attachment_attr_editor.dart';
|
||||
import 'package:solian/widgets/attachments/attachment_editor_thumbnail.dart';
|
||||
import 'package:solian/widgets/attachments/attachment_fullscreen.dart';
|
||||
|
||||
class AttachmentEditorPopup extends StatefulWidget {
|
||||
@ -264,6 +265,21 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
|
||||
);
|
||||
}
|
||||
|
||||
void _showAttachmentThumbnailEditor(Attachment element, int idx) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AttachmentEditorThumbnailDialog(
|
||||
item: element,
|
||||
pool: widget.pool,
|
||||
initialItem: element.metadata?['thumbnail'],
|
||||
onUpdate: (value) {
|
||||
_attachments[idx]!.metadata ??= {};
|
||||
_attachments[idx]!.metadata!['thumbnail'] = value;
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _showEdit(Attachment element, int index) {
|
||||
showDialog(
|
||||
context: context,
|
||||
@ -455,11 +471,12 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildListEntry(Attachment element, int index) {
|
||||
Widget _buildListEntry(Attachment element, int idx) {
|
||||
var fileType = element.mimetype.split('/').firstOrNull;
|
||||
fileType ??= 'unknown';
|
||||
|
||||
final canBePreview = fileType.toLowerCase() == 'image';
|
||||
final canHasThumbnail = fileType.toLowerCase() != 'image';
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.only(left: 16, right: 8, bottom: 16),
|
||||
@ -491,14 +508,23 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
|
||||
],
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
color: Colors.teal,
|
||||
icon: const Icon(Icons.preview),
|
||||
visualDensity: const VisualDensity(horizontal: -4),
|
||||
onPressed: canBePreview
|
||||
? () => _showAttachmentPreview(element)
|
||||
: null,
|
||||
),
|
||||
if (canBePreview)
|
||||
IconButton(
|
||||
color: Colors.teal,
|
||||
icon: const Icon(Icons.preview),
|
||||
visualDensity: const VisualDensity(horizontal: -4),
|
||||
onPressed: () => _showAttachmentPreview(element),
|
||||
),
|
||||
if (canHasThumbnail)
|
||||
IconButton(
|
||||
color: Colors.teal,
|
||||
icon: const Icon(Icons.add_photo_alternate),
|
||||
visualDensity: const VisualDensity(horizontal: -4),
|
||||
onPressed: () => _showAttachmentThumbnailEditor(
|
||||
element,
|
||||
idx,
|
||||
),
|
||||
),
|
||||
PopupMenuButton(
|
||||
icon: const Icon(Icons.more_horiz),
|
||||
iconColor: Theme.of(context).colorScheme.primary,
|
||||
@ -514,7 +540,7 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
|
||||
horizontal: 8,
|
||||
),
|
||||
),
|
||||
onTap: () => _showEdit(element, index),
|
||||
onTap: () => _showEdit(element, idx),
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: ListTile(
|
||||
@ -527,7 +553,7 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
|
||||
onTap: () {
|
||||
_deleteAttachment(element).then((_) {
|
||||
widget.onRemove(element.rid);
|
||||
setState(() => _attachments.removeAt(index));
|
||||
setState(() => _attachments.removeAt(idx));
|
||||
});
|
||||
},
|
||||
),
|
||||
@ -541,7 +567,7 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> {
|
||||
),
|
||||
onTap: () {
|
||||
widget.onRemove(element.rid);
|
||||
setState(() => _attachments.removeAt(index));
|
||||
setState(() => _attachments.removeAt(idx));
|
||||
},
|
||||
),
|
||||
],
|
||||
|
144
lib/widgets/attachments/attachment_editor_thumbnail.dart
Normal file
144
lib/widgets/attachments/attachment_editor_thumbnail.dart
Normal file
@ -0,0 +1,144 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:solian/exts.dart';
|
||||
import 'package:solian/models/attachment.dart';
|
||||
import 'package:solian/providers/content/attachment.dart';
|
||||
import 'package:solian/widgets/attachments/attachment_editor.dart';
|
||||
|
||||
class AttachmentEditorThumbnailDialog extends StatefulWidget {
|
||||
final Attachment item;
|
||||
final String pool;
|
||||
final String? initialItem;
|
||||
final Function(String? id) onUpdate;
|
||||
|
||||
const AttachmentEditorThumbnailDialog({
|
||||
super.key,
|
||||
required this.item,
|
||||
required this.pool,
|
||||
required this.initialItem,
|
||||
required this.onUpdate,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AttachmentEditorThumbnailDialog> createState() =>
|
||||
_AttachmentEditorThumbnailDialogState();
|
||||
}
|
||||
|
||||
class _AttachmentEditorThumbnailDialogState
|
||||
extends State<AttachmentEditorThumbnailDialog> {
|
||||
bool _isLoading = false;
|
||||
|
||||
final TextEditingController _attachmentController = TextEditingController();
|
||||
|
||||
void _promptUploadNewAttachment() {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => AttachmentEditorPopup(
|
||||
pool: widget.pool,
|
||||
singleMode: true,
|
||||
imageOnly: true,
|
||||
autoUpload: true,
|
||||
onAdd: (value) {
|
||||
widget.onUpdate(value);
|
||||
_attachmentController.text = value;
|
||||
},
|
||||
initialAttachments: const [],
|
||||
onRemove: (_) {},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _updateAttachment() async {
|
||||
setState(() => _isLoading = true);
|
||||
|
||||
final AttachmentProvider attach = Get.find();
|
||||
|
||||
widget.item.metadata ??= {};
|
||||
widget.item.metadata!['thumbnail'] = _attachmentController.text;
|
||||
|
||||
try {
|
||||
await attach.updateAttachment(
|
||||
widget.item.id,
|
||||
widget.item.alt,
|
||||
isMature: widget.item.isMature,
|
||||
metadata: widget.item.metadata!,
|
||||
);
|
||||
|
||||
Get.find<AttachmentProvider>().clearCache(id: widget.item.rid);
|
||||
} catch (e) {
|
||||
context.showErrorDialog(e);
|
||||
} finally {
|
||||
setState(() => _isLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (widget.initialItem != null) {
|
||||
_attachmentController.text = widget.initialItem!;
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_attachmentController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text('postThumbnail'.tr),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Card(
|
||||
margin: EdgeInsets.zero,
|
||||
child: ListTile(
|
||||
title: Text('postThumbnailAttachmentNew'.tr),
|
||||
contentPadding: const EdgeInsets.only(left: 12, right: 9),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
),
|
||||
onTap: () {
|
||||
_promptUploadNewAttachment();
|
||||
},
|
||||
),
|
||||
),
|
||||
const Row(children: <Widget>[
|
||||
Expanded(child: Divider()),
|
||||
Text('OR'),
|
||||
Expanded(child: Divider()),
|
||||
]).paddingOnly(top: 12, bottom: 16, left: 16, right: 16),
|
||||
TextField(
|
||||
controller: _attachmentController,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
border: const OutlineInputBorder(),
|
||||
prefixText: '#',
|
||||
labelText: 'postThumbnailAttachment'.tr,
|
||||
),
|
||||
onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(),
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: _isLoading
|
||||
? null
|
||||
: () {
|
||||
_updateAttachment().then((_) {
|
||||
widget.onUpdate(_attachmentController.text);
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Text('confirm'.tr),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -299,14 +299,14 @@ class _PostItemState extends State<PostItem> {
|
||||
return AttachmentList(
|
||||
parentId: widget.item.id.toString(),
|
||||
attachmentsId: attachments,
|
||||
autoload: true,
|
||||
autoload: false,
|
||||
isGrid: true,
|
||||
).paddingOnly(left: 36, top: 4, bottom: 4);
|
||||
} else if (attachments.length > 1) {
|
||||
return AttachmentList(
|
||||
parentId: widget.item.id.toString(),
|
||||
attachmentsId: attachments,
|
||||
autoload: true,
|
||||
autoload: false,
|
||||
isColumn: true,
|
||||
).paddingOnly(left: 60, right: 24);
|
||||
} else {
|
||||
@ -314,7 +314,7 @@ class _PostItemState extends State<PostItem> {
|
||||
flatMaxHeight: MediaQuery.of(context).size.width,
|
||||
parentId: widget.item.id.toString(),
|
||||
attachmentsId: attachments,
|
||||
autoload: true,
|
||||
autoload: false,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ name: solian
|
||||
description: "The Solar Network App"
|
||||
publish_to: "none"
|
||||
|
||||
version: 1.2.1+30
|
||||
version: 1.2.1+32
|
||||
|
||||
environment:
|
||||
sdk: ">=3.3.4 <4.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user