mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-26 00:36:11 +00:00
Merge pull request #173 from michaelschattgen/feature-tapholdswipe
Overhaul entry interaction
This commit is contained in:
commit
c12c6ab107
16 changed files with 246 additions and 117 deletions
|
@ -3,8 +3,15 @@ package com.beemdevelopment.aegis.helpers;
|
||||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.beemdevelopment.aegis.db.DatabaseEntry;
|
||||||
|
import com.beemdevelopment.aegis.ui.views.EntryAdapter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||||
|
|
||||||
|
private DatabaseEntry _selectedEntry;
|
||||||
|
|
||||||
private final ItemTouchHelperAdapter _adapter;
|
private final ItemTouchHelperAdapter _adapter;
|
||||||
private boolean _positionChanged = false;
|
private boolean _positionChanged = false;
|
||||||
private boolean _isLongPressDragEnabled = true;
|
private boolean _isLongPressDragEnabled = true;
|
||||||
|
@ -22,6 +29,10 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||||
_isLongPressDragEnabled = enabled;
|
_isLongPressDragEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSelectedEntry(DatabaseEntry entry) {
|
||||||
|
_selectedEntry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isItemViewSwipeEnabled() {
|
public boolean isItemViewSwipeEnabled() {
|
||||||
return false;
|
return false;
|
||||||
|
@ -30,7 +41,15 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||||
@Override
|
@Override
|
||||||
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||||
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
|
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
|
||||||
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
|
int swipeFlags = 0;
|
||||||
|
|
||||||
|
int position = viewHolder.getAdapterPosition();
|
||||||
|
EntryAdapter adapter = (EntryAdapter)recyclerView.getAdapter();
|
||||||
|
if (adapter.getEntryAt(position) != _selectedEntry)
|
||||||
|
{
|
||||||
|
dragFlags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return makeMovementFlags(dragFlags, swipeFlags);
|
return makeMovementFlags(dragFlags, swipeFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,4 +75,6 @@ public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||||
_positionChanged = false;
|
_positionChanged = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.beemdevelopment.aegis.helpers;
|
||||||
|
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
|
||||||
|
import androidx.annotation.ColorInt;
|
||||||
|
|
||||||
|
import com.beemdevelopment.aegis.R;
|
||||||
|
|
||||||
|
public class ThemeHelper {
|
||||||
|
private ThemeHelper() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getThemeColor(int attributeId, Resources.Theme currentTheme) {
|
||||||
|
TypedValue typedValue = new TypedValue();
|
||||||
|
currentTheme.resolveAttribute(attributeId, typedValue, true);
|
||||||
|
@ColorInt int color = typedValue.data;
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package com.beemdevelopment.aegis.ui;
|
package com.beemdevelopment.aegis.ui;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -11,6 +12,7 @@ import android.graphics.Rect;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.SubMenu;
|
import android.view.SubMenu;
|
||||||
|
@ -18,6 +20,10 @@ import android.widget.LinearLayout;
|
||||||
import android.widget.SearchView;
|
import android.widget.SearchView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.view.ActionMode;
|
||||||
|
import androidx.core.view.MenuItemCompat;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.AegisApplication;
|
import com.beemdevelopment.aegis.AegisApplication;
|
||||||
import com.beemdevelopment.aegis.R;
|
import com.beemdevelopment.aegis.R;
|
||||||
import com.beemdevelopment.aegis.SortCategory;
|
import com.beemdevelopment.aegis.SortCategory;
|
||||||
|
@ -71,6 +77,9 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||||
private String _checkedGroup;
|
private String _checkedGroup;
|
||||||
private boolean _searchSubmitted;
|
private boolean _searchSubmitted;
|
||||||
|
|
||||||
|
private DatabaseEntry _selectedEntry;
|
||||||
|
private ActionMode _actionMode;
|
||||||
|
|
||||||
private Menu _menu;
|
private Menu _menu;
|
||||||
private SearchView _searchView;
|
private SearchView _searchView;
|
||||||
private FloatingActionsMenu _fabMenu;
|
private FloatingActionsMenu _fabMenu;
|
||||||
|
@ -78,6 +87,8 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||||
|
|
||||||
private FabScrollHelper _fabScrollHelper;
|
private FabScrollHelper _fabScrollHelper;
|
||||||
|
|
||||||
|
private ActionMode.Callback _actionModeCallbacks = new ActionModeCallbacks();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -483,43 +494,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private BottomSheetDialog createBottomSheet(final DatabaseEntry entry) {
|
|
||||||
BottomSheetDialog dialog = new BottomSheetDialog(this);
|
|
||||||
dialog.setContentView(R.layout.bottom_sheet_edit_entry);
|
|
||||||
dialog.setCancelable(true);
|
|
||||||
dialog.getWindow().setLayout(LinearLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
LinearLayout.LayoutParams.WRAP_CONTENT);
|
|
||||||
dialog.show();
|
|
||||||
|
|
||||||
dialog.findViewById(R.id.copy_button).setOnClickListener(view -> {
|
|
||||||
dialog.dismiss();
|
|
||||||
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
|
||||||
ClipData clip = ClipData.newPlainText("text/plain", entry.getInfo().getOtp());
|
|
||||||
clipboard.setPrimaryClip(clip);
|
|
||||||
Toast.makeText(this, getString(R.string.code_copied), Toast.LENGTH_SHORT).show();
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.findViewById(R.id.delete_button).setOnClickListener(view -> {
|
|
||||||
dialog.dismiss();
|
|
||||||
Dialogs.showDeleteEntryDialog(this, (d, which) -> {
|
|
||||||
deleteEntry(entry);
|
|
||||||
// update the filter list if the group no longer exists
|
|
||||||
if (entry.getGroup() != null) {
|
|
||||||
if (!_db.getGroups().contains(entry.getGroup())) {
|
|
||||||
updateGroupFilterMenu();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.findViewById(R.id.edit_button).setOnClickListener(view -> {
|
|
||||||
dialog.dismiss();
|
|
||||||
startEditProfileActivity(CODE_EDIT_ENTRY, entry, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
return dialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deleteEntry(DatabaseEntry entry) {
|
private void deleteEntry(DatabaseEntry entry) {
|
||||||
DatabaseEntry oldEntry = _db.removeEntry(entry);
|
DatabaseEntry oldEntry = _db.removeEntry(entry);
|
||||||
saveDatabase();
|
saveDatabase();
|
||||||
|
@ -682,7 +656,29 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEntryClick(DatabaseEntry entry) {
|
public void onEntryClick(DatabaseEntry entry) {
|
||||||
createBottomSheet(entry).show();
|
if (_selectedEntry != null) {
|
||||||
|
if (_selectedEntry == entry) {
|
||||||
|
_actionMode.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText("text/plain", entry.getInfo().getOtp());
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
|
Toast.makeText(this, getString(R.string.code_copied), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLongEntryClick(DatabaseEntry entry) {
|
||||||
|
if (_selectedEntry != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedEntry = entry;
|
||||||
|
_entryListView.setActionModeState(true, entry);
|
||||||
|
_actionMode = this.startSupportActionMode(_actionModeCallbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -707,6 +703,10 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLocked() {
|
public void onLocked() {
|
||||||
|
if (_actionMode != null) {
|
||||||
|
_actionMode.finish();
|
||||||
|
}
|
||||||
|
|
||||||
_entryListView.clearEntries();
|
_entryListView.clearEntries();
|
||||||
_loaded = false;
|
_loaded = false;
|
||||||
|
|
||||||
|
@ -716,4 +716,50 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
|
||||||
|
|
||||||
super.onLocked();
|
super.onLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ActionModeCallbacks implements ActionMode.Callback {
|
||||||
|
@Override
|
||||||
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||||
|
MenuInflater inflater = mode.getMenuInflater();
|
||||||
|
inflater.inflate(R.menu.menu_action_mode, menu);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||||
|
switch (item.getItemId()) {
|
||||||
|
case R.id.action_edit:
|
||||||
|
startEditProfileActivity(CODE_EDIT_ENTRY, _selectedEntry, false);
|
||||||
|
mode.finish();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case R.id.action_delete:
|
||||||
|
Dialogs.showDeleteEntryDialog(MainActivity.this, (d, which) -> {
|
||||||
|
deleteEntry(_selectedEntry);
|
||||||
|
|
||||||
|
if (_selectedEntry.getGroup() != null) {
|
||||||
|
if (!_db.getGroups().contains(_selectedEntry.getGroup())) {
|
||||||
|
updateGroupFilterMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mode.finish();
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyActionMode(ActionMode mode) {
|
||||||
|
_entryListView.setActionModeState(false, null);
|
||||||
|
_selectedEntry = null;
|
||||||
|
_actionMode = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
||||||
private EntryListView _view;
|
private EntryListView _view;
|
||||||
private List<DatabaseEntry> _entries;
|
private List<DatabaseEntry> _entries;
|
||||||
private List<DatabaseEntry> _shownEntries;
|
private List<DatabaseEntry> _shownEntries;
|
||||||
|
private DatabaseEntry _selectedEntry;
|
||||||
private boolean _showAccountName;
|
private boolean _showAccountName;
|
||||||
private boolean _tapToReveal;
|
private boolean _tapToReveal;
|
||||||
private int _tapToRevealTime;
|
private int _tapToRevealTime;
|
||||||
|
@ -185,6 +186,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
||||||
if (_sortCategory == category) {
|
if (_sortCategory == category) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_sortCategory = category;
|
_sortCategory = category;
|
||||||
if (apply) {
|
if (apply) {
|
||||||
updateShownEntries();
|
updateShownEntries();
|
||||||
|
@ -274,6 +276,8 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(final EntryHolder holder, int position) {
|
public void onBindViewHolder(final EntryHolder holder, int position) {
|
||||||
DatabaseEntry entry = _shownEntries.get(position);
|
DatabaseEntry entry = _shownEntries.get(position);
|
||||||
|
holder.setFocused(entry == _selectedEntry);
|
||||||
|
|
||||||
boolean showProgress = !isPeriodUniform() && entry.getInfo() instanceof TotpInfo;
|
boolean showProgress = !isPeriodUniform() && entry.getInfo() instanceof TotpInfo;
|
||||||
holder.setData(entry, _showAccountName, showProgress, _tapToReveal);
|
holder.setData(entry, _showAccountName, showProgress, _tapToReveal);
|
||||||
holder.setTapToRevealTime(_tapToRevealTime);
|
holder.setTapToRevealTime(_tapToRevealTime);
|
||||||
|
@ -283,7 +287,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
int position = holder.getAdapterPosition();
|
int position = holder.getAdapterPosition();
|
||||||
if (_tapToReveal && holder.isCodeHidden()) {
|
if (_tapToReveal && holder.isCodeHidden() && _selectedEntry == null) {
|
||||||
holder.revealCode();
|
holder.revealCode();
|
||||||
} else {
|
} else {
|
||||||
_view.onEntryClick(_shownEntries.get(position));
|
_view.onEntryClick(_shownEntries.get(position));
|
||||||
|
@ -294,6 +298,11 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
||||||
@Override
|
@Override
|
||||||
public boolean onLongClick(View v) {
|
public boolean onLongClick(View v) {
|
||||||
int position = holder.getAdapterPosition();
|
int position = holder.getAdapterPosition();
|
||||||
|
if (_selectedEntry == null) {
|
||||||
|
setSelectedEntry(_shownEntries.get(position));
|
||||||
|
holder.setFocused(true);
|
||||||
|
}
|
||||||
|
|
||||||
return _view.onLongEntryClick(_shownEntries.get(position));
|
return _view.onLongEntryClick(_shownEntries.get(position));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -360,6 +369,18 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
|
||||||
return period;
|
return period;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSelectedEntry(DatabaseEntry entry) {
|
||||||
|
if (entry == null) {
|
||||||
|
notifyItemChanged(_shownEntries.indexOf(_selectedEntry));
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedEntry = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDragAndDropAllowed() {
|
||||||
|
return _sortCategory == SortCategory.CUSTOM && _groupFilter == null && _searchFilter == null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPeriodUniform() {
|
public boolean isPeriodUniform() {
|
||||||
return getUniformPeriod() != -1;
|
return getUniformPeriod() != -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import com.amulyakhare.textdrawable.TextDrawable;
|
||||||
import com.beemdevelopment.aegis.R;
|
import com.beemdevelopment.aegis.R;
|
||||||
import com.beemdevelopment.aegis.db.DatabaseEntry;
|
import com.beemdevelopment.aegis.db.DatabaseEntry;
|
||||||
import com.beemdevelopment.aegis.helpers.TextDrawableHelper;
|
import com.beemdevelopment.aegis.helpers.TextDrawableHelper;
|
||||||
|
import com.beemdevelopment.aegis.helpers.ThemeHelper;
|
||||||
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
||||||
import com.beemdevelopment.aegis.otp.HotpInfo;
|
import com.beemdevelopment.aegis.otp.HotpInfo;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfo;
|
import com.beemdevelopment.aegis.otp.OtpInfo;
|
||||||
|
@ -33,6 +34,7 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
private int _tapToRevealTime;
|
private int _tapToRevealTime;
|
||||||
|
|
||||||
private PeriodProgressBar _progressBar;
|
private PeriodProgressBar _progressBar;
|
||||||
|
private View _view;
|
||||||
|
|
||||||
private UiRefresher _refresher;
|
private UiRefresher _refresher;
|
||||||
private Handler _hiddenHandler;
|
private Handler _hiddenHandler;
|
||||||
|
@ -40,6 +42,8 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
public EntryHolder(final View view) {
|
public EntryHolder(final View view) {
|
||||||
super(view);
|
super(view);
|
||||||
|
|
||||||
|
_view = view.findViewById(R.id.rlCardEntry);
|
||||||
|
|
||||||
_profileName = view.findViewById(R.id.profile_account_name);
|
_profileName = view.findViewById(R.id.profile_account_name);
|
||||||
_profileCode = view.findViewById(R.id.profile_code);
|
_profileCode = view.findViewById(R.id.profile_code);
|
||||||
_profileIssuer = view.findViewById(R.id.profile_issuer);
|
_profileIssuer = view.findViewById(R.id.profile_issuer);
|
||||||
|
@ -49,6 +53,7 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
_progressBar = view.findViewById(R.id.progressBar);
|
_progressBar = view.findViewById(R.id.progressBar);
|
||||||
int primaryColorId = view.getContext().getResources().getColor(R.color.colorPrimary);
|
int primaryColorId = view.getContext().getResources().getColor(R.color.colorPrimary);
|
||||||
_progressBar.getProgressDrawable().setColorFilter(primaryColorId, PorterDuff.Mode.SRC_IN);
|
_progressBar.getProgressDrawable().setColorFilter(primaryColorId, PorterDuff.Mode.SRC_IN);
|
||||||
|
_view.setBackground(_view.getContext().getResources().getDrawable(R.color.card_background));
|
||||||
|
|
||||||
_refresher = new UiRefresher(new UiRefresher.Listener() {
|
_refresher = new UiRefresher(new UiRefresher.Listener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -135,6 +140,15 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFocused(boolean focused) {
|
||||||
|
if (focused) {
|
||||||
|
_view.setBackgroundColor(ThemeHelper.getThemeColor(R.attr.cardBackgroundFocused, _view.getContext().getTheme()));
|
||||||
|
} else {
|
||||||
|
_view.setBackgroundColor(ThemeHelper.getThemeColor(R.attr.cardBackground, _view.getContext().getTheme()));
|
||||||
|
}
|
||||||
|
_view.setSelected(focused);
|
||||||
|
}
|
||||||
|
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
_refresher.destroy();
|
_refresher.destroy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.AnimationUtils;
|
import android.view.animation.AnimationUtils;
|
||||||
import android.view.animation.LayoutAnimationController;
|
import android.view.animation.LayoutAnimationController;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.R;
|
import com.beemdevelopment.aegis.R;
|
||||||
import com.beemdevelopment.aegis.SortCategory;
|
import com.beemdevelopment.aegis.SortCategory;
|
||||||
|
@ -128,6 +129,12 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setActionModeState(boolean enabled, DatabaseEntry entry) {
|
||||||
|
_touchCallback.setSelectedEntry(entry);
|
||||||
|
_touchCallback.setIsLongPressDragEnabled(enabled && _adapter.isDragAndDropAllowed());
|
||||||
|
_adapter.setSelectedEntry(entry);
|
||||||
|
}
|
||||||
|
|
||||||
public void setSortCategory(SortCategory sortCategory, boolean apply) {
|
public void setSortCategory(SortCategory sortCategory, boolean apply) {
|
||||||
_touchCallback.setIsLongPressDragEnabled(sortCategory == SortCategory.CUSTOM);
|
_touchCallback.setIsLongPressDragEnabled(sortCategory == SortCategory.CUSTOM);
|
||||||
_adapter.setSortCategory(sortCategory, apply);
|
_adapter.setSortCategory(sortCategory, apply);
|
||||||
|
@ -164,9 +171,9 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||||
_listener.onEntryClick(entry);
|
_listener.onEntryClick(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onLongEntryClick(DatabaseEntry entry) {
|
public boolean onLongEntryClick(DatabaseEntry entry) {
|
||||||
return false;
|
_listener.onLongEntryClick(entry);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -265,6 +272,7 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
||||||
void onEntryMove(DatabaseEntry entry1, DatabaseEntry entry2);
|
void onEntryMove(DatabaseEntry entry1, DatabaseEntry entry2);
|
||||||
void onEntryDrop(DatabaseEntry entry);
|
void onEntryDrop(DatabaseEntry entry);
|
||||||
void onEntryChange(DatabaseEntry entry);
|
void onEntryChange(DatabaseEntry entry);
|
||||||
|
void onLongEntryClick(DatabaseEntry entry);
|
||||||
void onScroll(int dx, int dy);
|
void onScroll(int dx, int dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
app/src/main/res/drawable/ic_delete_white.xml
Normal file
5
app/src/main/res/drawable/ic_delete_white.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/ic_mode_edit.xml
Normal file
5
app/src/main/res/drawable/ic_mode_edit.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
|
||||||
|
</vector>
|
|
@ -1,72 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:background="?attr/background"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:id="@+id/copy_button"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:background="?attr/background"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:src="@drawable/ic_content_copy_black_24dp"
|
|
||||||
android:tint="?attr/iconColorPrimary"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/copy"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
android:background="?attr/background"
|
|
||||||
android:id="@+id/edit_button"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:src="@drawable/ic_create_black_24dp"
|
|
||||||
android:tint="?attr/iconColorPrimary"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/edit"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:id="@+id/delete_button"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true"
|
|
||||||
|
|
||||||
android:orientation="horizontal">
|
|
||||||
<ImageView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:src="@drawable/ic_delete_black_24dp"
|
|
||||||
android:tint="?attr/iconColorPrimary"/>
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/delete"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
|
@ -11,6 +11,7 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:background="?attr/cardBackground"
|
android:background="?attr/cardBackground"
|
||||||
|
android:id="@+id/rlCardEntry"
|
||||||
android:paddingTop="10dp"
|
android:paddingTop="10dp"
|
||||||
android:paddingBottom="10dp"
|
android:paddingBottom="10dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:background="?attr/cardBackground"
|
android:background="?attr/cardBackground"
|
||||||
|
android:id="@+id/rlCardEntry"
|
||||||
android:paddingTop="5dp"
|
android:paddingTop="5dp"
|
||||||
android:paddingBottom="5dp"
|
android:paddingBottom="5dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:background="?attr/cardBackground"
|
android:background="?attr/cardBackground"
|
||||||
|
android:id="@+id/rlCardEntry"
|
||||||
android:paddingTop="5dp"
|
android:paddingTop="5dp"
|
||||||
android:paddingBottom="5dp"
|
android:paddingBottom="5dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
18
app/src/main/res/menu/menu_action_mode.xml
Normal file
18
app/src/main/res/menu/menu_action_mode.xml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_edit"
|
||||||
|
android:orderInCategory="90"
|
||||||
|
android:icon="@drawable/ic_mode_edit"
|
||||||
|
android:title="Edit"
|
||||||
|
app:showAsAction="always" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_delete"
|
||||||
|
android:title="@string/action_delete"
|
||||||
|
android:orderInCategory="100"
|
||||||
|
android:icon="@drawable/ic_delete_white"
|
||||||
|
android:tint="?attr/iconColorPrimary"
|
||||||
|
app:showAsAction="always"/>
|
||||||
|
</menu>
|
|
@ -4,6 +4,7 @@
|
||||||
<attr name="secondaryText" format="color" />
|
<attr name="secondaryText" format="color" />
|
||||||
<attr name="backgroundColor" format="color" />
|
<attr name="backgroundColor" format="color" />
|
||||||
<attr name="cardBackground" format="color" />
|
<attr name="cardBackground" format="color" />
|
||||||
|
<attr name="cardBackgroundFocused" format="color" />
|
||||||
<attr name="codePrimaryText" format="color" />
|
<attr name="codePrimaryText" format="color" />
|
||||||
<attr name="iconColorPrimary" format="color" />
|
<attr name="iconColorPrimary" format="color" />
|
||||||
<attr name="iconColorInverted" format="color" />
|
<attr name="iconColorInverted" format="color" />
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<color name="divider">#BDBDBD</color>
|
<color name="divider">#BDBDBD</color>
|
||||||
<color name="background">#f2f2f2</color>
|
<color name="background">#f2f2f2</color>
|
||||||
<color name="card_background">#ffffff</color>
|
<color name="card_background">#ffffff</color>
|
||||||
|
<color name="card_background_focused">#DBDBDB</color>
|
||||||
|
|
||||||
<color name="colorSwirlPrimary">#434343</color>
|
<color name="colorSwirlPrimary">#434343</color>
|
||||||
<color name="colorSwirlError">#FF5252</color>
|
<color name="colorSwirlError">#FF5252</color>
|
||||||
|
@ -31,6 +32,8 @@
|
||||||
<color name="code_primary_text_dark">#ffffff</color>
|
<color name="code_primary_text_dark">#ffffff</color>
|
||||||
|
|
||||||
<color name="card_background_dark">#424242</color>
|
<color name="card_background_dark">#424242</color>
|
||||||
|
<color name="card_background_focused_dark">#6B6B6B</color>
|
||||||
|
<color name="card_background_focused_true_dark">#1B1B1B</color>
|
||||||
<color name="primary_text_dark">#ffffff</color>
|
<color name="primary_text_dark">#ffffff</color>
|
||||||
<color name="hint_text_dark">#a7a7a7</color>
|
<color name="hint_text_dark">#a7a7a7</color>
|
||||||
<color name="secondary_text_dark">#FF5252</color>
|
<color name="secondary_text_dark">#FF5252</color>
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
<item name="background">@null</item>
|
<item name="background">@null</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="AppTheme.ActionMode" parent="@style/Widget.AppCompat.ActionMode">
|
||||||
|
<item name="android:actionModeBackground">@color/colorPrimary</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="Theme.Intro" parent="Theme.AppCompat.NoActionBar">
|
<style name="Theme.Intro" parent="Theme.AppCompat.NoActionBar">
|
||||||
<item name="swirl_ridgeColor">@color/primary_text_inverted</item>
|
<item name="swirl_ridgeColor">@color/primary_text_inverted</item>
|
||||||
<item name="swirl_errorColor">@color/colorSwirlError</item>
|
<item name="swirl_errorColor">@color/colorSwirlError</item>
|
||||||
|
@ -20,18 +24,44 @@
|
||||||
<item name="primaryText">@color/primary_text</item>
|
<item name="primaryText">@color/primary_text</item>
|
||||||
<item name="secondaryText">@color/secondary_text</item>
|
<item name="secondaryText">@color/secondary_text</item>
|
||||||
<item name="cardBackground">@color/card_background</item>
|
<item name="cardBackground">@color/card_background</item>
|
||||||
|
<item name="cardBackgroundFocused">@color/card_background_focused</item>
|
||||||
<item name="codePrimaryText">@color/code_primary_text</item>
|
<item name="codePrimaryText">@color/code_primary_text</item>
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
<item name="background">@color/background</item>
|
<item name="background">@color/background</item>
|
||||||
<item name="bottomSheetDialogTheme">@style/Theme.Design.Light.BottomSheetDialog</item>
|
|
||||||
|
|
||||||
<item name="iconColorPrimary">@color/icon_primary</item>
|
<item name="iconColorPrimary">@color/icon_primary</item>
|
||||||
<item name="iconColorInverted">@color/icon_primary_inverted</item>
|
<item name="iconColorInverted">@color/icon_primary_inverted</item>
|
||||||
|
|
||||||
<item name="swirl_ridgeColor">@color/colorSwirlPrimary</item>
|
<item name="swirl_ridgeColor">@color/colorSwirlPrimary</item>
|
||||||
<item name="swirl_errorColor">@color/colorSwirlError</item>
|
<item name="swirl_errorColor">@color/colorSwirlError</item>
|
||||||
|
|
||||||
|
<item name="actionModeStyle">@style/ActionModeStyle</item>
|
||||||
|
<item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
|
||||||
|
</style>
|
||||||
|
<style name="ActionModeStyle" parent="@style/Widget.AppCompat.Light.ActionMode.Inverse">
|
||||||
|
<item name="background">@color/colorPrimary</item>
|
||||||
|
<item name="titleTextStyle">@style/ActionModeTitleTextStyle</item>
|
||||||
|
<item name="iconColorPrimary">@color/icon_primary</item>
|
||||||
|
<item name="iconColorInverted">@color/icon_primary_inverted</item>
|
||||||
|
</style>
|
||||||
|
<style name="ActionModeStyle.Dark" parent="@style/Widget.AppCompat.Light.ActionMode.Inverse">
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="background">@color/colorPrimary</item>
|
||||||
|
<item name="titleTextStyle">@style/ActionModeTitleTextStyle</item>
|
||||||
|
<item name="iconColorPrimary">@color/icon_primary</item>
|
||||||
|
<item name="iconColorInverted">@color/icon_primary_inverted</item>
|
||||||
|
</style>
|
||||||
|
<style name="ActionModeStyle.TrueBlack" parent="@style/Widget.AppCompat.Light.ActionMode.Inverse">
|
||||||
|
<item name="colorPrimary">@color/background_true_dark</item>
|
||||||
|
<item name="background">@color/background_true_dark</item>
|
||||||
|
<item name="titleTextStyle">@style/ActionModeTitleTextStyle</item>
|
||||||
|
<item name="iconColorPrimary">@color/icon_primary</item>
|
||||||
|
<item name="iconColorInverted">@color/icon_primary_inverted</item>
|
||||||
|
</style>
|
||||||
|
<style name="ActionModeTitleTextStyle" parent="@style/TextAppearance.AppCompat.Widget.ActionMode.Title">
|
||||||
|
<item name="android:textColor">@android:color/white</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="AppTheme.NoActionBar">
|
<style name="AppTheme.NoActionBar">
|
||||||
<item name="windowActionBar">false</item>
|
<item name="windowActionBar">false</item>
|
||||||
|
@ -53,27 +83,30 @@
|
||||||
<item name="primaryText">@color/primary_text_dark</item>
|
<item name="primaryText">@color/primary_text_dark</item>
|
||||||
<item name="secondaryText">@color/secondary_text_dark</item>
|
<item name="secondaryText">@color/secondary_text_dark</item>
|
||||||
<item name="cardBackground">@color/card_background_dark</item>
|
<item name="cardBackground">@color/card_background_dark</item>
|
||||||
|
<item name="cardBackgroundFocused">@color/card_background_focused_dark</item>
|
||||||
<item name="codePrimaryText">@color/code_primary_text_dark</item>
|
<item name="codePrimaryText">@color/code_primary_text_dark</item>
|
||||||
<item name="colorPrimary">@color/colorPrimary</item>
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
<item name="colorAccent">@color/colorAccent</item>
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
<item name="background">@color/background_dark</item>
|
<item name="background">@color/background_dark</item>
|
||||||
<item name="bottomSheetDialogTheme">@style/Theme.Design.BottomSheetDialog</item>
|
|
||||||
|
|
||||||
<item name="iconColorPrimary">@color/icon_primary_dark</item>
|
<item name="iconColorPrimary">@color/icon_primary_dark</item>
|
||||||
<item name="iconColorInverted">@color/icon_primary_dark_inverted</item>
|
<item name="iconColorInverted">@color/icon_primary_dark_inverted</item>
|
||||||
|
|
||||||
<item name="swirl_ridgeColor">@color/colorSwirlPrimaryDark</item>
|
<item name="swirl_ridgeColor">@color/colorSwirlPrimaryDark</item>
|
||||||
<item name="swirl_errorColor">@color/colorSwirlErrorDark</item>
|
<item name="swirl_errorColor">@color/colorSwirlErrorDark</item>
|
||||||
|
|
||||||
|
<item name="actionModeStyle">@style/ActionModeStyle.Dark</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.TrueBlack" parent="AppTheme.Dark">
|
<style name="AppTheme.TrueBlack" parent="AppTheme.Dark">
|
||||||
<item name="colorPrimary">@color/background_true_dark</item>
|
<item name="colorPrimary">@color/background_true_dark</item>
|
||||||
<item name="cardBackground">@color/background_true_dark</item>
|
<item name="cardBackground">@color/background_true_dark</item>
|
||||||
<item name="background">@color/background_true_dark</item>
|
<item name="background">@color/background_true_dark</item>
|
||||||
<item name="bottomSheetDialogTheme">@style/Theme.Design.BottomSheetDialog</item>
|
<item name="cardBackgroundFocused">@color/card_background_focused_true_dark</item>
|
||||||
<item name="colorPrimaryDark">@color/background_true_dark</item>
|
<item name="colorPrimaryDark">@color/background_true_dark</item>
|
||||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
|
||||||
|
<item name="actionModeStyle">@style/ActionModeStyle.TrueBlack</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="AppTheme.TrueBlack.Preferences" parent="AppTheme.TrueBlack">
|
<style name="AppTheme.TrueBlack.Preferences" parent="AppTheme.TrueBlack">
|
||||||
|
|
Loading…
Add table
Reference in a new issue