diff --git a/assets/debug/fake_video_note.mp4 b/assets/debug/fake_video_note.mp4 new file mode 100644 index 0000000..9e1a713 Binary files /dev/null and b/assets/debug/fake_video_note.mp4 differ diff --git a/lib/frontend/commands/command_registry.dart b/lib/frontend/commands/command_registry.dart index 612b5d0..1bea90a 100644 --- a/lib/frontend/commands/command_registry.dart +++ b/lib/frontend/commands/command_registry.dart @@ -1,6 +1,7 @@ import 'anim_command.dart'; import 'crush_command.dart'; import 'epsh_files_command.dart'; +import 'fake_video_message_command.dart'; import 'info_command.dart'; import 'send_control_command.dart'; import 'slash_command.dart'; @@ -22,6 +23,11 @@ const List kSlashCommands = [ run: runCrush, hidden: true, ), + SlashCommand( + '/FakeVideoMessage', + 'кружок с подменённой длиной: [13:37 | 10000 (сек)]', + run: runFakeVideoMessage, + ), SlashCommand( '/sendControlPayload', 'CONTROL в текущий чат: [event | json]', diff --git a/lib/frontend/commands/fake_video_message_command.dart b/lib/frontend/commands/fake_video_message_command.dart new file mode 100644 index 0000000..546f65e --- /dev/null +++ b/lib/frontend/commands/fake_video_message_command.dart @@ -0,0 +1,67 @@ +import 'probe_send.dart'; +import 'slash_command.dart'; + +const String _noteAsset = 'assets/debug/fake_video_note.mp4'; +const String _usage = + 'Формат: /FakeVideoMessage 13:37 (мм:сс) или /FakeVideoMessage 10000 (секунды)'; + +int? parseFakeDurationMs(String raw) { + final input = raw.trim(); + if (input.isEmpty) return null; + + final negative = input.startsWith('-'); + final body = negative ? input.substring(1).trim() : input; + if (body.isEmpty) return null; + + int? seconds; + if (body.contains(':')) { + final parts = body.split(':'); + if (parts.length > 3) return null; + var total = 0; + for (var i = 0; i < parts.length; i++) { + final value = int.tryParse(parts[i]); + if (value == null || value < 0) return null; + if (i > 0 && value > 59) return null; + total = total * 60 + value; + } + seconds = total; + } else { + final value = int.tryParse(body); + if (value == null || value < 0) return null; + seconds = value; + } + + final ms = seconds * 1000; + return negative ? -ms : ms; +} + +String formatDurationMs(int ms) { + final sign = ms < 0 ? '-' : ''; + final totalSeconds = (ms.abs() / 1000).round(); + final hours = totalSeconds ~/ 3600; + final minutes = (totalSeconds % 3600) ~/ 60; + final seconds = totalSeconds % 60; + final mm = minutes.toString().padLeft(2, '0'); + final ss = seconds.toString().padLeft(2, '0'); + return hours > 0 ? '$sign$hours:$mm:$ss' : '$sign$minutes:$ss'; +} + +Future runFakeVideoMessage(CommandContext ctx) async { + final durationMs = parseFakeDurationMs(ctx.args); + if (durationMs == null) { + ctx.notify(_usage); + return; + } + + ctx.notify( + 'Кружок с подменой: ${formatDurationMs(durationMs)} ' + '(duration=$durationMs мс)', + ); + + try { + final file = await assetToTempFile(_noteAsset, extension: 'mp4'); + await ctx.sendVideoNote(file, durationMs); + } catch (e) { + ctx.notify('Не удалось подготовить кружок: $e'); + } +} diff --git a/lib/frontend/commands/slash_command.dart b/lib/frontend/commands/slash_command.dart index 20ab681..36af2f7 100644 --- a/lib/frontend/commands/slash_command.dart +++ b/lib/frontend/commands/slash_command.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import '../../backend/modules/messages.dart'; import '../../core/media/gallery_source.dart'; @@ -18,6 +20,7 @@ class CommandContext { final Future Function(String id, String text) updateMessage; final Future Function(List photos, String caption) sendPhotos; + final Future Function(File file, int durationMs) sendVideoNote; const CommandContext({ required this.accountId, @@ -31,6 +34,7 @@ class CommandContext { required this.postMessage, required this.updateMessage, required this.sendPhotos, + required this.sendVideoNote, }); void notifyAntiFlood() => diff --git a/lib/frontend/screens/chats/chat_screen.dart b/lib/frontend/screens/chats/chat_screen.dart index 07bc5bd..50b856e 100644 --- a/lib/frontend/screens/chats/chat_screen.dart +++ b/lib/frontend/screens/chats/chat_screen.dart @@ -3985,6 +3985,7 @@ class _ChatScreenState extends State postMessage: _postCommandMessage, updateMessage: _updateCommandMessage, sendPhotos: _sendPhotos, + sendVideoNote: _sendVideoNote, ); Future _scheduleMessage() async { diff --git a/pubspec.yaml b/pubspec.yaml index 18e0240..17411ca 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -150,6 +150,7 @@ flutter: - assets/emoji_keywords.json - assets/lottie/ - assets/wallpapers/patterns/ + - assets/debug/ fonts: - family: Inter