Skip to content

Commit 8f95cec

Browse files
committed
[Highlights] Added highlights page
1 parent 16a86b2 commit 8f95cec

File tree

20 files changed

+542
-8
lines changed

20 files changed

+542
-8
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"formatVersion": 1,
3+
"database": {
4+
"version": 2,
5+
"identityHash": "d5dd1a0120d5842be17e8ea9a19ee039",
6+
"entities": [
7+
{
8+
"tableName": "SecureElement",
9+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`data` BLOB, `title` TEXT, `type` INTEGER NOT NULL, `favorite` INTEGER NOT NULL DEFAULT false, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `created_at` INTEGER, `modified_at` INTEGER)",
10+
"fields": [
11+
{
12+
"fieldPath": "detail",
13+
"columnName": "data",
14+
"affinity": "BLOB",
15+
"notNull": false
16+
},
17+
{
18+
"fieldPath": "title",
19+
"columnName": "title",
20+
"affinity": "TEXT",
21+
"notNull": false
22+
},
23+
{
24+
"fieldPath": "type",
25+
"columnName": "type",
26+
"affinity": "INTEGER",
27+
"notNull": true
28+
},
29+
{
30+
"fieldPath": "favorite",
31+
"columnName": "favorite",
32+
"affinity": "INTEGER",
33+
"notNull": true,
34+
"defaultValue": "false"
35+
},
36+
{
37+
"fieldPath": "id",
38+
"columnName": "id",
39+
"affinity": "INTEGER",
40+
"notNull": true
41+
},
42+
{
43+
"fieldPath": "createdAt",
44+
"columnName": "created_at",
45+
"affinity": "INTEGER",
46+
"notNull": false
47+
},
48+
{
49+
"fieldPath": "modifiedAt",
50+
"columnName": "modified_at",
51+
"affinity": "INTEGER",
52+
"notNull": false
53+
}
54+
],
55+
"primaryKey": {
56+
"autoGenerate": true,
57+
"columnNames": [
58+
"id"
59+
]
60+
},
61+
"indices": [],
62+
"foreignKeys": []
63+
},
64+
{
65+
"tableName": "MasterPassword",
66+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `hash` BLOB)",
67+
"fields": [
68+
{
69+
"fieldPath": "id",
70+
"columnName": "id",
71+
"affinity": "INTEGER",
72+
"notNull": true
73+
},
74+
{
75+
"fieldPath": "hash",
76+
"columnName": "hash",
77+
"affinity": "BLOB",
78+
"notNull": false
79+
}
80+
],
81+
"primaryKey": {
82+
"autoGenerate": true,
83+
"columnNames": [
84+
"id"
85+
]
86+
},
87+
"indices": [],
88+
"foreignKeys": []
89+
}
90+
],
91+
"views": [],
92+
"setupQueries": [
93+
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
94+
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd5dd1a0120d5842be17e8ea9a19ee039')"
95+
]
96+
}
97+
}

app/src/main/java/de/davis/passwordmanager/database/SecureElementDatabase.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
package de.davis.passwordmanager.database;
22

3+
import android.content.ContentValues;
34
import android.content.Context;
5+
import android.database.sqlite.SQLiteDatabase;
46

7+
import androidx.annotation.NonNull;
8+
import androidx.room.AutoMigration;
59
import androidx.room.Database;
610
import androidx.room.Room;
711
import androidx.room.RoomDatabase;
812
import androidx.room.TypeConverters;
13+
import androidx.room.migration.AutoMigrationSpec;
14+
import androidx.sqlite.db.SupportSQLiteDatabase;
915

1016
import de.davis.passwordmanager.database.converter.Converters;
1117
import de.davis.passwordmanager.database.daos.MasterPasswordDao;
@@ -14,9 +20,19 @@
1420
import de.davis.passwordmanager.security.element.SecureElement;
1521

