use snackbars instead of toasts (in most cases)

This commit is contained in:
Philipp Crocoll
2025-04-08 10:37:40 +02:00
parent e76f3999b6
commit 17241bc422
41 changed files with 1080 additions and 747 deletions

View File

@@ -29,6 +29,14 @@ namespace keepass2android
}
public enum MessageSeverity
{
Info,
Warning,
Error
}
/// <summary>
/// Interface through which Activities and the logic layer can access some app specific functionalities and Application static data
/// </summary>
@@ -102,10 +110,13 @@ namespace keepass2android
Context ctx,
string messageSuffix = "");
/// <summary>
/// Returns a Handler object which can run tasks on the UI thread
/// </summary>
Handler UiThreadHandler { get; }
void ShowMessage(Context ctx, int resourceId, MessageSeverity severity);
void ShowMessage(Context ctx, string text, MessageSeverity severity);
/// <summary>
/// Returns a Handler object which can run tasks on the UI thread
/// </summary>
Handler UiThreadHandler { get; }
IProgressDialog CreateProgressDialog(Context ctx);

View File

@@ -94,7 +94,7 @@ namespace keepass2android
}
if ((resultCode == Result.Canceled) && (data != null) && (data.HasExtra("EXTRA_ERROR_MESSAGE")))
{
ShowToast(data.GetStringExtra("EXTRA_ERROR_MESSAGE"));
ShowErrorToast(data.GetStringExtra("EXTRA_ERROR_MESSAGE"));
}
if (resultCode == Result.Ok)
@@ -150,7 +150,7 @@ namespace keepass2android
protected abstract void StartFileChooser(string path, int requestCode, bool isForSave);
protected abstract void ShowToast(string text);
protected abstract void ShowErrorToast(string text);
protected abstract void ShowInvalidSchemeMessage(string dataString);
@@ -208,7 +208,7 @@ namespace keepass2android
{
return () =>
{
ShowToast(_app.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message);
ShowErrorToast(_app.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message);
ReturnCancel();
};
}

View File

@@ -130,24 +130,24 @@ namespace keepass2android
if ( !String.IsNullOrEmpty(message) ) {
Kp2aLog.Log("OnFinish message: " + message);
if (makeDialog && ctx != null)
{
try
{
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ctx);
builder.SetMessage(message)
.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => ((Dialog)sender).Dismiss())
.Show();
{
try
{
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ctx);
builder.SetMessage(message)
.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => ((Dialog)sender).Dismiss())
.Show();
}
catch (Exception)
{
Toast.MakeText(ctx, message, ToastLength.Long).Show();
}
}
{
Toast.MakeText(ctx, message, ToastLength.Long).Show();
}
}
else
Toast.MakeText(ctx ?? Application.Context, message, ToastLength.Long).Show();
}
}
}
}
}

View File

@@ -59,7 +59,7 @@ namespace keepass2android
}
catch (ActivityNotFoundException)
{
Toast.MakeText(Context, Resource.String.no_url_handler, ToastLength.Long).Show();
App.Kp2a.ShowMessage(Context, Resource.String.no_url_handler, MessageSeverity.Error);
}
};
@@ -71,7 +71,7 @@ namespace keepass2android
}
catch (ActivityNotFoundException)
{
Toast.MakeText(Context, Resource.String.no_url_handler, ToastLength.Long).Show();
App.Kp2a.ShowMessage(Context, Resource.String.no_url_handler, MessageSeverity.Error);
}
};
FindViewById(Resource.Id.translate).Click += delegate
@@ -82,7 +82,7 @@ namespace keepass2android
}
catch (ActivityNotFoundException)
{
Toast.MakeText(Context, Resource.String.no_url_handler, ToastLength.Long).Show();
App.Kp2a.ShowMessage(Context, Resource.String.no_url_handler, MessageSeverity.Error);
}
}; FindViewById(Resource.Id.donate).Click += delegate
{

View File

@@ -183,7 +183,7 @@ namespace keepass2android
// Verify that a password or keyfile is set
if (password.Length == 0 && !keyfileCheckbox.Checked)
{
Toast.MakeText(this, Resource.String.error_nopass, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.error_nopass, MessageSeverity.Error);
return;
}
@@ -207,7 +207,7 @@ namespace keepass2android
}
catch (Exception)
{
Toast.MakeText(this, Resource.String.error_adding_keyfile, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.error_adding_keyfile, MessageSeverity.Error);
return;
}
}
@@ -235,7 +235,7 @@ namespace keepass2android
if (! pass.Equals(confpass))
{
// Passwords do not match
Toast.MakeText(this, Resource.String.error_pass_match, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.error_pass_match, MessageSeverity.Error);
return false;
}
return true;

View File

@@ -41,7 +41,7 @@ namespace keepass2android
string requestedUrl = Intent.GetStringExtra(ChooseForAutofillActivityBase.ExtraQueryString);
if (requestedUrl == null)
{
Toast.MakeText(this, "Cannot execute query for null.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Cannot execute query for null.", MessageSeverity.Error);
RestartApp();
return;
}

View File

@@ -78,7 +78,7 @@ namespace keepass2android
var task = new EntryActivity.WriteBinaryTask(_activity, App.Kp2a, new ActionOnFinish(_activity, (success, message, activity) =>
{
if (!success)
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
}
), ((EntryActivity)_activity).Entry.Binaries.Get(_binaryToSave), ioc);
ProgressTask pt = new ProgressTask(App.Kp2a, _activity, task);
@@ -107,8 +107,8 @@ namespace keepass2android
public const int requestCodeBinaryFilename = 42376;
public const int requestCodeSelFileStorageForWriteAttachment = 42377;
protected override View? SnackbarAnchorView => FindViewById(Resource.Id.main_content);
public static void Launch(Activity act, PwEntry pw, int pos, AppTask appTask, ActivityFlags? flags = null, int historyIndex=-1)
{
@@ -767,9 +767,9 @@ namespace keepass2android
if (parent == null || (parent.Exists() && !parent.IsDirectory))
{
Toast.MakeText(this,
App.Kp2a.ShowMessage(this,
Resource.String.error_invalid_path,
ToastLength.Long).Show();
MessageSeverity.Error);
return null;
}
@@ -778,9 +778,9 @@ namespace keepass2android
// Create parent directory
if (!parent.Mkdirs())
{
Toast.MakeText(this,
App.Kp2a.ShowMessage(this,
Resource.String.error_could_not_create_parent,
ToastLength.Long).Show();
MessageSeverity.Error);
return null;
}
@@ -794,18 +794,18 @@ namespace keepass2android
}
catch (Exception exWrite)
{
Toast.MakeText(this,
App.Kp2a.ShowMessage(this,
GetString(Resource.String.SaveAttachment_Failed, new Java.Lang.Object[] {filename})
+ exWrite.Message, ToastLength.Long).Show();
+ exWrite.Message, MessageSeverity.Error);
return null;
}
finally
{
MemUtil.ZeroByteArray(pbData);
}
Toast.MakeText(this,
App.Kp2a.ShowMessage(this,
GetString(Resource.String.SaveAttachment_doneMessage, new Java.Lang.Object[] {filename}),
ToastLength.Short).Show();
MessageSeverity.Info);
return Uri.Parse("content://" + AttachmentContentProvider.Authority + "/"
+ filename);
}
@@ -838,7 +838,7 @@ namespace keepass2android
catch (ActivityNotFoundException)
{
//ignore
Toast.MakeText(this, "Couldn't open file", ToastLength.Short).Show();
App.Kp2a.ShowMessage(this, "Couldn't open file", MessageSeverity.Error);
}
}
@@ -1558,7 +1558,7 @@ namespace keepass2android
}
catch (ActivityNotFoundException)
{
Toast.MakeText(this, Resource.String.no_url_handler, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.no_url_handler, MessageSeverity.Error);
}
return true;
}

