Skip to content

Commit

Permalink
feat: ctrl + click or ctrl + enter copies without closing window
Browse files Browse the repository at this point in the history
  • Loading branch information
KRTirtho committed Sep 1, 2023
1 parent d04a8cb commit f040556
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 127 deletions.
101 changes: 60 additions & 41 deletions lib/components/root/emoji.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:collection/collection.dart';
import 'package:flemozi/components/root/twemoji.dart';
import 'package:flemozi/hooks/use_window_listeners.dart';
import 'package:flemozi/intents/close_window.dart';
Expand Down Expand Up @@ -83,6 +84,46 @@ class Emoji extends HookWidget {
},
);

final copyEmoji = useCallback((RatioEmojiType emoji, FocusNode focusNode) {
focusNode.requestFocus();
Clipboard.setData(
ClipboardData(text: emoji.emoji),
);
SnackBar snackBar = SnackBar(
content: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.copy,
color: Theme.of(context).colorScheme.background,
),
const SizedBox(width: 10),
Text(
"Copied ${emoji.aliases.firstOrNull} ",
),
Twemoji(
emoji: emoji.emoji,
height: 20,
width: 20,
),
],
),
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 2),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
final keys = RawKeyboard.instance.keysPressed;
const controls = [
LogicalKeyboardKey.control,
LogicalKeyboardKey.controlLeft,
LogicalKeyboardKey.controlRight,
];
if (controls.none((element) => keys.contains(element))) {
Actions.invoke(context, const CloseWindowIntent());
}
}, []);

return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
Expand Down Expand Up @@ -151,49 +192,27 @@ class Emoji extends HookWidget {
message: emoji.description,
key: tooltipKey,
triggerMode: TooltipTriggerMode.manual,
child: MaterialButton(
child: RawKeyboardListener(
focusNode: focusNode,
padding: EdgeInsets.zero,
focusColor: Theme.of(context).colorScheme.primary,
highlightColor: Theme.of(context).colorScheme.primary,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
onPressed: () {
focusNode.requestFocus();
Clipboard.setData(
ClipboardData(text: emoji.emoji),
);
SnackBar snackBar = SnackBar(
content: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.copy,
color:
Theme.of(context).colorScheme.background,
),
const SizedBox(width: 10),
Text(
"Copied ${emoji.aliases.firstOrNull} ",
),
Twemoji(
emoji: emoji.emoji,
height: 20,
width: 20,
),
],
),
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 2),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Actions.invoke(context, const CloseWindowIntent());
onKey: (value) {
if (value.isKeyPressed(LogicalKeyboardKey.enter)) {
copyEmoji(emoji, focusNode);
}
},
child: Twemoji(
emoji: emoji.emoji,
child: MaterialButton(
padding: EdgeInsets.zero,
focusColor: Theme.of(context).colorScheme.primary,
highlightColor: Theme.of(context).colorScheme.primary,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
onPressed: () {
copyEmoji(emoji, focusNode);
},
child: Twemoji(
emoji: emoji.emoji,
),
),
),
),
Expand Down
96 changes: 57 additions & 39 deletions lib/components/root/emoticon.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:collection/collection.dart';
import 'package:flemozi/collections/emoticons.dart';
import 'package:flemozi/hooks/use_window_listeners.dart';
import 'package:flemozi/intents/close_window.dart';
Expand Down Expand Up @@ -123,6 +124,42 @@ class Emoticon extends HookWidget {
};
}, [focusNode]);

void copyEmoticon() {
focusNode.requestFocus();
Clipboard.setData(
ClipboardData(text: emoticon["emoticon"]!),
);
SnackBar snackBar = SnackBar(
content: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.copy,
color: Theme.of(context).colorScheme.background,
),
const SizedBox(width: 10),
Text(
"${emoticon["emoticon"]} was copied to clipboard",
),
],
),
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 2),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);

final keys = RawKeyboard.instance.keysPressed;
const controls = [
LogicalKeyboardKey.control,
LogicalKeyboardKey.controlLeft,
LogicalKeyboardKey.controlRight,
];
if (controls.none((element) => keys.contains(element))) {
Actions.invoke(context, const CloseWindowIntent());
}
}

