Files
keepass2android/src/keepass2android-app/Utils/MessagePresenter.cs
2025-05-13 11:10:26 +02:00

166 lines
4.8 KiB
C#

using Android.OS;
using Android.Views;
using Google.Android.Material.Snackbar;
namespace keepass2android.Utils
{
public struct Message
{
public Message()
{
Text = null;
Severity = MessageSeverity.Info;
}
public string Text { get; set; }
public MessageSeverity Severity { get; set; }
public bool ShowOnSubsequentScreens { get; set; } = true;
}
public interface IMessagePresenter
{
void ShowMessage(Message message);
List<Message> PendingMessages
{
get;
}
}
internal class NonePresenter : IMessagePresenter
{
public void ShowMessage(Message message)
{
PendingMessages.Add(message);
}
public List<Message> PendingMessages
{
get;
set;
} = new List<Message>();
}
internal class ToastPresenter : IMessagePresenter
{
public void ShowMessage(Message message)
{
new Handler(Looper.MainLooper).Post(() =>
{
Toast.MakeText(App.Context, message.Text, ToastLength.Long).Show();
});
}
public List<Message> PendingMessages => new();
}
internal class ChainedSnackbarPresenter: IMessagePresenter
{
internal ChainedSnackbarPresenter(View anchorView)
{
this.AnchorView = anchorView;
}
private DateTime nextSnackbarShowTime = DateTime.Now;
private List<Message> queuedMessages = new List<Message>();
public View AnchorView { get; set; }
private TimeSpan chainingTime = TimeSpan.FromSeconds(1.5);
private Snackbar snackbar;
private Message lastMessage;
public void ShowMessage(Message message)
{
if (DateTime.Now <= nextSnackbarShowTime)
{
var waitDuration = nextSnackbarShowTime - DateTime.Now;
nextSnackbarShowTime = nextSnackbarShowTime.Add(chainingTime);
if (!queuedMessages.Any())
{
if (Looper.MainLooper != null)
{
new Handler(Looper.MainLooper).PostDelayed(ShowNextSnackbar,
(long)waitDuration.TotalMilliseconds);
}
else
{
Kp2aLog.Log("Currently cannot show message");
}
}
queuedMessages.Add(message);
return;
}
ShowSnackbarNow(message);
nextSnackbarShowTime = DateTime.Now.Add(chainingTime);
}
public List<Message> PendingMessages
{
get
{
List<Message> pendingMessages = new List<Message>();
if (snackbar?.IsShown == true)
{
pendingMessages.Add(lastMessage);
}
pendingMessages.AddRange(queuedMessages);
return pendingMessages;
}
}
private void ShowNextSnackbar()
{
if (!queuedMessages.Any())
{
return;
}
ShowSnackbarNow(queuedMessages.First());
queuedMessages.RemoveAt(0);
if (!queuedMessages.Any())
{
new Handler().PostDelayed(() => { ShowNextSnackbar(); }, (long)chainingTime.TotalMilliseconds);
}
}
private void ShowSnackbarNow(Message message)
{
snackbar = Snackbar
.Make(AnchorView, message.Text,
Snackbar.LengthLong);
snackbar.SetTextMaxLines(10);
if ((int)Build.VERSION.SdkInt >= 23)
{
if (message.Severity == MessageSeverity.Error)
{
snackbar.SetBackgroundTint(App.Context.GetColor(Resource.Color.md_theme_errorContainer));
snackbar.SetTextColor(App.Context.GetColor(Resource.Color.md_theme_onErrorContainer));
}
else if (message.Severity == MessageSeverity.Warning)
{
snackbar.SetBackgroundTint(App.Context.GetColor(Resource.Color.md_theme_inverseSurface));
snackbar.SetTextColor(App.Context.GetColor(Resource.Color.md_theme_inverseOnSurface));
}
else
{
snackbar.SetBackgroundTint(App.Context.GetColor(Resource.Color.md_theme_secondaryContainer));
snackbar.SetTextColor(App.Context.GetColor(Resource.Color.md_theme_onSecondaryContainer));
}
}
snackbar.Show();
lastMessage = message;
}
}
}