View File

@@ -64,10 +64,10 @@ namespace keepass2android
{
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden, Theme = "@style/Kp2aTheme_ActionBar")]
public class EntryEditActivity : LockCloseActivity {
public const String KeyEntry = "entry";
protected override View? SnackbarAnchorView => FindViewById(Resource.Id.main_content);
public const String KeyEntry = "entry";
public const String KeyParent = "parent";
public const String KeyTemplateUuid = "KeyTemplateUuid";
@@ -715,7 +715,7 @@ namespace keepass2android
}
catch(Exception exAttach)
{
Toast.MakeText(this, GetString(Resource.String.AttachFailed)+" "+exAttach.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, GetString(Resource.String.AttachFailed)+" "+exAttach.Message, MessageSeverity.Error);
}
State.EntryModified = true;
PopulateBinaries();
@@ -833,7 +833,7 @@ namespace keepass2android
string s = Util.GetFilenameFromInternalFileChooser(data, this);
if (s == null)
{
Toast.MakeText(this, "No URI retrieved.", ToastLength.Short).Show();
App.Kp2a.ShowMessage(this, "No URI retrieved.", MessageSeverity.Error);
return;
}
uri = Uri.Parse(s);
@@ -1139,7 +1139,7 @@ namespace keepass2android
}
else
{
Toast.MakeText(this, "did not find target field", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "did not find target field", MessageSeverity.Error);
}
@@ -1158,7 +1158,8 @@ namespace keepass2android
{
if (GoogleApiAvailability.Instance.IsGooglePlayServicesAvailable(this) != ConnectionResult.Success)
{
Toast.MakeText(this, Resource.String.qr_scanning_error_no_google_play_services, ToastLength.Long);
App.Kp2a.ShowMessage(this, Resource.String.qr_scanning_error_no_google_play_services,
MessageSeverity.Error);
return;
}
@@ -1178,7 +1179,7 @@ namespace keepass2android
}
else
{
Toast.MakeText(this, "Scanned code should contain an otpauth:// text.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Scanned code should contain an otpauth:// text.", MessageSeverity.Warning);
}
}))
.AddOnFailureListener(new FailureListener((e) =>
@@ -1503,7 +1504,7 @@ namespace keepass2android
// Require title
String title = Util.GetEditText(this, Resource.Id.entry_title);
if ( title.Length == 0 ) {
Toast.MakeText(this, Resource.String.error_title_required, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.error_title_required, MessageSeverity.Error);
return false;
}
@@ -1513,7 +1514,7 @@ namespace keepass2android
DateTime newExpiry = new DateTime();
if ((State.Entry.Expires) && (!DateTime.TryParse( Util.GetEditText(this,Resource.Id.entry_expires), out newExpiry)))
{
Toast.MakeText(this, Resource.String.error_invalid_expiry_date, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.error_invalid_expiry_date, MessageSeverity.Error);
return false;
}
State.Entry.ExpiryTime = newExpiry.ToUniversalTime();
@@ -1527,13 +1528,13 @@ namespace keepass2android
string key = keyView.Text;
if (String.IsNullOrEmpty(key)) {
Toast.MakeText(this, Resource.String.error_string_key, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.error_string_key, MessageSeverity.Error);
return false;
}
if (allKeys.Contains(key))
{
Toast.MakeText(this, GetString(Resource.String.error_string_duplicate_key, new Object[]{key}), ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, GetString(Resource.String.error_string_duplicate_key, new Object[]{key}), MessageSeverity.Error);
return false;
}

View File

@@ -29,9 +29,9 @@ namespace keepass2android
var exportDb = new ExportDatabaseActivity.ExportDb(_activity, App.Kp2a, new ActionOnFinish(_activity, (success, message, activity) =>
{
if (!success)
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
else
Toast.MakeText(activity, _activity.GetString(Resource.String.export_database_successful), ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, _activity.GetString(Resource.String.export_database_successful), MessageSeverity.Info);
activity.Finish();
}
), _ffp, ioc);

View File

@@ -107,7 +107,7 @@ namespace keepass2android
{
if (!success)
{
Toast.MakeText(activity, messageOrFilename, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, messageOrFilename, MessageSeverity.Error);
return;
}
SaveFile(new IOConnectionInfo { Path = FileSelectHelper.ConvertFilenameToIocPath(messageOrFilename) });

View File

@@ -115,6 +115,7 @@ namespace keepass2android
string keyContent = keyContentTxt.Text;
string toastMsg = null;
MessageSeverity severity = MessageSeverity.Info;
if (!string.IsNullOrEmpty(keyName) && !string.IsNullOrEmpty(keyContent))
{
try
@@ -128,7 +129,9 @@ namespace keepass2android
{
toastMsg = ctx.GetString(Resource.String.private_key_save_failed,
new Java.Lang.Object[] { e.Message });
}
severity = MessageSeverity.Error;
}
}
else
{
@@ -136,7 +139,7 @@ namespace keepass2android
}
if (toastMsg!= null) {
Toast.MakeText(_activity, toastMsg, ToastLength.Long).Show();
App.Kp2a.ShowMessage(_activity, toastMsg, severity);
}
UpdatePrivateKeyNames(keyNamesAdapter, fileStorage, ctx);
@@ -153,7 +156,7 @@ namespace keepass2android
int msgId = deleted ? Resource.String.private_key_delete : Resource.String.private_key_delete_failed;
string msg = ctx.GetString(msgId, new Java.Lang.Object[] { keyName });
Toast.MakeText(_activity, msg, ToastLength.Long).Show();
App.Kp2a.ShowMessage(_activity, msg, deleted ? MessageSeverity.Info :MessageSeverity.Error);
UpdatePrivateKeyNames(keyNamesAdapter, fileStorage, ctx);
keySpinner.SetSelection(SftpKeySpinnerCreateNewIdx);
@@ -581,9 +584,9 @@ namespace keepass2android
// Make sure file name exists
if (filename.Length == 0)
{
Toast.MakeText(_activity,
App.Kp2a.ShowMessage(_activity,
Resource.String.error_filename_required,
ToastLength.Long).Show();
MessageSeverity.Error);
return false;
}
@@ -604,9 +607,9 @@ namespace keepass2android
}
catch (NoFileStorageFoundException)
{
Toast.MakeText(_activity,
App.Kp2a.ShowMessage(_activity,
"Unexpected scheme in "+filename,
ToastLength.Long).Show();
MessageSeverity.Error);
return false;
}
@@ -620,9 +623,9 @@ namespace keepass2android
if (parent == null || (parent.Exists() && !parent.IsDirectory))
{
Toast.MakeText(_activity,
App.Kp2a.ShowMessage(_activity,
Resource.String.error_invalid_path,
ToastLength.Long).Show();
MessageSeverity.Error);
return false;
}
@@ -631,9 +634,9 @@ namespace keepass2android
// Create parent dircetory
if (!parent.Mkdirs())
{
Toast.MakeText(_activity,
App.Kp2a.ShowMessage(_activity,
Resource.String.error_could_not_create_parent,
ToastLength.Long).Show();
MessageSeverity.Error);
return false;
}
@@ -643,11 +646,11 @@ namespace keepass2android
}
catch (Java.IO.IOException ex)
{
Toast.MakeText(
App.Kp2a.ShowMessage(
_activity,
_activity.GetText(Resource.String.error_file_not_create) + " "
+ ex.LocalizedMessage,
ToastLength.Long).Show();
MessageSeverity.Error);
return false;
}
@@ -700,7 +703,7 @@ namespace keepass2android
_activity.StartActivityForResult(i, _requestCode);
#else
Toast.MakeText(LocaleManager.LocalizedAppContext, "File chooser is excluded!", ToastLength.Long).Show();
App.Kp2a.ShowMessage(LocaleManager.LocalizedAppContext, "File chooser is excluded!", MessageSeverity.Error);
#endif
return true;
}
@@ -782,7 +785,7 @@ namespace keepass2android
{
if (!success)
{
Toast.MakeText(newActivity, messageOrFilename, ToastLength.Long).Show();
App.Kp2a.ShowMessage(newActivity, messageOrFilename, MessageSeverity.Error);
return;
}
var ioc = new IOConnectionInfo { Path = ConvertFilenameToIocPath(messageOrFilename) };

View File

@@ -251,7 +251,7 @@ namespace keepass2android
catch (Exception e)
{
CheckCurrentRadioButton();
Toast.MakeText(this, e.ToString(), ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, e.ToString(), MessageSeverity.Error);
FindViewById(Resource.Id.radio_buttons).Visibility = ViewStates.Visible;
FindViewById(Resource.Id.fingerprint_auth_container).Visibility = ViewStates.Gone;
}

View File

@@ -543,7 +543,7 @@ namespace keepass2android
}
catch (Exception e)
{
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, e.Message, MessageSeverity.Error);
}
return password;

