This commit is contained in:
otsmr 2025-04-21 18:20:12 +02:00
parent 1e89809f27
commit 8f29461f72
7 changed files with 114 additions and 60 deletions

View file

@ -42,7 +42,7 @@ class PermissionHandlerViewState extends State<PermissionHandlerView> {
// } // }
if (statuses[Permission.camera]!.isPermanentlyDenied) { if (statuses[Permission.camera]!.isPermanentlyDenied) {
openAppSettings(); await openAppSettings();
// setState(() {}); // setState(() {});
} else { } else {
// if (statuses[Permission.camera]!.isDenied) { // if (statuses[Permission.camera]!.isDenied) {
@ -74,7 +74,7 @@ class PermissionHandlerViewState extends State<PermissionHandlerView> {
icon: const Icon(Icons.perm_camera_mic), icon: const Icon(Icons.perm_camera_mic),
onPressed: () async { onPressed: () async {
try { try {
permissionServices(); await permissionServices();
if (await checkPermissions()) { if (await checkPermissions()) {
widget.onSuccess(); widget.onSuccess();
} }

View file

@ -81,7 +81,7 @@
"settingsTitle": "Einstellungen", "settingsTitle": "Einstellungen",
"settingsChats": "Chats", "settingsChats": "Chats",
"settingsPreSelectedReactions": "Vorgewählte Reaktions-Emojis", "settingsPreSelectedReactions": "Vorgewählte Reaktions-Emojis",
"settingsPreSelectedReactionsError": "Es können maximal 6 Reaktionen ausgewählt werden.", "settingsPreSelectedReactionsError": "Es können maximal 12 Reaktionen ausgewählt werden.",
"settingsProfile": "Profil", "settingsProfile": "Profil",
"settingsProfileCustomizeAvatar": "Avatar anpassen", "settingsProfileCustomizeAvatar": "Avatar anpassen",
"settingsProfileEditDisplayName": "Anzeigename", "settingsProfileEditDisplayName": "Anzeigename",

View file

@ -136,7 +136,7 @@
"@settingsChats": {}, "@settingsChats": {},
"settingsPreSelectedReactions": "Preselected reaction emojis", "settingsPreSelectedReactions": "Preselected reaction emojis",
"@settingsPreSelectedReactions": {}, "@settingsPreSelectedReactions": {},
"settingsPreSelectedReactionsError": "A maximum of 6 reactions can be selected.", "settingsPreSelectedReactionsError": "A maximum of 12 reactions can be selected.",
"@settingsPreSelectedReactionsError": {}, "@settingsPreSelectedReactionsError": {},
"settingsProfile": "Profile", "settingsProfile": "Profile",
"@settingsProfile": {}, "@settingsProfile": {},

View file

@ -561,6 +561,10 @@ class _ReactionButtonsState extends State<ReactionButtons> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final firstRowEmojis = selectedEmojis.take(6).toList();
final secondRowEmojis =
selectedEmojis.length > 6 ? selectedEmojis.skip(6).toList() : [];
return AnimatedPositioned( return AnimatedPositioned(
duration: Duration(milliseconds: 200), // Animation duration duration: Duration(milliseconds: 200), // Animation duration
bottom: widget.show ? 100 : 90, bottom: widget.show ? 100 : 90,
@ -570,28 +574,83 @@ class _ReactionButtonsState extends State<ReactionButtons> {
child: AnimatedOpacity( child: AnimatedOpacity(
opacity: widget.show ? 1.0 : 0.0, // Fade in/out opacity: widget.show ? 1.0 : 0.0, // Fade in/out
duration: Duration(milliseconds: 150), duration: Duration(milliseconds: 150),
child: Row( child: Column(
children: [
if (secondRowEmojis.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: List.generate( children: secondRowEmojis
6, .map((emoji) => EmojiReactionWidget(
(index) { userId: widget.userId,
final emoji = selectedEmojis[index]; responseToMessageId: widget.responseToMessageId,
hide: widget.hide,
show: widget.show,
emoji: emoji,
))
.toList(),
),
if (secondRowEmojis.isNotEmpty) SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: firstRowEmojis
.map((emoji) => EmojiReactionWidget(
userId: widget.userId,
responseToMessageId: widget.responseToMessageId,
hide: widget.hide,
show: widget.show,
emoji: emoji,
))
.toList(),
),
],
),
),
);
}
}
class EmojiReactionWidget extends StatefulWidget {
final int userId;
final int responseToMessageId;
final Function hide;
final bool show;
final String emoji;
const EmojiReactionWidget({
super.key,
required this.userId,
required this.responseToMessageId,
required this.hide,
required this.show,
required this.emoji,
});
@override
_EmojiReactionWidgetState createState() => _EmojiReactionWidgetState();
}
class _EmojiReactionWidgetState extends State<EmojiReactionWidget> {
int selectedShortReaction = -1;
@override
Widget build(BuildContext context) {
return AnimatedSize( return AnimatedSize(
duration: Duration(milliseconds: 200), // Animation duration duration: Duration(milliseconds: 200),
curve: Curves.linearToEaseOut, curve: Curves.linearToEaseOut,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
sendTextMessage( sendTextMessage(
widget.userId, widget.userId,
TextMessageContent( TextMessageContent(
text: emoji, text: widget.emoji,
responseToMessageId: widget.responseToMessageId, responseToMessageId: widget.responseToMessageId,
), ),
PushKind.reaction, PushKind.reaction,
); );
setState(() { setState(() {
selectedShortReaction = index; selectedShortReaction = 0; // Assuming index is 0 for this example
}); });
Future.delayed(Duration(milliseconds: 300), () { Future.delayed(Duration(milliseconds: 300), () {
setState(() { setState(() {
@ -600,32 +659,27 @@ class _ReactionButtonsState extends State<ReactionButtons> {
}); });
}); });
}, },
child: (selectedShortReaction == index) child: (selectedShortReaction ==
0) // Assuming index is 0 for this example
? EmojiAnimationFlying( ? EmojiAnimationFlying(
emoji: emoji, emoji: widget.emoji,
duration: Duration(milliseconds: 300), duration: Duration(milliseconds: 300),
startPosition: 0.0, startPosition: 0.0,
size: (widget.show) ? 40 : 10) size: (widget.show) ? 40 : 10,
)
: AnimatedOpacity( : AnimatedOpacity(
opacity: (selectedShortReaction == -1) opacity: (selectedShortReaction == -1) ? 1 : 0, // Fade in/out
? 1
: 0, // Fade in/out
duration: Duration(milliseconds: 150), duration: Duration(milliseconds: 150),
child: SizedBox( child: SizedBox(
width: widget.show ? 40 : 10, width: widget.show ? 40 : 10,
child: Center( child: Center(
child: EmojiAnimation( child: EmojiAnimation(
emoji: emoji, emoji: widget.emoji,
), ),
), ),
), ),
), ),
), ),
); );
},
),
),
),
);
} }
} }

View file

@ -34,7 +34,7 @@ class _ChatReactionSelectionView extends State<ChatReactionSelectionView> {
if (selectedEmojis.contains(emoji)) { if (selectedEmojis.contains(emoji)) {
selectedEmojis.remove(emoji); selectedEmojis.remove(emoji);
} else { } else {
if (selectedEmojis.length < 6) { if (selectedEmojis.length < 12) {
selectedEmojis.add(emoji); selectedEmojis.add(emoji);
var user = await getUser(); var user = await getUser();
if (user != null) { if (user != null) {

View file

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/views/settings/chat_reactions_view.dart'; import 'package:twonly/src/views/settings/chat/chat_reactions_view.dart';
class ChatSettingsView extends StatefulWidget { class ChatSettingsView extends StatefulWidget {
const ChatSettingsView({super.key}); const ChatSettingsView({super.key});

View file

@ -7,7 +7,7 @@ import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/utils/storage.dart';
import 'package:twonly/src/views/settings/account_view.dart'; import 'package:twonly/src/views/settings/account_view.dart';
import 'package:twonly/src/views/settings/appearance_view.dart'; import 'package:twonly/src/views/settings/appearance_view.dart';
import 'package:twonly/src/views/settings/chat_settings_view.dart'; import 'package:twonly/src/views/settings/chat/chat_settings_view.dart';
import 'package:twonly/src/views/settings/notification_view.dart'; import 'package:twonly/src/views/settings/notification_view.dart';
import 'package:twonly/src/views/settings/profile/profile_view.dart'; import 'package:twonly/src/views/settings/profile/profile_view.dart';
import 'package:twonly/src/views/settings/help_view.dart'; import 'package:twonly/src/views/settings/help_view.dart';