1622
@TypeConverters({Converters.class})
17-
@Database(version = 1, entities = {SecureElement.class, MasterPassword.class})
23+
@Database(version = 2, entities = {SecureElement.class, MasterPassword.class}, autoMigrations = {@AutoMigration(from = 1, to = 2, spec = SecureElementDatabase.TimestampSpec.class)})
1824
public abstract class SecureElementDatabase extends RoomDatabase {
1925

26+
public static class TimestampSpec implements AutoMigrationSpec{
27+
28+
@Override
29+
public void onPostMigrate(@NonNull SupportSQLiteDatabase db) {
30+
ContentValues cv = new ContentValues();
31+
cv.put("created_at", System.currentTimeMillis());
32+
db.update("SecureElement", SQLiteDatabase.CONFLICT_REPLACE, cv, "created_at is ?", new Object[]{null});
33+
}
34+
}
35+
2036
public static final String DB_NAME = "secure_element_database";
2137
private static SecureElementDatabase database;
2238

app/src/main/java/de/davis/passwordmanager/database/converter/Converters.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.google.gson.Gson;
66
import com.google.gson.GsonBuilder;
77

8+
import java.util.Date;
9+
810
import de.davis.passwordmanager.gson.ElementDetailTypeAdapter;
911
import de.davis.passwordmanager.security.Cryptography;
1012
import de.davis.passwordmanager.security.element.ElementDetail;
@@ -24,4 +26,14 @@ public static ElementDetail convertByteArray(byte[] data){
2426
byte[] decrypted = Cryptography.decryptAES(data);
2527
return gson.fromJson(new String(decrypted), ElementDetail.class);
2628
}
29+
30+
@TypeConverter
31+
public static Date fromTimestamp(Long value) {
32+
return value == null ? null : new Date(value);
33+
}
34+
35+
@TypeConverter
36+
public static Long dateToTimestamp(Date date) {
37+
return date == null ? null : date.getTime();
38+
}
2739
}

app/src/main/java/de/davis/passwordmanager/database/daos/SecureElementDao.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import androidx.room.Query;
99
import androidx.room.Update;
1010

11+
import java.time.Instant;
12+
import java.util.Date;
1113
import java.util.List;
1214

