From 1c8895483d1539814f8fbe49671daa2df1b33a06 Mon Sep 17 00:00:00 2001
From: ZenonEl <165126589+ZenonEl@users.noreply.github.com>
Date: Mon, 30 Mar 2026 06:40:58 +0400
Subject: [PATCH] fix(settings): add settings state display and enable/disable
toggle closes #34
- Show current action, delay, and enabled/disabled status in settings menus
- Add Enable/Disable toggle buttons for default action (previously only Off existed)
- Show confirmation with current state after every settings change
- UPSERT queries now properly set IsActive=1 when configuring actions
- Add GetDefaultActionSettings and SetDefaultActionIsActive to IDefaultAction interfaces
- Add missing resource strings for both EN and RU locales
---
Database/Interfaces/IDefaultAction.cs | 2 +
Database/Repositories/SqLite/DefaultAction.cs | 52 +++++++--
Resources/texts.resx | 39 +++++++
Resources/texts.ru-RU.resx | 33 ++++++
.../IParameterizedCallBackQuery.cs | 54 ++++++++-
.../ICallBackQuery/ISettingsCallbackQuery.cs | 39 ++++++-
TelegramBot/Menu/Users.cs | 107 +++++++++++++++++-
TelegramBot/Utils/Keyboard/Users.cs | 1 +
8 files changed, 304 insertions(+), 23 deletions(-)
diff --git a/Database/Interfaces/IDefaultAction.cs b/Database/Interfaces/IDefaultAction.cs
index 19cf9d0..c4c9015 100644
--- a/Database/Interfaces/IDefaultAction.cs
+++ b/Database/Interfaces/IDefaultAction.cs
@@ -25,6 +25,7 @@ public interface IDefaultActionSetter
public bool SetAutoSendVideoActionToUser(int userId, string action, string type);
+ public bool SetDefaultActionIsActive(int userId, string type, bool isActive);
}
public interface IDefaultActionGetter
@@ -33,4 +34,5 @@ public interface IDefaultActionGetter
public int GetDefaultActionId(int userId, string type);
public string GetDefaultActionByUserIDAndType(int userID, string type);
+ public (string Action, string ActionCondition, bool IsActive) GetDefaultActionSettings(int userId, string type);
}
\ No newline at end of file
diff --git a/Database/Repositories/SqLite/DefaultAction.cs b/Database/Repositories/SqLite/DefaultAction.cs
index b000f54..74cb4ae 100644
--- a/Database/Repositories/SqLite/DefaultAction.cs
+++ b/Database/Repositories/SqLite/DefaultAction.cs
@@ -58,9 +58,9 @@ public SqliteDefaultActionSetter(string connectionString)
public bool SetAutoSendVideoConditionToUser(int userId, string actionCondition, string type)
{
const string query = @"
- INSERT INTO DefaultUsersActions (UserId, Type, ActionCondition)
- VALUES (@userId, @type, @actionCondition)
- ON CONFLICT(UserId, Type)
+ INSERT INTO DefaultUsersActions (UserId, Type, ActionCondition, IsActive)
+ VALUES (@userId, @type, @actionCondition, 1)
+ ON CONFLICT(UserId, Type)
DO UPDATE SET ActionCondition = @actionCondition";
using var connection = new SqliteConnection(_connectionString);
@@ -70,14 +70,25 @@ ON CONFLICT(UserId, Type)
public bool SetAutoSendVideoActionToUser(int userId, string action, string type)
{
const string query = @"
- INSERT INTO DefaultUsersActions (UserId, Type, Action)
- VALUES (@userId, @type, @action)
- ON CONFLICT(UserId, Type)
- DO UPDATE SET Action = @action";
+ INSERT INTO DefaultUsersActions (UserId, Type, Action, IsActive)
+ VALUES (@userId, @type, @action, 1)
+ ON CONFLICT(UserId, Type)
+ DO UPDATE SET Action = @action, IsActive = 1";
using var connection = new SqliteConnection(_connectionString);
return connection.Execute(query, new {userId, type, action}) > 0;
}
+
+ public bool SetDefaultActionIsActive(int userId, string type, bool isActive)
+ {
+ const string query = @"
+ UPDATE DefaultUsersActions
+ SET IsActive = @isActive
+ WHERE UserId = @userId AND Type = @type";
+
+ using var connection = new SqliteConnection(_connectionString);
+ return connection.Execute(query, new {userId, type, isActive}) > 0;
+ }
}
public class SqliteDefaultActionGetter : IDefaultActionGetter
@@ -129,7 +140,7 @@ public string GetDefaultActionByUserIDAndType(int userID, string type)
try
{
using var connection = new SqliteConnection(_connectionString);
-
+
var result = connection.QueryFirstOrDefault<(string Action, string ActionCondition)>(
@"SELECT Action, ActionCondition
FROM DefaultUsersActions
@@ -138,8 +149,8 @@ FROM DefaultUsersActions
AND IsActive = 1",
new { userID, type });
- return result != default
- ? $"{result.Action};{result.ActionCondition}"
+ return result != default
+ ? $"{result.Action};{result.ActionCondition}"
: UsersAction.NO_VALUE;
}
catch (Exception ex)
@@ -148,4 +159,25 @@ FROM DefaultUsersActions
return "";
}
}
+
+ public (string Action, string ActionCondition, bool IsActive) GetDefaultActionSettings(int userId, string type)
+ {
+ try
+ {
+ using var connection = new SqliteConnection(_connectionString);
+
+ var result = connection.QueryFirstOrDefault<(string Action, string ActionCondition, bool IsActive)>(
+ @"SELECT Action, ActionCondition, IsActive
+ FROM DefaultUsersActions
+ WHERE UserId = @userId AND Type = @type",
+ new { userId, type });
+
+ return result;
+ }
+ catch (Exception ex)
+ {
+ Log.Error(ex, "An error occurred in the method {MethodName}", nameof(GetDefaultActionSettings));
+ return (string.Empty, string.Empty, false);
+ }
+ }
}
\ No newline at end of file
diff --git a/Resources/texts.resx b/Resources/texts.resx
index b744dc5..60c6c5a 100644
--- a/Resources/texts.resx
+++ b/Resources/texts.resx
@@ -326,9 +326,42 @@ Are you sure you want to unmute them? If not, type /start
Default action successfully changed.
+
+ Default action has been disabled.
+
Default action not changed.
+
+ Current settings:
+
+
+ Action
+
+
+ Delay
+
+
+ Status
+
+
+ not configured
+
+
+ enabled
+
+
+ disabled
+
+
+ sec.
+
+
+ Enable Auto-Send
+
+
+ Please specify the IDs of groups or users:
+
⏳ Time is up, the default action will be performed...
@@ -379,6 +412,12 @@ Are you sure you want to unmute them? If not, type /start
Only Me
+
+ Enable
+
+
+ Disable
+
Disable Auto-Send
diff --git a/Resources/texts.ru-RU.resx b/Resources/texts.ru-RU.resx
index e130a92..b2749b0 100644
--- a/Resources/texts.ru-RU.resx
+++ b/Resources/texts.ru-RU.resx
@@ -331,9 +331,42 @@ ID: {0}
Действие по умолчанию успешно изменено.
+
+ Действие по умолчанию отключено.
+
Действие по умолчанию не изменено.
+
+ Текущие настройки:
+
+
+ Действие
+
+
+ Задержка
+
+
+ Статус
+
+
+ не настроено
+
+
+ включено
+
+
+ отключено
+
+
+ сек.
+
+
+ Включить авто-рассылку
+
+
+ Укажите ID групп или пользователей:
+
⏳ Время вышло, будет выполнено действие по умолчанию...
diff --git a/TelegramBot/Handlers/ICallBackQuery/IParameterizedCallBackQuery.cs b/TelegramBot/Handlers/ICallBackQuery/IParameterizedCallBackQuery.cs
index 393b527..d21d4af 100644
--- a/TelegramBot/Handlers/ICallBackQuery/IParameterizedCallBackQuery.cs
+++ b/TelegramBot/Handlers/ICallBackQuery/IParameterizedCallBackQuery.cs
@@ -49,25 +49,31 @@ public class SetAutoSendTimeCommand : IBotCallbackQueryHandlers
public string Name => "user_set_auto_send_video_time_to:";
private readonly IDefaultActionSetter _defaultActionSetter;
+ private readonly IDefaultActionGetter _defaultActionGetter;
private readonly IUserGetter _userGetter;
public SetAutoSendTimeCommand(
IUserGetter userGetter,
- IDefaultActionSetter defaultActionSetter)
+ IDefaultActionSetter defaultActionSetter,
+ IDefaultActionGetter defaultActionGetter)
{
_userGetter = userGetter;
_defaultActionSetter = defaultActionSetter;
+ _defaultActionGetter = defaultActionGetter;
}
public async Task ExecuteAsync(Update update, ITelegramBotClient botClient, CancellationToken ct)
{
string callbackQueryData = update.CallbackQuery!.Data!.Split(':')[1];
var chatId = update.CallbackQuery!.Message!.Chat.Id;
+ int userId = _userGetter.GetUserIDbyTelegramID(chatId);
bool result = Users.SetAutoSendVideoTimeToUser(chatId, callbackQueryData, _defaultActionSetter, _userGetter);
- var message = result
- ? Config.GetResourceString("AutoSendTimeChangedMessage") + callbackQueryData
+ string statusText = Users.FormatSettingsStatus(_defaultActionGetter, userId);
+ var message = result
+ ? Config.GetResourceString("AutoSendTimeChangedMessage") + callbackQueryData + " " + Config.GetResourceString("SettingsSecondsLabel")
: Config.GetResourceString("AutoSendTimeNotChangedMessage");
+ message += "\n\n" + statusText;
await CommonUtilities.SendMessage(
botClient,
@@ -112,6 +118,45 @@ public async Task ExecuteAsync(Update update, ITelegramBotClient botClient, Canc
{
string action = update.CallbackQuery!.Data!.Split(':')[1];
long chatId = update.CallbackQuery!.Message!.Chat.Id;
+ int userId = _userGetter.GetUserIDbyTelegramID(chatId);
+
+ // Handle "enable" action: re-enable existing settings without changing them
+ if (action == "enable")
+ {
+ bool enableResult = _defaultActionSetter.SetDefaultActionIsActive(userId, UsersActionTypes.DEFAULT_MEDIA_DISTRIBUTION, true);
+ string enableMessage = enableResult
+ ? Config.GetResourceString("DefaultActionChangedMessage")
+ : Config.GetResourceString("DefaultActionNotChangedMessage");
+
+ string statusText = Users.FormatSettingsStatus(_defaultActionGetter, userId);
+ await CommonUtilities.SendMessage(
+ botClient,
+ update,
+ KeyboardUtils.GetReturnButtonMarkup("user_set_video_send_users"),
+ cancellationToken,
+ enableMessage + "\n\n" + statusText
+ );
+ return;
+ }
+
+ // Handle "off" action: disable the default action
+ if (action == UsersAction.OFF)
+ {
+ bool disableResult = _defaultActionSetter.SetDefaultActionIsActive(userId, UsersActionTypes.DEFAULT_MEDIA_DISTRIBUTION, false);
+ string disableMessage = disableResult
+ ? Config.GetResourceString("DefaultActionDisabledMessage")
+ : Config.GetResourceString("DefaultActionNotChangedMessage");
+
+ string statusText = Users.FormatSettingsStatus(_defaultActionGetter, userId);
+ await CommonUtilities.SendMessage(
+ botClient,
+ update,
+ KeyboardUtils.GetReturnButtonMarkup("user_set_video_send_users"),
+ cancellationToken,
+ disableMessage + "\n\n" + statusText
+ );
+ return;
+ }
List extendActions = new List
{
@@ -148,12 +193,13 @@ await CommonUtilities.SendMessage(
if (result)
{
+ string confirmStatusText = Users.FormatSettingsStatus(_defaultActionGetter, userId);
await CommonUtilities.SendMessage(
botClient,
update,
KeyboardUtils.GetReturnButtonMarkup("user_set_video_send_users"),
cancellationToken,
- Config.GetResourceString("DefaultActionChangedMessage")
+ Config.GetResourceString("DefaultActionChangedMessage") + "\n\n" + confirmStatusText
);
return;
}
diff --git a/TelegramBot/Handlers/ICallBackQuery/ISettingsCallbackQuery.cs b/TelegramBot/Handlers/ICallBackQuery/ISettingsCallbackQuery.cs
index f6eb7a0..c4bd509 100644
--- a/TelegramBot/Handlers/ICallBackQuery/ISettingsCallbackQuery.cs
+++ b/TelegramBot/Handlers/ICallBackQuery/ISettingsCallbackQuery.cs
@@ -45,31 +45,64 @@ public async Task ExecuteAsync(Update update, ITelegramBotClient botClient, Canc
public class VideoDefaultActionsMenuCommand : IBotCallbackQueryHandlers
{
+ private readonly IDefaultActionGetter _defaultActionGetter;
+ private readonly IUserGetter _userGetter;
+
+ public VideoDefaultActionsMenuCommand(
+ IDefaultActionGetter defaultActionGetter,
+ IUserGetter userGetter)
+ {
+ _defaultActionGetter = defaultActionGetter;
+ _userGetter = userGetter;
+ }
+
public string Name => "video_default_actions_menu";
public async Task ExecuteAsync(Update update, ITelegramBotClient botClient, CancellationToken ct)
{
- await Users.ViewVideoDefaultActionsMenu(botClient, update);
+ await Users.ViewVideoDefaultActionsMenu(botClient, update, _defaultActionGetter, _userGetter);
}
}
public class UserSetAutoSendVideoTimeCommand : IBotCallbackQueryHandlers
{
+ private readonly IDefaultActionGetter _defaultActionGetter;
+ private readonly IUserGetter _userGetter;
+
+ public UserSetAutoSendVideoTimeCommand(
+ IDefaultActionGetter defaultActionGetter,
+ IUserGetter userGetter)
+ {
+ _defaultActionGetter = defaultActionGetter;
+ _userGetter = userGetter;
+ }
+
public string Name => "user_set_auto_send_video_time";
public async Task ExecuteAsync(Update update, ITelegramBotClient botClient, CancellationToken ct)
{
- await Users.ViewAutoSendVideoTimeMenu(botClient, update);
+ await Users.ViewAutoSendVideoTimeMenu(botClient, update, _defaultActionGetter, _userGetter);
}
}
public class UserSetVideoSendUsersCommand : IBotCallbackQueryHandlers
{
+ private readonly IDefaultActionGetter _defaultActionGetter;
+ private readonly IUserGetter _userGetter;
+
+ public UserSetVideoSendUsersCommand(
+ IDefaultActionGetter defaultActionGetter,
+ IUserGetter userGetter)
+ {
+ _defaultActionGetter = defaultActionGetter;
+ _userGetter = userGetter;
+ }
+
public string Name => "user_set_video_send_users";
public async Task ExecuteAsync(Update update, ITelegramBotClient botClient, CancellationToken ct)
{
- await Users.ViewUsersVideoSentUsersActionsMenu(botClient, update);
+ await Users.ViewUsersVideoSentUsersActionsMenu(botClient, update, _defaultActionGetter, _userGetter);
}
}
diff --git a/TelegramBot/Menu/Users.cs b/TelegramBot/Menu/Users.cs
index 425d385..9f44893 100644
--- a/TelegramBot/Menu/Users.cs
+++ b/TelegramBot/Menu/Users.cs
@@ -10,6 +10,7 @@
// (по вашему выбору) любой более поздней версии.
+using System.Text;
using TelegramMediaRelayBot.Database;
using TelegramMediaRelayBot.Database.Interfaces;
using TelegramMediaRelayBot.TelegramBot.Utils;
@@ -98,39 +99,133 @@ await CommonUtilities.SendMessage(
);
}
- public static async Task ViewVideoDefaultActionsMenu(ITelegramBotClient botClient, Update update)
+ public static async Task ViewVideoDefaultActionsMenu(ITelegramBotClient botClient, Update update,
+ IDefaultActionGetter? defaultActionGetter = null, IUserGetter? userGetter = null)
{
+ string statusText = "";
+ if (defaultActionGetter != null && userGetter != null)
+ {
+ long chatId = CommonUtilities.GetIDfromUpdate(update);
+ int userId = userGetter.GetUserIDbyTelegramID(chatId);
+ statusText = FormatSettingsStatus(defaultActionGetter, userId);
+ }
+
+ string message = Config.GetResourceString("VideoDefaultActionsMenuText");
+ if (!string.IsNullOrEmpty(statusText))
+ message += "\n\n" + statusText;
+
await CommonUtilities.SendMessage(
botClient,
update,
UsersDefaultActionsMenuKB.GetDefaultVideoDistributionKeyboardMarkup(),
cancellationToken,
- Config.GetResourceString("VideoDefaultActionsMenuText")
+ message
);
}
- public static async Task ViewUsersVideoSentUsersActionsMenu(ITelegramBotClient botClient, Update update)
+ public static async Task ViewUsersVideoSentUsersActionsMenu(ITelegramBotClient botClient, Update update,
+ IDefaultActionGetter? defaultActionGetter = null, IUserGetter? userGetter = null)
{
+ string statusText = "";
+ if (defaultActionGetter != null && userGetter != null)
+ {
+ long chatId = CommonUtilities.GetIDfromUpdate(update);
+ int userId = userGetter.GetUserIDbyTelegramID(chatId);
+ var settings = defaultActionGetter.GetDefaultActionSettings(userId, UsersActionTypes.DEFAULT_MEDIA_DISTRIBUTION);
+ if (!string.IsNullOrEmpty(settings.Action))
+ {
+ string actionName = GetActionDisplayName(settings.Action);
+ string activeIndicator = settings.IsActive ? "✅" : "❌";
+ statusText = $"{activeIndicator} {Config.GetResourceString("SettingsActionLabel")}: {actionName}";
+ }
+ }
+
+ string message = Config.GetResourceString("UsersVideoSentUsersMenuText");
+ if (!string.IsNullOrEmpty(statusText))
+ message += "\n\n" + statusText;
+
await CommonUtilities.SendMessage(
botClient,
update,
UsersDefaultActionsMenuKB.GetUsersVideoSentUsersKeyboardMarkup(),
cancellationToken,
- Config.GetResourceString("UsersVideoSentUsersMenuText")
+ message
);
}
- public static async Task ViewAutoSendVideoTimeMenu(ITelegramBotClient botClient, Update update)
+ public static async Task ViewAutoSendVideoTimeMenu(ITelegramBotClient botClient, Update update,
+ IDefaultActionGetter? defaultActionGetter = null, IUserGetter? userGetter = null)
{
+ string statusText = "";
+ if (defaultActionGetter != null && userGetter != null)
+ {
+ long chatId = CommonUtilities.GetIDfromUpdate(update);
+ int userId = userGetter.GetUserIDbyTelegramID(chatId);
+ var settings = defaultActionGetter.GetDefaultActionSettings(userId, UsersActionTypes.DEFAULT_MEDIA_DISTRIBUTION);
+ if (!string.IsNullOrEmpty(settings.ActionCondition))
+ {
+ string activeIndicator = settings.IsActive ? "✅" : "❌";
+ statusText = $"{activeIndicator} {Config.GetResourceString("SettingsDelayLabel")}: {settings.ActionCondition} {Config.GetResourceString("SettingsSecondsLabel")}";
+ }
+ }
+
+ string message = Config.GetResourceString("AutoSendVideoTimeMenuText");
+ if (!string.IsNullOrEmpty(statusText))
+ message += "\n\n" + statusText;
+
await CommonUtilities.SendMessage(
botClient,
update,
UsersDefaultActionsMenuKB.GetUsersAutoSendVideoTimeKeyboardMarkup(),
cancellationToken,
- Config.GetResourceString("AutoSendVideoTimeMenuText")
+ message
);
}
+ public static string FormatSettingsStatus(IDefaultActionGetter defaultActionGetter, int userId)
+ {
+ var settings = defaultActionGetter.GetDefaultActionSettings(userId, UsersActionTypes.DEFAULT_MEDIA_DISTRIBUTION);
+
+ if (string.IsNullOrEmpty(settings.Action) && string.IsNullOrEmpty(settings.ActionCondition))
+ return $"📋 {Config.GetResourceString("SettingsCurrentStateText")} {Config.GetResourceString("SettingsNotConfigured")}";
+
+ var sb = new StringBuilder();
+ sb.AppendLine($"📋 {Config.GetResourceString("SettingsCurrentStateText")}");
+
+ string statusIndicator = settings.IsActive ? "✅" : "❌";
+ string statusText = settings.IsActive
+ ? Config.GetResourceString("SettingsEnabled")
+ : Config.GetResourceString("SettingsDisabled");
+ sb.AppendLine($" {Config.GetResourceString("SettingsStatusLabel")}: {statusIndicator} {statusText}");
+
+ if (!string.IsNullOrEmpty(settings.Action))
+ {
+ string actionName = GetActionDisplayName(settings.Action);
+ sb.AppendLine($" {Config.GetResourceString("SettingsActionLabel")}: {actionName}");
+ }
+
+ if (!string.IsNullOrEmpty(settings.ActionCondition))
+ {
+ sb.AppendLine($" {Config.GetResourceString("SettingsDelayLabel")}: {settings.ActionCondition} {Config.GetResourceString("SettingsSecondsLabel")}");
+ }
+
+ return sb.ToString().TrimEnd();
+ }
+
+ private static string GetActionDisplayName(string action)
+ {
+ return action switch
+ {
+ UsersAction.SEND_MEDIA_TO_ALL_CONTACTS => Config.GetResourceString("AllContactsButtonText"),
+ UsersAction.SEND_MEDIA_TO_DEFAULT_GROUPS => Config.GetResourceString("DefaultGroupsButtonText"),
+ UsersAction.SEND_MEDIA_TO_SPECIFIED_USERS => Config.GetResourceString("SpecifiedContactsButtonText"),
+ UsersAction.SEND_MEDIA_TO_SPECIFIED_GROUPS => Config.GetResourceString("SpecifiedGroupsButtonText"),
+ UsersAction.SEND_MEDIA_ONLY_TO_ME => Config.GetResourceString("OnlyMeButtonText"),
+ UsersAction.OFF => Config.GetResourceString("DisableAutoSendButtonText"),
+ _ => action
+ };
+ }
+
public static bool SetAutoSendVideoTimeToUser(long chatId, string time, IDefaultActionSetter defaultActionSetter, IUserGetter userGetter)
{
int userId = userGetter.GetUserIDbyTelegramID(chatId);
diff --git a/TelegramBot/Utils/Keyboard/Users.cs b/TelegramBot/Utils/Keyboard/Users.cs
index 9e8ec9d..967a273 100644
--- a/TelegramBot/Utils/Keyboard/Users.cs
+++ b/TelegramBot/Utils/Keyboard/Users.cs
@@ -271,6 +271,7 @@ public static InlineKeyboardMarkup GetUsersVideoSentUsersKeyboardMarkup()
},
new[]
{
+ InlineKeyboardButton.WithCallbackData(Config.GetResourceString("EnableAutoSendButtonText"), "user_set_video_send_users:enable"),
InlineKeyboardButton.WithCallbackData(Config.GetResourceString("DisableAutoSendButtonText"), $"user_set_video_send_users:{UsersAction.OFF}"),
},
new[]