return CallbackShortcuts(
bindings: {
LogicalKeySet(LogicalKeyboardKey.escape): () {
Expand All @@ -132,47 +169,28 @@ class Emoticon extends HookWidget {
child: Tooltip(
key: tooltipKey,
message: emoticon["description"]!,
child: MaterialButton(
child: RawKeyboardListener(
focusNode: focusNode,
padding: EdgeInsets.zero,
focusColor: Theme.of(context).colorScheme.primary,
highlightColor: Theme.of(context).colorScheme.primary,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
onPressed: () {
focusNode.requestFocus();
Clipboard.setData(
ClipboardData(text: emoticon["emoticon"]!),
);
SnackBar snackBar = SnackBar(
content: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.copy,
color:
Theme.of(context).colorScheme.background,
),
const SizedBox(width: 10),
Text(
"${emoticon["emoticon"]} was copied to clipboard",
),
],
),
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 2),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Actions.invoke(context, const CloseWindowIntent());
onKey: (value) {
if (value.isKeyPressed(LogicalKeyboardKey.enter)) {
copyEmoticon();
}
},
child: AutoSizeText(
emoticon["emoticon"]!,
maxLines: 1,
minFontSize: 5,
maxFontSize: 20,
child: MaterialButton(
padding: EdgeInsets.zero,
focusColor: Theme.of(context).colorScheme.primary,
highlightColor: Theme.of(context).colorScheme.primary,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
onPressed: copyEmoticon,
child: AutoSizeText(
emoticon["emoticon"]!,
maxLines: 1,
minFontSize: 5,
maxFontSize: 20,
),
),
),
),
Expand Down
112 changes: 65 additions & 47 deletions lib/components/root/gif.dart
Original file line number Diff line number Diff line change
Expand Up @@ -214,61 +214,79 @@ class Gif extends HookConsumerWidget {
fit: BoxFit.contain,
placeholder: (context, url) => placeholder,
);
Future<void> copyGif() async {
final imageFile = await DefaultCacheManager()
.getFileFromCache(gif)
.then((s) async => await s?.file.readAsBytes());
if (imageFile == null) {
return;
}
await ClipboardWriter.instance.write([
DataWriterItem(suggestedName: basename(gif))
..add(Formats.png(imageFile))
..add(Formats.bmp(imageFile))
..add(Formats.webp(imageFile))
..add(Formats.gif(imageFile))
..add(Formats.tiff(imageFile))
..add(
Formats.htmlText(
'<meta http-equiv="content-type" content="text/html; charset=utf-8"><img src="$gif">',
),
)
]);
SnackBar snackBar = SnackBar(
content: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(width: 35, child: image),
const SizedBox(width: 10),
const Text("Copied to clipboard!"),
],
),
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 2),
);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(snackBar);
final keys = RawKeyboard.instance.keysPressed;
const controls = [
LogicalKeyboardKey.control,
LogicalKeyboardKey.controlLeft,
LogicalKeyboardKey.controlRight,
];
if (controls.none((element) => keys.contains(element))) {
Actions.invoke(context, const CloseWindowIntent());
}
}
}

return CallbackShortcuts(
bindings: {
LogicalKeySet(LogicalKeyboardKey.escape): () {
FocusScope.of(context).requestFocus(searchFocusNode);
},
},
child: InkWell(
borderRadius: BorderRadius.circular(10),
onTap: () async {
final imageFile = await DefaultCacheManager()
.getFileFromCache(gif)
.then((s) async => await s?.file.readAsBytes());
if (imageFile == null) {
return;
}
await ClipboardWriter.instance.write([
DataWriterItem(suggestedName: basename(gif))
..add(Formats.png(imageFile))
..add(Formats.bmp(imageFile))
..add(Formats.webp(imageFile))
..add(Formats.gif(imageFile))
..add(Formats.tiff(imageFile))
..add(
Formats.htmlText(
'<meta http-equiv="content-type" content="text/html; charset=utf-8"><img src="$gif">',
),
)
]);
SnackBar snackBar = SnackBar(
content: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(width: 35, child: image),
const SizedBox(width: 10),
const Text("Copied to clipboard!"),
],
child: HookBuilder(builder: (context) {
return RawKeyboardListener(
focusNode: index == 0 ? focusNode : useFocusNode(),
onKey: (value) {
if (value.isKeyPressed(LogicalKeyboardKey.enter)) {
copyGif();
}
},
child: InkWell(
borderRadius: BorderRadius.circular(10),
onTap: copyGif,
canRequestFocus: true,
focusColor: Theme.of(context).colorScheme.secondary,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: image,
),
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 2),
);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(snackBar);
Actions.invoke(context, const CloseWindowIntent());
}
},
focusNode: index == 0 ? focusNode : null,
canRequestFocus: true,
focusColor: Theme.of(context).colorScheme.secondary,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: image,
),
),
),
);
}),
);
},
),
Expand Down

0 comments on commit f040556

Please sign in to comment.