View File

@@ -56,6 +56,8 @@ namespace keepass2android
public const int RequestCodeActivateRealSearch = 12366;
protected override View? SnackbarAnchorView => FindViewById(Resource.Id.main_content);
static readonly Dictionary<int /*resource id*/, int /*prio*/> bottomBarElementsPriority = new Dictionary<int, int>()
{
{ Resource.Id.cancel_insert_element, 20 },
@@ -927,7 +929,7 @@ namespace keepass2android
{
((GroupBaseActivity)activity)?.StopMovingElements();
if (!String.IsNullOrEmpty(message))
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
}));
var progressTask = new ProgressTask(App.Kp2a, this, moveElement);
progressTask.Run();
@@ -1328,7 +1330,7 @@ namespace keepass2android
{
Handler.Post(() =>
{
Toast.MakeText(ActiveActivity ?? LocaleManager.LocalizedAppContext, "Unrecoverable error: " + Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(ActiveActivity ?? LocaleManager.LocalizedAppContext, "Unrecoverable error: " + Message, MessageSeverity.Error);
});
App.Kp2a.Lock(false);

View File

@@ -111,9 +111,10 @@ namespace keepass2android
SetResult (Result.Ok, intent);
Finish ();
} else {
Toast.MakeText (this, Resource.String.error_no_name, ToastLength.Long).Show ();
}
} else
{
App.Kp2a.ShowMessage(this, Resource.String.error_no_name, MessageSeverity.Error);
}
};
if (Intent.HasExtra(KeyGroupUuid))

View File

@@ -316,7 +316,7 @@ namespace keepass2android
try { ck.AddUserKey(new KcpKeyFile(strAbs)); }
catch (InvalidOperationException)
{
Toast.MakeText(LocaleManager.LocalizedAppContext,Resource.String.error_adding_keyfile,ToastLength.Long).Show();
App.Kp2a.ShowMessage(LocaleManager.LocalizedAppContext,Resource.String.error_adding_keyfile, MessageSeverity.Error);
return false;
}
catch (Exception) { throw; }

View File

@@ -21,8 +21,10 @@ using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Google.Android.Material.Dialog;
using keepass2android;
using keepass2android.Utils;
namespace keepass2android
{
@@ -76,19 +78,34 @@ namespace keepass2android
base.OnPause();
TimeoutHelper.Pause(this);
}
App.Kp2a.MessagePresenter = new NonePresenter();
}
protected override void OnDestroy()
{
base.OnDestroy();
GC.Collect();
}
protected override void OnResume() {
base.OnResume();
TimeoutHelper.Resume(this);
}
protected override void OnResume()
{
base.OnResume();
TimeoutHelper.Resume(this);
var snackbarAnchorView = SnackbarAnchorView;
if (snackbarAnchorView != null)
{
App.Kp2a.MessagePresenter = new ChainedSnackbarPresenter(snackbarAnchorView);
}
else
{
App.Kp2a.MessagePresenter = new ToastPresenter();
}
}
protected virtual View? SnackbarAnchorView => null;
public const int RequestCodeChallengeYubikey = 793;

View File

@@ -145,7 +145,7 @@ namespace keepass2android
catch (Exception e)
{
Kp2aLog.LogUnexpectedError(e);
Toast.MakeText(this, "No Yubikey OTP found!", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "No Yubikey OTP found!", MessageSeverity.Error);
Finish();
return;
}

View File

