* update
@@ -4,7 +4,7 @@ | ||
4 | 4 | import androidx.room.RoomDatabase; |
5 | 5 | |
6 | 6 | //@Database(entities = {User.class, Question.class, Option.class}, version = 2) |
7 | -public abstract class AppDatabase extends RoomDatabase { | |
7 | +public abstract class AppDatabase{ | |
8 | 8 | |
9 | 9 | // public abstract OptionDao optionDao(); |
10 | 10 | // |
@@ -1,5 +1,10 @@ | ||
1 | 1 | package com.xynotec.dictdroid.data.local.dao; |
2 | 2 | |
3 | +import com.xynotec.dictdroid.data.model.Favorite; | |
4 | +import com.xynotec.dictdroid.data.model.History; | |
5 | + | |
6 | +import java.util.List; | |
7 | + | |
3 | 8 | import javax.inject.Inject; |
4 | 9 | |
5 | 10 | public class AppDbHelper implements DbHelper { |
@@ -9,4 +14,24 @@ | ||
9 | 14 | public AppDbHelper(AppDatabase appDatabase) { |
10 | 15 | this.mAppDatabase = appDatabase; |
11 | 16 | } |
17 | + | |
18 | + @Override | |
19 | + public List<History> getHistory() { | |
20 | + return null; | |
21 | + } | |
22 | + | |
23 | + @Override | |
24 | + public List<Favorite> getFavorite() { | |
25 | + return null; | |
26 | + } | |
27 | + | |
28 | + @Override | |
29 | + public void insertHistory(History history) { | |
30 | + | |
31 | + } | |
32 | + | |
33 | + @Override | |
34 | + public void insertFavorite(Favorite favorite) { | |
35 | + | |
36 | + } | |
12 | 37 | } |
@@ -1,4 +1,16 @@ | ||
1 | 1 | package com.xynotec.dictdroid.data.local.dao; |
2 | 2 | |
3 | +import com.xynotec.dictdroid.data.model.Favorite; | |
4 | +import com.xynotec.dictdroid.data.model.History; | |
5 | + | |
6 | +import java.util.List; | |
7 | + | |
3 | 8 | public interface DbHelper { |
9 | + | |
10 | + List<History> getHistory(); | |
11 | + List<Favorite> getFavorite(); | |
12 | + void insertHistory(History history); | |
13 | + void insertFavorite(Favorite favorite); | |
14 | + | |
15 | + | |
4 | 16 | } |
@@ -0,0 +1,16 @@ | ||
1 | +package com.xynotec.dictdroid.data.local.dao; | |
2 | + | |
3 | +import javax.inject.Inject; | |
4 | + | |
5 | +import io.realm.RealmConfiguration; | |
6 | + | |
7 | +public class HistoryDao { | |
8 | + | |
9 | + RealmConfiguration mConfig; | |
10 | + | |
11 | + @Inject | |
12 | + public HistoryDao(RealmConfiguration config) { | |
13 | + mConfig = config; | |
14 | + } | |
15 | + | |
16 | +} |
@@ -3,11 +3,16 @@ | ||
3 | 3 | import android.content.Context; |
4 | 4 | |
5 | 5 | import com.google.gson.Gson; |
6 | +import com.xynotec.dictdroid.data.local.dao.DbHelper; | |
6 | 7 | import com.xynotec.dictdroid.data.local.prefs.PreferencesHelper; |
8 | +import com.xynotec.dictdroid.data.model.Favorite; | |
9 | +import com.xynotec.dictdroid.data.model.History; | |
7 | 10 | import com.xynotec.dictdroid.data.remote.ApiHelper; |
8 | 11 | //import com.xynotec.coinmarketcap.data.remote.cryptocurrency.listting.latest.CryptocurrencyListingsLatestResponse; |
9 | 12 | //import com.xynotec.coinmarketcap.data.remote.cryptocurrency.quotes.latest.CryptocurrencyQuotesLatestResponse; |
10 | 13 | |
14 | +import java.util.List; | |
15 | + | |
11 | 16 | import javax.inject.Inject; |
12 | 17 | import javax.inject.Singleton; |
13 | 18 |
@@ -22,10 +27,12 @@ | ||
22 | 27 | private final ApiHelper mApiHelper; |
23 | 28 | |
24 | 29 | private final PreferencesHelper mPreferencesHelper; |
30 | + private final DbHelper mDbHelper; | |
25 | 31 | |
26 | 32 | @Inject |
27 | - public AppDataManager(Context context, PreferencesHelper preferencesHelper, ApiHelper apiHelper, Gson gson) { | |
33 | + public AppDataManager(Context context, DbHelper dbHelper, PreferencesHelper preferencesHelper, ApiHelper apiHelper, Gson gson) { | |
28 | 34 | mContext = context; |
35 | + mDbHelper = dbHelper; | |
29 | 36 | mPreferencesHelper = preferencesHelper; |
30 | 37 | mApiHelper = apiHelper; |
31 | 38 | mGson = gson; |
@@ -161,6 +168,26 @@ | ||
161 | 168 | return mPreferencesHelper.getPopUpSizeHeight(context); |
162 | 169 | } |
163 | 170 | |
171 | + @Override | |
172 | + public List<History> getHistory() { | |
173 | + return mDbHelper.getHistory(); | |
174 | + } | |
175 | + | |
176 | + @Override | |
177 | + public List<Favorite> getFavorite() { | |
178 | + return mDbHelper.getFavorite(); | |
179 | + } | |
180 | + | |
181 | + @Override | |
182 | + public void insertHistory(History history) { | |
183 | + mDbHelper.insertHistory(history); | |
184 | + } | |
185 | + | |
186 | + @Override | |
187 | + public void insertFavorite(Favorite favorite) { | |
188 | + mDbHelper.insertFavorite(favorite); | |
189 | + } | |
190 | + | |
164 | 191 | // @Override |
165 | 192 | // public Single<CryptocurrencyListingsLatestResponse> doCryptoCurrencyListingsLatest(CryptocurrencyListingsLatestResponse.LatestRequest request) { |
166 | 193 | // return mApiHelper.doCryptoCurrencyListingsLatest(request); |
@@ -4,5 +4,8 @@ | ||
4 | 4 | import com.xynotec.dictdroid.data.local.prefs.PreferencesHelper; |
5 | 5 | import com.xynotec.dictdroid.data.remote.ApiHelper; |
6 | 6 | |
7 | +import java.util.List; | |
8 | + | |
7 | 9 | public interface DataManager extends DbHelper, PreferencesHelper, ApiHelper { |
10 | + | |
8 | 11 | } |
@@ -7,6 +7,9 @@ | ||
7 | 7 | |
8 | 8 | import com.google.gson.Gson; |
9 | 9 | import com.google.gson.GsonBuilder; |
10 | +import com.xynotec.dictdroid.data.local.dao.AppDatabase; | |
11 | +import com.xynotec.dictdroid.data.local.dao.AppDbHelper; | |
12 | +import com.xynotec.dictdroid.data.local.dao.DbHelper; | |
10 | 13 | import com.xynotec.dictdroid.data.local.prefs.AppPreferencesHelper; |
11 | 14 | import com.xynotec.dictdroid.data.local.prefs.PreferencesHelper; |
12 | 15 | import com.xynotec.dictdroid.ende.BuildConfig; |
@@ -23,6 +26,9 @@ | ||
23 | 26 | |
24 | 27 | import dagger.Module; |
25 | 28 | import dagger.Provides; |
29 | +import io.realm.Realm; | |
30 | +import io.realm.RealmConfiguration; | |
31 | + | |
26 | 32 | import javax.inject.Singleton; |
27 | 33 | |
28 | 34 |
@@ -51,12 +57,12 @@ | ||
51 | 57 | // return BuildConfig.API_KEY; |
52 | 58 | // } |
53 | 59 | // |
54 | -// @Provides | |
55 | -// @Singleton | |
60 | + @Provides | |
61 | + @Singleton | |
56 | 62 | // AppDatabase provideAppDatabase(@DatabaseInfo String dbName, Context context) { |
57 | -// return Room.databaseBuilder(context, AppDatabase.class, dbName).fallbackToDestructiveMigration() | |
58 | -// .build(); | |
59 | -// } | |
63 | + AppDatabase provideAppDatabase(Context context) { | |
64 | + return null; | |
65 | + } | |
60 | 66 | |
61 | 67 | // @Provides |
62 | 68 | // @Singleton |
@@ -89,14 +95,14 @@ | ||
89 | 95 | // return AppConstants.DB_NAME; |
90 | 96 | // } |
91 | 97 | // |
92 | -// @Provides | |
93 | -// @Singleton | |
94 | -// DbHelper provideDbHelper(AppDbHelper appDbHelper) { | |
95 | -// return appDbHelper; | |
96 | -// } | |
97 | -// | |
98 | 98 | @Provides |
99 | 99 | @Singleton |
100 | + DbHelper provideDbHelper(AppDbHelper appDbHelper) { | |
101 | + return appDbHelper; | |
102 | + } | |
103 | + | |
104 | + @Provides | |
105 | + @Singleton | |
100 | 106 | Gson provideGson() { |
101 | 107 | Log.d(TAG, "provideGson"); |
102 | 108 | return new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); |
@@ -114,6 +120,15 @@ | ||
114 | 120 | return appPreferencesHelper; |
115 | 121 | } |
116 | 122 | |
123 | + @Provides | |
124 | + @Singleton | |
125 | + RealmConfiguration provideRealmConfiguration(Context context) { | |
126 | + Realm.init(context); | |
127 | + RealmConfiguration realmConfig = new RealmConfiguration.Builder().build(); | |
128 | + Realm.setDefaultConfiguration(realmConfig); | |
129 | + return realmConfig; | |
130 | + } | |
131 | + | |
117 | 132 | // @Provides |
118 | 133 | // @Singleton |
119 | 134 | // ApiHeader.ProtectedApiHeader provideProtectedApiHeader(@ApiInfo String apiKey, |
@@ -0,0 +1,75 @@ | ||
1 | +package com.xynotec.realm.livemodel; | |
2 | + | |
3 | +import androidx.annotation.MainThread; | |
4 | +import androidx.annotation.NonNull; | |
5 | +import androidx.lifecycle.LiveData; | |
6 | + | |
7 | +import io.realm.ObjectChangeSet; | |
8 | +import io.realm.RealmModel; | |
9 | +import io.realm.RealmObject; | |
10 | +import io.realm.RealmObjectChangeListener; | |
11 | + | |
12 | +public class LiveRealmObject<T extends RealmModel> extends LiveData<T> { | |
13 | + // The listener will listen until the object is deleted. | |
14 | + // An invalidated object shouldn't be set in LiveData, null is set instead. | |
15 | + private RealmObjectChangeListener<T> listener = new RealmObjectChangeListener<T>() { | |
16 | + @Override | |
17 | + public void onChange(@NonNull T object, ObjectChangeSet objectChangeSet) { | |
18 | + if (!objectChangeSet.isDeleted()) { | |
19 | + setValue(object); | |
20 | + } else { | |
21 | + setValue(null); | |
22 | + } | |
23 | + } | |
24 | + }; | |
25 | + | |
26 | + /** | |
27 | + * Wraps the provided managed RealmObject as a LiveData. | |
28 | + * | |
29 | + * The provided object should not be null, should be managed, and should be valid. | |
30 | + * | |
31 | + * @param object the managed RealmModel to wrap as LiveData | |
32 | + */ | |
33 | + @MainThread | |
34 | + public LiveRealmObject(@NonNull T object) { | |
35 | + //noinspection ConstantConditions | |
36 | + if (object == null) { | |
37 | + throw new IllegalArgumentException("The object cannot be null!"); | |
38 | + } | |
39 | + if (!RealmObject.isManaged(object)) { | |
40 | + throw new IllegalArgumentException("LiveRealmObject only supports managed RealmModel instances!"); | |
41 | + } | |
42 | + if (!RealmObject.isValid(object)) { | |
43 | + throw new IllegalArgumentException("The provided RealmObject is no longer valid, and therefore cannot be observed for changes."); | |
44 | + } | |
45 | + setValue(object); | |
46 | + } | |
47 | + | |
48 | + // We should start observing and stop observing, depending on whether we have observers. | |
49 | + // Deleted objects can no longer be observed. | |
50 | + // We can also no longer observe the object if all local Realm instances on this thread (the UI thread) are closed. | |
51 | + | |
52 | + /** | |
53 | + * Starts observing the RealmObject, if it is still valid. | |
54 | + */ | |
55 | + @Override | |
56 | + protected void onActive() { | |
57 | + super.onActive(); | |
58 | + T object = getValue(); | |
59 | + if (object != null && RealmObject.isValid(object)) { | |
60 | + RealmObject.addChangeListener(object, listener); | |
61 | + } | |
62 | + } | |
63 | + | |
64 | + /** | |
65 | + * Stops observing the RealmObject. | |
66 | + */ | |
67 | + @Override | |
68 | + protected void onInactive() { | |
69 | + super.onInactive(); | |
70 | + T object = getValue(); | |
71 | + if (object != null && RealmObject.isValid(object)) { | |
72 | + RealmObject.removeChangeListener(object, listener); | |
73 | + } | |
74 | + } | |
75 | +} |
@@ -0,0 +1,67 @@ | ||
1 | +package com.xynotec.realm.livemodel; | |
2 | + | |
3 | +import androidx.annotation.MainThread; | |
4 | +import androidx.annotation.NonNull; | |
5 | +import androidx.annotation.Nullable; | |
6 | +import androidx.lifecycle.LiveData; | |
7 | + | |
8 | +import java.util.List; | |
9 | + | |
10 | +import io.realm.OrderedCollectionChangeSet; | |
11 | +import io.realm.OrderedRealmCollectionChangeListener; | |
12 | +import io.realm.RealmModel; | |
13 | +import io.realm.RealmResults; | |
14 | + | |
15 | +public class LiveRealmResults<T extends RealmModel> extends LiveData<List<T>> { | |
16 | + private final RealmResults<T> results; | |
17 | + | |
18 | + // The listener will notify the observers whenever a change occurs. | |
19 | + // The results are modified in change. This could be expanded to also return the change set in a pair. | |
20 | + private OrderedRealmCollectionChangeListener<RealmResults<T>> listener = new OrderedRealmCollectionChangeListener<RealmResults<T>>() { | |
21 | + @Override | |
22 | + public void onChange(@NonNull RealmResults<T> results, @Nullable OrderedCollectionChangeSet changeSet) { | |
23 | + LiveRealmResults.this.setValue(results); | |
24 | + } | |
25 | + }; | |
26 | + | |
27 | + @MainThread | |
28 | + public LiveRealmResults(@NonNull RealmResults<T> results) { | |
29 | + //noinspection ConstantConditions | |
30 | + if (results == null) { | |
31 | + throw new IllegalArgumentException("Results cannot be null!"); | |
32 | + } | |
33 | + if (!results.isValid()) { | |
34 | + throw new IllegalArgumentException("The provided RealmResults is no longer valid, the Realm instance it belongs to is closed. It can no longer be observed for changes."); | |
35 | + } | |
36 | + this.results = results; | |
37 | + if (results.isLoaded()) { | |
38 | + // we should not notify observers when results aren't ready yet (async query). | |
39 | + // however, synchronous query should be set explicitly. | |
40 | + setValue(results); | |
41 | + } | |
42 | + } | |
43 | + | |
44 | + // We should start observing and stop observing, depending on whether we have observers. | |
45 | + | |
46 | + /** | |
47 | + * Starts observing the RealmResults, if it is still valid. | |
48 | + */ | |
49 | + @Override | |
50 | + protected void onActive() { | |
51 | + super.onActive(); | |
52 | + if (results.isValid()) { // invalidated results can no longer be observed. | |
53 | + results.addChangeListener(listener); | |
54 | + } | |
55 | + } | |
56 | + | |
57 | + /** | |
58 | + * Stops observing the RealmResults. | |
59 | + */ | |
60 | + @Override | |
61 | + protected void onInactive() { | |
62 | + super.onInactive(); | |
63 | + if (results.isValid()) { | |
64 | + results.removeChangeListener(listener); | |
65 | + } | |
66 | + } | |
67 | +} |
@@ -0,0 +1,36 @@ | ||
1 | +package com.xynotec.utils; | |
2 | + | |
3 | +import java.util.ArrayList; | |
4 | +import java.util.Collections; | |
5 | + | |
6 | +public class LimitStackList <T> { | |
7 | + | |
8 | + final static int LIMIT_SIZE = 50; | |
9 | + | |
10 | + int size = LIMIT_SIZE; | |
11 | + | |
12 | + private ArrayList<T> list = new ArrayList<T>(); | |
13 | + | |
14 | + public LimitStackList (int size) | |
15 | + { | |
16 | + this.size = size; | |
17 | + } | |
18 | + | |
19 | + public void add(T obj) | |
20 | + { | |
21 | + list.remove(obj);// remove duplicate first | |
22 | + | |
23 | + list.add(0, obj); | |
24 | + | |
25 | + int length = list.size(); | |
26 | + if (list.size() > length) | |
27 | + list.remove(length - 1); | |
28 | + } | |
29 | + | |
30 | + public ArrayList<T> getList() | |
31 | + { | |
32 | + return list; | |
33 | + } | |
34 | + | |
35 | + | |
36 | +} |