Add settings for swipe actions

This commit is contained in:
Inex Code 2020-10-14 06:26:33 +03:00
parent 23936fa7f1
commit c97cb326f8
4 changed files with 253 additions and 22 deletions

View file

@ -71,6 +71,9 @@ class MatrixState extends State<Matrix> {
File wallpaper; File wallpaper;
bool renderHtml = false; bool renderHtml = false;
String swipeToEndAction;
String swipeToStartAction = 'reply';
String jitsiInstance = 'https://meet.jit.si/'; String jitsiInstance = 'https://meet.jit.si/';
void clean() async { void clean() async {
@ -283,6 +286,16 @@ class MatrixState extends State<Matrix> {
store.getItem('chat.fluffy.renderHtml').then((final render) async { store.getItem('chat.fluffy.renderHtml').then((final render) async {
renderHtml = render == '1'; renderHtml = render == '1';
}); });
store
.getItem('dev.inex.furrychat.swipeToEndAction')
.then((final action) async {
swipeToEndAction = action ?? swipeToEndAction;
});
store
.getItem('dev.inex.furrychat.swipeToStartAction')
.then((final action) async {
swipeToStartAction = action ?? swipeToStartAction;
});
} }
if (kIsWeb) { if (kIsWeb) {
onFocusSub = html.window.onFocus.listen((_) => webHasFocus = true); onFocusSub = html.window.onFocus.listen((_) => webHasFocus = true);

View file

@ -514,6 +514,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"edit": "Edit",
"@edit": {
"type": "text",
"placeholders": {}
},
"editDisplayname": "Edit displayname", "editDisplayname": "Edit displayname",
"@editDisplayname": { "@editDisplayname": {
"type": "text", "type": "text",
@ -1439,6 +1444,16 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"swipeToEndAction": "Swipe to right action",
"@swipeToEndAction": {
"type": "text",
"placeholders": {}
},
"swipeToStartAction": "Swipe to left action",
"@swipeToStartAction": {
"type": "text",
"placeholders": {}
},
"donate": "Donate", "donate": "Donate",
"@donate": { "@donate": {
"type": "text", "type": "text",

View file

@ -317,8 +317,10 @@ class _ChatState extends State<_Chat> {
return true; return true;
} }
void forwardEventsAction(BuildContext context) async { void forwardEventsAction(BuildContext context, {Event event}) async {
if (selectedEvents.length == 1) { if (event != null) {
Matrix.of(context).shareContent = event.content;
} else if (selectedEvents.length == 1) {
Matrix.of(context).shareContent = selectedEvents.first.content; Matrix.of(context).shareContent = selectedEvents.first.content;
} else { } else {
Matrix.of(context).shareContent = { Matrix.of(context).shareContent = {
@ -412,6 +414,128 @@ class _ChatState extends State<_Chat> {
e.type != 'm.reaction') e.type != 'm.reaction')
.toList(); .toList();
SwipeDirection _getSwipeDirection(Event event) {
var swipeToEndAction = Matrix.of(context).swipeToEndAction;
var swipeToStartAction = Matrix.of(context).swipeToStartAction;
var client = Matrix.of(context).client;
if (event.senderId != client.userID && swipeToEndAction == 'edit') {
swipeToEndAction = null;
}
if (event.senderId != client.userID && swipeToStartAction == 'edit') {
swipeToStartAction = null;
}
if (swipeToEndAction != null && swipeToStartAction != null) {
return SwipeDirection.horizontal;
}
if (swipeToEndAction != null) {
return SwipeDirection.startToEnd;
}
if (swipeToStartAction != null) {
return SwipeDirection.endToStart;
}
return null;
}
Widget _getSwipeBackground(Event event, {bool isSecondary = false}) {
var alignToRight, action;
if (_getSwipeDirection(event) == SwipeDirection.horizontal) {
if (isSecondary) {
alignToRight = true;
action = Matrix.of(context).swipeToStartAction;
} else {
alignToRight = false;
action = Matrix.of(context).swipeToEndAction;
}
} else if (isSecondary) {
return null;
} else if (_getSwipeDirection(event) == SwipeDirection.endToStart) {
alignToRight = true;
action = Matrix.of(context).swipeToStartAction;
} else {
alignToRight = false;
action = Matrix.of(context).swipeToStartAction;
}
switch (action) {
case 'reply':
return Container(
color: Theme.of(context).primaryColor.withAlpha(100),
padding: EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
mainAxisAlignment:
alignToRight ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [
Icon(Icons.reply_outlined),
SizedBox(width: 2.0),
Text(L10n.of(context).reply)
],
),
);
case 'forward':
return Container(
color: Theme.of(context).primaryColor.withAlpha(100),
padding: EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
mainAxisAlignment:
alignToRight ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [
Icon(Icons.forward_outlined),
SizedBox(width: 2.0),
Text(L10n.of(context).forward)
],
),
);
case 'edit':
return Container(
color: Theme.of(context).primaryColor.withAlpha(100),
padding: EdgeInsets.symmetric(horizontal: 12.0),
child: Row(
mainAxisAlignment:
alignToRight ? MainAxisAlignment.end : MainAxisAlignment.start,
children: [
Icon(Icons.edit_outlined),
SizedBox(width: 2.0),
Text(L10n.of(context).edit)
],
),
);
default:
return Container(
color: Theme.of(context).primaryColor.withAlpha(100),
);
}
}
void _handleSwipe(SwipeDirection direction, Event event) {
var action;
if (direction == SwipeDirection.endToStart) {
action = Matrix.of(context).swipeToStartAction;
} else {
action = Matrix.of(context).swipeToEndAction;
}
switch (action) {
case 'reply':
replyAction(replyTo: event);
break;
case 'forward':
forwardEventsAction(context, event: event);
break;
case 'edit':
setState(() {
editEvent = event;
sendController.text = editEvent
.getDisplayEvent(timeline)
.getLocalizedBody(MatrixLocals(L10n.of(context)),
withSenderNamePrefix: false, hideReply: true);
selectedEvents.clear();
});
inputFocus.requestFocus();
break;
default:
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
matrix = Matrix.of(context); matrix = Matrix.of(context);
@ -672,26 +796,16 @@ class _ChatState extends State<_Chat> {
child: Swipeable( child: Swipeable(
key: ValueKey( key: ValueKey(
filteredEvents[i - 1].eventId), filteredEvents[i - 1].eventId),
background: Container( background: _getSwipeBackground(
color: Theme.of(context) filteredEvents[i - 1]),
.primaryColor secondaryBackground:
.withAlpha(100), _getSwipeBackground(
padding: EdgeInsets.symmetric( filteredEvents[i - 1],
horizontal: 12.0), isSecondary: true),
alignment: Alignment.centerLeft, direction: _getSwipeDirection(
child: Row( filteredEvents[i - 1]),
children: [ onSwipe: (direction) => _handleSwipe(
Icon(Icons.reply), direction, filteredEvents[i - 1]),
SizedBox(width: 2.0),
Text(L10n.of(context).reply)
],
),
),
direction: SwipeDirection.startToEnd,
onSwipe: (direction) {
replyAction(
replyTo: filteredEvents[i - 1]);
},
child: Message(filteredEvents[i - 1], child: Message(filteredEvents[i - 1],
onAvatarTab: (Event event) { onAvatarTab: (Event event) {
sendController.text += sendController.text +=

View file

@ -22,6 +22,74 @@ class ChatSettings extends StatefulWidget {
} }
class _ChatSettingsState extends State<ChatSettings> { class _ChatSettingsState extends State<ChatSettings> {
String _getActionDescription(String action) {
switch (action) {
case 'reply':
return L10n.of(context).reply;
case 'forward':
return L10n.of(context).forward;
case 'edit':
return L10n.of(context).edit;
default:
return L10n.of(context).none;
}
}
void _changeSwipeAction(bool isToEnd, String action) async {
if (isToEnd) {
Matrix.of(context).swipeToEndAction = action;
await Matrix.of(context)
.store
.setItem('chat.fluffy.swipeToEndAction', action);
setState(() => null);
} else {
Matrix.of(context).swipeToStartAction = action;
await Matrix.of(context)
.store
.setItem('chat.fluffy.swipeToStartAction', action);
setState(() => null);
}
}
Widget _swipeActionChooser(BuildContext context, bool isToEnd) {
return ListView(
children: [
ListTile(
title: Text(L10n.of(context).none),
leading: Icon(Icons.clear_outlined),
onTap: () {
_changeSwipeAction(isToEnd, null);
Navigator.of(context).pop();
},
),
ListTile(
title: Text(L10n.of(context).reply),
leading: Icon(Icons.reply_outlined),
onTap: () {
_changeSwipeAction(isToEnd, 'reply');
Navigator.of(context).pop();
},
),
ListTile(
title: Text(L10n.of(context).forward),
leading: Icon(Icons.forward_outlined),
onTap: () {
_changeSwipeAction(isToEnd, 'forward');
Navigator.of(context).pop();
},
),
ListTile(
title: Text(L10n.of(context).edit),
leading: Icon(Icons.edit_outlined),
onTap: () {
_changeSwipeAction(isToEnd, 'edit');
Navigator.of(context).pop();
},
),
],
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -42,6 +110,27 @@ class _ChatSettingsState extends State<ChatSettings> {
}, },
), ),
), ),
Divider(thickness: 1),
ListTile(
title: Text(L10n.of(context).swipeToEndAction),
onTap: () => showModalBottomSheet(
context: context,
builder: (BuildContext context) =>
_swipeActionChooser(context, true),
),
subtitle: Text(
_getActionDescription(Matrix.of(context).swipeToEndAction)),
),
ListTile(
title: Text(L10n.of(context).swipeToStartAction),
onTap: () => showModalBottomSheet(
context: context,
builder: (BuildContext context) =>
_swipeActionChooser(context, false),
),
subtitle: Text(
_getActionDescription(Matrix.of(context).swipeToStartAction)),
),
], ],
), ),
); );