@@ -66,6 +66,7 @@ using Exception = System.Exception;
using String = System.String;
using Toolbar = AndroidX.AppCompat.Widget.Toolbar;
using AndroidX.Core.Content;
using Google.Android.Material.Snackbar;
namespace keepass2android
{
@@ -309,7 +310,7 @@ namespace keepass2android
catch (Exception e)
{
Kp2aLog.Log(e.ToString());
Toast.MakeText(this, "Error: " + e.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Error: " + e.Message, MessageSeverity.Error);
return;
}
@@ -328,8 +329,7 @@ namespace keepass2android
ChallengeInfo temp = _challengeProv.Encrypt(_challengeSecret);
if (!temp.Save(_otpAuxIoc))
{
Toast.MakeText(this, Resource.String.ErrorUpdatingChalAuxFile, ToastLength.Long)
.Show();
App.Kp2a.ShowMessage(this, Resource.String.ErrorUpdatingChalAuxFile, MessageSeverity.Error);
return false;
}
@@ -348,7 +348,7 @@ namespace keepass2android
}
else
{
Toast.MakeText(this, Resource.String.bad_resp, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.bad_resp, MessageSeverity.Error);
}
}
}
@@ -458,7 +458,7 @@ namespace keepass2android
}
else
{
Toast.MakeText(Activity,GetErrorMessage(), ToastLength.Long).Show();
App.Kp2a.ShowMessage(Activity,GetErrorMessage(), MessageSeverity.Error);
}
return;
@@ -957,7 +957,7 @@ namespace keepass2android
{
btn.SetImageResource(Resource.Drawable.baseline_fingerprint_24);
}, 1300);
Toast.MakeText(this, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, message, MessageSeverity.Error);
}
public void OnBiometricAttemptFailed(string message)
@@ -1036,7 +1036,7 @@ namespace keepass2android
if (_appnameclickCount == 6)
{
Kp2aLog.LogUnexpectedError(new Exception("some blabla"));
Toast.MakeText(this, "Once again and the app will crash.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Once again and the app will crash.", MessageSeverity.Warning);
}
if (_appnameclickCount == 7)
@@ -1123,7 +1123,7 @@ namespace keepass2android
//For security reasons: discard the OTP (otherwise the user might not select a database now and forget
//about the OTP, but it would still be stored in the Intents and later be passed to PasswordActivity again.
Toast.MakeText(this, GetString(Resource.String.otp_discarded_because_no_db), ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, GetString(Resource.String.otp_discarded_because_no_db), MessageSeverity.Warning);
GoToFileSelectActivity();
return false;
}
@@ -1400,7 +1400,7 @@ namespace keepass2android
string errorMessage;
if (!CreateCompositeKey(out compositeKey, out errorMessage)) return (() =>
{
Toast.MakeText(this, errorMessage, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, errorMessage, MessageSeverity.Warning);
_performingLoad = false;
});
return () => { PerformLoadDatabaseWithCompositeKey(compositeKey); };
@@ -1668,7 +1668,7 @@ namespace keepass2android
//did we find a field?
if (!foundEmptyField)
{
Toast.MakeText(this, GetString(Resource.String.otp_discarded_no_space), ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, GetString(Resource.String.otp_discarded_no_space), MessageSeverity.Error);
}
}
@@ -1729,80 +1729,128 @@ namespace keepass2android
UsedFingerprintUnlock = false;
}
protected override View? SnackbarAnchorView => FindViewById(Resource.Id.main_content);
protected override void OnResume()
{
base.OnResume();
_activityDesign.ReapplyTheme();
{
base.OnResume();
_activityDesign.ReapplyTheme();
Kp2aLog.Log("starting: " + _starting + ", Finishing: " + IsFinishing + ", _performingLoad: " + _performingLoad);
Kp2aLog.Log("starting: " + _starting + ", Finishing: " + IsFinishing + ", _performingLoad: " +
_performingLoad);
CheckBox cbOfflineMode = (CheckBox)FindViewById(Resource.Id.work_offline);
App.Kp2a.OfflineMode = cbOfflineMode.Checked = App.Kp2a.OfflineModePreference; //this won't overwrite new user settings because every change is directly saved in settings
LinearLayout offlineModeContainer = FindViewById<LinearLayout>(Resource.Id.work_offline_container);
var cachingFileStorage = App.Kp2a.GetFileStorage(_ioConnection) as CachingFileStorage;
if ((cachingFileStorage != null) && cachingFileStorage.IsCached(_ioConnection))
{
offlineModeContainer.Visibility = ViewStates.Visible;
}
else
{
offlineModeContainer.Visibility = ViewStates.Gone;
App.Kp2a.OfflineMode = false;
}
CheckBox cbOfflineMode = (CheckBox)FindViewById(Resource.Id.work_offline);
App.Kp2a.OfflineMode =
cbOfflineMode.Checked =
App.Kp2a
.OfflineModePreference; //this won't overwrite new user settings because every change is directly saved in settings
LinearLayout offlineModeContainer = FindViewById<LinearLayout>(Resource.Id.work_offline_container);
var cachingFileStorage = App.Kp2a.GetFileStorage(_ioConnection) as CachingFileStorage;
if ((cachingFileStorage != null) && cachingFileStorage.IsCached(_ioConnection))
{
offlineModeContainer.Visibility = ViewStates.Visible;
}
else
{
offlineModeContainer.Visibility = ViewStates.Gone;
App.Kp2a.OfflineMode = false;
}
View killButton = FindViewById(Resource.Id.kill_app);
if (PreferenceManager.GetDefaultSharedPreferences(this)
.GetBoolean(GetString(Resource.String.show_kill_app_key), false))
{
killButton.Click += (sender, args) =>
{
_killOnDestroy = true;
View killButton = FindViewById(Resource.Id.kill_app);
if (PreferenceManager.GetDefaultSharedPreferences(this)
.GetBoolean(GetString(Resource.String.show_kill_app_key), false))
{
killButton.Click += (sender, args) =>
{
_killOnDestroy = true;
SetResult(Result.Canceled);
Finish();
Finish();
};
killButton.Visibility = ViewStates.Visible;
};
killButton.Visibility = ViewStates.Visible;
}
else
{
killButton.Visibility = ViewStates.Gone;
}
}
else
{
killButton.Visibility = ViewStates.Gone;
}
TryGetOtpFromClipboard();
TryGetOtpFromClipboard();
if (!_keepPasswordInOnResume)
{
if (
_lastOnPauseTime < DateTime.Now - TimeSpan.FromSeconds(5) //only clear when user left the app for more than 5 seconds (allows to use Yubiclip, also allows to switch shortly to another app)
&&
PreferenceManager.GetDefaultSharedPreferences(this)
.GetBoolean(GetString(Resource.String.ClearPasswordOnLeave_key), true))
{
ClearEnteredPassword();
}
if (!_keepPasswordInOnResume)
{
if (
_lastOnPauseTime <
DateTime.Now -
TimeSpan.FromSeconds(
5) //only clear when user left the app for more than 5 seconds (allows to use Yubiclip, also allows to switch shortly to another app)
&&
PreferenceManager.GetDefaultSharedPreferences(this)
.GetBoolean(GetString(Resource.String.ClearPasswordOnLeave_key), true))
{
ClearEnteredPassword();
}
}
}
_keepPasswordInOnResume = false;
_keepPasswordInOnResume = false;
MakePasswordMaskedOrVisible();
MakePasswordMaskedOrVisible();
UpdateOkButtonState();
UpdateOkButtonState();
if (KeyProviderTypes.Contains(KeyProviders.Challenge))
{
FindViewById(Resource.Id.otpInitView).Visibility = _challengeSecret == null ? ViewStates.Visible : ViewStates.Gone;
}
if (KeyProviderTypes.Contains(KeyProviders.Challenge))
{
FindViewById(Resource.Id.otpInitView).Visibility =
_challengeSecret == null ? ViewStates.Visible : ViewStates.Gone;
}
/*
Snackbar snackbar = Snackbar
.Make(FindViewById(Resource.Id.main_content),
"snack snack snack snack snack snack snack snack snack snack snack snack snack snack snacksnack snack snacksnack snack snacksnack snack snack snack snack snack snack snack snack snack snack snack snack snack snack snacksnack snack snacksnack snack snacksnack snack snack snack snack snacksnack snack snack ",
Snackbar.LengthLong);
snackbar.SetTextMaxLines(5);
snackbar.SetBackgroundTint(GetColor(Resource.Color.md_theme_secondaryContainer));
snackbar.SetTextColor(GetColor(Resource.Color.md_theme_onSecondaryContainer));
snackbar.SetAction("dismiss",
view => snackbar.SetBackgroundTint(GetColor(Resource.Color.md_theme_surfaceContainer)));
//use !IsFinishing to make sure we're not starting another activity when we're already finishing (e.g. due to TaskComplete in OnActivityResult)
//use !performingLoad to make sure we're not already loading the database (after ActivityResult from File-Prepare-Activity; this would cause _loadDbFileTask to exist when we reload later!)
if ( !IsFinishing && !_performingLoad)
snackbar.Show();
new Handler().PostDelayed(() =>
{
Snackbar snackbar2 = Snackbar
.Make(FindViewById(Resource.Id.main_content), "snack snack snack ",
Snackbar.LengthLong);
snackbar2.SetTextMaxLines(5);
snackbar2.SetBackgroundTint(GetColor(Resource.Color.md_theme_errorContainer));
snackbar2.SetTextColor(GetColor(Resource.Color.md_theme_onErrorContainer));
snackbar2.Show();
}, 1500);
new Handler().PostDelayed(() =>
{
Snackbar snackbar2 = Snackbar
.Make(FindViewById(Resource.Id.main_content), "snack snack warn ",
Snackbar.LengthLong);
snackbar2.SetTextMaxLines(5);
snackbar2.SetBackgroundTint(GetColor(Resource.Color.md_theme_inverseSurface));
snackbar2.SetTextColor(GetColor(Resource.Color.md_theme_inverseOnSurface));
snackbar2.Show();
}, 2500);*/
//use !IsFinishing to make sure we're not starting another activity when we're already finishing (e.g. due to TaskComplete in OnActivityResult)
//use !performingLoad to make sure we're not already loading the database (after ActivityResult from File-Prepare-Activity; this would cause _loadDbFileTask to exist when we reload later!)
if ( !IsFinishing && !_performingLoad)
{
@@ -1954,7 +2002,7 @@ namespace keepass2android
btn.Tag = error;
Toast.MakeText(this, Resource.String.fingerprint_reenable2, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.fingerprint_reenable2, MessageSeverity.Error);
_biometricDec = null;
return false;
@@ -2024,7 +2072,7 @@ namespace keepass2android
/*
private void errorMessage(CharSequence text)
{
Toast.MakeText(this, text, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, text, MessageSeverity.Error);
}
*/
@@ -2084,7 +2132,9 @@ namespace keepass2android
_act.LoadingErrorCount++;
}
if ((Exception != null) && (Exception.Message == KeePassLib.Resources.KLRes.FileCorrupted))
if ((Exception != null) && (Exception.Message == KeePassLib.Resources.KLRes.FileCorrupted))
{
Message = _act.GetString(Resource.String.CorruptDatabaseHelp);
}
@@ -2150,7 +2200,8 @@ namespace keepass2android
}
else
{
DisplayMessage(_act);
MessageSeverity severity = Success ? MessageSeverity.Info : MessageSeverity.Error;
App.Kp2a.ShowMessage(_act, Message, severity);
if (Success)
{
_act.LaunchNextActivity();
@@ -2234,7 +2285,7 @@ namespace keepass2android
private void ShowError(string message)
{
App.Kp2a.ShowToast(message);
App.Kp2a.ShowToast(message, MessageSeverity.Error);
}
}
private class PasswordActivityBroadcastReceiver : BroadcastReceiver

View File

@@ -128,11 +128,11 @@ namespace keepass2android
Kp2aLog.LogUnexpectedError(e);
}
if (String.IsNullOrEmpty(_requestedUrl))
Toast.MakeText(this, GetString(Resource.String.query_credentials, new Java.Lang.Object[] {pluginDisplayName}), ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, GetString(Resource.String.query_credentials, new Java.Lang.Object[] {pluginDisplayName}), MessageSeverity.Info);
else
Toast.MakeText(this,
App.Kp2a.ShowMessage(this,
GetString(Resource.String.query_credentials_for_url,
new Java.Lang.Object[] { pluginDisplayName, _requestedUrl }), ToastLength.Long).Show(); ;
new Java.Lang.Object[] { pluginDisplayName, _requestedUrl }), MessageSeverity.Info); ;
}
private void StartQuery()

