[Architecture] Implement dagger for homework

This commit is contained in:
Kacper Ziubryniewicz 2019-11-04 22:13:07 +01:00
parent e1d902ceb5
commit 8f80bc70ed
21 changed files with 257 additions and 50 deletions

View File

@ -1,6 +1,7 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
apply plugin: 'io.fabric' apply plugin: 'io.fabric'
@ -91,7 +92,7 @@ tasks.whenTaskAdded { task ->
dependencies { dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
annotationProcessor "androidx.room:room-compiler:${versions.room}" kapt "androidx.room:room-compiler:${versions.room}"
debugImplementation "com.amitshekhar.android:debug-db:1.0.5" debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}" implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}"
@ -164,6 +165,11 @@ dependencies {
implementation "io.github.wulkanowy:signer-android:0.1.1" implementation "io.github.wulkanowy:signer-android:0.1.1"
implementation "androidx.work:work-runtime-ktx:${versions.work}" implementation "androidx.work:work-runtime-ktx:${versions.work}"
api "com.google.dagger:dagger:${versions.dagger}"
api "com.google.dagger:dagger-android-support:${versions.dagger}"
kapt "com.google.dagger:dagger-compiler:${versions.dagger}"
kapt "com.google.dagger:dagger-android-processor:${versions.dagger}"
} }
repositories { repositories {
mavenCentral() mavenCentral()

View File

@ -22,6 +22,7 @@ import android.util.Pair;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import androidx.multidex.MultiDex;
import androidx.work.Configuration; import androidx.work.Configuration;
import com.chuckerteam.chucker.api.ChuckerCollector; import com.chuckerteam.chucker.api.ChuckerCollector;
@ -59,6 +60,8 @@ import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import cat.ereza.customactivityoncrash.config.CaocConfig; import cat.ereza.customactivityoncrash.config.CaocConfig;
import dagger.android.AndroidInjector;
import dagger.android.support.DaggerApplication;
import im.wangchao.mhttp.MHttp; import im.wangchao.mhttp.MHttp;
import im.wangchao.mhttp.internal.cookie.PersistentCookieJar; import im.wangchao.mhttp.internal.cookie.PersistentCookieJar;
import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache; import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache;
@ -77,6 +80,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.debuglog.DebugLog;
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore; import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile; import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull; import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull;
import pl.szczodrzynski.edziennik.di.DaggerAppComponent;
import pl.szczodrzynski.edziennik.network.NetworkUtils; import pl.szczodrzynski.edziennik.network.NetworkUtils;
import pl.szczodrzynski.edziennik.network.TLSSocketFactory; import pl.szczodrzynski.edziennik.network.TLSSocketFactory;
import pl.szczodrzynski.edziennik.sync.SyncWorker; import pl.szczodrzynski.edziennik.sync.SyncWorker;
@ -90,7 +94,7 @@ import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_
import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_MOBIDZIENNIK; import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_MOBIDZIENNIK;
import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_VULCAN; import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_VULCAN;
public class App extends androidx.multidex.MultiDexApplication implements Configuration.Provider { public class App extends DaggerApplication implements Configuration.Provider {
private static final String TAG = "App"; private static final String TAG = "App";
public static int profileId = -1; public static int profileId = -1;
private Context mContext; private Context mContext;
@ -181,6 +185,17 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
return Icon.createWithBitmap(bitmap); return Icon.createWithBitmap(bitmap);
} }
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.factory().create(this);
}
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -543,6 +558,7 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
appConfig = new AppConfig(this); appConfig = new AppConfig(this);
} }
} }
public void saveConfig() public void saveConfig()
{ {
try { try {
@ -724,5 +740,4 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
devMode = false; devMode = false;
} }
} }
} }

View File