1315
import de.davis.passwordmanager.security.element.SecureElement;
@@ -17,13 +19,22 @@
1719
public abstract class SecureElementDao {
1820

1921
@Insert(onConflict = OnConflictStrategy.REPLACE)
20-
public abstract void insertAll(SecureElement... element);
22+
protected abstract void insertNew(SecureElement element);
2123

22-
@Insert(onConflict = OnConflictStrategy.REPLACE)
23-
public abstract void insert(SecureElement element);
24+
public void insert(SecureElement element){
25+
Date date = Date.from(Instant.now());
26+
element.setCreatedAt(date);
27+
insertNew(element);
28+
}
2429

2530
@Update
26-
public abstract void update(SecureElement element);
31+
protected abstract void updateElement(SecureElement element);
32+
33+
public void update(SecureElement element){
34+
Date date = Date.from(Instant.now());
35+
element.setModifiedAt(date);
36+
updateElement(element);
37+
}
2738

2839
@Delete
2940
public abstract void delete(SecureElement element);
@@ -42,4 +53,13 @@ public abstract class SecureElementDao {
4253

4354
@Query("SELECT count(*) FROM SecureElement")
4455
public abstract Single<Integer> count();
56+
57+
@Query("SELECT * FROM SecureElement WHERE favorite ORDER BY ROWID ASC LIMIT :limit")
58+
public abstract LiveData<List<SecureElement>> getFavorites(int limit);
59+
60+
@Query("SELECT * FROM SecureElement ORDER BY created_at DESC LIMIT :limit")
61+
public abstract LiveData<List<SecureElement>> getLastCreated(int limit);
62+
63+
@Query("SELECT * FROM SecureElement WHERE modified_at is not NULL ORDER BY modified_at DESC LIMIT :limit")
64+
public abstract LiveData<List<SecureElement>> getLastModified(int limit);
4565
}

app/src/main/java/de/davis/passwordmanager/security/element/SecureElement.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import net.greypanther.natsort.SimpleNaturalComparator;
1818

1919
import java.io.Serializable;
20+
import java.util.Date;
2021

2122
import de.davis.passwordmanager.R;
2223
import de.davis.passwordmanager.dashboard.Item;
@@ -40,9 +41,18 @@ public class SecureElement implements Serializable, Comparable<SecureElement>, I
4041
@ElementType
4142
private int type;
4243

44+
@ColumnInfo(defaultValue = "false")
45+
private boolean favorite;
46+
4347
@PrimaryKey(autoGenerate = true)
4448
private long id;
4549

50+
@ColumnInfo(name = "created_at")
51+
private Date createdAt;
52+
53+
@ColumnInfo(name = "modified_at")
54+
private Date modifiedAt;
55+
4656
public Drawable getIcon(Context context) {
4757
int px = (int) TypedValue.applyDimension(
4858
TypedValue.COMPLEX_UNIT_DIP,
@@ -56,11 +66,14 @@ public Drawable getIcon(Context context) {
5666
}
5767

5868

59-
public SecureElement(ElementDetail detail, String title, long id, @ElementType int type) {
69+
public SecureElement(ElementDetail detail, String title, long id, @ElementType int type, Date createdAt, Date modifiedAt, boolean favorite) {
6070
this.detail = detail;
6171
this.title = title;
6272
this.id = id;
6373
this.type = type;
74+
this.createdAt = createdAt;
75+
this.modifiedAt = modifiedAt;
76+
this.favorite = favorite;
6477
}
6578

6679
@Ignore
@@ -117,6 +130,30 @@ public int getTypeName(){
117130
}
118131
}
119132

133+
public boolean isFavorite() {
134+
return favorite;
135+
}
136+
137+
public void setFavorite(boolean favorite) {
138+
this.favorite = favorite;
139+
}
140+
141+
public Date getCreatedAt() {
142+
return createdAt;
143+
}
144+
145+
public Date getModifiedAt() {
146+
return modifiedAt;
147+
}
148+
149+
public void setCreatedAt(Date createdAt) {
150+
this.createdAt = createdAt;
151+
}
152+
153+
public void setModifiedAt(Date modifiedAt) {
154+
this.modifiedAt = modifiedAt;
155+
}
156+
120157
@Override
121158
public int compareTo(SecureElement o) {
122159
return SimpleNaturalComparator.getInstance().compare(getTitle().toLowerCase(), o.getTitle().toLowerCase());

app/src/main/java/de/davis/passwordmanager/ui/dashboard/DashboardFragment.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import de.davis.passwordmanager.dashboard.viewholders.BasicViewHolder;
3636
import de.davis.passwordmanager.databinding.FragmentDashboardBinding;
3737
import de.davis.passwordmanager.manager.ActivityResultManager;
38+
import de.davis.passwordmanager.security.element.SecureElement;
3839
import de.davis.passwordmanager.security.element.SecureElementDetail;
3940
import de.davis.passwordmanager.security.element.SecureElementManager;
4041
import de.davis.passwordmanager.ui.callbacks.SearchViewBackPressedHandler;
@@ -160,6 +161,16 @@ public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
160161
scrollingViewModel.setConsumedY(dy);
161162
}
162163
});
164+
165+
if(getArguments() == null)
166+
return;
167+
168+
SecureElement element = (SecureElement) getArguments().getSerializable("element");
169+
if(element == null)
170+
return;
171+
172+
onItemClickedListener.onClicked(element);
173+
oldState = false;
163174
}
164175

165176
@Override

app/src/main/java/de/davis/passwordmanager/ui/elements/password/ViewPasswordFragment.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package de.davis.passwordmanager.ui.elements.password;
22

3+
import static de.davis.passwordmanager.utils.BackgroundUtil.doInBackground;
4+
35
import android.os.Bundle;
46
import android.view.LayoutInflater;
57
import android.view.View;
@@ -13,6 +15,7 @@
1315
import com.google.android.material.textfield.TextInputLayout;
1416

1517
import de.davis.passwordmanager.R;
18+
import de.davis.passwordmanager.database.SecureElementDatabase;
1619
import de.davis.passwordmanager.databinding.FragmentViewPasswordBinding;
1720
import de.davis.passwordmanager.listeners.OnInformationChangedListener;
1821
import de.davis.passwordmanager.manager.ActivityResultManager;
@@ -68,6 +71,8 @@ public void fillInElement(@NonNull SecureElement password) {
6871

6972
setStrengthValues(details);
7073
manageOrigin(details);
74+
75+
doInBackground(() -> SecureElementDatabase.getInstance().getSecureElementDao().update(password));
7176
}
7277

7378
@Override

0 commit comments

Comments
 (0)