show the full category of the password

with a small style revamp
This commit is contained in:
Mohamed Zenadi 2015-08-12 22:33:48 +02:00
parent 0cb325f4b1
commit 58d93d757d
11 changed files with 80 additions and 70 deletions

Binary file not shown.

View file

@ -31,6 +31,7 @@ android {
dependencies { dependencies {
compile 'com.android.support:appcompat-v7:22.2.1' compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:recyclerview-v7:22.2.1' compile 'com.android.support:recyclerview-v7:22.2.1'
compile 'com.android.support:cardview-v7:22.2.1'
compile 'com.android.support:design:22.2.1' compile 'com.android.support:design:22.2.1'
compile 'org.sufficientlysecure:openpgp-api:7.0' compile 'org.sufficientlysecure:openpgp-api:7.0'
compile 'org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r' compile 'org.eclipse.jgit:org.eclipse.jgit:3.7.1.201504261725-r'

View file

@ -60,7 +60,8 @@ public class PasswordFragment extends Fragment{
passListStack = new Stack<ArrayList<PasswordItem>>(); passListStack = new Stack<ArrayList<PasswordItem>>();
scrollPosition = new Stack<Integer>(); scrollPosition = new Stack<Integer>();
pathStack = new Stack<File>(); pathStack = new Stack<File>();
recyclerAdapter = new PasswordRecyclerAdapter((PasswordStore) getActivity(), mListener, PasswordRepository.getPasswords(new File(path))); recyclerAdapter = new PasswordRecyclerAdapter((PasswordStore) getActivity(), mListener,
PasswordRepository.getPasswords(new File(path), PasswordRepository.getRepositoryDirectory(getActivity())));
} }
@Override @Override
@ -98,8 +99,8 @@ public class PasswordFragment extends Fragment{
if (item.getType() == PasswordItem.TYPE_CATEGORY) { if (item.getType() == PasswordItem.TYPE_CATEGORY) {
// push the current password list (non filtered plz!) // push the current password list (non filtered plz!)
passListStack.push(pathStack.isEmpty() ? passListStack.push(pathStack.isEmpty() ?
PasswordRepository.getPasswords() : PasswordRepository.getPasswords(PasswordRepository.getRepositoryDirectory(activity)) :
PasswordRepository.getPasswords(pathStack.peek())); PasswordRepository.getPasswords(pathStack.peek(), PasswordRepository.getRepositoryDirectory(activity)));
//push the category were we're going //push the category were we're going
pathStack.push(item.getFile()); pathStack.push(item.getFile());
@ -107,7 +108,7 @@ public class PasswordFragment extends Fragment{
recyclerView.scrollToPosition(0); recyclerView.scrollToPosition(0);
recyclerAdapter.clear(); recyclerAdapter.clear();
recyclerAdapter.addAll(PasswordRepository.getPasswords(item.getFile())); recyclerAdapter.addAll(PasswordRepository.getPasswords(item.getFile(), PasswordRepository.getRepositoryDirectory(activity)));
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); ((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} else { } else {
@ -140,7 +141,7 @@ public class PasswordFragment extends Fragment{
pathStack.clear(); pathStack.clear();
scrollPosition.clear(); scrollPosition.clear();
recyclerAdapter.clear(); recyclerAdapter.clear();
recyclerAdapter.addAll(PasswordRepository.getPasswords()); recyclerAdapter.addAll(PasswordRepository.getPasswords(PasswordRepository.getRepositoryDirectory(getActivity())));
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false); ((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
} }
@ -151,8 +152,8 @@ public class PasswordFragment extends Fragment{
public void refreshAdapter() { public void refreshAdapter() {
recyclerAdapter.clear(); recyclerAdapter.clear();
recyclerAdapter.addAll(pathStack.isEmpty() ? recyclerAdapter.addAll(pathStack.isEmpty() ?
PasswordRepository.getPasswords() : PasswordRepository.getPasswords(PasswordRepository.getRepositoryDirectory(getActivity())) :
PasswordRepository.getPasswords(pathStack.peek())); PasswordRepository.getPasswords(pathStack.peek(), PasswordRepository.getRepositoryDirectory(getActivity())));
} }
/** /**
@ -177,8 +178,8 @@ public class PasswordFragment extends Fragment{
private void recursiveFilter(String filter, File dir) { private void recursiveFilter(String filter, File dir) {
// on the root the pathStack is empty // on the root the pathStack is empty
ArrayList<PasswordItem> passwordItems = dir == null ? ArrayList<PasswordItem> passwordItems = dir == null ?
PasswordRepository.getPasswords() : PasswordRepository.getPasswords(PasswordRepository.getRepositoryDirectory(getActivity())) :
PasswordRepository.getPasswords(dir); PasswordRepository.getPasswords(dir, PasswordRepository.getRepositoryDirectory(getActivity()));
boolean rec = settings.getBoolean("filter_recursively", true); boolean rec = settings.getBoolean("filter_recursively", true);
for (PasswordItem item : passwordItems) { for (PasswordItem item : passwordItems) {

View file

@ -34,7 +34,6 @@ import java.io.File;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import java.util.TreeSet;
public class PasswordStore extends AppCompatActivity { public class PasswordStore extends AppCompatActivity {
private static final String TAG = "PwdStrAct"; private static final String TAG = "PwdStrAct";
@ -226,7 +225,7 @@ public class PasswordStore extends AppCompatActivity {
File dir = new File(settings.getString("git_external_repo", null)); File dir = new File(settings.getString("git_external_repo", null));
if (dir.exists() && dir.isDirectory() && !FileUtils.listFiles(dir, null, true).isEmpty() && if (dir.exists() && dir.isDirectory() && !FileUtils.listFiles(dir, null, true).isEmpty() &&
!PasswordRepository.getPasswords(dir).isEmpty()) { !PasswordRepository.getPasswords(dir, PasswordRepository.getRepositoryDirectory(this)).isEmpty()) {
PasswordRepository.closeRepository(); PasswordRepository.closeRepository();
checkLocalRepository(); checkLocalRepository();
return; // if not empty, just show me the passwords! return; // if not empty, just show me the passwords!
@ -468,7 +467,7 @@ public class PasswordStore extends AppCompatActivity {
dir.exists() && dir.exists() &&
dir.isDirectory() && dir.isDirectory() &&
!FileUtils.listFiles(dir, null, true).isEmpty() && !FileUtils.listFiles(dir, null, true).isEmpty() &&
!PasswordRepository.getPasswords(dir).isEmpty()) { !PasswordRepository.getPasswords(dir, PasswordRepository.getRepositoryDirectory(this)).isEmpty()) {
PasswordRepository.closeRepository(); PasswordRepository.closeRepository();
checkLocalRepository(); checkLocalRepository();
return; // if not empty, just show me the passwords! return; // if not empty, just show me the passwords!

View file

@ -11,6 +11,7 @@ public class PasswordItem implements Comparable{
private String name; private String name;
private PasswordItem parent; private PasswordItem parent;
private File file; private File file;
private String fullPathName;
public boolean selected = false; public boolean selected = false;
/** Create a password item /** Create a password item
@ -20,11 +21,12 @@ public class PasswordItem implements Comparable{
* @param parent * @param parent
* @param type * @param type
*/ */
protected PasswordItem(String name, PasswordItem parent, char type, File file) { protected PasswordItem(String name, PasswordItem parent, char type, File file, File rootDir) {
this.name = name; this.name = name;
this.parent = parent; this.parent = parent;
this.type = type; this.type = type;
this.file = file; this.file = file;
this.fullPathName = file.getAbsolutePath().replace(rootDir.getAbsolutePath(), "").replace(file.getName(), "");
} }
/** Create a new Category item /** Create a new Category item
@ -33,8 +35,8 @@ public class PasswordItem implements Comparable{
* @param parent * @param parent
* @return * @return
*/ */
public static PasswordItem newCategory(String name, File file, PasswordItem parent) { public static PasswordItem newCategory(String name, File file, PasswordItem parent, File rootDir) {
return new PasswordItem(name, parent, TYPE_CATEGORY, file); return new PasswordItem(name, parent, TYPE_CATEGORY, file, rootDir);
} }
/** Create a new parentless category item /** Create a new parentless category item
@ -42,8 +44,8 @@ public class PasswordItem implements Comparable{
* @param name * @param name
* @return * @return
*/ */
public static PasswordItem newCategory(String name, File file) { public static PasswordItem newCategory(String name, File file, File rootDir) {
return new PasswordItem(name, null, TYPE_CATEGORY, file); return new PasswordItem(name, null, TYPE_CATEGORY, file, rootDir);
} }
/** Create a new password item /** Create a new password item
@ -52,8 +54,8 @@ public class PasswordItem implements Comparable{
* @param parent * @param parent
* @return * @return
*/ */
public static PasswordItem newPassword(String name, File file, PasswordItem parent) { public static PasswordItem newPassword(String name, File file, PasswordItem parent, File rootDir) {
return new PasswordItem(name, parent, TYPE_PASSWORD, file); return new PasswordItem(name, parent, TYPE_PASSWORD, file, rootDir);
} }
/** Create a new parentless password item /** Create a new parentless password item
@ -61,8 +63,8 @@ public class PasswordItem implements Comparable{
* @param name * @param name
* @return * @return
*/ */
public static PasswordItem newPassword(String name, File file) { public static PasswordItem newPassword(String name, File file, File rootDir) {
return new PasswordItem(name, null, TYPE_PASSWORD, file); return new PasswordItem(name, null, TYPE_PASSWORD, file, rootDir);
} }
public char getType(){ public char getType(){
@ -81,6 +83,10 @@ public class PasswordItem implements Comparable{
return this.file; return this.file;
} }
public String getFullPathName() {
return this.fullPathName;
}
@Override @Override
public String toString(){ public String toString(){
return this.getName().replace(".gpg", ""); return this.getName().replace(".gpg", "");

View file

@ -1,6 +1,7 @@
package com.zeapo.pwdstore.utils; package com.zeapo.pwdstore.utils;
import android.support.v7.view.ActionMode; import android.support.v7.view.ActionMode;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@ -31,12 +32,14 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
public static class ViewHolder extends RecyclerView.ViewHolder { public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case // each data item is just a string in this case
public View view; public View view;
public CardView card;
public TextView name; public TextView name;
public TextView type; public TextView type;
public ViewHolder(View v) { public ViewHolder(View v) {
super(v); super(v);
view = v; view = v;
card = (CardView) view.findViewById(R.id.password_card);
name = (TextView) view.findViewById(R.id.label); name = (TextView) view.findViewById(R.id.label);
type = (TextView) view.findViewById(R.id.type); type = (TextView) view.findViewById(R.id.type);
} }
@ -68,23 +71,11 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
int sdk = android.os.Build.VERSION.SDK_INT; int sdk = android.os.Build.VERSION.SDK_INT;
if (pass.getType() == PasswordItem.TYPE_CATEGORY) { if (pass.getType() == PasswordItem.TYPE_CATEGORY) {
holder.type.setText("C"); holder.type.setText(pass.getFullPathName());
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) { holder.card.setCardBackgroundColor(activity.getResources().getColor(R.color.deep_orange_400));
holder.type.setBackgroundDrawable(activity.getResources().getDrawable(R.drawable.category_rectangle));
} else { } else {
holder.type.setBackground(activity.getResources().getDrawable(R.drawable.category_rectangle)); holder.type.setText(pass.getFullPathName());
} holder.card.setCardBackgroundColor(activity.getResources().getColor(R.color.light_blue_600));
holder.type.setTextColor(activity.getResources().getColor(R.color.deep_orange_50));
} else {
holder.type.setText("P");
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
holder.type.setBackgroundDrawable(activity.getResources().getDrawable(R.drawable.password_rectangle));
} else {
holder.type.setBackground(activity.getResources().getDrawable(R.drawable.password_rectangle));
}
holder.type.setTextColor(activity.getResources().getColor(R.color.blue_grey_50));
} }
holder.view.setOnClickListener(new View.OnClickListener() { holder.view.setOnClickListener(new View.OnClickListener() {

View file

@ -155,8 +155,8 @@ public class PasswordRepository {
* Gets the password items in the root directory * Gets the password items in the root directory
* @return a list of passwords in the root direcotyr * @return a list of passwords in the root direcotyr
*/ */
public static ArrayList<PasswordItem> getPasswords() { public static ArrayList<PasswordItem> getPasswords(File rootDir) {
return getPasswords(repository.getWorkTree()); return getPasswords(rootDir, rootDir);
} }
public static File getWorkTree() { public static File getWorkTree() {
@ -183,7 +183,7 @@ public class PasswordRepository {
* @param path the directory path * @param path the directory path
* @return a list of password items * @return a list of password items
*/ */
public static ArrayList<PasswordItem> getPasswords(File path) { public static ArrayList<PasswordItem> getPasswords(File path, File rootDir) {
//We need to recover the passwords then parse the files //We need to recover the passwords then parse the files
ArrayList<File> passList = getFilesList(path); ArrayList<File> passList = getFilesList(path);
@ -193,12 +193,12 @@ public class PasswordRepository {
for (File file : passList) { for (File file : passList) {
if (file.isFile()) { if (file.isFile()) {
passwordList.add(PasswordItem.newPassword(file.getName(), file)); passwordList.add(PasswordItem.newPassword(file.getName(), file, rootDir));
} else { } else {
// ignore .git directory // ignore .git directory
if (file.getName().equals(".git")) if (file.getName().equals(".git"))
continue; continue;
passwordList.add(PasswordItem.newCategory(file.getName(), file)); passwordList.add(PasswordItem.newCategory(file.getName(), file, rootDir));
} }
} }
sort(passwordList); sort(passwordList);

View file

@ -25,8 +25,8 @@
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
app:elevation="6dp" app:elevation="6dp"
app:pressedTranslationZ="12dp" app:pressedTranslationZ="12dp"
app:backgroundTint="@color/blue_grey_500" app:backgroundTint="@color/indigo_A700"
app:rippleColor="@color/blue_grey_50" app:rippleColor="@color/blue_500"
app:borderWidth="0dp" app:borderWidth="0dp"
android:layout_margin="@dimen/fab_compat_margin" android:layout_margin="@dimen/fab_compat_margin"
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"

View file

@ -1,30 +1,41 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@drawable/password_row_background"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"
android:layout_gravity="start|center_vertical"> android:layout_gravity="start|center_vertical">
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/password_card"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="60dp"
card_view:contentPaddingTop="4dp"
card_view:contentPaddingLeft="4dp"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="3dp"
card_view:cardBackgroundColor="@color/light_blue_600">
<TextView <TextView
android:id="@+id/type" android:id="@+id/type"
android:text="TYPE" android:text="TYPE"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:paddingLeft="16dp" android:textColor="@android:color/white"
android:paddingRight="16dp" android:textStyle="italic"
android:textStyle="bold" android:maxLines="1" />
android:layout_gravity="center_horizontal|center_vertical"
/>
<TextView <TextView
android:id="@+id/label" android:id="@+id/label"
android:text="FILE_NAME" android:text="FILE_NAME"
android:layout_marginTop="8dp" android:layout_width="match_parent"
android:layout_marginBottom="8dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:padding="8dp"/> android:padding="8dp"
</LinearLayout> android:textColor="@android:color/white"
android:textStyle="bold" />
</android.support.v7.widget.CardView>
</LinearLayout>

View file

@ -152,5 +152,6 @@
<string name="show_password_pref_summary">Control the visibility of the passwords once decrypted, this does not disable the password copy</string> <string name="show_password_pref_summary">Control the visibility of the passwords once decrypted, this does not disable the password copy</string>
<string name="toast_password_copied">Password copied into the clipboard</string> <string name="toast_password_copied">Password copied into the clipboard</string>
<string name="pwd_generate_button">Generate</string> <string name="pwd_generate_button">Generate</string>
<string name="category_string">"Category: "</string>
</resources> </resources>

View file

@ -2,15 +2,15 @@
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">@color/blue_grey_500</item> <item name="colorPrimary">@color/indigo_A400</item>
<item name="colorPrimaryDark">@color/blue_grey_700</item> <item name="colorPrimaryDark">@color/indigo_A700</item>
<item name="android:windowBackground">@color/blue_grey_50</item> <item name="android:windowBackground">@color/indigo_50</item>
<item name="android:textColorPrimary">@color/teal_900</item> <item name="android:textColorPrimary">@color/blue_500</item>
<item name="android:textColor">@color/text_color</item> <item name="android:textColor">@color/text_color</item>
<item name="actionModeStyle">@style/ActionMode</item> <item name="actionModeStyle">@style/ActionMode</item>
</style> </style>
<style name="ActionMode" parent="@style/Widget.AppCompat.ActionMode"> <style name="ActionMode" parent="@style/Widget.AppCompat.ActionMode">
<item name="background">@color/blue_grey_700</item> <item name="background">@color/indigo_A700</item>
</style> </style>
</resources> </resources>