* introduce FAB for search
* introduce TOTP preview on PwEntryView first steps towards #803
This commit is contained in:
@@ -72,8 +72,9 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
private IDatabaseFormat _databaseFormat = new KdbxDatabaseFormat(KdbxFormat.Default);
|
||||
private bool? _hasTotpEntries;
|
||||
|
||||
public bool ReloadRequested { get; set; }
|
||||
public bool ReloadRequested { get; set; }
|
||||
|
||||
public bool DidOpenFileChange()
|
||||
{
|
||||
@@ -104,8 +105,9 @@ namespace keepass2android
|
||||
SearchHelper = new SearchDbHelper(app);
|
||||
|
||||
_databaseFormat = databaseFormat;
|
||||
_hasTotpEntries = null;
|
||||
|
||||
CanWrite = databaseFormat.CanWrite && !fileStorage.IsReadOnly(iocInfo);
|
||||
CanWrite = databaseFormat.CanWrite && !fileStorage.IsReadOnly(iocInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -200,8 +202,21 @@ namespace keepass2android
|
||||
|
||||
trans.CommitWrite();
|
||||
}
|
||||
|
||||
}
|
||||
_hasTotpEntries = null;
|
||||
|
||||
}
|
||||
|
||||
public bool HasTotpEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_hasTotpEntries == null)
|
||||
{
|
||||
_hasTotpEntries = true;
|
||||
}
|
||||
return _hasTotpEntries.Value;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateGlobals(PwGroup currentGroup, bool checkForDuplicateUuids )
|
||||
{
|
||||
|
@@ -39,6 +39,8 @@ using Android.Support.V4.View;
|
||||
using Android.Views.Autofill;
|
||||
using CursorAdapter = Android.Support.V4.Widget.CursorAdapter;
|
||||
using Object = Java.Lang.Object;
|
||||
using Android.Text;
|
||||
using KeeTrayTOTP.Libraries;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@@ -115,6 +117,7 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||
|
||||
FindViewById(Resource.Id.fabAddNew).Visibility = (showAddGroup || showAddEntry) ? ViewStates.Visible : ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabSearch).Visibility = (showAddGroup || showAddEntry) ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
|
||||
UpdateBottomBarElementVisibility(Resource.Id.insert_element, false);
|
||||
@@ -262,6 +265,7 @@ namespace keepass2android
|
||||
private bool hasCalledOtherActivity = false;
|
||||
private IMenuItem searchItem;
|
||||
private IMenuItem searchItemDummy;
|
||||
private bool isPaused;
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
@@ -281,8 +285,39 @@ namespace keepass2android
|
||||
RefreshIfDirty();
|
||||
|
||||
SetSearchItemVisibility();
|
||||
}
|
||||
|
||||
isPaused = false;
|
||||
System.Threading.Tasks.Task.Run(UpdateTotpCountdown);
|
||||
}
|
||||
private async System.Threading.Tasks.Task UpdateTotpCountdown()
|
||||
{
|
||||
|
||||
while (!isPaused )
|
||||
{
|
||||
RunOnUiThread(() =>
|
||||
{
|
||||
var listView = FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment)
|
||||
.ListView;
|
||||
if (listView != null)
|
||||
{
|
||||
int count = listView.Count;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var item = listView.GetChildAt(i);
|
||||
if (item is PwEntryView)
|
||||
{
|
||||
var entryView = (PwEntryView)item;
|
||||
entryView.UpdateTotp();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
await System.Threading.Tasks.Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateInfotexts()
|
||||
{
|
||||
@@ -390,6 +425,13 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPause()
|
||||
{
|
||||
base.OnPause();
|
||||
isPaused = true;
|
||||
}
|
||||
|
||||
|
||||
private void UpdatePostNotificationsPermissionInfo(bool hideForever=false)
|
||||
{
|
||||
const string prefsKey = "DidShowNotificationPermissionInfo";
|
||||
@@ -572,6 +614,17 @@ namespace keepass2android
|
||||
};
|
||||
}
|
||||
|
||||
if (FindViewById(Resource.Id.fabSearch) != null)
|
||||
{
|
||||
FindViewById(Resource.Id.fabSearch).Click += (sender, args) =>
|
||||
{
|
||||
if (searchView?.Iconified != false)
|
||||
ActivateSearchView();
|
||||
else
|
||||
searchView.Iconified = true;
|
||||
};
|
||||
}
|
||||
|
||||
if (FindViewById(Resource.Id.fabCancelAddNew) != null)
|
||||
{
|
||||
FindViewById(Resource.Id.fabAddNew).Click += (sender, args) =>
|
||||
@@ -580,6 +633,7 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.fabAddNewGroup).Visibility = AddGroupEnabled ? ViewStates.Visible : ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNewEntry).Visibility = AddEntryEnabled ? ViewStates.Visible : ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabSearch).Visibility = ViewStates.Gone;
|
||||
};
|
||||
|
||||
FindViewById(Resource.Id.fabCancelAddNew).Click += (sender, args) =>
|
||||
@@ -588,6 +642,7 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Visible;
|
||||
FindViewById(Resource.Id.fabSearch).Visibility = ViewStates.Visible;
|
||||
};
|
||||
|
||||
|
||||
@@ -1028,6 +1083,7 @@ namespace keepass2android
|
||||
|
||||
searchView.Iconified = false;
|
||||
AppTask.CanActivateSearchViewOnStart = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1267,6 +1323,7 @@ namespace keepass2android
|
||||
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Gone;
|
||||
FindViewById(Resource.Id.fabSearch).Visibility = ViewStates.Gone;
|
||||
|
||||
UpdateBottomBarElementVisibility(Resource.Id.insert_element, true);
|
||||
UpdateBottomBarElementVisibility(Resource.Id.cancel_insert_element, true);
|
||||
@@ -1330,6 +1387,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
ListView.ItemClick += (sender, args) => ((GroupListItemView)args.View).OnClick();
|
||||
|
||||
|
||||
StyleListView();
|
||||
|
||||
|
BIN
src/keepass2android/Resources/drawable-mdpi/ic_fab_search.png
Normal file
BIN
src/keepass2android/Resources/drawable-mdpi/ic_fab_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
BIN
src/keepass2android/Resources/drawable-xhdpi/ic_fab_search.png
Normal file
BIN
src/keepass2android/Resources/drawable-xhdpi/ic_fab_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
@@ -61,6 +61,28 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:text="group detail"
|
||||
style="@style/GroupDetailInSearchResult" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/totp_layout"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/totp_text"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:text=""/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/TotpCountdownProgressBar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginRight="30dp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView android:id="@+id/right_arrow"
|
||||
|
@@ -400,5 +400,14 @@
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="160dp"
|
||||
android:visibility="gone"/>
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fabSearch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom|right"
|
||||
android:src="@drawable/ic_fab_search"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="88dp"
|
||||
android:visibility="gone"/>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
</RelativeLayout>
|
@@ -1988,6 +1988,12 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_entry_totp.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-mdpi\ic_fab_search.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable-xhdpi\ic_fab_search.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
@@ -26,6 +26,9 @@ using Android.Text;
|
||||
using Android.Text.Style;
|
||||
using Android.Preferences;
|
||||
using KeePass.Util.Spr;
|
||||
using KeeTrayTOTP.Libraries;
|
||||
using PluginTOTP;
|
||||
using Microsoft.Graph;
|
||||
|
||||
|
||||
namespace keepass2android.view
|
||||
@@ -37,8 +40,11 @@ namespace keepass2android.view
|
||||
private readonly TextView _textView;
|
||||
private readonly TextView _textviewDetails;
|
||||
private readonly TextView _textgroupFullPath;
|
||||
private readonly ProgressBar _totpCountdown;
|
||||
private readonly TextView _totpText;
|
||||
private readonly LinearLayout _totpLayout;
|
||||
|
||||
private int _pos;
|
||||
private int _pos;
|
||||
|
||||
private int? _defaultTextColor;
|
||||
|
||||
@@ -82,7 +88,11 @@ namespace keepass2android.view
|
||||
_textgroupFullPath = (TextView)ev.FindViewById(Resource.Id.group_detail);
|
||||
_textgroupFullPath.TextSize = PrefsUtil.GetListDetailTextSize(groupActivity);
|
||||
|
||||
_showDetail = PreferenceManager.GetDefaultSharedPreferences(groupActivity).GetBoolean(
|
||||
_totpCountdown = ev.FindViewById<ProgressBar>(Resource.Id.TotpCountdownProgressBar);
|
||||
_totpText = ev.FindViewById<TextView>(Resource.Id.totp_text);
|
||||
_totpLayout = ev.FindViewById<LinearLayout>(Resource.Id.totp_layout);
|
||||
|
||||
_showDetail = PreferenceManager.GetDefaultSharedPreferences(groupActivity).GetBoolean(
|
||||
groupActivity.GetString(Resource.String.ShowUsernameInList_key),
|
||||
Resources.GetBoolean(Resource.Boolean.ShowUsernameInList_default));
|
||||
|
||||
@@ -112,20 +122,20 @@ namespace keepass2android.view
|
||||
ev.FindViewById(Resource.Id.icon).Visibility = ViewStates.Visible;
|
||||
ev.FindViewById(Resource.Id.check_mark).Visibility = ViewStates.Invisible;
|
||||
|
||||
Database db = App.Kp2a.FindDatabaseForElement(_entry);
|
||||
_db = App.Kp2a.FindDatabaseForElement(_entry);
|
||||
|
||||
ImageView iv = (ImageView)ev.FindViewById(Resource.Id.icon);
|
||||
bool isExpired = pw.Expires && pw.ExpiryTime < DateTime.Now;
|
||||
if (isExpired)
|
||||
{
|
||||
db.DrawableFactory.AssignDrawableTo(iv, Context, db.KpDatabase, PwIcon.Expired, PwUuid.Zero, false);
|
||||
_db.DrawableFactory.AssignDrawableTo(iv, Context, _db.KpDatabase, PwIcon.Expired, PwUuid.Zero, false);
|
||||
} else
|
||||
{
|
||||
db.DrawableFactory.AssignDrawableTo(iv, Context, db.KpDatabase, pw.IconId, pw.CustomIconUuid, false);
|
||||
_db.DrawableFactory.AssignDrawableTo(iv, Context, _db.KpDatabase, pw.IconId, pw.CustomIconUuid, false);
|
||||
}
|
||||
|
||||
String title = pw.Strings.ReadSafe(PwDefs.TitleField);
|
||||
title = SprEngine.Compile(title, new SprContext(_entry, db.KpDatabase, SprCompileFlags.All));
|
||||
title = SprEngine.Compile(title, new SprContext(_entry, _db.KpDatabase, SprCompileFlags.All));
|
||||
var str = new SpannableString(title);
|
||||
|
||||
if (isExpired)
|
||||
@@ -146,7 +156,7 @@ namespace keepass2android.view
|
||||
_textView.SetTextColor(new Color((int)_defaultTextColor));
|
||||
|
||||
String detail = pw.Strings.ReadSafe(PwDefs.UserNameField);
|
||||
detail = SprEngine.Compile(detail, new SprContext(_entry, db.KpDatabase, SprCompileFlags.All));
|
||||
detail = SprEngine.Compile(detail, new SprContext(_entry, _db.KpDatabase, SprCompileFlags.All));
|
||||
|
||||
if ((_showDetail == false) || (String.IsNullOrEmpty(detail)))
|
||||
{
|
||||
@@ -173,7 +183,7 @@ namespace keepass2android.view
|
||||
String groupDetail = pw.ParentGroup.GetFullPath();
|
||||
if (App.Kp2a.OpenDatabases.Count() > 1)
|
||||
{
|
||||
groupDetail += "(" + App.Kp2a.GetFileStorage(db.Ioc).GetDisplayName(db.Ioc) + ")";
|
||||
groupDetail += "(" + App.Kp2a.GetFileStorage(_db.Ioc).GetDisplayName(_db.Ioc) + ")";
|
||||
}
|
||||
|
||||
var strGroupDetail = new SpannableString (groupDetail);
|
||||
@@ -186,7 +196,25 @@ namespace keepass2android.view
|
||||
_textgroupFullPath.Visibility = ViewStates.Visible;
|
||||
}
|
||||
|
||||
}
|
||||
//try to get totp data
|
||||
UpdateTotp();
|
||||
|
||||
|
||||
if (_totpData?.IsTotpEntry == true)
|
||||
{
|
||||
_totpLayout.Visibility = ViewStates.Visible;
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_totpLayout.Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void ConvertView(PwEntry pw, int pos)
|
||||
{
|
||||
@@ -248,6 +276,29 @@ namespace keepass2android.view
|
||||
{
|
||||
LaunchEntry();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private TotpData _totpData;
|
||||
|
||||
private Database _db;
|
||||
|
||||
public void UpdateTotp()
|
||||
{
|
||||
|
||||
_totpData = new Kp2aTotp().TryGetTotpData(new PwEntryOutput(_entry, _db));
|
||||
|
||||
if (_totpData == null)
|
||||
return;
|
||||
Kp2aLog.Log("UpdateTotp");
|
||||
TOTPProvider prov = new TOTPProvider(_totpData);
|
||||
string totp = prov.GenerateByByte(_totpData.TotpSecret);
|
||||
|
||||
_totpText.Text = totp;
|
||||
var progressBar = _totpCountdown;
|
||||
progressBar.Progress = prov.Timer;
|
||||
progressBar.Max = prov.Duration;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user