View File

@@ -35,6 +35,7 @@ using KeePassLib;
using KeePassLib.Serialization;
using Toolbar = AndroidX.AppCompat.Widget.Toolbar;
using AndroidX.Core.Content;
using keepass2android.Utils;
namespace keepass2android
{
@@ -203,7 +204,7 @@ namespace keepass2android
btn.SetImageResource(Resource.Drawable.baseline_fingerprint_24);
}, 1300);
Toast.MakeText(this, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, message, MessageSeverity.Error);
}
@@ -325,7 +326,7 @@ namespace keepass2android
{
Kp2aLog.Log("QuickUnlock not successful!");
App.Kp2a.Lock(false);
Toast.MakeText(this, GetString(Resource.String.QuickUnlock_fail), ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, GetString(Resource.String.QuickUnlock_fail), MessageSeverity.Error);
Finish();
}
@@ -383,8 +384,9 @@ namespace keepass2android
{
base.OnResume();
_design.ReapplyTheme();
CheckIfUnloaded();
App.Kp2a.MessagePresenter = new ChainedSnackbarPresenter(FindViewById(Resource.Id.main_content));
CheckIfUnloaded();
InitFingerprintUnlock();
@@ -449,7 +451,8 @@ namespace keepass2android
protected override void OnPause()
{
if (_biometryIdentifier != null)
App.Kp2a.MessagePresenter = new NonePresenter();
if (_biometryIdentifier != null)
{
Kp2aLog.Log("FP: Stop listening");
_biometryIdentifier.StopListening();

View File

@@ -1,5 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<ScrollView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/entry_scroll"
android:background="?android:attr/colorBackground"
@@ -267,4 +273,5 @@
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</ScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -392,7 +392,7 @@ namespace keepass2android
if (ioc.Path.Length == 0)
{
// No file name
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.FileNotFound, MessageSeverity.Error);
return false;
}
@@ -400,7 +400,7 @@ namespace keepass2android
if (!dbFile.Exists())
{
// File does not exist
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.FileNotFound, MessageSeverity.Error);
return false;
}
}
@@ -408,7 +408,7 @@ namespace keepass2android
{
if (!ioc.Path.StartsWith("content://"))
{
Toast.MakeText(this, Resource.String.error_can_not_handle_uri, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.error_can_not_handle_uri, MessageSeverity.Error);
return false;
}
IoUtil.TryTakePersistablePermissions(this.ContentResolver, intent.Data);
@@ -468,7 +468,7 @@ namespace keepass2android
}
catch (Exception e)
{
Toast.MakeText(this, "Failed to open child databases",ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Failed to open child databases", MessageSeverity.Error);
Kp2aLog.LogUnexpectedError(e);
}

View File

@@ -70,15 +70,15 @@ namespace keepass2android
protected Bundle State { get; set; }
protected override void ShowToast(string text)
protected override void ShowErrorToast(string text)
{
Toast.MakeText(this, text, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, text, MessageSeverity.Error);
}
protected override void ShowInvalidSchemeMessage(string dataString)
{
Toast.MakeText(this, Resources.GetString(Resource.String.unknown_uri_scheme, new Java.Lang.Object[] { dataString }),
ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resources.GetString(Resource.String.unknown_uri_scheme, new Java.Lang.Object[] { dataString }),
MessageSeverity.Error);
}
protected override string IntentToFilename(Intent data)
@@ -194,7 +194,7 @@ namespace keepass2android
StartActivityForResult(intent, requestCode);
#else
Toast.MakeText(this, "File chooser is excluded!", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "File chooser is excluded!", MessageSeverity.Error);
#endif
}