@ -9,7 +9,6 @@ import android.os.*
import android.view.Gravity import android.view.Gravity
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
@ -26,6 +25,7 @@ import com.mikepenz.materialdrawer.model.ProfileDrawerItem
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IProfile import com.mikepenz.materialdrawer.model.interfaces.IProfile
import dagger.android.support.DaggerAppCompatActivity
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
@ -78,7 +78,7 @@ import java.io.IOException
import java.util.* import java.util.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
class MainActivity : AppCompatActivity() { class MainActivity : DaggerAppCompatActivity() {
companion object { companion object {
var useOldMessages = false var useOldMessages = false
@ -340,7 +340,7 @@ class MainActivity : AppCompatActivity() {
if (!profileListEmpty) { if (!profileListEmpty) {
handleIntent(intent?.extras) handleIntent(intent?.extras)
} }
app.db.profileDao().getAllFull().observe(this, Observer { profiles -> app.db.profileDao().allFull.observe(this, Observer { profiles ->
// TODO fix weird -1 profiles ??? // TODO fix weird -1 profiles ???
profiles.removeAll { it.id < 0 } profiles.removeAll { it.id < 0 }
drawer.setProfileList(profiles) drawer.setProfileList(profiles)
@ -357,7 +357,7 @@ class MainActivity : AppCompatActivity() {
if (app.profile != null) if (app.profile != null)
setDrawerItems() setDrawerItems()
app.db.metadataDao().getUnreadCounts().observe(this, Observer { unreadCounters -> app.db.metadataDao().unreadCounts.observe(this, Observer { unreadCounters ->
unreadCounters.map { unreadCounters.map {
it.type = it.thingType it.type = it.thingType
} }

View File

@ -10,6 +10,8 @@ import androidx.room.TypeConverters;
import androidx.room.migration.Migration; import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase; import androidx.sqlite.db.SupportSQLiteDatabase;
import javax.inject.Singleton;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterDate; import pl.szczodrzynski.edziennik.data.db.converters.ConverterDate;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterDateInt; import pl.szczodrzynski.edziennik.data.db.converters.ConverterDateInt;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterJsonObject; import pl.szczodrzynski.edziennik.data.db.converters.ConverterJsonObject;
@ -74,6 +76,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.teams.Team;
import pl.szczodrzynski.edziennik.data.db.modules.teams.TeamDao; import pl.szczodrzynski.edziennik.data.db.modules.teams.TeamDao;
import pl.szczodrzynski.edziennik.utils.models.Date; import pl.szczodrzynski.edziennik.utils.models.Date;
@Singleton
@Database(entities = { @Database(entities = {
Grade.class, Grade.class,
//GradeCategory.class, //GradeCategory.class,
@ -114,33 +117,60 @@ import pl.szczodrzynski.edziennik.utils.models.Date;
public abstract class AppDb extends RoomDatabase { public abstract class AppDb extends RoomDatabase {
public abstract GradeDao gradeDao(); public abstract GradeDao gradeDao();
//public abstract GradeCategoryDao gradeCategoryDao(); //public abstract GradeCategoryDao gradeCategoryDao();
public abstract TeacherDao teacherDao(); public abstract TeacherDao teacherDao();
public abstract TeacherAbsenceDao teacherAbsenceDao(); public abstract TeacherAbsenceDao teacherAbsenceDao();
public abstract TeacherAbsenceTypeDao teacherAbsenceTypeDao(); public abstract TeacherAbsenceTypeDao teacherAbsenceTypeDao();
public abstract SubjectDao subjectDao(); public abstract SubjectDao subjectDao();
public abstract NoticeDao noticeDao(); public abstract NoticeDao noticeDao();
public abstract LessonDao lessonDao(); public abstract LessonDao lessonDao();
public abstract LessonChangeDao lessonChangeDao(); public abstract LessonChangeDao lessonChangeDao();
public abstract TeamDao teamDao(); public abstract TeamDao teamDao();
public abstract AttendanceDao attendanceDao(); public abstract AttendanceDao attendanceDao();
public abstract EventDao eventDao(); public abstract EventDao eventDao();
public abstract EventTypeDao eventTypeDao(); public abstract EventTypeDao eventTypeDao();
public abstract LoginStoreDao loginStoreDao(); public abstract LoginStoreDao loginStoreDao();
public abstract ProfileDao profileDao(); public abstract ProfileDao profileDao();
public abstract LuckyNumberDao luckyNumberDao(); public abstract LuckyNumberDao luckyNumberDao();
public abstract AnnouncementDao announcementDao(); public abstract AnnouncementDao announcementDao();
public abstract GradeCategoryDao gradeCategoryDao(); public abstract GradeCategoryDao gradeCategoryDao();
public abstract FeedbackMessageDao feedbackMessageDao(); public abstract FeedbackMessageDao feedbackMessageDao();
public abstract MessageDao messageDao(); public abstract MessageDao messageDao();
public abstract MessageRecipientDao messageRecipientDao(); public abstract MessageRecipientDao messageRecipientDao();
public abstract DebugLogDao debugLogDao(); public abstract DebugLogDao debugLogDao();
public abstract EndpointTimerDao endpointTimerDao(); public abstract EndpointTimerDao endpointTimerDao();
public abstract LessonRangeDao lessonRangeDao(); public abstract LessonRangeDao lessonRangeDao();
public abstract NotificationDao notificationDao(); public abstract NotificationDao notificationDao();
public abstract ClassroomDao classroomDao(); public abstract ClassroomDao classroomDao();
public abstract NoticeTypeDao noticeTypeDao(); public abstract NoticeTypeDao noticeTypeDao();
public abstract AttendanceTypeDao attendanceTypeDao(); public abstract AttendanceTypeDao attendanceTypeDao();
public abstract MetadataDao metadataDao(); public abstract MetadataDao metadataDao();
private static volatile AppDb INSTANCE; private static volatile AppDb INSTANCE;

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.data.db
import android.content.Context
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
@Module
internal class DatabaseModule {
@Singleton
@Provides
fun provideDatabase(context: Context) = AppDb.getDatabase(context)
@Singleton
@Provides
fun provideEventDao(database: AppDb) = database.eventDao()
@Singleton
@Provides
fun provideMetadataDao(database: AppDb) = database.metadataDao()
}

View File

@ -1,19 +1,22 @@
package pl.szczodrzynski.edziennik.data.db.modules.events; package pl.szczodrzynski.edziennik.data.db.modules.events;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData; import androidx.lifecycle.LiveData;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import androidx.room.Dao; import androidx.room.Dao;
import androidx.room.Insert; import androidx.room.Insert;
import androidx.room.OnConflictStrategy; import androidx.room.OnConflictStrategy;
import androidx.room.Query; import androidx.room.Query;
import androidx.room.RawQuery; import androidx.room.RawQuery;
import androidx.room.Transaction; import androidx.room.Transaction;
import androidx.annotation.NonNull; import androidx.sqlite.db.SimpleSQLiteQuery;
import android.util.Log; import androidx.sqlite.db.SupportSQLiteQuery;
import java.util.List; import java.util.List;
import javax.inject.Singleton;
import pl.szczodrzynski.edziennik.utils.models.Date; import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Time; import pl.szczodrzynski.edziennik.utils.models.Time;
@ -21,6 +24,7 @@ import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_HOMEWORK; import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_HOMEWORK;
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_LESSON_CHANGE; import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_LESSON_CHANGE;
@Singleton
@Dao @Dao
public abstract class EventDao { public abstract class EventDao {
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
@ -34,26 +38,32 @@ public abstract class EventDao {
@Query("DELETE FROM events WHERE profileId = :profileId AND eventId = :id") @Query("DELETE FROM events WHERE profileId = :profileId AND eventId = :id")
public abstract void remove(int profileId, long id); public abstract void remove(int profileId, long id);
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId") @Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
public abstract void removeMetadata(int profileId, int thingType, long thingId); public abstract void removeMetadata(int profileId, int thingType, long thingId);
@Transaction @Transaction
public void remove(int profileId, int type, long id) { public void remove(int profileId, int type, long id) {
remove(profileId, id); remove(profileId, id);
removeMetadata(profileId, type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, id); removeMetadata(profileId, type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, id);
} }
@Transaction @Transaction
public void remove(Event event) { public void remove(Event event) {
remove(event.profileId, event.type, event.id); remove(event.profileId, event.type, event.id);
} }
@Transaction @Transaction
public void remove(int profileId, Event event) { public void remove(int profileId, Event event) {
remove(profileId, event.type, event.id); remove(profileId, event.type, event.id);
} }
@Query("DELETE FROM events WHERE teamId = :teamId AND eventId = :id") @Query("DELETE FROM events WHERE teamId = :teamId AND eventId = :id")
public abstract void removeByTeamId(long teamId, long id); public abstract void removeByTeamId(long teamId, long id);
@RawQuery(observedEntities = {Event.class}) @RawQuery(observedEntities = {Event.class})
abstract LiveData<List<EventFull>> getAll(SupportSQLiteQuery query); abstract LiveData<List<EventFull>> getAll(SupportSQLiteQuery query);
public LiveData<List<EventFull>> getAll(int profileId, String filter) { public LiveData<List<EventFull>> getAll(int profileId, String filter) {
String query = "SELECT \n" + String query = "SELECT \n" +
"*, \n" + "*, \n" +
@ -71,24 +81,31 @@ public abstract class EventDao {
Log.d("DB", query); Log.d("DB", query);
return getAll(new SimpleSQLiteQuery(query)); return getAll(new SimpleSQLiteQuery(query));
} }
public LiveData<List<EventFull>> getAll(int profileId) { public LiveData<List<EventFull>> getAll(int profileId) {
return getAll(profileId, "1"); return getAll(profileId, "1");
} }
public List<EventFull> getAllNow(int profileId) { public List<EventFull> getAllNow(int profileId) {
return getAllNow(profileId, "1"); return getAllNow(profileId, "1");
} }
public LiveData<List<EventFull>> getAllWhere(int profileId, String filter) { public LiveData<List<EventFull>> getAllWhere(int profileId, String filter) {
return getAll(profileId, filter); return getAll(profileId, filter);
} }
public LiveData<List<EventFull>> getAllByType(int profileId, int type, String filter) { public LiveData<List<EventFull>> getAllByType(int profileId, int type, String filter) {
return getAll(profileId, "eventType = "+type+" AND "+filter); return getAll(profileId, "eventType = "+type+" AND "+filter);
} }
public LiveData<List<EventFull>> getAllByDate(int profileId, @NonNull Date date) { public LiveData<List<EventFull>> getAllByDate(int profileId, @NonNull Date date) {
return getAll(profileId, "eventDate = '"+date.getStringY_m_d()+"'"); return getAll(profileId, "eventDate = '"+date.getStringY_m_d()+"'");
} }
public List<EventFull> getAllByDateNow(int profileId, @NonNull Date date) { public List<EventFull> getAllByDateNow(int profileId, @NonNull Date date) {
return getAllNow(profileId, "eventDate = '"+date.getStringY_m_d()+"'"); return getAllNow(profileId, "eventDate = '"+date.getStringY_m_d()+"'");
} }
public LiveData<List<EventFull>> getAllByDateTime(int profileId, @NonNull Date date, Time time) { public LiveData<List<EventFull>> getAllByDateTime(int profileId, @NonNull Date date, Time time) {
if (time == null) if (time == null)
return getAllByDate(profileId, date); return getAllByDate(profileId, date);
@ -97,6 +114,7 @@ public abstract class EventDao {
@RawQuery @RawQuery
abstract List<EventFull> getAllNow(SupportSQLiteQuery query); abstract List<EventFull> getAllNow(SupportSQLiteQuery query);
public List<EventFull> getAllNow(int profileId, String filter) { public List<EventFull> getAllNow(int profileId, String filter) {
return getAllNow(new SimpleSQLiteQuery("SELECT \n" + return getAllNow(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" + "*, \n" +
@ -112,6 +130,7 @@ public abstract class EventDao {
"WHERE events.profileId = "+profileId+" AND events.eventBlacklisted = 0 AND "+filter+"\n" + "WHERE events.profileId = "+profileId+" AND events.eventBlacklisted = 0 AND "+filter+"\n" +
"ORDER BY eventStartTime, addedDate ASC")); "ORDER BY eventStartTime, addedDate ASC"));
} }
public List<EventFull> getNotNotifiedNow(int profileId) { public List<EventFull> getNotNotifiedNow(int profileId) {
return getAllNow(profileId, "notified = 0"); return getAllNow(profileId, "notified = 0");
} }

View File

@ -9,7 +9,8 @@ import androidx.room.Transaction;
import java.util.List; import java.util.List;
import pl.szczodrzynski.edziennik.data.db.modules.notices.Notice; import javax.inject.Singleton;
import pl.szczodrzynski.edziennik.data.db.modules.announcements.Announcement; import pl.szczodrzynski.edziennik.data.db.modules.announcements.Announcement;
import pl.szczodrzynski.edziennik.data.db.modules.attendance.Attendance; import pl.szczodrzynski.edziennik.data.db.modules.attendance.Attendance;
import pl.szczodrzynski.edziennik.data.db.modules.events.Event; import pl.szczodrzynski.edziennik.data.db.modules.events.Event;
@ -17,6 +18,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.grades.Grade;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange; import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull; import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull;
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message; import pl.szczodrzynski.edziennik.data.db.modules.messages.Message;
import pl.szczodrzynski.edziennik.data.db.modules.notices.Notice;
import pl.szczodrzynski.edziennik.utils.models.UnreadCounter; import pl.szczodrzynski.edziennik.utils.models.UnreadCounter;
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_ANNOUNCEMENT; import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_ANNOUNCEMENT;
@ -28,6 +30,7 @@ import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_MESSAGE; import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_MESSAGE;
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_NOTICE; import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_NOTICE;
@Singleton
@Dao @Dao
public abstract class MetadataDao { public abstract class MetadataDao {
@Insert(onConflict = OnConflictStrategy.IGNORE) @Insert(onConflict = OnConflictStrategy.IGNORE)
@ -43,7 +46,6 @@ public abstract class MetadataDao {
abstract void updateNotified(int profileId, int thingType, long thingId, boolean notified); abstract void updateNotified(int profileId, int thingType, long thingId, boolean notified);
@Transaction @Transaction
public void setSeen(List<Metadata> metadataList) { public void setSeen(List<Metadata> metadataList) {
for (Metadata metadata: metadataList) { for (Metadata metadata: metadataList) {
@ -152,7 +154,6 @@ public abstract class MetadataDao {
} }
@Query("UPDATE metadata SET seen = :seen WHERE profileId = :profileId AND thingType = :thingType") @Query("UPDATE metadata SET seen = :seen WHERE profileId = :profileId AND thingType = :thingType")
public abstract void setAllSeen(int profileId, int thingType, boolean seen); public abstract void setAllSeen(int profileId, int thingType, boolean seen);
@ -166,7 +167,6 @@ public abstract class MetadataDao {
public abstract void setAllNotified(int profileId, boolean notified); public abstract void setAllNotified(int profileId, boolean notified);
@Query("SELECT count() FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND seen = 0") @Query("SELECT count() FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND seen = 0")
public abstract LiveData<Integer> countUnseen(int profileId, int thingType); public abstract LiveData<Integer> countUnseen(int profileId, int thingType);
@ -183,7 +183,6 @@ public abstract class MetadataDao {
public abstract LiveData<Integer> countUnseen(); public abstract LiveData<Integer> countUnseen();
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId") @Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
public abstract void delete(int profileId, int thingType, long thingId); public abstract void delete(int profileId, int thingType, long thingId);
@ -191,12 +190,10 @@ public abstract class MetadataDao {
public abstract void deleteAll(int profileId); public abstract void deleteAll(int profileId);
@Query("SELECT profileId, thingType, COUNT(thingId) AS count FROM metadata WHERE seen = 0 GROUP BY profileId, thingType") @Query("SELECT profileId, thingType, COUNT(thingId) AS count FROM metadata WHERE seen = 0 GROUP BY profileId, thingType")
public abstract LiveData<List<UnreadCounter>> getUnreadCounts(); public abstract LiveData<List<UnreadCounter>> getUnreadCounts();
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = "+TYPE_GRADE+" AND thingId NOT IN (SELECT gradeId FROM grades WHERE profileId = :profileId);") @Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = "+TYPE_GRADE+" AND thingId NOT IN (SELECT gradeId FROM grades WHERE profileId = :profileId);")
public abstract void deleteUnusedGrades(int profileId); public abstract void deleteUnusedGrades(int profileId);

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di
import dagger.Component
import dagger.android.AndroidInjector
import dagger.android.support.AndroidSupportInjectionModule
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.DatabaseModule
import javax.inject.Singleton
@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
BindingModule::class,
AppModule::class,
DatabaseModule::class
])
interface AppComponent : AndroidInjector<App> {
@Component.Factory
interface Factory : AndroidInjector.Factory<App>
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di
import android.content.Context
import dagger.Module
import dagger.Provides
import pl.szczodrzynski.edziennik.App
import javax.inject.Singleton
@Module
internal class AppModule {
@Singleton
@Provides
fun provideContext(app: App): Context = app
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.di.scopes.PerActivity
import pl.szczodrzynski.edziennik.di.scopes.PerFragment
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
import pl.szczodrzynski.edziennik.ui.modules.homework.list.HomeworkListFragment
@Module
@Suppress("unused")
internal abstract class BindingModule {
/**
* ACTIVITIES
*/
@PerActivity
@ContributesAndroidInjector
abstract fun bindMainActivity(): MainActivity
/**
* FRAGMENTS
*/
@PerFragment
@ContributesAndroidInjector
abstract fun bindHomeworkFragment(): HomeworkFragment
@PerFragment
@ContributesAndroidInjector
abstract fun bindHomeworkListFragment(): HomeworkListFragment
}

View File

@ -0,0 +1,11 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di.scopes
import javax.inject.Scope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerActivity

View File

@ -0,0 +1,11 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di.scopes
import javax.inject.Scope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerFragment

View File

@ -5,11 +5,11 @@
package pl.szczodrzynski.edziennik.ui.base package pl.szczodrzynski.edziennik.ui.base
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import dagger.android.support.DaggerFragment
abstract class BaseFragment<T : BasePresenter<out BaseView>> : Fragment(), BaseView { abstract class BaseFragment<T : BasePresenter<out BaseView>> : DaggerFragment(), BaseView {
abstract val presenter: T abstract var presenter: T
override fun showMessage(text: String) { override fun showMessage(text: String) {
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show() Toast.makeText(activity, text, Toast.LENGTH_SHORT).show()

View File

@ -17,18 +17,21 @@ import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
import pl.szczodrzynski.edziennik.utils.Themes import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
import javax.inject.Inject
class HomeworkFragment : BaseFragment<HomeworkPresenter>(), HomeworkView { class HomeworkFragment : BaseFragment<HomeworkPresenter>(), HomeworkView {
companion object { companion object {
var pageSelection = 0 var pageSelection = 0
} }
override lateinit var app: App
private lateinit var activity: MainActivity private lateinit var activity: MainActivity
private lateinit var b: FragmentHomeworkBinding private lateinit var b: FragmentHomeworkBinding
override val presenter: HomeworkPresenter = HomeworkPresenter() @Inject
override lateinit var presenter: HomeworkPresenter
@Inject
lateinit var app: App
override val markAsReadSuccessString: String override val markAsReadSuccessString: String
get() = getString(R.string.main_menu_mark_as_read_success) get() = getString(R.string.main_menu_mark_as_read_success)
@ -40,8 +43,6 @@ class HomeworkFragment : BaseFragment<HomeworkPresenter>(), HomeworkView {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity) activity = (getActivity() as MainActivity)
app = activity.application as App
context!!.theme.applyStyle(Themes.appTheme, true) context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null) if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false) return inflater.inflate(R.layout.fragment_loading, container, false)

View File

@ -7,9 +7,13 @@ package pl.szczodrzynski.edziennik.ui.modules.homework
import android.os.AsyncTask import android.os.AsyncTask
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
import pl.szczodrzynski.edziennik.data.db.modules.metadata.MetadataDao
import pl.szczodrzynski.edziennik.ui.base.BasePresenter import pl.szczodrzynski.edziennik.ui.base.BasePresenter
import javax.inject.Inject
class HomeworkPresenter : BasePresenter<HomeworkView>() { class HomeworkPresenter @Inject constructor(
private val metadataDao: MetadataDao
) : BasePresenter<HomeworkView>() {
override fun onAttachView(view: HomeworkView) { override fun onAttachView(view: HomeworkView) {
super.onAttachView(view) super.onAttachView(view)
@ -31,7 +35,7 @@ class HomeworkPresenter : BasePresenter<HomeworkView>() {
view?.apply { view?.apply {
closeBottomSheet() closeBottomSheet()
AsyncTask.execute { AsyncTask.execute {
app.db.metadataDao().setAllSeen(App.profileId, Metadata.TYPE_HOMEWORK, true) metadataDao.setAllSeen(App.profileId, Metadata.TYPE_HOMEWORK, true)
} }
showMessage(markAsReadSuccessString) showMessage(markAsReadSuccessString)
} }

View File

@ -4,13 +4,10 @@
package pl.szczodrzynski.edziennik.ui.modules.homework package pl.szczodrzynski.edziennik.ui.modules.homework
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.ui.base.BaseView import pl.szczodrzynski.edziennik.ui.base.BaseView
interface HomeworkView : BaseView { interface HomeworkView : BaseView {
var app: App
val markAsReadSuccessString: String val markAsReadSuccessString: String
fun initView() fun initView()

View File

@ -19,12 +19,16 @@ import androidx.recyclerview.widget.RecyclerView
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
import pl.szczodrzynski.edziennik.data.db.modules.metadata.MetadataDao
import pl.szczodrzynski.edziennik.databinding.RowHomeworkItemBinding import pl.szczodrzynski.edziennik.databinding.RowHomeworkItemBinding
import pl.szczodrzynski.edziennik.utils.Utils.bs import pl.szczodrzynski.edziennik.utils.Utils.bs
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import javax.inject.Inject
import kotlin.math.abs import kotlin.math.abs
class HomeworkListAdapter : RecyclerView.Adapter<HomeworkListAdapter.ViewHolder>() { class HomeworkListAdapter @Inject constructor(
private val metadataDao: MetadataDao
) : RecyclerView.Adapter<HomeworkListAdapter.ViewHolder>() {
val homeworkList: MutableList<EventFull> = mutableListOf() val homeworkList: MutableList<EventFull> = mutableListOf()
lateinit var onItemEditClick: (homework: EventFull) -> Unit lateinit var onItemEditClick: (homework: EventFull) -> Unit
@ -55,7 +59,7 @@ class HomeworkListAdapter : RecyclerView.Adapter<HomeworkListAdapter.ViewHolder>
homework.seen = true homework.seen = true
AsyncTask.execute { AsyncTask.execute {
app.db.metadataDao().setSeen(App.profileId, homework, true) metadataDao.setSeen(App.profileId, homework, true)
} }
} }
else -> b.homeworkItemTopic.background = null else -> b.homeworkItemTopic.background = null
@ -86,7 +90,6 @@ class HomeworkListAdapter : RecyclerView.Adapter<HomeworkListAdapter.ViewHolder>
fun getString(resId: Int, vararg formatArgs: Any): String = itemView.context.getString(resId, *formatArgs) fun getString(resId: Int, vararg formatArgs: Any): String = itemView.context.getString(resId, *formatArgs)
fun getDrawable(resId: Int): Drawable? = ContextCompat.getDrawable(itemView.context, resId) fun getDrawable(resId: Int): Drawable? = ContextCompat.getDrawable(itemView.context, resId)
val app: App get() = itemView.context.applicationContext as App
val resources: Resources get() = itemView.context.resources val resources: Resources get() = itemView.context.resources
fun dateDiffString(diff: Int): String { fun dateDiffString(diff: Int): String {

View File

@ -20,17 +20,21 @@ import pl.szczodrzynski.edziennik.databinding.HomeworkListBinding
import pl.szczodrzynski.edziennik.ui.base.BaseFragment import pl.szczodrzynski.edziennik.ui.base.BaseFragment
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
import pl.szczodrzynski.edziennik.utils.Themes import pl.szczodrzynski.edziennik.utils.Themes
import javax.inject.Inject
class HomeworkListFragment : BaseFragment<HomeworkListPresenter>(), HomeworkListView { class HomeworkListFragment : BaseFragment<HomeworkListPresenter>(), HomeworkListView {
override lateinit var app: App
private lateinit var activity: MainActivity private lateinit var activity: MainActivity
private lateinit var b: HomeworkListBinding private lateinit var b: HomeworkListBinding
private lateinit var homeworkAdapter: HomeworkListAdapter @Inject
override lateinit var presenter: HomeworkListPresenter
override val presenter: HomeworkListPresenter = HomeworkListPresenter() @Inject
lateinit var app: App
@Inject
lateinit var homeworkAdapter: HomeworkListAdapter
override val viewLifecycle: Lifecycle override val viewLifecycle: Lifecycle
get() = lifecycle get() = lifecycle
@ -52,7 +56,6 @@ class HomeworkListFragment : BaseFragment<HomeworkListPresenter>(), HomeworkList
activity = (getActivity() as MainActivity?) ?: return null activity = (getActivity() as MainActivity?) ?: return null
if (context == null) if (context == null)
return null return null
app = activity.application as App
context!!.theme.applyStyle(Themes.appTheme, true) context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null) if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false) return inflater.inflate(R.layout.fragment_loading, container, false)
@ -66,11 +69,11 @@ class HomeworkListFragment : BaseFragment<HomeworkListPresenter>(), HomeworkList
if (app.profile == null || !isAdded) if (app.profile == null || !isAdded)
return return
val layoutManager = LinearLayoutManager(context) val layoutManager = LinearLayoutManager(context).apply {
layoutManager.reverseLayout = true reverseLayout = true
layoutManager.stackFromEnd = true stackFromEnd = true
}
homeworkAdapter = HomeworkListAdapter()
homeworkAdapter.onItemEditClick = presenter::onItemEditClick homeworkAdapter.onItemEditClick = presenter::onItemEditClick
b.homeworkView.apply { b.homeworkView.apply {

View File

@ -6,12 +6,17 @@ package pl.szczodrzynski.edziennik.ui.modules.homework.list
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.modules.events.Event import pl.szczodrzynski.edziennik.data.db.modules.events.Event
import pl.szczodrzynski.edziennik.data.db.modules.events.EventDao
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
import pl.szczodrzynski.edziennik.ui.base.BasePresenter import pl.szczodrzynski.edziennik.ui.base.BasePresenter
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkDate import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkDate
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import javax.inject.Inject
class HomeworkListPresenter : BasePresenter<HomeworkListView>() { class HomeworkListPresenter @Inject constructor(
private val app: App,
private val eventDao: EventDao
) : BasePresenter<HomeworkListView>() {
fun onAttachView(view: HomeworkListView, homeworkDate: Int?) { fun onAttachView(view: HomeworkListView, homeworkDate: Int?) {
super.onAttachView(view) super.onAttachView(view)
@ -28,8 +33,7 @@ class HomeworkListPresenter : BasePresenter<HomeworkListView>() {
} }
view?.run { view?.run {
app.db.eventDao() eventDao.getAllByType(App.profileId, Event.TYPE_HOMEWORK, filter)
.getAllByType(App.profileId, Event.TYPE_HOMEWORK, filter)
.observe({ viewLifecycle }, { homeworkList -> .observe({ viewLifecycle }, { homeworkList ->
if (app.profile == null) return@observe if (app.profile == null) return@observe

View File

@ -5,14 +5,11 @@
package pl.szczodrzynski.edziennik.ui.modules.homework.list package pl.szczodrzynski.edziennik.ui.modules.homework.list
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
import pl.szczodrzynski.edziennik.ui.base.BaseView import pl.szczodrzynski.edziennik.ui.base.BaseView
interface HomeworkListView : BaseView { interface HomeworkListView : BaseView {
var app: App
val viewLifecycle: Lifecycle val viewLifecycle: Lifecycle
fun initView() fun initView()

View File

@ -47,7 +47,8 @@ buildscript {
navlib : "e4ad01dc87", navlib : "e4ad01dc87",
gifdrawable : "1.2.15" gifdrawable : "1.2.15",
dagger : "2.24"
] ]
} }