improving text_layer editor

This commit is contained in:
otsmr 2025-06-06 09:40:51 +02:00
parent 0bd810f82c
commit 41b67090f3
6 changed files with 60 additions and 23 deletions

View file

@ -3,6 +3,7 @@ import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/src/database/twonly_database.dart';
import 'package:twonly/src/providers/image_editor.provider.dart';
import 'package:twonly/src/services/api/media_received.dart';
import 'package:twonly/src/services/api/media_send.dart';
import 'package:twonly/src/services/api.service.dart';
@ -52,6 +53,7 @@ void main() async {
providers: [
ChangeNotifierProvider(create: (_) => settingsController),
ChangeNotifierProvider(create: (_) => CustomChangeProvider()),
ChangeNotifierProvider(create: (_) => ImageEditorProvider()),
],
child: App(),
),

View file

@ -0,0 +1,11 @@
import 'package:flutter/foundation.dart';
class ImageEditorProvider with ChangeNotifier, DiagnosticableTreeMixin {
bool _someTextViewIsAlreadyEditing = false;
bool get someTextViewIsAlreadyEditing => _someTextViewIsAlreadyEditing;
Future<void> updateSomeTextViewIsAlreadyEditing(bool update) async {
_someTextViewIsAlreadyEditing = update;
notifyListeners();
}
}

View file

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:provider/provider.dart';
import 'package:twonly/src/providers/image_editor.provider.dart';
import 'package:twonly/src/views/camera/image_editor/action_button.dart';
import 'package:twonly/src/views/camera/image_editor/data/layer.dart';
@ -65,6 +67,9 @@ class _TextViewState extends State<TextLayer> {
setState(() {
widget.layerData.isDeleted = textController.text == "";
widget.layerData.isEditing = false;
context
.read<ImageEditorProvider>()
.updateSomeTextViewIsAlreadyEditing(false);
widget.layerData.text = textController.text;
});
},
@ -75,6 +80,9 @@ class _TextViewState extends State<TextLayer> {
setState(() {
widget.layerData.isDeleted = textController.text == "";
widget.layerData.isEditing = false;
context
.read<ImageEditorProvider>()
.updateSomeTextViewIsAlreadyEditing(false);
});
}
});
@ -96,6 +104,7 @@ class _TextViewState extends State<TextLayer> {
),
);
}
return Stack(
key: _widgetKey,
children: [
@ -110,15 +119,25 @@ class _TextViewState extends State<TextLayer> {
});
},
onScaleEnd: (d) {
if (deleteLayer) widget.layerData.isDeleted = true;
if (deleteLayer) {
widget.layerData.isDeleted = true;
textController.text = "";
}
elementIsScaled = false;
setState(() {});
},
onTap: () {
setState(() {
widget.layerData.isEditing = true;
});
},
onTap: (context
.watch<ImageEditorProvider>()
.someTextViewIsAlreadyEditing)
? null
: () {
setState(() {
context
.read<ImageEditorProvider>()
.updateSomeTextViewIsAlreadyEditing(true);
widget.layerData.isEditing = true;
});
},
onScaleUpdate: (detail) {
if (detail.pointerCount == 1) {
widget.layerData.offset = Offset(

View file

@ -53,7 +53,7 @@ class LayersViewer extends StatelessWidget {
}),
...layers.whereType<TextLayerData>().map((layerItem) {
return TextLayer(
key: GlobalKey(),
// key: GlobalKey(),
layerData: layerItem,
onUpdate: onUpdate,
);

View file

@ -56,6 +56,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
String? sendNextMediaToUserName;
double tabDownPosition = 0;
bool sendingOrLoadingImage = true;
bool loadingImage = true;
bool isDisposed = false;
HashSet<int> selectedUserIds = HashSet();
double widthRatio = 1, heightRatio = 1, pixelRatio = 1;
@ -78,6 +79,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
} else if (widget.videoFilePath != null) {
setState(() {
sendingOrLoadingImage = false;
loadingImage = false;
});
videoController = VideoPlayerController.file(widget.videoFilePath!);
videoController?.setLooping(true);
@ -381,6 +383,7 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
);
setState(() {
sendingOrLoadingImage = false;
loadingImage = false;
});
}
@ -535,11 +538,12 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
mainAxisAlignment: MainAxisAlignment.center,
children: [
SaveToGalleryButton(
getMergedImage: getMergedImage,
mediaUploadId: mediaUploadId,
videoFilePath: widget.videoFilePath,
sendNextMediaToUserName: sendNextMediaToUserName,
isLoading: sendingOrLoadingImage),
getMergedImage: getMergedImage,
mediaUploadId: mediaUploadId,
videoFilePath: widget.videoFilePath,
sendNextMediaToUserName: sendNextMediaToUserName,
isLoading: loadingImage,
),
if (sendNextMediaToUserName != null) SizedBox(width: 10),
if (sendNextMediaToUserName != null)
OutlinedButton(

View file

@ -17,17 +17,18 @@ import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/views/settings/subscription/subscription.view.dart';
class ShareImageView extends StatefulWidget {
const ShareImageView(
{super.key,
required this.imageBytesFuture,
required this.isRealTwonly,
required this.mirrorVideo,
required this.maxShowTime,
required this.selectedUserIds,
required this.updateStatus,
required this.videoUploadHandler,
required this.mediaUploadId,
this.enableVideoAudio});
const ShareImageView({
super.key,
required this.imageBytesFuture,
required this.isRealTwonly,
required this.mirrorVideo,
required this.maxShowTime,
required this.selectedUserIds,
required this.updateStatus,
required this.videoUploadHandler,
required this.mediaUploadId,
this.enableVideoAudio,
});
final Future<Uint8List?> imageBytesFuture;
final bool isRealTwonly;
final bool mirrorVideo;