View File

@@ -57,7 +57,7 @@ namespace keepass2android
// Verify that passwords match
if ( ! pass.Equals(confpass) ) {
// Passwords do not match
Toast.MakeText(Context, Resource.String.error_pass_match, ToastLength.Long).Show();
App.Kp2a.ShowMessage(Context, Resource.String.error_pass_match, MessageSeverity.Error);
return;
}
@@ -67,7 +67,7 @@ namespace keepass2android
// Verify that a password or keyfile is set
if ( pass.Length == 0 && keyfile.Length == 0 ) {
Toast.MakeText(Context, Resource.String.error_nopass, ToastLength.Long).Show();
App.Kp2a.ShowMessage(Context, Resource.String.error_nopass, MessageSeverity.Error);
return;
}
@@ -114,7 +114,7 @@ namespace keepass2android
edit.PutString(App.Kp2a.CurrentDb.CurrentFingerprintModePrefKey, FingerprintUnlockMode.Disabled.ToString());
edit.Commit();
Toast.MakeText(_dlg.Context, Resource.String.fingerprint_reenable, ToastLength.Long).Show();
App.Kp2a.ShowMessage(_dlg.Context, Resource.String.fingerprint_reenable, MessageSeverity.Warning);
_dlg.Context.StartActivity(typeof(BiometricSetupActivity));
}

View File

@@ -121,7 +121,7 @@ namespace keepass2android
} catch (Exception e)
{
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, e.Message, MessageSeverity.Error);
SetResult(Result.Canceled);
Finish();
return;
@@ -184,7 +184,7 @@ namespace keepass2android
createUrlEntry.Click += (sender, e) =>
{
GroupActivity.Launch(this, new CreateEntryThenCloseTask { Url = searchUrl, ShowUserNotifications = (AppTask as SelectEntryTask)?.ShowUserNotifications ?? ActivationCondition.Always }, new ActivityLaunchModeRequestCode(0));
Toast.MakeText(this, GetString(Resource.String.select_group_then_add, new Java.Lang.Object[] { GetString(Resource.String.add_entry) }), ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, GetString(Resource.String.select_group_then_add, new Java.Lang.Object[] { GetString(Resource.String.add_entry) }), MessageSeverity.Info);
};
}
else

View File

@@ -56,7 +56,7 @@ namespace keepass2android
OnFinish onFinish = new ActionOnFinish(_activity, (success, message, activity) =>
{
if (!String.IsNullOrEmpty(message))
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
// Tell the adapter to refresh it's list
BaseAdapter adapter = (activity as GroupBaseActivity)?.ListAdapter;

View File

@@ -161,7 +161,7 @@ namespace PluginTOTP
return;
try
{
_uiThreadHandler.Post(() => Toast.MakeText(_ctx, warning, ToastLength.Short).Show());
_uiThreadHandler.Post(() => App.Kp2a.ShowMessage(_ctx, warning, MessageSeverity.Warning));
}
catch (Exception e)
{

View File

@@ -0,0 +1,153 @@
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)
{
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);
new Handler().PostDelayed(() => { ShowNextSnackbar(); }, (long)waitDuration.TotalMilliseconds);
if (queuedMessages.Any())
{
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;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -43,8 +43,10 @@ using keepass2android.Io;
using keepass2android.addons.OtpKeyProv;
using keepass2android.database.edit;
using keepass2android;
using keepass2android.Utils;
using KeePassLib.Interfaces;
using KeePassLib.Utility;
using Message = keepass2android.Utils.Message;
#if !NoNet
#if !EXCLUDE_JAVAFILESTORAGE
using Android.Gms.Common;
@@ -52,6 +54,8 @@ using Keepass2android.Javafilestorage;
using GoogleDriveFileStorage = keepass2android.Io.GoogleDriveFileStorage;
using GoogleDriveAppDataFileStorage = keepass2android.Io.GoogleDriveAppDataFileStorage;
using PCloudFileStorage = keepass2android.Io.PCloudFileStorage;
using static keepass2android.Util;
using static Android.Provider.Telephony.MmsSms;
#endif
#endif
@@ -472,6 +476,7 @@ namespace keepass2android
private readonly HashSet<RealProgressDialog> _activeProgressDialogs = new HashSet<RealProgressDialog>();
// Whether the app is currently showing a dialog that requires user input, like a yesNoCancel dialog
private bool _isShowingUserInputDialog = false;
private IMessagePresenter? _messagePresenter;
private void AskForReload(Activity activity, Action<bool> actionOnResult)
{
@@ -977,7 +982,7 @@ namespace keepass2android
#endif
private void ShowValidationWarning(string error)
{
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.CertificateWarning, error));
App.Kp2a.ShowMessage(LocaleManager.LocalizedAppContext, LocaleManager.LocalizedAppContext.GetString(Resource.String.CertificateWarning, error), MessageSeverity.Warning);
}
@@ -1026,19 +1031,15 @@ namespace keepass2android
return newDatabase;
}
internal void ShowToast(string message)
internal void ShowToast(string message, MessageSeverity severity)
{
var handler = new Handler(Looper.MainLooper);
handler.Post(() => { var toast = Toast.MakeText(LocaleManager.LocalizedAppContext, message, ToastLength.Long);
toast.SetGravity(GravityFlags.Center, 0, 0);
toast.Show();
});
App.Kp2a.ShowMessage(LocaleManager.LocalizedAppContext, message, severity);
}
public void CouldntSaveToRemote(IOConnectionInfo ioc, Exception e)
{
var errorMessage = GetErrorMessageForFileStorageException(e);
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.CouldNotSaveToRemote, errorMessage));
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.CouldNotSaveToRemote, errorMessage), MessageSeverity.Error);
}
private string GetErrorMessageForFileStorageException(Exception e)
@@ -1056,28 +1057,28 @@ namespace keepass2android
public void CouldntOpenFromRemote(IOConnectionInfo ioc, Exception ex)
{
var errorMessage = GetErrorMessageForFileStorageException(ex);
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.CouldNotLoadFromRemote, errorMessage));
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.CouldNotLoadFromRemote, errorMessage), MessageSeverity.Error);
}
public void UpdatedCachedFileOnLoad(IOConnectionInfo ioc)
{
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.UpdatedCachedFileOnLoad,
new Java.Lang.Object[] { LocaleManager.LocalizedAppContext.GetString(Resource.String.database_file) }));
new Java.Lang.Object[] { LocaleManager.LocalizedAppContext.GetString(Resource.String.database_file) }), MessageSeverity.Info);
}
public void UpdatedRemoteFileOnLoad(IOConnectionInfo ioc)
{
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.UpdatedRemoteFileOnLoad));
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.UpdatedRemoteFileOnLoad), MessageSeverity.Warning);
}
public void NotifyOpenFromLocalDueToConflict(IOConnectionInfo ioc)
{
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.NotifyOpenFromLocalDueToConflict));
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.NotifyOpenFromLocalDueToConflict), MessageSeverity.Info);
}
public void LoadedFromRemoteInSync(IOConnectionInfo ioc)
{
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.LoadedFromRemoteInSync));
ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.LoadedFromRemoteInSync), MessageSeverity.Info);
}
public void ClearOfflineCache()
@@ -1286,7 +1287,47 @@ namespace keepass2android
return GetResourceString("filestoragename_" + protocolId);
}
}
public void ShowMessage(Context ctx, int resourceId, MessageSeverity severity)
{
ShowMessage(ctx, ctx.Resources.GetString(resourceId), severity);
}
public void ShowMessage(Context ctx, string text, MessageSeverity severity)
{
if (string.IsNullOrWhiteSpace(text))
{
return;
}
MessagePresenter.ShowMessage(new Message{Text=text, Severity = severity});
}
public IMessagePresenter MessagePresenter
{
get => _messagePresenter ?? new ToastPresenter();
set
{
if (value == null)
{
// Presenter is being reset. Use a NonePresenter to remember pending messages
value = new NonePresenter();
}
// transfer pending messages to new presenter
if (_messagePresenter != null)
{
foreach (var message in _messagePresenter.PendingMessages)
{
if (message.ShowOnSubsequentScreens)
{
value.ShowMessage(message);
}
}
}
_messagePresenter = value;
}
}
}
///Application class for Keepass2Android: Contains static Database variable to be used by all components.

View File

@@ -646,8 +646,8 @@ namespace keepass2android
string totp = prov.GenerateByByte(totpData.TotpSecret);
CopyToClipboardService.CopyValueToClipboardWithTimeout(activity, totp, true);
Toast.MakeText(activity, activity.GetString(Resource.String.TotpCopiedToClipboard),
ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, activity.GetString(Resource.String.TotpCopiedToClipboard),
MessageSeverity.Info);
}
@@ -990,9 +990,9 @@ namespace keepass2android
if (ToastEnable) {
String toastMessage = groupBaseActivity.GetString (Resource.String.NavigationToGroupCompleted_message, new Java.Lang.Object[] { FullGroupName});
Toast.MakeText (groupBaseActivity, toastMessage, ToastLength.Long).Show ();
}
App.Kp2a.ShowMessage(groupBaseActivity, toastMessage, MessageSeverity.Info);
}
groupBaseActivity.StartTask (TaskToBeLaunchedAfterNavigation);
return;

View File

@@ -28,7 +28,7 @@ namespace keepass2android
public void UpdatedCachedFileOnLoad(IOConnectionInfo ioc)
{
_app.ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.UpdatedCachedFileOnLoad,
new Java.Lang.Object[] { LocaleManager.LocalizedAppContext.GetString(Resource.String.otp_aux_file) }));
new Java.Lang.Object[] { LocaleManager.LocalizedAppContext.GetString(Resource.String.otp_aux_file) }), MessageSeverity.Info);
}
public void UpdatedRemoteFileOnLoad(IOConnectionInfo ioc)
@@ -49,12 +49,12 @@ namespace keepass2android
public void ResolvedCacheConflictByUsingRemote(IOConnectionInfo ioc)
{
_app.ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.ResolvedCacheConflictByUsingRemoteOtpAux));
_app.ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.ResolvedCacheConflictByUsingRemoteOtpAux), MessageSeverity.Info);
}
public void ResolvedCacheConflictByUsingLocal(IOConnectionInfo ioc)
{
_app.ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.ResolvedCacheConflictByUsingLocalOtpAux));
_app.ShowToast(LocaleManager.LocalizedAppContext.GetString(Resource.String.ResolvedCacheConflictByUsingLocalOtpAux), MessageSeverity.Info);
}
}
}

View File

@@ -35,6 +35,7 @@ using Console = System.Console;
using Environment = Android.OS.Environment;
using Google.Android.Material.AppBar;
using Android.Util;
using keepass2android.Utils;
namespace keepass2android
{
@@ -75,7 +76,7 @@ namespace keepass2android
public const string NoForwardToPasswordActivity = "NoForwardToPasswordActivity";
protected override void OnCreate(Bundle savedInstanceState)
protected override void OnCreate(Bundle savedInstanceState)
{
_design.ApplyTheme();
base.OnCreate(savedInstanceState);
@@ -327,7 +328,7 @@ namespace keepass2android
}
catch (NoFileStorageFoundException)
{
Toast.MakeText(this, "Don't know how to handle " + newConnectionInfo.Path, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Don't know how to handle " + newConnectionInfo.Path, MessageSeverity.Error);
return;
}
@@ -376,7 +377,7 @@ namespace keepass2android
Finish();
} catch (Java.IO.FileNotFoundException)
{
Toast.MakeText(this, Resource.String.FileNotFound, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.FileNotFound, MessageSeverity.Error);
}
}
}
@@ -432,8 +433,9 @@ namespace keepass2android
base.OnResume();
App.Kp2a.OfflineMode = false; //no matter what the preferences are, file selection or db creation is performed offline. PasswordActivity might set this to true.
Kp2aLog.Log("FileSelect.OnResume");
App.Kp2a.MessagePresenter = new ChainedSnackbarPresenter(FindViewById(Resource.Id.main_content));
_design.ReapplyTheme();
_design.ReapplyTheme();
// Check to see if we need to change modes
if (ShowRecentFiles() != _recentMode)
@@ -485,7 +487,7 @@ namespace keepass2android
catch (Exception e)
{
Kp2aLog.LogUnexpectedError(e);
Toast.MakeText(this, "Error: " + e.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Error: " + e.Message, MessageSeverity.Error);
Finish();
}
@@ -503,7 +505,8 @@ namespace keepass2android
protected override void OnPause()
{
base.OnPause();
Kp2aLog.Log("FileSelect.OnPause");
App.Kp2a.MessagePresenter = new NonePresenter();
Kp2aLog.Log("FileSelect.OnPause");
}
protected override void OnDestroy()

View File

@@ -94,7 +94,7 @@ namespace keepass2android.search
catch (Exception e)
{
Kp2aLog.Log("Failed to transform " + intent.Data.LastPathSegment + " to an ElementAndDatabaseId object. ");
Toast.MakeText(this, "Bad path passed. Please provide database and element ID.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Bad path passed. Please provide database and element ID.", MessageSeverity.Error);
Finish();
return;
}
@@ -121,7 +121,7 @@ namespace keepass2android.search
edit.PutLong(GetString(Resource.String.UsageCount_key), 1000);
edit.PutBoolean("DismissedDonateReminder", true);
edit.Commit();
Toast.MakeText(this, "Please go to Settings - App - Display to disable donation requests.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Please go to Settings - App - Display to disable donation requests.", MessageSeverity.Error);
}
@@ -142,7 +142,7 @@ namespace keepass2android.search
}
} catch (Exception e) {
Kp2aLog.LogUnexpectedError(e);
Toast.MakeText(this,e.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this,e.Message, MessageSeverity.Error);
Finish();
return;
}

View File

@@ -96,7 +96,7 @@ namespace keepass2android.search
catch (Exception e)
{
Kp2aLog.LogUnexpectedError(e);
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, e.Message, MessageSeverity.Error);
Finish();
return;
}

View File

@@ -52,7 +52,7 @@ namespace keepass2android.services.AutofillBase
if (requestedUrl == null && requestedUuid == null)
{
Kp2aLog.Log("ChooseForAutofillActivityBase: no requestedUrl and no requestedUuid");
Toast.MakeText(this, "Cannot execute query for null.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Cannot execute query for null.", MessageSeverity.Error);
RestartApp();
return;
}
@@ -255,7 +255,7 @@ namespace keepass2android.services.AutofillBase
{
if (dataset == null)
{
Toast.MakeText(this, "Failed to build an autofill dataset.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Failed to build an autofill dataset.", MessageSeverity.Error);
return;
}
ReplyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, dataset);

View File

@@ -710,9 +710,9 @@ namespace keepass2android
string message = _service.GetString(Resource.String.ClearClipboard) + " "
+ _service.GetString(Resource.String.ClearClipboardWarning);
Android.Util.Log.Debug("KP2A", message);
Toast.MakeText(_service,
App.Kp2a.ShowMessage(_service,
message,
ToastLength.Long).Show();
MessageSeverity.Error);
}
}
@@ -781,7 +781,7 @@ namespace keepass2android
InputMethodManager imeManager = (InputMethodManager)ApplicationContext.GetSystemService(InputMethodService);
if (imeManager == null)
{
Toast.MakeText(this, Resource.String.not_possible_im_picker, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.not_possible_im_picker, MessageSeverity.Error);
return;
}
try
@@ -799,7 +799,7 @@ namespace keepass2android
}
catch (Exception)
{
Toast.MakeText(this, Resource.String.not_possible_im_picker, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.not_possible_im_picker, MessageSeverity.Error);
}
return;
}
@@ -813,7 +813,7 @@ namespace keepass2android
if (!IsKp2aInputMethodEnabled)
{
//must be enabled in settings first
Toast.MakeText(this, Resource.String.please_activate_keyboard, ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, Resource.String.please_activate_keyboard, MessageSeverity.Info);
Intent settingsIntent = new Intent(Android.Provider.Settings.ActionInputMethodSettings);
try
{
@@ -824,7 +824,7 @@ namespace keepass2android
{
//seems like on Huawei devices this call can fail.
Kp2aLog.LogUnexpectedError(e);
Toast.MakeText(this, "Failed to switch keyboard.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Failed to switch keyboard.", MessageSeverity.Error);
}
}
@@ -847,7 +847,7 @@ namespace keepass2android
{
//seems like on Huawei devices this call can fail.
Kp2aLog.LogUnexpectedError(e);
Toast.MakeText(this, "Failed to switch keyboard.", ToastLength.Long).Show();
App.Kp2a.ShowMessage(this, "Failed to switch keyboard.", MessageSeverity.Error);
}

View File

@@ -123,7 +123,7 @@ namespace keepass2android
{
db.KpDatabase.DefaultUserName = previousUsername;
db.KpDatabase.DefaultUserNameChanged = previousUsernameChanged;
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
}
}));
ProgressTask pt = new ProgressTask(App.Kp2a, Activity, save);
@@ -189,7 +189,7 @@ namespace keepass2android
{
db.KpDatabase.Name = previousName;
db.KpDatabase.NameChanged = previousNameChanged;
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
}
else
{
@@ -261,7 +261,7 @@ namespace keepass2android
{
return () =>
{
Toast.MakeText(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, MessageSeverity.Error);
};
}
@@ -357,7 +357,7 @@ namespace keepass2android
{
return () =>
{
Toast.MakeText(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(Activity, App.Kp2a.GetResourceString(UiStringKey.ErrorOcurred) + " " + e.Message, MessageSeverity.Error);
};
}
@@ -415,7 +415,7 @@ namespace keepass2android
if (!success)
{
db.KpDatabase.DataCipherUuid = previousCipher;
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
return;
}
preferenceChangeEventArgs.Preference.Summary =
@@ -628,7 +628,7 @@ namespace keepass2android
catch (Exception ex)
{
Kp2aLog.LogUnexpectedError(ex);
Toast.MakeText(LocaleManager.LocalizedAppContext, ex.Message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(LocaleManager.LocalizedAppContext, ex.Message, MessageSeverity.Error);
}
}
);
@@ -1076,7 +1076,7 @@ namespace keepass2android
if (!success)
{
db.KpDatabase.KdfParameters = previousKdfParams;
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
return;
}
UpdateKdfScreen();

View File

@@ -74,10 +74,10 @@ namespace keepass2android
(success, message, activity) =>
{
if (!success)
Toast.MakeText(activity, message, ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, message, MessageSeverity.Error);
else
Toast.MakeText(activity, _activity.GetString(Resource.String.export_keyfile_successful),
ToastLength.Long).Show();
App.Kp2a.ShowMessage(activity, _activity.GetString(Resource.String.export_keyfile_successful),
MessageSeverity.Info);
activity.Finish();
}
), ioc);

View File

@@ -94,7 +94,7 @@ namespace keepass2android.settings
String strRounds = inputEditText.Text;
if (!(ulong.TryParse(strRounds, out paramValue)))
{
Toast.MakeText(Context, Resource.String.error_param_not_number, ToastLength.Long).Show();
App.Kp2a.ShowMessage(Context, Resource.String.error_param_not_number, MessageSeverity.Error);
return;
}