├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── idkotlin │ │ └── idreminder │ │ └── TodoInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── idkotlin │ │ │ └── idreminder │ │ │ ├── BaseApp.kt │ │ │ ├── data │ │ │ ├── entity │ │ │ │ └── Reminder.kt │ │ │ ├── mapper │ │ │ │ └── Mapper.kt │ │ │ ├── repository │ │ │ │ └── ReminderImpl.kt │ │ │ └── source │ │ │ │ ├── local │ │ │ │ └── room │ │ │ │ │ ├── AppDatabase.kt │ │ │ │ │ └── ReminderDao.kt │ │ │ │ └── remote │ │ │ │ └── service │ │ │ │ └── TodoService.kt │ │ │ ├── domain │ │ │ ├── executor │ │ │ │ └── scheduler │ │ │ │ │ ├── BaseSchedulerProvider.kt │ │ │ │ │ └── SchedulerProvider.kt │ │ │ └── repository │ │ │ │ └── IReminderRepository.kt │ │ │ └── presentation │ │ │ ├── di │ │ │ ├── component │ │ │ │ ├── ActivityComponent.kt │ │ │ │ ├── ApplicationComponent.kt │ │ │ │ └── FragmentComponent.kt │ │ │ ├── module │ │ │ │ ├── ActivityModule.kt │ │ │ │ ├── ApplicationModule.kt │ │ │ │ ├── DataModule.kt │ │ │ │ ├── FragmentModule.kt │ │ │ │ ├── InteractorModule.kt │ │ │ │ └── PresenterModule.kt │ │ │ ├── qualifier │ │ │ │ ├── Local.kt │ │ │ │ └── Remote.kt │ │ │ └── scope │ │ │ │ ├── ActivityScope.kt │ │ │ │ ├── ApplicationScope.kt │ │ │ │ └── FragmentScope.kt │ │ │ ├── extension │ │ │ ├── activity │ │ │ │ └── AppCompatActivityExt.kt │ │ │ ├── collection │ │ │ │ ├── ArrayExt.kt │ │ │ │ └── CollectionExt.kt │ │ │ ├── fragment │ │ │ │ └── FragmentExt.kt │ │ │ ├── notification │ │ │ │ └── NotificationExt.kt │ │ │ └── toast │ │ │ │ └── ToastExt.kt │ │ │ ├── receiver │ │ │ ├── AlarmReceiver.kt │ │ │ └── BootReceiver.kt │ │ │ ├── ui │ │ │ ├── base │ │ │ │ ├── BaseActivity.kt │ │ │ │ ├── BaseActivityMvp.kt │ │ │ │ ├── BaseAdapter.kt │ │ │ │ ├── BaseContract.kt │ │ │ │ ├── BaseFragment.kt │ │ │ │ ├── BaseFragmentMvp.kt │ │ │ │ ├── MultiSelectAdapter.kt │ │ │ │ ├── RxPresenter.kt │ │ │ │ └── bus │ │ │ │ │ ├── Event.kt │ │ │ │ │ └── RxBus.kt │ │ │ └── reminder │ │ │ │ ├── ReminderActivity.kt │ │ │ │ ├── ReminderAdapter.kt │ │ │ │ └── fragment │ │ │ │ ├── add │ │ │ │ ├── ReminderAddFragment.kt │ │ │ │ ├── ReminderAddFragmentContract.kt │ │ │ │ └── ReminderAddFragmentPresenter.kt │ │ │ │ └── list │ │ │ │ ├── ReminderFragment.kt │ │ │ │ ├── ReminderFragmentContract.kt │ │ │ │ └── ReminderFragmentPresenter.kt │ │ │ └── util │ │ │ ├── AppUtil.kt │ │ │ ├── PreferencesUtil.kt │ │ │ ├── ReminderUtil.kt │ │ │ └── Util.kt │ └── res │ │ ├── drawable-anydpi │ │ └── ic_library_add.xml │ │ ├── drawable-hdpi │ │ ├── ic_add.png │ │ ├── ic_check.png │ │ ├── ic_date_range.png │ │ ├── ic_delete.png │ │ ├── ic_notifications.png │ │ ├── ic_notifications_active.png │ │ ├── ic_notifications_off.png │ │ ├── ic_repeat.png │ │ ├── ic_subject.png │ │ ├── ic_timer.png │ │ └── ic_unfold_more.png │ │ ├── drawable-mdpi │ │ ├── ic_add.png │ │ ├── ic_check.png │ │ ├── ic_date_range.png │ │ ├── ic_delete.png │ │ ├── ic_notifications.png │ │ ├── ic_notifications_active.png │ │ ├── ic_notifications_off.png │ │ ├── ic_repeat.png │ │ ├── ic_subject.png │ │ ├── ic_timer.png │ │ └── ic_unfold_more.png │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable-xhdpi │ │ ├── ic_add.png │ │ ├── ic_check.png │ │ ├── ic_date_range.png │ │ ├── ic_delete.png │ │ ├── ic_notifications.png │ │ ├── ic_notifications_active.png │ │ ├── ic_notifications_off.png │ │ ├── ic_repeat.png │ │ ├── ic_subject.png │ │ ├── ic_timer.png │ │ └── ic_unfold_more.png │ │ ├── drawable-xxhdpi │ │ ├── ic_add.png │ │ ├── ic_check.png │ │ ├── ic_date_range.png │ │ ├── ic_delete.png │ │ ├── ic_notifications.png │ │ ├── ic_notifications_active.png │ │ ├── ic_notifications_off.png │ │ ├── ic_repeat.png │ │ ├── ic_subject.png │ │ ├── ic_timer.png │ │ └── ic_unfold_more.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_add.png │ │ ├── ic_check.png │ │ ├── ic_date_range.png │ │ ├── ic_delete.png │ │ ├── ic_notifications.png │ │ ├── ic_notifications_active.png │ │ ├── ic_notifications_off.png │ │ ├── ic_repeat.png │ │ ├── ic_subject.png │ │ ├── ic_timer.png │ │ └── ic_unfold_more.png │ │ ├── drawable │ │ ├── ic_launcher_background.xml │ │ └── recycler_scrollbar.xml │ │ ├── layout │ │ ├── activity_example.xml │ │ ├── activity_reminder.xml │ │ ├── adapter_reminder.xml │ │ ├── fragment_reminder_add.xml │ │ └── fragment_reminder_list.xml │ │ ├── menu │ │ ├── add.xml │ │ ├── main.xml │ │ └── multi_select.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── idkotlin │ └── idreminder │ └── TodoUnitTest.kt ├── art ├── ss1.png ├── ss2.png └── ss3.png ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Temp files 2 | *~ 3 | *.bak 4 | *.backup 5 | \#* 6 | .\#* 7 | *\# 8 | *.swp 9 | *.swap 10 | *.sav 11 | *.save 12 | *.autosav 13 | *.autosave 14 | 15 | *.iml 16 | .gradle 17 | /local.properties 18 | /gradle.properties 19 | /.idea/ 20 | .DS_Store 21 | /build 22 | /captures 23 | release.keystore 24 | signing.properties 25 | /library/build -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IDReminder 2 | 3 | ## About App 4 | A minimal notification reminder for Android build with Kotlin + Clean Architecture + RxJava + Dagger2 + MVP + Room 5 | 6 | ## Features 7 | :white_check_mark: Kotlin: Yes, fully written in Kotlin. :scream: :heart:
8 | :white_check_mark: Clean architecture: The whole project is based on uncle Bob's clean architecture approach.
9 | :white_check_mark: Material Design: Not a fully Material Design App, but I am trying my best.
10 | :white_check_mark: Usage of libraries:
11 | * [Dagger 2](https://github.com/google/dagger) - for dependency injection
12 | * [RxJava 2, RxAndroid 2](https://github.com/ReactiveX/RxJava) - for data manipulation
13 | * [Room](https://developer.android.com/topic/libraries/architecture/room.html) - for data persistence
14 | 15 | ## Screenshots 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ## Contact 24 | - **Website**: https://idkotlin.com/ 25 | - **Email**: kodeartisan@gmail.com 26 | - **Facebook**: https://www.facebook.com/dika.budiaji 27 | 28 | ## Future Roadmap 29 | - add icon app 30 | - Write test cases 31 | 32 |

33 |

Proudly :muscle: made in Kotlin

34 |

-------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | apply plugin: 'kotlin-kapt' 8 | 9 | android { 10 | compileSdkVersion 26 11 | defaultConfig { 12 | applicationId "com.idkotlin.idreminder" 13 | minSdkVersion 16 14 | targetSdkVersion 26 15 | versionCode 1 16 | versionName "1.0" 17 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 18 | } 19 | 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | } 28 | 29 | dependencies { 30 | implementation fileTree(dir: 'libs', include: ['*.jar']) 31 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" 32 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 33 | testImplementation 'junit:junit:4.12' 34 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 35 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 36 | 37 | // android support 38 | implementation "com.android.support:appcompat-v7:$android_support_version" 39 | implementation "com.android.support:cardview-v7:$android_support_version" 40 | implementation "com.android.support:recyclerview-v7:$android_support_version" 41 | implementation "com.android.support:design:$android_support_version" 42 | 43 | // reactive extension 44 | implementation "io.reactivex.rxjava2:rxjava:$rxjava_version" 45 | implementation "io.reactivex.rxjava2:rxandroid:$rxandroid_version" 46 | implementation "com.jakewharton.rxrelay2:rxrelay:$rxrelay_version" 47 | 48 | // dependency injection 49 | implementation "com.google.dagger:dagger:$dagger_version" 50 | kapt "com.google.dagger:dagger-compiler:$dagger_version" 51 | 52 | // room database 53 | implementation "android.arch.persistence.room:runtime:$room_version" 54 | implementation "android.arch.persistence.room:rxjava2:$room_version" 55 | kapt "android.arch.persistence.room:compiler:$room_version" 56 | 57 | // others 58 | implementation "com.amulyakhare:com.amulyakhare.textdrawable:$text_drawable_version" 59 | 60 | } 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/idkotlin/idreminder/TodoInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class TodoInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.koeartisan.kotlintemplpate", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/BaseApp.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder 2 | 3 | import android.app.Application 4 | import com.tutorial.learnlinuxpro.presentation.di.component.ApplicationComponent 5 | import com.tutorial.learnlinuxpro.presentation.di.component.DaggerApplicationComponent 6 | import com.tutorial.learnlinuxpro.presentation.di.module.ApplicationModule 7 | import com.tutorial.learnlinuxpro.presentation.util.Util 8 | 9 | /** 10 | * Created by kodeartisan on 26/10/17. 11 | */ 12 | class BaseApp : Application() { 13 | 14 | companion object { 15 | lateinit var appComponent: ApplicationComponent 16 | } 17 | 18 | override fun onCreate() { 19 | super.onCreate() 20 | appComponent = createApplicationComponent() 21 | Util.init(this) 22 | } 23 | 24 | private fun createApplicationComponent(): ApplicationComponent { 25 | return DaggerApplicationComponent.builder() 26 | .applicationModule(ApplicationModule(this)) 27 | .build() 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/data/entity/Reminder.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.data.entity 2 | 3 | import android.arch.persistence.room.ColumnInfo 4 | import android.arch.persistence.room.Entity 5 | import android.arch.persistence.room.PrimaryKey 6 | 7 | /** 8 | * Created by kodeartisan on 19/11/17. 9 | */ 10 | @Entity(tableName = "reminders") 11 | data class Reminder(@ColumnInfo(name = "title") var title: String, 12 | @ColumnInfo(name = "date") var date: String, 13 | @ColumnInfo(name = "time") var time: String, 14 | @ColumnInfo(name = "repeat") var repeat: Boolean, 15 | @ColumnInfo(name = "repeat_no") var repeatNo: Int, 16 | @ColumnInfo(name = "repeat_type") var repeatType: String, 17 | @ColumnInfo(name = "active") var active: Boolean) 18 | { 19 | @PrimaryKey(autoGenerate = true) 20 | @ColumnInfo(name = "id") var id:Long = 0 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/data/mapper/Mapper.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.data.mapper 2 | 3 | /** 4 | * Created by kodeartisan on 19/11/17. 5 | */ 6 | abstract class Mapper { 7 | 8 | abstract fun map(from: From): To 9 | abstract fun reverse(to: To): From 10 | 11 | fun map(froms: List): List? { 12 | if(froms.isNotEmpty()) { 13 | val results = ArrayList(froms.size) 14 | froms.mapTo(results) { map(it) } 15 | 16 | return results 17 | } 18 | 19 | return null 20 | } 21 | 22 | fun reverse(tos: List): List? { 23 | if(tos.isNotEmpty()) { 24 | val results = ArrayList(tos.size) 25 | tos.mapTo(results) { reverse(it) } 26 | 27 | return results 28 | } 29 | 30 | return null 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/data/repository/ReminderImpl.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.data.repository 2 | 3 | import android.support.annotation.NonNull 4 | import com.idkotlin.idreminder.data.entity.Reminder 5 | import com.idkotlin.idreminder.domain.executor.scheduler.BaseSchedulerProvider 6 | import com.idkotlin.idreminder.domain.repository.IReminderRepository 7 | import com.tutorial.learnlinuxpro.data.source.local.room.AppDatabase 8 | import io.reactivex.Observable 9 | import io.reactivex.Single 10 | import javax.inject.Inject 11 | 12 | /** 13 | * Created by kodeartisan on 27/11/17. 14 | */ 15 | class ReminderImpl @Inject constructor(@NonNull private val schedulerProvider: BaseSchedulerProvider, @NonNull private val appDatabase: AppDatabase): IReminderRepository { 16 | 17 | private val TAG = ReminderImpl::class.java.name 18 | 19 | override fun fetch(): Single> = appDatabase.reminderDao().getReminders().subscribeOn(schedulerProvider.multi()) 20 | 21 | override fun delete(reminders: List): Observable = Observable.fromCallable { 22 | appDatabase.reminderDao().delete(reminders) 23 | } 24 | 25 | 26 | override fun insert(reminder: Reminder): Observable = Observable.fromCallable { appDatabase.reminderDao().insert(reminder) } 27 | 28 | override fun update(reminder: Reminder): Observable = Observable.fromCallable{ appDatabase.reminderDao().update(reminder) } 29 | 30 | 31 | 32 | 33 | 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/data/source/local/room/AppDatabase.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.data.source.local.room 2 | 3 | import android.arch.persistence.room.Database 4 | import android.arch.persistence.room.RoomDatabase 5 | import com.idkotlin.idreminder.data.entity.Reminder 6 | import com.idkotlin.idreminder.data.source.local.room.ReminderDao 7 | 8 | /** 9 | * Created by kodeartisan on 16/10/17. 10 | */ 11 | @Database(entities = arrayOf(Reminder::class), version = 2, exportSchema = false) 12 | abstract class AppDatabase: RoomDatabase() { 13 | 14 | abstract fun reminderDao(): ReminderDao 15 | 16 | 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/data/source/local/room/ReminderDao.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.data.source.local.room 2 | 3 | import android.arch.persistence.room.* 4 | import com.idkotlin.idreminder.data.entity.Reminder 5 | import io.reactivex.Single 6 | 7 | /** 8 | * Created by kodeartisan on 19/11/17. 9 | */ 10 | @Dao 11 | interface ReminderDao{ 12 | 13 | @Query("SELECT * FROM reminders order by id DESC") 14 | fun getReminders(): Single> 15 | 16 | @Query("SELECT * FROM reminders where id = :id") 17 | fun getReminder(id: Int): Single 18 | 19 | @Insert 20 | fun insert(reminder: Reminder): Long 21 | 22 | @Delete 23 | fun delete(reminder: List) 24 | 25 | @Update 26 | fun update(reminder: Reminder): Int 27 | 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/data/source/remote/service/TodoService.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.data.source.remote.service 2 | 3 | /** 4 | * Created by kodeartisan on 26/10/17. 5 | */ 6 | interface TodoService { 7 | 8 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/domain/executor/scheduler/BaseSchedulerProvider.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.domain.executor.scheduler 2 | 3 | import android.support.annotation.NonNull 4 | import io.reactivex.Scheduler 5 | 6 | 7 | /** 8 | * Created by kodeartisan on 12/10/17. 9 | */ 10 | interface BaseSchedulerProvider { 11 | 12 | @NonNull 13 | fun computation() : Scheduler 14 | 15 | @NonNull 16 | fun multi() : Scheduler 17 | 18 | @NonNull 19 | fun io() : Scheduler 20 | 21 | @NonNull 22 | fun ui() : Scheduler 23 | 24 | 25 | 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/domain/executor/scheduler/SchedulerProvider.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.domain.executor.scheduler 2 | 3 | import io.reactivex.Scheduler 4 | import io.reactivex.android.schedulers.AndroidSchedulers 5 | import io.reactivex.schedulers.Schedulers 6 | 7 | /** 8 | * Created by kodeartisan on 12/10/17. 9 | */ 10 | class SchedulerProvider : BaseSchedulerProvider { 11 | 12 | override fun computation(): Scheduler = Schedulers.computation() 13 | 14 | override fun multi(): Scheduler = Schedulers.newThread() 15 | 16 | override fun io(): Scheduler = Schedulers.io() 17 | 18 | override fun ui(): Scheduler = AndroidSchedulers.mainThread() 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/domain/repository/IReminderRepository.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.domain.repository 2 | 3 | import com.idkotlin.idreminder.data.entity.Reminder 4 | import io.reactivex.Observable 5 | import io.reactivex.Single 6 | 7 | /** 8 | * Created by kodeartisan on 27/11/17. 9 | */ 10 | interface IReminderRepository { 11 | 12 | fun fetch(): Single> 13 | fun delete(reminders: List): Observable 14 | fun insert(reminder: Reminder): Observable 15 | fun update(reminder: Reminder): Observable 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/component/ActivityComponent.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.component 2 | 3 | import com.idkotlin.idreminder.presentation.ui.reminder.ReminderActivity 4 | import com.tutorial.learnlinuxpro.presentation.di.module.ActivityModule 5 | import com.tutorial.learnlinuxpro.presentation.di.module.PresenterModule 6 | import com.tutorial.learnlinuxpro.presentation.di.scope.ActivityScope 7 | import dagger.Component 8 | 9 | /** 10 | * Created by kodeartisan on 12/10/17. 11 | */ 12 | @ActivityScope 13 | @Component(dependencies = arrayOf(ApplicationComponent::class) ,modules = arrayOf(ActivityModule::class, PresenterModule::class)) 14 | interface ActivityComponent { 15 | 16 | fun inject(target: ReminderActivity) 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/component/ApplicationComponent.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.component 2 | 3 | import android.app.AlarmManager 4 | import android.app.NotificationManager 5 | import com.idkotlin.idreminder.domain.executor.scheduler.BaseSchedulerProvider 6 | import com.idkotlin.idreminder.domain.repository.IReminderRepository 7 | import com.idkotlin.idreminder.presentation.di.scope.ApplicationScope 8 | import com.idkotlin.idreminder.presentation.receiver.AlarmReceiver 9 | import com.tutorial.learnlinuxpro.data.source.local.room.AppDatabase 10 | import com.tutorial.learnlinuxpro.presentation.bus.RxBus 11 | import com.tutorial.learnlinuxpro.presentation.di.module.ApplicationModule 12 | import com.tutorial.learnlinuxpro.presentation.di.module.DataModule 13 | import dagger.Component 14 | import javax.inject.Singleton 15 | 16 | /** 17 | * Created by kodeartisan on 12/10/17. 18 | */ 19 | @Singleton 20 | @ApplicationScope 21 | @Component(modules = arrayOf(ApplicationModule::class, DataModule::class)) 22 | interface ApplicationComponent { 23 | 24 | fun getSchedulerProvider(): BaseSchedulerProvider 25 | fun getAppDatabase(): AppDatabase 26 | fun getIReminderRepository(): IReminderRepository 27 | fun getRxBus(): RxBus 28 | fun getAlarmManager(): AlarmManager 29 | fun getNotificationManager(): NotificationManager 30 | 31 | fun inject(target: AlarmReceiver) 32 | 33 | 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/component/FragmentComponent.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.component 2 | 3 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.add.ReminderAddFragment 4 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.list.ReminderFragment 5 | import com.tutorial.learnlinuxpro.presentation.di.module.FragmentModule 6 | import com.tutorial.learnlinuxpro.presentation.di.module.PresenterModule 7 | import com.tutorial.learnlinuxpro.presentation.di.scope.FragmentScope 8 | import dagger.Component 9 | 10 | /** 11 | * Created by kodeartisan on 18/10/17. 12 | */ 13 | @FragmentScope 14 | @Component(dependencies = arrayOf(ApplicationComponent::class), modules = arrayOf(FragmentModule::class, PresenterModule::class)) 15 | interface FragmentComponent { 16 | 17 | fun inject(target: ReminderFragment) 18 | fun inject(target: ReminderAddFragment) 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/module/ActivityModule.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.module 2 | 3 | import android.support.v7.app.AppCompatActivity 4 | import com.tutorial.learnlinuxpro.presentation.di.scope.ActivityScope 5 | import dagger.Module 6 | import dagger.Provides 7 | 8 | /** 9 | * Created by kodeartisan on 12/10/17. 10 | */ 11 | @Module 12 | class ActivityModule(private val activity: AppCompatActivity) { 13 | 14 | @Provides 15 | @ActivityScope 16 | fun provideActivity() = activity 17 | 18 | @Provides 19 | @ActivityScope 20 | fun provideActivityContext() = activity.baseContext 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/module/ApplicationModule.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.module 2 | 3 | import android.app.AlarmManager 4 | import android.app.NotificationManager 5 | import android.arch.persistence.room.Room 6 | import android.content.Context 7 | import com.idkotlin.idreminder.BaseApp 8 | import com.idkotlin.idreminder.domain.executor.scheduler.BaseSchedulerProvider 9 | import com.idkotlin.idreminder.domain.executor.scheduler.SchedulerProvider 10 | import com.tutorial.learnlinuxpro.data.source.local.room.AppDatabase 11 | import com.tutorial.learnlinuxpro.presentation.bus.RxBus 12 | import dagger.Module 13 | import dagger.Provides 14 | import javax.inject.Singleton 15 | 16 | /** 17 | * Created by kodeartisan on 12/10/17. 18 | */ 19 | @Module 20 | class ApplicationModule(private val app: BaseApp) { 21 | 22 | @Provides 23 | @Singleton 24 | fun provideApplication(): BaseApp = app 25 | 26 | @Provides 27 | @Singleton 28 | fun provideContext(): Context = app 29 | 30 | @Provides 31 | @Singleton 32 | fun provideSchedulerProvider(): BaseSchedulerProvider = SchedulerProvider() 33 | 34 | @Provides 35 | @Singleton 36 | fun provideAppDatabase(context: Context): AppDatabase { 37 | return Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, "data.db") 38 | .build() 39 | } 40 | 41 | @Provides 42 | @Singleton 43 | fun provideRxBus(): RxBus = RxBus() 44 | 45 | @Provides 46 | @Singleton 47 | fun provideAlarmManager(): AlarmManager = app.getSystemService(Context.ALARM_SERVICE) as AlarmManager 48 | 49 | @Provides 50 | @Singleton 51 | fun provideNotificationManager(): NotificationManager = app.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager 52 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/module/DataModule.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.module 2 | 3 | import com.idkotlin.idreminder.data.repository.ReminderImpl 4 | import com.idkotlin.idreminder.domain.repository.IReminderRepository 5 | import dagger.Module 6 | import dagger.Provides 7 | import javax.inject.Singleton 8 | 9 | /** 10 | * Created by kodeartisan on 12/10/17. 11 | */ 12 | @Module 13 | class DataModule { 14 | 15 | @Singleton 16 | @Provides 17 | fun reminderRepository(reminderImpl: ReminderImpl): IReminderRepository = reminderImpl 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/module/FragmentModule.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.module 2 | 3 | import android.support.v4.app.Fragment 4 | import com.tutorial.learnlinuxpro.presentation.di.scope.FragmentScope 5 | import dagger.Module 6 | import dagger.Provides 7 | 8 | /** 9 | * Created by kodeartisan on 18/10/17. 10 | */ 11 | @Module 12 | class FragmentModule(private val mFragment: Fragment) { 13 | 14 | @FragmentScope 15 | @Provides 16 | fun provideActivity() = mFragment.activity 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/module/InteractorModule.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.di.module 2 | 3 | import dagger.Module 4 | 5 | /** 6 | * Created by kodeartisan on 28/11/17. 7 | */ 8 | @Module 9 | class InteractorModule { 10 | 11 | 12 | 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/module/PresenterModule.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.module 2 | 3 | import android.support.annotation.NonNull 4 | import com.idkotlin.idreminder.domain.executor.scheduler.BaseSchedulerProvider 5 | import com.idkotlin.idreminder.domain.repository.IReminderRepository 6 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.add.ReminderAddFragmentContract 7 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.add.ReminderAddFragmentPresenter 8 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.list.ReminderFragmentContract 9 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.list.ReminderFragmentPresenter 10 | import com.tutorial.learnlinuxpro.presentation.di.scope.FragmentScope 11 | import dagger.Module 12 | import dagger.Provides 13 | 14 | /** 15 | * Created by kodeartisan on 12/10/17. 16 | */ 17 | @Module 18 | class PresenterModule { 19 | 20 | @FragmentScope 21 | @Provides 22 | fun reminderFragmentPresenter(@NonNull baseSchedulerProvider: BaseSchedulerProvider, @NonNull iReminderRepository: IReminderRepository): ReminderFragmentContract.Presenter = ReminderFragmentPresenter(baseSchedulerProvider, iReminderRepository) 23 | 24 | @FragmentScope 25 | @Provides 26 | fun reminderAddFragmentPresenter(@NonNull baseSchedulerProvider: BaseSchedulerProvider, @NonNull iReminderRepository: IReminderRepository): ReminderAddFragmentContract.Presenter = ReminderAddFragmentPresenter(baseSchedulerProvider, iReminderRepository) 27 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/qualifier/Local.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.di.qualifier 2 | 3 | import javax.inject.Qualifier 4 | 5 | /** 6 | * Created by kodeartisan on 26/10/17. 7 | */ 8 | @Qualifier 9 | annotation class Local 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/qualifier/Remote.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.di.qualifier 2 | 3 | import javax.inject.Qualifier 4 | 5 | /** 6 | * Created by kodeartisan on 26/10/17. 7 | */ 8 | @Qualifier 9 | annotation class Remote -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/scope/ActivityScope.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.scope 2 | 3 | import javax.inject.Scope 4 | 5 | /** 6 | * Created by kodeartisan on 12/10/17. 7 | */ 8 | @Scope 9 | annotation class ActivityScope -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/scope/ApplicationScope.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.di.scope 2 | 3 | import javax.inject.Scope 4 | 5 | /** 6 | * Created by kodeartisan on 30/11/17. 7 | */ 8 | @Scope 9 | annotation class ApplicationScope -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/di/scope/FragmentScope.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.di.scope 2 | 3 | import javax.inject.Scope 4 | 5 | /** 6 | * Created by kodeartisan on 12/10/17. 7 | */ 8 | @Scope 9 | annotation class FragmentScope -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/extension/activity/AppCompatActivityExt.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.extension.activity 2 | 3 | import android.support.v4.app.Fragment 4 | import android.support.v7.app.AppCompatActivity 5 | import com.tutorial.learnlinuxpro.presentation.extension.fragment.inTransaction 6 | 7 | /** 8 | * Created by kodeartisan on 18/10/17. 9 | */ 10 | fun AppCompatActivity.addFragment(fragment: Fragment, frameId: Int) { 11 | supportFragmentManager.inTransaction { add(frameId, fragment) } 12 | } 13 | 14 | fun AppCompatActivity.replaceFragment(fragment: Fragment, frameId: Int) { 15 | supportFragmentManager.inTransaction { replace(frameId, fragment) } 16 | } 17 | 18 | fun AppCompatActivity.replaceFragment(fragment: Fragment, frameId: Int, nameBackstack: String) { 19 | supportFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(nameBackstack) } 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/extension/collection/ArrayExt.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | package com.tutorial.learnlinuxpro.presentation.extension.collection 3 | 4 | import android.util.SparseArray 5 | import android.util.SparseBooleanArray 6 | import android.util.SparseIntArray 7 | import java.util.* 8 | 9 | /** 10 | * Created by kodeartisan on 14/10/17. 11 | */ 12 | 13 | /** 14 | * Iterate the receiver [Array] using an index. 15 | * 16 | * @f an action to invoke on each array element. 17 | */ 18 | inline fun Array.forEachByIndex(f: (T) -> Unit) { 19 | val lastIndex = size - 1 20 | for (i in 0..lastIndex) { 21 | f(get(i)) 22 | } 23 | } 24 | 25 | /** 26 | * Iterate the receiver [Array] using an index. 27 | * 28 | * @f an action to invoke on each array element (index, element). 29 | */ 30 | inline fun Array.forEachWithIndex(f: (Int, T) -> Unit) { 31 | val lastIndex = size - 1 32 | for (i in 0..lastIndex) { 33 | f(i, get(i)) 34 | } 35 | } 36 | 37 | /** 38 | * Iterate the receiver [Array] backwards using an index. 39 | * 40 | * @f an action to invoke on each array element. 41 | */ 42 | inline fun Array.forEachReversedByIndex(f: (T) -> Unit) { 43 | var i = size - 1 44 | while (i >= 0) { 45 | f(get(i)) 46 | i-- 47 | } 48 | } 49 | 50 | /** 51 | * Iterate the receiver [Array] backwards using an index. 52 | * 53 | * @f an action to invoke on each array element (index, element). 54 | */ 55 | inline fun Array.forEachReversedWithIndex(f: (Int, T) -> Unit) { 56 | var i = size - 1 57 | while (i >= 0) { 58 | f(i, get(i)) 59 | i-- 60 | } 61 | } 62 | 63 | /** 64 | * Create a [Sequence] instance that wraps the original [SparseArray] returning its elements when being iterated. 65 | */ 66 | inline fun SparseArray.asSequence(): Sequence = SparseArraySequence(this) 67 | 68 | /** 69 | * Create a [Sequence] instance that wraps the original [SparseBooleanArray] returning its elements when being iterated. 70 | */ 71 | inline fun SparseBooleanArray.asSequence(): Sequence = SparseBooleanArraySequence(this) 72 | 73 | /** 74 | * Create a [Sequence] instance that wraps the original [SparseIntArray] returning its elements when being iterated. 75 | */ 76 | inline fun SparseIntArray.asSequence(): Sequence = SparseIntArraySequence(this) 77 | 78 | @PublishedApi 79 | internal class SparseArraySequence(private val a: SparseArray) : Sequence { 80 | override fun iterator(): Iterator = SparseArrayIterator() 81 | 82 | private inner class SparseArrayIterator : Iterator { 83 | private var index = 0 84 | private val size = a.size() 85 | 86 | override fun hasNext() = size > index 87 | 88 | override fun next(): T { 89 | if (a.size() != size) throw ConcurrentModificationException() 90 | return a.valueAt(index++) 91 | } 92 | } 93 | } 94 | 95 | @PublishedApi 96 | internal class SparseBooleanArraySequence(private val a: SparseBooleanArray) : Sequence { 97 | override fun iterator(): Iterator = SparseIntArrayIterator() 98 | 99 | private inner class SparseIntArrayIterator : Iterator { 100 | private var index = 0 101 | private val size = a.size() 102 | 103 | override fun hasNext() = size > index 104 | 105 | override fun next(): Boolean { 106 | if (a.size() != size) throw ConcurrentModificationException() 107 | return a.get(index++) 108 | } 109 | } 110 | } 111 | 112 | @PublishedApi 113 | internal class SparseIntArraySequence(private val a: SparseIntArray) : Sequence { 114 | override fun iterator(): Iterator = SparseIntArrayIterator() 115 | 116 | private inner class SparseIntArrayIterator : Iterator { 117 | private var index = 0 118 | private val size = a.size() 119 | 120 | override fun hasNext() = size > index 121 | 122 | override fun next(): Int { 123 | if (a.size() != size) throw ConcurrentModificationException() 124 | return a.get(index++) 125 | } 126 | } 127 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/extension/collection/CollectionExt.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused", "NOTHING_TO_INLINE") 2 | package com.tutorial.learnlinuxpro.presentation.extension.collection 3 | 4 | /** 5 | * Created by kodeartisan on 14/10/17. 6 | */ 7 | /** 8 | * Iterate the receiver [List] using an index. 9 | * 10 | * @f an action to invoke on each list element. 11 | */ 12 | inline fun List.forEachByIndex(f: (T) -> Unit) { 13 | val lastIndex = size - 1 14 | for (i in 0..lastIndex) { 15 | f(get(i)) 16 | } 17 | } 18 | 19 | /** 20 | * Iterate the receiver [List] using an index. 21 | * 22 | * @f an action to invoke on each list element (index, element). 23 | */ 24 | inline fun List.forEachWithIndex(f: (Int, T) -> Unit) { 25 | val lastIndex = size - 1 26 | for (i in 0..lastIndex) { 27 | f(i, get(i)) 28 | } 29 | } 30 | 31 | /** 32 | * Iterate the receiver [List] backwards using an index. 33 | * 34 | * @f an action to invoke on each list element. 35 | */ 36 | inline fun List.forEachReversedByIndex(f: (T) -> Unit) { 37 | var i = size - 1 38 | while (i >= 0) { 39 | f(get(i)) 40 | i-- 41 | } 42 | } 43 | 44 | /** 45 | * Iterate the receiver [List] backwards using an index. 46 | * 47 | * @f an action to invoke on each list element (index, element). 48 | */ 49 | inline fun List.forEachReversedWithIndex(f: (Int, T) -> Unit) { 50 | var i = size - 1 51 | while (i >= 0) { 52 | f(i, get(i)) 53 | i-- 54 | } 55 | } 56 | 57 | /** 58 | * Convert the Android pair to a Kotlin one. 59 | * 60 | * @see [toAndroidPair]. 61 | */ 62 | inline fun android.util.Pair.toKotlinPair(): Pair { 63 | return first to second 64 | } 65 | 66 | /** 67 | * Convert the Kotlin pair to an Android one. 68 | * 69 | * @see [toKotlinPair]. 70 | */ 71 | inline fun Pair.toAndroidPair(): android.util.Pair { 72 | return android.util.Pair(first, second) 73 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/extension/fragment/FragmentExt.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.extension.fragment 2 | 3 | import android.support.v4.app.FragmentManager 4 | import android.support.v4.app.FragmentTransaction 5 | 6 | 7 | /** 8 | * Created by kodeartisan on 18/10/17. 9 | */ 10 | 11 | inline fun FragmentManager.inTransaction(func: FragmentTransaction.() -> Unit) { 12 | val fragmentTransaction = beginTransaction() 13 | fragmentTransaction.func() 14 | fragmentTransaction.commit() 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/extension/notification/NotificationExt.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.extension.notification 2 | 3 | /** 4 | * Created by kodeartisan on 14/10/17. 5 | */ 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/extension/toast/ToastExt.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("NOTHING_TO_INLINE", "unused") 2 | package com.tutorial.learnlinuxpro.presentation.extension.toast 3 | 4 | import android.content.Context 5 | import android.support.v4.app.Fragment 6 | import android.widget.Toast 7 | 8 | /** 9 | * Created by kodeartisan on 14/10/17. 10 | */ 11 | fun Context.toast(message: Int) = Toast.makeText(this, message, Toast.LENGTH_SHORT).show() 12 | fun Context.toast(message: CharSequence) = Toast.makeText(this, message, Toast.LENGTH_SHORT).show() 13 | inline fun Context.longToast(message: CharSequence) = Toast.makeText(this, message, Toast.LENGTH_LONG).show() 14 | inline fun Context.longToast(message: Int) = Toast.makeText(this, message, Toast.LENGTH_LONG).show() 15 | inline fun Fragment.toast(message: Int): Unit = activity.toast(message) 16 | inline fun Fragment.toast(message: CharSequence): Unit = activity.toast(message) 17 | inline fun Fragment.longToast(message: Int): Unit = activity.longToast(message) 18 | inline fun Fragment.longToast(message: CharSequence): Unit = activity.longToast(message) -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/receiver/AlarmReceiver.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.receiver 2 | 3 | import android.app.AlarmManager 4 | import android.app.PendingIntent 5 | import android.content.BroadcastReceiver 6 | import android.content.ComponentName 7 | import android.content.Context 8 | import android.content.Intent 9 | import android.content.pm.PackageManager 10 | import android.graphics.BitmapFactory 11 | import android.media.RingtoneManager 12 | import android.os.SystemClock 13 | import android.support.v4.app.NotificationCompat 14 | import android.util.Log 15 | import com.idkotlin.idreminder.BaseApp 16 | import com.idkotlin.idreminder.R 17 | import com.idkotlin.idreminder.data.entity.Reminder 18 | import com.idkotlin.idreminder.presentation.util.ReminderUtil 19 | import com.tutorial.learnlinuxpro.data.source.local.room.AppDatabase 20 | import com.tutorial.learnlinuxpro.presentation.di.component.ApplicationComponent 21 | import io.reactivex.Observable 22 | import io.reactivex.android.schedulers.AndroidSchedulers 23 | import io.reactivex.disposables.Disposable 24 | import io.reactivex.schedulers.Schedulers 25 | import java.util.* 26 | import javax.inject.Inject 27 | 28 | /** 29 | * Created by kodeartisan on 30/11/17. 30 | */ 31 | class AlarmReceiver: BroadcastReceiver() { 32 | 33 | private val TAG = AlarmReceiver::class.java.name 34 | 35 | private lateinit var mPendingIntent: PendingIntent 36 | private lateinit var mReminderDbDisposable: Disposable 37 | 38 | 39 | 40 | override fun onReceive(context: Context?, intent: Intent?) { 41 | val reminderId = intent?.getStringExtra(ReminderUtil.REMINDERID) 42 | val reminderDb = BaseApp.appComponent.getAppDatabase().reminderDao() 43 | mReminderDbDisposable = reminderDb.getReminder(reminderId!!.toInt()) 44 | .subscribeOn(Schedulers.io()) 45 | .observeOn(AndroidSchedulers.mainThread()) 46 | .subscribe({ reminder: Reminder? -> createNotification(context!!, reminder!!) }, {}) 47 | 48 | } 49 | 50 | public fun cancelAlarm(context: Context, id: Int) { 51 | 52 | } 53 | 54 | 55 | 56 | private fun createNotification(context: Context, reminder: Reminder) { 57 | val notificationReminder = NotificationCompat.Builder(context, "1").apply { 58 | setLargeIcon(BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)) 59 | setSmallIcon(R.drawable.ic_notifications_active) 60 | setTicker(reminder.title) 61 | setContentText(reminder.title) 62 | setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)) 63 | setAutoCancel(true) 64 | setOnlyAlertOnce(true) 65 | }.build() 66 | 67 | BaseApp.appComponent.getNotificationManager().notify(reminder.id.toInt(), notificationReminder) 68 | if(!mReminderDbDisposable.isDisposed) mReminderDbDisposable.dispose() 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/receiver/BootReceiver.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.receiver 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.Context 5 | import android.content.Intent 6 | 7 | /** 8 | * Created by kodeartisan on 30/11/17. 9 | */ 10 | class BootReceiver: BroadcastReceiver() { 11 | 12 | override fun onReceive(context: Context?, intent: Intent?) { 13 | 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.ui.base 2 | 3 | import android.os.Bundle 4 | import android.support.annotation.NonNull 5 | import android.support.v7.app.AppCompatActivity 6 | import com.idkotlin.idreminder.BaseApp 7 | import io.reactivex.disposables.CompositeDisposable; 8 | import com.tutorial.learnlinuxpro.presentation.di.component.ActivityComponent 9 | import com.tutorial.learnlinuxpro.presentation.di.component.DaggerActivityComponent 10 | import com.tutorial.learnlinuxpro.presentation.bus.RxBus 11 | import javax.inject.Inject 12 | 13 | 14 | 15 | /** 16 | * Created by kodeartisan on 12/10/17. 17 | */ 18 | abstract class BaseActivity : AppCompatActivity() { 19 | 20 | protected val disposables = CompositeDisposable() 21 | 22 | @Inject 23 | lateinit var eventBus: RxBus 24 | 25 | abstract fun getLayoutId(): Int 26 | open fun initDependencies(){} 27 | open fun initWidget(){} 28 | open fun initVariables(savedInstanceState: Bundle?){} 29 | open fun initPresenter(){} 30 | open fun initListener(){} 31 | open fun handleEvent(@NonNull event: Any) {} 32 | 33 | 34 | override fun onCreate(savedInstanceState: Bundle?) { 35 | super.onCreate(savedInstanceState) 36 | setContentView(getLayoutId()) 37 | getActivityComponent() 38 | initDependencies() 39 | initPresenter() 40 | initWidget() 41 | initListener() 42 | initVariables(savedInstanceState) 43 | 44 | } 45 | 46 | 47 | fun getActivityComponent(): ActivityComponent { 48 | return DaggerActivityComponent.builder() 49 | .applicationComponent(BaseApp.appComponent) 50 | .build() 51 | } 52 | 53 | override fun onResume() { 54 | super.onResume() 55 | disposables.add(eventBus.asFlowable() 56 | .subscribe(this::processEvent)) 57 | } 58 | 59 | override fun onStop() { 60 | super.onStop() 61 | disposables.clear() 62 | } 63 | 64 | override fun onPause() { 65 | super.onPause() 66 | disposables.clear() 67 | } 68 | 69 | private fun processEvent(ob: Any) { 70 | if(ob != null) handleEvent(ob) 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/BaseActivityMvp.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.ui.base 2 | 3 | import android.os.Bundle 4 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseContract.BasePresenter 5 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseContract.BaseView 6 | import javax.inject.Inject 7 | 8 | /** 9 | * Created by kodeartisan on 13/10/17. 10 | */ 11 | abstract class BaseActivityMvp, in V: BaseView> : BaseActivity(), BaseView { 12 | 13 | @Inject lateinit var mPresenter: P 14 | 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | super.onCreate(savedInstanceState) 17 | } 18 | 19 | override fun initPresenter() { 20 | super.initPresenter() 21 | mPresenter.attachView(view = this as V) 22 | } 23 | 24 | override fun onDestroy() { 25 | super.onDestroy() 26 | mPresenter.detachView() 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/BaseAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.ui.base 2 | 3 | import android.content.Context 4 | import android.support.v7.widget.RecyclerView 5 | import android.util.Log 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | 9 | /** 10 | * Created by kodeartisan on 18/10/17. 11 | */ 12 | abstract class BaseAdapter 13 | constructor(val mContext: Context) : RecyclerView.Adapter() { 14 | 15 | var mData: MutableList = mutableListOf() 16 | 17 | protected lateinit var mItemClickListener: (View, Int) -> Unit 18 | protected lateinit var mItemLongClickListener: (View, Int) -> Unit 19 | protected val mLayoutInflater: LayoutInflater = LayoutInflater.from(mContext) 20 | 21 | override fun onBindViewHolder(holder: BaseViewHolder?, position: Int) { 22 | holder?.fillView(position = position) 23 | holder?.itemView?.setOnClickListener{mItemClickListener(holder.itemView, position)} 24 | holder?.itemView?.setOnLongClickListener{mItemLongClickListener(holder.itemView, position);false} 25 | } 26 | 27 | override fun getItemCount(): Int = mData.size 28 | 29 | fun setData(data: List) { 30 | mData.clear() 31 | mData.addAll(data) 32 | notifyDataSetChanged() 33 | 34 | } 35 | 36 | 37 | fun addSingleData(data: T) = mData.add(data) 38 | 39 | fun setItemClickListener(itemClick: (View, Int) -> Unit) { 40 | mItemClickListener = itemClick 41 | } 42 | 43 | fun setItemLongClickListener(itemLongClick: (View, Int) -> Unit) { 44 | 45 | mItemLongClickListener = itemLongClick 46 | } 47 | 48 | abstract class BaseViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) { 49 | 50 | abstract fun fillView(position: Int) 51 | } 52 | 53 | interface ItemClickListener { 54 | fun onItemClick(position: Int) 55 | } 56 | 57 | interface ItemLongClickListener { 58 | public fun onItemLongClick(itemView: View?, position: Int) 59 | } 60 | 61 | 62 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/BaseContract.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.ui.base 2 | 3 | /** 4 | * Created by kodeartisan on 12/10/17. 5 | */ 6 | interface BaseContract { 7 | 8 | interface BaseView { 9 | 10 | fun showError(msg: String) 11 | 12 | fun complete() 13 | 14 | 15 | } 16 | 17 | interface BasePresenter { 18 | 19 | 20 | fun attachView(view: T) 21 | 22 | 23 | fun detachView() 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/BaseFragment.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.ui.base 2 | 3 | import android.os.Bundle 4 | import android.support.v4.app.Fragment 5 | import android.support.v4.app.FragmentActivity 6 | import android.support.v7.app.AppCompatActivity 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import com.idkotlin.idreminder.BaseApp 11 | import com.tutorial.learnlinuxpro.presentation.bus.RxBus 12 | import com.tutorial.learnlinuxpro.presentation.di.component.DaggerFragmentComponent 13 | import com.tutorial.learnlinuxpro.presentation.di.component.FragmentComponent 14 | import javax.inject.Inject 15 | 16 | /** 17 | * Created by kodeartisan on 18/10/17. 18 | */ 19 | abstract class BaseFragment: Fragment() { 20 | 21 | @Inject 22 | lateinit var eventBus: RxBus 23 | 24 | protected lateinit var mInflater: LayoutInflater 25 | protected lateinit var mActivity: AppCompatActivity 26 | protected lateinit var mRootView: View 27 | 28 | abstract fun getLayoutId(): Int 29 | open fun initDependencies(){} 30 | open fun initWidget(){} 31 | open fun initVariables(savedInstanceState: Bundle?){} 32 | open fun initPresenter(){} 33 | open fun initListener(){} 34 | 35 | override fun onCreate(savedInstanceState: Bundle?) { 36 | super.onCreate(savedInstanceState) 37 | retainInstance = true 38 | } 39 | 40 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { 41 | super.onViewCreated(view, savedInstanceState) 42 | initDependencies() 43 | initPresenter() 44 | initVariables(savedInstanceState) 45 | initWidget() 46 | initListener() 47 | 48 | } 49 | 50 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { 51 | mRootView = inflater!!.inflate(getLayoutId(), container, false) 52 | mActivity = activity as AppCompatActivity 53 | mInflater = inflater 54 | 55 | return mRootView 56 | } 57 | 58 | private fun getSupportActivity(): FragmentActivity = super.getActivity() 59 | 60 | protected fun getFragmentComponent(): FragmentComponent = DaggerFragmentComponent 61 | .builder() 62 | .applicationComponent(BaseApp.appComponent) 63 | .build() 64 | 65 | 66 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/BaseFragmentMvp.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.ui.base 2 | 3 | import android.util.Log 4 | import com.tutorial.learnlinuxpro.presentation.di.module.FragmentModule 5 | import javax.inject.Inject 6 | 7 | /** 8 | * Created by kodeartisan on 18/10/17. 9 | */ 10 | abstract class BaseFragmentMvp, in V: BaseContract.BaseView> : BaseFragment(), BaseContract.BaseView { 11 | 12 | @Inject lateinit var mPresenter: P 13 | 14 | protected fun getFragmentModule(): FragmentModule = FragmentModule(this) 15 | 16 | override fun initPresenter() { 17 | super.initPresenter() 18 | mPresenter.attachView(view = this as V) 19 | } 20 | 21 | override fun onDetach() { 22 | super.onDetach() 23 | mPresenter.detachView() 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/MultiSelectAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.base 2 | 3 | import android.content.Context 4 | import android.support.annotation.NonNull 5 | import android.support.v7.widget.RecyclerView 6 | import android.util.Log 7 | import android.view.ActionMode 8 | import android.view.View 9 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseAdapter 10 | import android.support.v4.content.ContextCompat 11 | import com.idkotlin.idreminder.R 12 | import com.tutorial.learnlinuxpro.presentation.extension.collection.forEachWithIndex 13 | 14 | 15 | /** 16 | * Created by kodeartisan on 18/12/17. 17 | */ 18 | abstract class MultiSelectAdapter(context: Context): BaseAdapter(context) { 19 | 20 | var mIsMultiSelectMode = false 21 | var mMultiSelect = false 22 | var mActionMode: ActionMode? = null 23 | val mSelectedList = HashMap() 24 | private val mItemList = HashMap>() 25 | private lateinit var mActionModeCallback: ActionMode.Callback 26 | private lateinit var mRecyclerview: RecyclerView 27 | 28 | fun setActionModeCallback(actionModeCallback: ActionMode.Callback) = {mActionModeCallback = actionModeCallback} 29 | 30 | override fun onBindViewHolder(holder: BaseViewHolder?, position: Int, payloads: MutableList?) { 31 | processUpdate(position) 32 | holder as MultiSelectViewHolder 33 | 34 | super.onBindViewHolder(holder, position, payloads) 35 | holder.setState(checkState(position), position) 36 | 37 | } 38 | 39 | 40 | 41 | fun multiSelect(key: Int, value: T) { 42 | mActionMode?.let { 43 | if(mSelectedList.contains(key)) {mSelectedList.remove(key); Log.d("MultiSelect", "containKey: ${key}")} 44 | else { mSelectedList.put(key, value);} 45 | 46 | if(mSelectedList.size > 0) (mActionMode as ActionMode).title = "${mSelectedList.size} selected" 47 | else (mActionMode as ActionMode).title = "" 48 | 49 | } 50 | } 51 | 52 | fun setActive(@NonNull view: View, state: Boolean) {} 53 | 54 | fun select(position: Int){ 55 | if(mMultiSelect.not()) mMultiSelect = true 56 | 57 | processClick(position) 58 | } 59 | 60 | 61 | private fun processClick(position: Int) { 62 | Log.d("POSITION", position.toString()) 63 | if(mItemList.containsKey(position)) { 64 | when(mItemList[position]!!.state) { 65 | is State.ACTIVE -> {perform(Action.DESELECT, position, true, true)} 66 | is State.INACTIVE -> {perform(Action.SELECT, position, true, true)} 67 | } 68 | } 69 | val selectedItem = mItemList.filter { it.value.state == State.ACTIVE } 70 | mActionMode?.let { 71 | if(selectedItem.isNotEmpty()) (mActionMode as ActionMode).title = "${selectedItem.size} selected" 72 | else (mActionMode as ActionMode).title = "" 73 | } 74 | } 75 | 76 | fun setItemList(itemList: HashMap>) { 77 | mItemList.clear() 78 | mItemList.putAll(itemList) 79 | } 80 | 81 | fun checkState(position: Int): Boolean = when(mItemList[position]!!.state) { 82 | is State.ACTIVE -> true 83 | is State.INACTIVE -> false 84 | 85 | } 86 | 87 | fun getSelectedItemList(): List = getSelectedItemListInternal() 88 | 89 | fun getSelectedItemCount(): Int = getSelectedItemList().size 90 | 91 | fun deleteSelectedItemList() { 92 | val activeItemList = mItemList.filter { it.value.state == State.ACTIVE } 93 | val newData = mData.filterIndexed { index, t -> activeItemList.containsKey(index).not() } 94 | setData(newData) 95 | 96 | mActionMode?.finish() 97 | mMultiSelect = false 98 | refreshItemList() 99 | 100 | 101 | } 102 | 103 | fun clearSelectedItemList() { 104 | mItemList.clear() 105 | } 106 | 107 | private fun refreshItemList() { 108 | mItemList.clear() 109 | mData.forEachWithIndex { i, t -> mItemList.put(i, StateType(State.INACTIVE, t)) } 110 | } 111 | 112 | private fun getSelectedItemListInternal(): List { 113 | val selectedList = mutableListOf() 114 | mItemList.filter { it.value.state == State.ACTIVE } 115 | .map { selectedList.add(it.value.entity) } 116 | return selectedList 117 | } 118 | 119 | fun perform(action: Action, position: Int, withCallback: Boolean, withVibration: Boolean) { 120 | when(action) { 121 | is Action.SELECT -> { 122 | mItemList.put(position, StateType(State.ACTIVE, mData[position])) 123 | } 124 | is Action.DESELECT -> { 125 | mItemList.put(position, StateType(State.INACTIVE, mData[position])) 126 | } 127 | } 128 | 129 | notifyItemChanged(position) 130 | 131 | } 132 | 133 | 134 | private fun processUpdate(position: Int) { 135 | if(mItemList.containsKey(position)) { 136 | when(mItemList[position]!!.state) { 137 | is State.ACTIVE -> {} 138 | is State.INACTIVE -> {} 139 | } 140 | } else { 141 | mItemList.put(position, StateType(State.INACTIVE, mData[position])) 142 | //processUpdate(view, position) 143 | } 144 | } 145 | 146 | private fun processNotifyDataSetChanged(position: Int) { 147 | mRecyclerview.let { notifyItemChanged(position) } 148 | } 149 | 150 | override fun onAttachedToRecyclerView(recyclerView: RecyclerView?) { 151 | mRecyclerview = recyclerView!! 152 | 153 | 154 | super.onAttachedToRecyclerView(recyclerView) 155 | } 156 | sealed class Action { 157 | object SELECT: Action() 158 | object DESELECT: Action() 159 | } 160 | 161 | sealed class State { 162 | object ACTIVE: State() 163 | object INACTIVE: State() 164 | } 165 | 166 | data class StateType(val state: State, val entity: T) 167 | 168 | abstract class MultiSelectViewHolder(itemView: View?): BaseViewHolder(itemView) { 169 | 170 | private var state: Boolean? = null 171 | 172 | open fun onChangeState(state: Boolean, position: Int){ 173 | if(state) itemView.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.colorPrimary)) 174 | else itemView.setBackgroundColor(ContextCompat.getColor(itemView.context, R.color.colorPrimaryDark)) 175 | } 176 | 177 | fun setState(state: Boolean, position: Int) { 178 | this.state = state 179 | onChangeState(state, position) 180 | } 181 | 182 | } 183 | 184 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/RxPresenter.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.ui.base 2 | 3 | import android.util.Log 4 | import io.reactivex.disposables.CompositeDisposable 5 | import io.reactivex.disposables.Disposable 6 | 7 | /** 8 | * Created by kodeartisan on 12/10/17. 9 | */ 10 | open class RxPresenter: BaseContract.BasePresenter { 11 | 12 | 13 | 14 | lateinit var mView: T 15 | private var mCompositeDisposable: CompositeDisposable = CompositeDisposable() 16 | 17 | override fun attachView(view: T) { 18 | mView = view 19 | } 20 | 21 | open fun addSubscribe(disposable: Disposable) = mCompositeDisposable.add(disposable) 22 | 23 | private fun unsubscribe() = mCompositeDisposable.dispose() 24 | 25 | override fun detachView() { 26 | Log.d("RxPresenter", "unsubscribe") 27 | unsubscribe() 28 | } 29 | 30 | 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/bus/Event.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.bus 2 | 3 | import android.support.v4.app.Fragment 4 | 5 | /** 6 | * Created by kodeartisan on 19/10/17. 7 | */ 8 | class Event { 9 | 10 | class ChangeFragment(val fragment: Fragment) 11 | class BackPressed() 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/base/bus/RxBus.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.bus 2 | 3 | import android.os.Handler 4 | import io.reactivex.Observable 5 | import io.reactivex.subjects.PublishSubject 6 | import io.reactivex.BackpressureStrategy 7 | import io.reactivex.internal.operators.single.SingleInternalHelper.toFlowable 8 | import io.reactivex.Flowable 9 | import com.jakewharton.rxrelay2.PublishRelay 10 | import com.jakewharton.rxrelay2.Relay 11 | import dagger.Provides 12 | 13 | 14 | /** 15 | * Created by kodeartisan on 19/10/17. 16 | */ 17 | class RxBus { 18 | 19 | private val bus = PublishRelay.create().toSerialized() 20 | @Volatile private var isLocked: Boolean = false 21 | private val handler = Handler() 22 | 23 | fun send(o: Any) { 24 | bus.accept(o) 25 | } 26 | 27 | @JvmOverloads 28 | fun sendWithLock(event: Any, lockOutTime: Long = 500) { 29 | if (!isLocked) { 30 | isLocked = true 31 | send(event) 32 | handler.postDelayed({ isLocked = false }, lockOutTime) 33 | } 34 | } 35 | 36 | fun asFlowable(): Flowable { 37 | return bus.toFlowable(BackpressureStrategy.LATEST) 38 | } 39 | 40 | fun hasObservers(): Boolean { 41 | return bus.hasObservers() 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/reminder/ReminderActivity.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.reminder 2 | 3 | import android.app.AlarmManager 4 | import android.app.PendingIntent 5 | import android.content.Context 6 | import android.content.Intent 7 | import android.os.Bundle 8 | import android.os.SystemClock 9 | import android.support.v4.app.Fragment 10 | import com.idkotlin.idreminder.R 11 | import com.idkotlin.idreminder.presentation.receiver.AlarmReceiver 12 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.add.ReminderAddFragment 13 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.list.ReminderFragment 14 | import com.tutorial.learnlinuxpro.presentation.bus.Event 15 | import com.tutorial.learnlinuxpro.presentation.extension.activity.addFragment 16 | import com.tutorial.learnlinuxpro.presentation.extension.activity.replaceFragment 17 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseActivity 18 | import kotlinx.android.synthetic.main.activity_reminder.* 19 | 20 | class ReminderActivity : BaseActivity(){ 21 | 22 | private val TAG = ReminderActivity::class.java.name 23 | 24 | private lateinit var currentFragment: Fragment 25 | private val reminderFragment = ReminderFragment() 26 | private val reminderAddFragment = ReminderAddFragment() 27 | 28 | override fun getLayoutId(): Int = R.layout.activity_reminder 29 | 30 | override fun initDependencies() { 31 | super.initDependencies() 32 | getActivityComponent().inject(this) 33 | } 34 | 35 | override fun initVariables(savedInstanceState: Bundle?) { 36 | super.initVariables(savedInstanceState) 37 | if(savedInstanceState == null) initFragment() 38 | 39 | } 40 | 41 | override fun initWidget() { 42 | super.initWidget() 43 | initToolbar() 44 | 45 | } 46 | 47 | private fun initToolbar() { 48 | setSupportActionBar(toolbar) 49 | supportActionBar?.apply { 50 | title = getString(R.string.app_name) 51 | setDisplayShowTitleEnabled(true) 52 | elevation = 0f 53 | } 54 | 55 | } 56 | 57 | private fun initFragment() { 58 | val reminderFragment = ReminderFragment() 59 | currentFragment = reminderFragment 60 | addFragment(reminderFragment, R.id.container) 61 | } 62 | 63 | 64 | 65 | 66 | override fun handleEvent(event: Any) { 67 | 68 | when(event) { 69 | is Event.ChangeFragment-> { 70 | replaceFragment(event.fragment, R.id.container, "") 71 | } 72 | is Event.BackPressed -> { 73 | onBackPressed() 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/reminder/ReminderAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.reminder 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import android.media.Image 6 | import android.util.Log 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import android.widget.ImageView 10 | import android.widget.TextView 11 | import com.amulyakhare.textdrawable.TextDrawable 12 | import com.amulyakhare.textdrawable.util.ColorGenerator 13 | import com.idkotlin.idreminder.R 14 | import com.idkotlin.idreminder.data.entity.Reminder 15 | import com.idkotlin.idreminder.presentation.ui.base.MultiSelectAdapter 16 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseAdapter 17 | import kotlinx.android.synthetic.main.adapter_reminder.view.* 18 | 19 | /** 20 | * Created by kodeartisan on 29/11/17. 21 | */ 22 | class ReminderAdapter(context: Context): MultiSelectAdapter(context) { 23 | 24 | private val TAG = ReminderAdapter::class.java.simpleName 25 | val mColorGenerator = ColorGenerator.DEFAULT 26 | 27 | private lateinit var mActiveListener: (ImageView, Int) -> Unit 28 | 29 | fun setActiveListener(itemClick: (ImageView, Int) -> Unit) { 30 | mActiveListener = itemClick 31 | } 32 | 33 | override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): BaseViewHolder { 34 | val view = mLayoutInflater.inflate(R.layout.adapter_reminder, parent, false) 35 | return ReminderViewholder(view) 36 | 37 | } 38 | 39 | override fun onBindViewHolder(holder: BaseViewHolder?, position: Int, payloads: MutableList?) { 40 | super.onBindViewHolder(holder, position, payloads) 41 | (holder as ReminderViewholder)?.mIvActive?.setOnClickListener{mActiveListener(it.active_image, position)} 42 | } 43 | 44 | 45 | inner class ReminderViewholder(itemView: View?) : MultiSelectViewHolder(itemView) { 46 | 47 | private val TAG = ReminderViewholder::class.java.simpleName 48 | 49 | private lateinit var mReminder: Reminder 50 | private var mColor: Int? = null 51 | private val mTxtTitle: TextView? by lazy { itemView?.findViewById(R.id.title)} 52 | val mIvThumbnail: ImageView? by lazy { itemView?.findViewById(R.id.thumbnail_image) } 53 | val mIvActive: ImageView? by lazy { itemView?.findViewById(R.id.active_image) } 54 | private val mTxtDatetime: TextView? by lazy { itemView?.findViewById(R.id.date_time) } 55 | private val mTxtRepeatInfo: TextView? by lazy { itemView?.findViewById(R.id.repeat_info) } 56 | 57 | override fun fillView(position: Int) { 58 | mReminder = mData[position] 59 | setTitleDrawable() 60 | setTitle() 61 | setDateTime() 62 | setRepeatInfo() 63 | setActiveDrawable() 64 | } 65 | 66 | override fun onChangeState(state: Boolean, position: Int) { 67 | super.onChangeState(state, position) 68 | Log.d(TAG, "onChangeState ${state} position ${position}") 69 | } 70 | 71 | private fun setTitle() { 72 | mTxtTitle?.text = mReminder.title 73 | } 74 | 75 | private fun setTitleDrawable() { 76 | val letter = if(mReminder.title.isNotEmpty()) mReminder.title.substring(0, 1) else "A" 77 | val textDrawable = TextDrawable.builder().buildRound(letter, mColorGenerator.randomColor) 78 | 79 | mIvThumbnail?.setImageDrawable(textDrawable) 80 | } 81 | 82 | private fun setDateTime() { 83 | mTxtDatetime?.text = "${mReminder.date} - ${mReminder.time}" 84 | } 85 | 86 | private fun setRepeatInfo() { 87 | mTxtRepeatInfo?.text = if(mReminder.repeat) "Every ${mReminder.repeatNo} ${mReminder.repeatType}(s)" 88 | else "Repeat Off" 89 | 90 | } 91 | 92 | private fun setActiveDrawable() { 93 | val imageDrawable = if(mReminder.active) R.drawable.ic_notifications_active else R.drawable.ic_notifications_off 94 | mIvActive?.setImageResource(imageDrawable) 95 | 96 | } 97 | 98 | } 99 | 100 | 101 | 102 | 103 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/reminder/fragment/add/ReminderAddFragment.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.reminder.fragment.add 2 | 3 | import android.app.AlertDialog 4 | import android.app.DatePickerDialog 5 | import android.app.TimePickerDialog 6 | import android.os.Bundle 7 | import android.support.v7.app.AppCompatActivity 8 | import android.text.InputType 9 | import android.util.Log 10 | import android.view.Menu 11 | import android.view.MenuInflater 12 | import android.view.MenuItem 13 | import android.widget.* 14 | import com.idkotlin.idreminder.R 15 | import com.idkotlin.idreminder.data.entity.Reminder 16 | import com.idkotlin.idreminder.presentation.receiver.AlarmReceiver 17 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.list.ReminderFragment 18 | import com.idkotlin.idreminder.presentation.util.ReminderUtil 19 | import com.tutorial.learnlinuxpro.presentation.bus.Event 20 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseFragmentMvp 21 | import kotlinx.android.synthetic.main.fragment_reminder_add.* 22 | import java.util.* 23 | 24 | /** 25 | * Created by kodeartisan on 27/11/17. 26 | */ 27 | class ReminderAddFragment: BaseFragmentMvp, ReminderAddFragmentContract.View>(), ReminderAddFragmentContract.View { 28 | 29 | public val TAG = ReminderFragment::class.java.name 30 | 31 | private var mTitle = "" 32 | private var mDate = "" 33 | private var mTime = "" 34 | private var mActive = true 35 | private var mRepeat = true 36 | private var mRepeatNo = 1 37 | private var mRepeatType = "Hour" 38 | private var mRepeatTime: Long = 0 39 | 40 | private val mCalendar = Calendar.getInstance() 41 | private var mHour = mCalendar.get(Calendar.HOUR_OF_DAY) 42 | private var mMinute = mCalendar.get(Calendar.MINUTE) 43 | private var mYear = mCalendar.get(Calendar.YEAR) 44 | private var mMonth = mCalendar.get(Calendar.MONTH) + 1 45 | private var mDay = mCalendar.get(Calendar.DATE) 46 | 47 | 48 | override fun getLayoutId(): Int = R.layout.fragment_reminder_add 49 | 50 | override fun onCreate(savedInstanceState: Bundle?) { 51 | super.onCreate(savedInstanceState) 52 | setHasOptionsMenu(true) 53 | } 54 | 55 | override fun initDependencies() { 56 | super.initDependencies() 57 | getFragmentComponent().inject(this) 58 | } 59 | 60 | override fun initWidget() { 61 | super.initWidget() 62 | 63 | 64 | } 65 | 66 | override fun initVariables(savedInstanceState: Bundle?) { 67 | super.initVariables(savedInstanceState) 68 | mDate = "${mCalendar.get(Calendar.DATE)}/${mCalendar.get(Calendar.MONTH) + 1}/${mCalendar.get(Calendar.YEAR)}" 69 | mTime = "${mCalendar.get(Calendar.HOUR_OF_DAY)}:${mCalendar.get(Calendar.MINUTE)}" 70 | 71 | set_date.text = mDate 72 | set_time.text = mTime 73 | set_repeat_no.text = mRepeatNo.toString() 74 | set_repeat_type.text = mRepeatType 75 | set_repeat.text = "Every ${mRepeatNo} ${mRepeatType} (s)" 76 | } 77 | 78 | override fun initListener() { 79 | super.initListener() 80 | date.setOnClickListener { showDatePicker() } 81 | time.setOnClickListener { showTimePicker() } 82 | RepeatNo.setOnClickListener { showRepeatNoPicker() } 83 | RepeatType.setOnClickListener { showRepeatTypePicker() } 84 | repeat_switch.setOnCheckedChangeListener({ compoundButton: CompoundButton, isChecked: Boolean -> 85 | run { 86 | 87 | mRepeat = isChecked 88 | 89 | set_repeat.text = if(isChecked) "Every ${mRepeatNo} ${mRepeatType} (s)" 90 | else "Off" 91 | } 92 | }) 93 | btn_active.setOnClickListener { setActiveState() } 94 | } 95 | 96 | override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { 97 | inflater?.inflate(R.menu.add, menu) 98 | } 99 | 100 | 101 | 102 | override fun onOptionsItemSelected(item: MenuItem?): Boolean { 103 | when(item?.itemId) { 104 | R.id.action_insert -> { 105 | insertReminder() 106 | } 107 | } 108 | return super.onOptionsItemSelected(item) 109 | } 110 | 111 | private fun showTimePicker() { 112 | (TimePickerDialog(context, 113 | { timePicker: TimePicker, hourOfDay: Int, minute: Int -> run{ 114 | mHour = hourOfDay 115 | mMinute = minute 116 | mTime = if(mMinute < 10) "${hourOfDay}:0${minute}" else "${hourOfDay}:${minute}" 117 | set_time.text = mTime 118 | } }, 119 | mCalendar.get(Calendar.HOUR_OF_DAY), 120 | mCalendar.get(Calendar.MINUTE), 121 | true)).show() 122 | 123 | } 124 | 125 | private fun showDatePicker() { 126 | 127 | (DatePickerDialog( 128 | context, 129 | { _: DatePicker, year: Int, monthOfYear: Int, dayOfMonth: Int -> run{ 130 | 131 | mDay = dayOfMonth 132 | mMonth = monthOfYear 133 | mYear = year 134 | mDate = "${dayOfMonth}/${monthOfYear + 1}/${year}" 135 | 136 | set_date.text = mDate 137 | }}, 138 | mCalendar.get(Calendar.YEAR), 139 | mCalendar.get(Calendar.MONTH), 140 | mCalendar.get(Calendar.DAY_OF_MONTH) 141 | )).show() 142 | } 143 | 144 | private fun showRepeatNoPicker() { 145 | 146 | val input = EditText(context).apply { 147 | inputType = InputType.TYPE_CLASS_NUMBER 148 | } 149 | 150 | (AlertDialog.Builder(context).apply { 151 | setTitle("Enter a Number") 152 | setView(input) 153 | setPositiveButton("Ok", { dialogInterface, which-> 154 | run { 155 | mRepeatNo = if (input.text.toString().length == 0) 1 else input.text.toString().toInt() 156 | set_repeat_no.text = mRepeatNo.toString() 157 | set_repeat.text = "Every ${mRepeatNo} ${mRepeatType} (s)" 158 | } 159 | }) 160 | setNegativeButton("Cancel", {dialog, which -> { 161 | 162 | }}) 163 | 164 | }).show() 165 | } 166 | 167 | private fun showRepeatTypePicker() { 168 | val repeatTypes = arrayOf("Minute", "Hour", "Day", "Week", "Month") 169 | 170 | (AlertDialog.Builder(context).apply { 171 | setTitle("Select Type") 172 | setItems(repeatTypes, { _, item -> 173 | run { 174 | mRepeatType = repeatTypes[item] 175 | set_repeat_type.text = mRepeatType 176 | set_repeat.text = "Every ${mRepeatNo} ${mRepeatType} (s)" 177 | } 178 | }) 179 | }).show() 180 | } 181 | 182 | override fun showError(msg: String) { 183 | 184 | } 185 | 186 | override fun complete() { 187 | } 188 | 189 | private fun setActiveState() { 190 | mActive = !mActive 191 | val activeImageState = if(mActive) R.drawable.ic_notifications_active else R.drawable.ic_notifications_off 192 | 193 | btn_active.setImageResource(activeImageState) 194 | } 195 | 196 | private fun insertReminder() { 197 | mTitle = reminder_title.text.toString() 198 | val reminder = Reminder(mTitle, mDate, mTime, mRepeat, mRepeatNo, mRepeatType, mActive) 199 | mPresenter.insert(reminder) 200 | 201 | } 202 | 203 | override fun onInsertData(id: Long) { 204 | Log.d(TAG, mCalendar.get(Calendar.DAY_OF_MONTH).toString()) 205 | mCalendar.apply { 206 | set(Calendar.MONTH, --mMonth) 207 | set(Calendar.YEAR, mYear) 208 | set(Calendar.DAY_OF_MONTH, mDay) 209 | set(Calendar.HOUR_OF_DAY, mHour) 210 | set(Calendar.MINUTE, mMinute) 211 | set(Calendar.SECOND, 0) 212 | } 213 | 214 | mRepeatTime = when(mRepeatType) { 215 | "Minute" -> { mRepeatNo * ReminderUtil.milMinute } 216 | "Hour" -> { mRepeatNo * ReminderUtil.milHour } 217 | "Day" -> { mRepeatNo * ReminderUtil.milDay } 218 | "Month" -> { mRepeatNo * ReminderUtil.milMonth } 219 | else -> { 0 } 220 | } 221 | 222 | if(mActive) { 223 | if(mRepeat) { 224 | ReminderUtil.setRepeatAlarm(activity.applicationContext, mCalendar, id.toInt(), mRepeatTime) 225 | } else { 226 | ReminderUtil.setAlarm(activity.applicationContext, mCalendar, id.toInt()) 227 | } 228 | } 229 | 230 | eventBus.send(Event.BackPressed()) 231 | 232 | 233 | } 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/reminder/fragment/add/ReminderAddFragmentContract.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.reminder.fragment.add 2 | 3 | import com.idkotlin.idreminder.data.entity.Reminder 4 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseContract 5 | 6 | /** 7 | * Created by kodeartisan on 28/11/17. 8 | */ 9 | interface ReminderAddFragmentContract { 10 | 11 | interface View : BaseContract.BaseView { 12 | fun onInsertData(id: Long) 13 | } 14 | 15 | interface Presenter: BaseContract.BasePresenter { 16 | fun insert(reminder: Reminder) 17 | } 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/reminder/fragment/add/ReminderAddFragmentPresenter.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.reminder.fragment.add 2 | 3 | import android.util.Log 4 | import com.idkotlin.idreminder.data.entity.Reminder 5 | import com.idkotlin.idreminder.domain.executor.scheduler.BaseSchedulerProvider 6 | import com.idkotlin.idreminder.domain.repository.IReminderRepository 7 | import com.tutorial.learnlinuxpro.presentation.ui.base.RxPresenter 8 | import javax.inject.Inject 9 | 10 | /** 11 | * Created by kodeartisan on 28/11/17. 12 | */ 13 | class ReminderAddFragmentPresenter @Inject constructor(private val schedulerProvider: BaseSchedulerProvider, private val reminderRepository: IReminderRepository) : RxPresenter(), ReminderAddFragmentContract.Presenter { 14 | 15 | val TAG = ReminderAddFragmentPresenter::class.java.simpleName 16 | 17 | override fun insert(reminder: Reminder) { 18 | 19 | reminderRepository.insert(reminder) 20 | .subscribeOn(schedulerProvider.io()) 21 | .observeOn(schedulerProvider.ui()) 22 | .subscribe(this::processInsert, this::processErrorInsert) 23 | } 24 | 25 | private fun processInsert(id: Long) { 26 | mView.onInsertData(id) 27 | } 28 | 29 | private fun processErrorInsert(throwable: Throwable) { 30 | Log.d(TAG, "error: ${throwable.printStackTrace()}") 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/reminder/fragment/list/ReminderFragment.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.reminder.fragment.list 2 | 3 | import android.os.Bundle 4 | import android.support.v7.widget.LinearLayoutManager 5 | import android.view.* 6 | import com.idkotlin.idreminder.R 7 | import com.idkotlin.idreminder.data.entity.Reminder 8 | import com.idkotlin.idreminder.presentation.ui.reminder.ReminderAdapter 9 | import com.idkotlin.idreminder.presentation.ui.reminder.fragment.add.ReminderAddFragment 10 | import com.idkotlin.idreminder.presentation.util.ReminderUtil 11 | import com.tutorial.learnlinuxpro.presentation.bus.Event 12 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseFragmentMvp 13 | import kotlinx.android.synthetic.main.fragment_reminder_list.* 14 | 15 | /** 16 | * Created by kodeartisan on 27/11/17. 17 | */ 18 | class ReminderFragment : BaseFragmentMvp, ReminderFragmentContract.View>(), ReminderFragmentContract.View { 19 | 20 | 21 | private val TAG = ReminderFragment::class.java.name 22 | 23 | private lateinit var mReminderAdapter: ReminderAdapter 24 | private val mReminders = mutableListOf() 25 | 26 | private val actionModeCallback: ActionMode.Callback by lazy { 27 | object : ActionMode.Callback { 28 | override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?) = when(item?.itemId) { 29 | R.id.action_multi_delete -> { 30 | mPresenter.delete(mReminderAdapter.getSelectedItemList()) 31 | mReminderAdapter.deleteSelectedItemList() 32 | true 33 | } 34 | else -> false 35 | } 36 | 37 | override fun onCreateActionMode(mode: ActionMode?, menu: Menu?): Boolean { 38 | activity.menuInflater.inflate(R.menu.multi_select, menu) 39 | return true 40 | } 41 | 42 | override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?): Boolean = false 43 | override fun onDestroyActionMode(mode: ActionMode?) { 44 | mReminderAdapter.mActionMode = null 45 | mReminderAdapter.mIsMultiSelectMode = false 46 | } 47 | } 48 | } 49 | 50 | 51 | override fun getLayoutId(): Int = R.layout.fragment_reminder_list 52 | 53 | override fun initDependencies() = getFragmentComponent().inject(this) 54 | 55 | override fun onCreate(savedInstanceState: Bundle?) { 56 | super.onCreate(savedInstanceState) 57 | setHasOptionsMenu(true) 58 | } 59 | 60 | override fun initVariables(savedInstanceState: Bundle?) { 61 | super.initVariables(savedInstanceState) 62 | mPresenter.start() 63 | 64 | } 65 | 66 | override fun initWidget() { 67 | super.initWidget() 68 | initRecyclerview() 69 | } 70 | 71 | private fun initRecyclerview() { 72 | mReminderAdapter = ReminderAdapter(context) 73 | mReminderAdapter.apply { 74 | setData(mReminders) 75 | setItemClickListener { view, i -> 76 | if(mMultiSelect) select(i) 77 | } 78 | setActiveListener { imageView, i -> mPresenter.update(mReminders[i], i) } 79 | setItemLongClickListener{ view: View, i: Int -> 80 | mActionMode = activity.startActionMode(actionModeCallback) 81 | select(i) 82 | } 83 | 84 | 85 | } 86 | 87 | recyclerview.apply { 88 | adapter = mReminderAdapter 89 | layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) 90 | setHasFixedSize(true) 91 | } 92 | } 93 | 94 | override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { 95 | inflater?.inflate(R.menu.main, menu) 96 | } 97 | 98 | 99 | 100 | override fun onOptionsItemSelected(item: MenuItem?): Boolean { 101 | when(item?.itemId) { 102 | R.id.action_add -> { 103 | eventBus.send(Event.ChangeFragment(ReminderAddFragment())) 104 | } 105 | } 106 | return super.onOptionsItemSelected(item) 107 | } 108 | 109 | override fun showError(msg: String) { 110 | 111 | } 112 | 113 | override fun complete() { 114 | 115 | } 116 | 117 | override fun onGetReminders(reminders: List) { 118 | this.mReminders.clear() 119 | this.mReminders.addAll(reminders) 120 | mReminderAdapter.setData(this.mReminders) 121 | } 122 | 123 | override fun onUpdateReminderItem(position: Int) { 124 | mReminderAdapter.notifyItemChanged(position) 125 | } 126 | 127 | override fun onDeletedReminders(reminders: List) { 128 | val filteredData = mReminderAdapter.mData.filter { mReminderAdapter.mSelectedList.keys.contains(it.id.toInt()).not()} 129 | filteredData.map { ReminderUtil.cancelAlarm(activity.applicationContext, it.id.toInt()) } 130 | mReminderAdapter.setData(filteredData) 131 | mReminderAdapter.mSelectedList.clear() 132 | mReminderAdapter.mActionMode?.finish() 133 | } 134 | 135 | 136 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/reminder/fragment/list/ReminderFragmentContract.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.reminder.fragment.list 2 | 3 | import com.idkotlin.idreminder.data.entity.Reminder 4 | import com.tutorial.learnlinuxpro.presentation.ui.base.BaseContract 5 | 6 | /** 7 | * Created by kodeartisan on 28/11/17. 8 | */ 9 | interface ReminderFragmentContract { 10 | 11 | interface View : BaseContract.BaseView { 12 | fun onGetReminders(reminders: List) 13 | fun onUpdateReminderItem(position: Int) 14 | fun onDeletedReminders(reminders: List) 15 | } 16 | 17 | interface Presenter: BaseContract.BasePresenter { 18 | fun start() 19 | fun insert(reminder: Reminder) 20 | fun update(reminder: Reminder, position: Int) 21 | fun delete(reminders: List) 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/ui/reminder/fragment/list/ReminderFragmentPresenter.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.ui.reminder.fragment.list 2 | 3 | import android.util.Log 4 | import com.idkotlin.idreminder.data.entity.Reminder 5 | import com.idkotlin.idreminder.domain.executor.scheduler.BaseSchedulerProvider 6 | import com.idkotlin.idreminder.domain.repository.IReminderRepository 7 | import com.tutorial.learnlinuxpro.presentation.ui.base.RxPresenter 8 | import io.reactivex.Completable 9 | import java.text.FieldPosition 10 | import javax.inject.Inject 11 | 12 | /** 13 | * Created by kodeartisan on 28/11/17. 14 | */ 15 | class ReminderFragmentPresenter @Inject constructor(private val schedulerProvider: BaseSchedulerProvider, private val reminderRepository: IReminderRepository) : RxPresenter(),ReminderFragmentContract.Presenter { 16 | 17 | 18 | val TAG = ReminderFragmentPresenter::class.java.simpleName 19 | 20 | private var updatePosition = 0 21 | 22 | override fun start() { 23 | val addSubscribe = addSubscribe( 24 | reminderRepository.fetch() 25 | .subscribeOn(schedulerProvider.io()) 26 | .observeOn(schedulerProvider.ui()) 27 | .subscribe(this::processData, this::processError) 28 | ) 29 | } 30 | 31 | override fun insert(reminder: Reminder) { 32 | if(reminder != null) { 33 | val addSubscribe = addSubscribe(Completable.fromCallable({ 34 | reminderRepository.insert(reminder) 35 | }).subscribeOn(schedulerProvider.io()).subscribe()) 36 | } 37 | } 38 | 39 | override fun delete(reminders: List) { 40 | Log.d(TAG, reminders.size.toString()) 41 | mView.onDeletedReminders(reminders) 42 | addSubscribe(reminderRepository.delete(reminders) 43 | .subscribeOn(schedulerProvider.io()) 44 | .observeOn(schedulerProvider.ui()) 45 | .subscribe({mView.onDeletedReminders(reminders)}, {it.printStackTrace()})) 46 | } 47 | 48 | override fun update(reminder: Reminder, position: Int) { 49 | updatePosition = position 50 | reminder.apply { 51 | active = !active 52 | } 53 | 54 | addSubscribe(reminderRepository.update(reminder) 55 | .subscribeOn(schedulerProvider.io()) 56 | .observeOn(schedulerProvider.ui()) 57 | .subscribe(this::processUpdateReminderItem, {it.printStackTrace()})) 58 | } 59 | 60 | private fun processUpdateReminderItem(id: Int) { 61 | mView.onUpdateReminderItem(updatePosition) 62 | } 63 | 64 | private fun processData(reminders: List){ 65 | mView.onGetReminders(reminders) 66 | } 67 | 68 | private fun processError(error: Throwable) { 69 | Log.d(TAG, error.message) 70 | } 71 | 72 | 73 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/util/AppUtil.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.util 2 | 3 | import android.content.ActivityNotFoundException 4 | import android.content.Intent 5 | import android.net.Uri 6 | 7 | /** 8 | * Created by kodeartisan on 25/10/17. 9 | */ 10 | object AppUtil { 11 | 12 | fun goToMarket(packageName: String) { 13 | 14 | 15 | try { 16 | var intent: Intent = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=${packageName}")) 17 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 18 | Util.getContext().startActivity(intent) 19 | } catch (anfe: ActivityNotFoundException) { 20 | var intent: Intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=${packageName}")) 21 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 22 | Util.getContext().startActivity(intent) 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/util/PreferencesUtil.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.util 2 | 3 | import android.content.Context 4 | import android.content.SharedPreferences 5 | 6 | /** 7 | * Created by kodeartisan on 23/10/17. 8 | */ 9 | object PreferencesUtil { 10 | 11 | // private lateinit var sharedPreferences: SharedPreferences 12 | val RATE_IT: String = "RATE_IT" 13 | private val SETTING: String = "SETTING" 14 | 15 | private val sharedPreferences: SharedPreferences = Util.getContext().getSharedPreferences(SETTING, Context.MODE_PRIVATE) 16 | 17 | 18 | init { 19 | 20 | } 21 | 22 | 23 | 24 | fun putInt(key: String, value: Int): Boolean { 25 | val editor: SharedPreferences.Editor = sharedPreferences.edit() 26 | 27 | editor.putInt(key, value) 28 | 29 | return editor.commit() 30 | } 31 | 32 | fun putBoolean(key: String, value: Boolean): Boolean { 33 | val editor: SharedPreferences.Editor = sharedPreferences.edit() 34 | 35 | editor.putBoolean(key, value) 36 | 37 | return editor.commit() 38 | } 39 | 40 | fun putString(key: String, value: String): Boolean { 41 | val editor: SharedPreferences.Editor = sharedPreferences.edit() 42 | 43 | editor.putString(key, value) 44 | 45 | return editor.commit() 46 | } 47 | 48 | fun getInt(key: String, defaultValue: Int): Int = sharedPreferences.getInt(key, defaultValue) 49 | 50 | fun getString(key: String, defaultValue: String): String = sharedPreferences.getString(key, defaultValue) 51 | 52 | fun getBoolean(key: String, defaultValue: Boolean): Boolean = sharedPreferences.getBoolean(key, defaultValue) 53 | 54 | 55 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/util/ReminderUtil.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder.presentation.util 2 | 3 | import android.app.AlarmManager 4 | import android.app.PendingIntent 5 | import android.content.Context 6 | import android.content.Intent 7 | import android.os.SystemClock 8 | import android.util.Log 9 | import com.idkotlin.idreminder.BaseApp 10 | import com.idkotlin.idreminder.presentation.receiver.AlarmReceiver 11 | import java.util.* 12 | 13 | /** 14 | * Created by kodeartisan on 27/11/17. 15 | */ 16 | object ReminderUtil { 17 | 18 | val TAG = ReminderUtil::class.java.name 19 | 20 | val milMinute = 60000L 21 | val milHour = 3600000L 22 | val milDay = 86400000L 23 | val milWeek = 604800000L 24 | val milMonth = 2592000000L 25 | 26 | val REMINDERID = "reminder_id" 27 | 28 | public fun setAlarm(context: Context, calendar: Calendar, id: Int) { 29 | val intent = Intent(context, AlarmReceiver::class.java).apply { 30 | putExtra(ReminderUtil.REMINDERID, id.toString()) 31 | } 32 | 33 | Log.d(TAG, "MINUTE: ${calendar.get(Calendar.MINUTE)}") 34 | Log.d(TAG, "HOUR: ${calendar.get(Calendar.HOUR_OF_DAY)}") 35 | Log.d(TAG, "DAY: ${calendar.get(Calendar.DAY_OF_MONTH)}") 36 | Log.d(TAG, "MONTH: ${calendar.get(Calendar.MONTH)}") 37 | 38 | val pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT) 39 | 40 | BaseApp.appComponent.getAlarmManager().set(AlarmManager.ELAPSED_REALTIME, 41 | SystemClock.elapsedRealtime() + getDiffTime(calendar), 42 | pendingIntent) 43 | 44 | // Restart alarm if device is rebooted 45 | /* val receiver = ComponentName(context, BootReceiver::class.java) 46 | val pm = context.packageManager 47 | pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)*/ 48 | 49 | } 50 | 51 | 52 | public fun setRepeatAlarm(context: Context, calendar: Calendar, id: Int, repeatTime: Long) { 53 | val intent = Intent(context, AlarmReceiver::class.java) 54 | intent.apply { putExtra(ReminderUtil.REMINDERID, id.toString()) } 55 | val mPendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT) 56 | 57 | Log.d(TAG, "MINUTE: ${calendar.get(Calendar.MINUTE)}") 58 | Log.d(TAG, "HOUR: ${calendar.get(Calendar.HOUR_OF_DAY)}") 59 | Log.d(TAG, "DAY: ${calendar.get(Calendar.DAY_OF_MONTH)}") 60 | Log.d(TAG, "MONTH: ${calendar.get(Calendar.MONTH)}") 61 | 62 | BaseApp.appComponent.getAlarmManager().setRepeating(AlarmManager.ELAPSED_REALTIME, 63 | SystemClock.elapsedRealtime() + getDiffTime(calendar), 64 | repeatTime, mPendingIntent) 65 | } 66 | 67 | private fun getDiffTime(calendar: Calendar): Long { 68 | val c = Calendar.getInstance() 69 | val currentTime = c.timeInMillis 70 | 71 | return calendar.timeInMillis - currentTime 72 | } 73 | 74 | public fun cancelAlarm(context: Context, id: Int) { 75 | val pendingIntent = PendingIntent.getBroadcast(context, id, Intent(context, AlarmReceiver::class.java), 0) 76 | BaseApp.appComponent.getAlarmManager().cancel(pendingIntent) 77 | } 78 | 79 | 80 | } -------------------------------------------------------------------------------- /app/src/main/java/com/idkotlin/idreminder/presentation/util/Util.kt: -------------------------------------------------------------------------------- 1 | package com.tutorial.learnlinuxpro.presentation.util 2 | 3 | import android.content.Context 4 | import android.support.annotation.NonNull 5 | 6 | /** 7 | * Created by kodeartisan on 23/10/17. 8 | */ 9 | object Util { 10 | 11 | private lateinit var context:Context 12 | 13 | fun init(@NonNull context:Context) { 14 | this.context = context.applicationContext 15 | } 16 | 17 | fun getContext(): Context = this.context 18 | 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-anydpi/ic_library_add.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_add.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_date_range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_date_range.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_notifications.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notifications_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_notifications_active.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_notifications_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_notifications_off.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_repeat.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_subject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_subject.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_timer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_timer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_unfold_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-hdpi/ic_unfold_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_add.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_date_range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_date_range.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_notifications.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notifications_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_notifications_active.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_notifications_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_notifications_off.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_repeat.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_subject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_subject.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_timer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_timer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_unfold_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-mdpi/ic_unfold_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_add.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_date_range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_date_range.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_notifications.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notifications_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_notifications_active.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_notifications_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_notifications_off.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_repeat.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_subject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_subject.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_timer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_timer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_unfold_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xhdpi/ic_unfold_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_add.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_date_range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_date_range.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_notifications.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_notifications_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_notifications_active.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_notifications_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_notifications_off.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_repeat.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_subject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_subject.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_timer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_timer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_unfold_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxhdpi/ic_unfold_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_add.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_check.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_date_range.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_date_range.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_delete.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_notifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_notifications.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_notifications_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_notifications_active.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_notifications_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_notifications_off.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_repeat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_repeat.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_subject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_subject.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_timer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_timer.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_unfold_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/drawable-xxxhdpi/ic_unfold_more.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/recycler_scrollbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_example.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_reminder.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 15 | 21 | 22 | 23 | 28 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_reminder.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 25 | 26 | 35 | 36 | 45 | 46 | 55 | 56 | 57 | 58 | 65 | 66 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_reminder_add.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 17 | 18 | 26 | 27 | 42 | 43 | 44 | 45 | 50 | 51 | 56 | 57 | 67 | 68 | 75 | 76 | 85 | 86 | 92 | 93 | 100 | 101 | 107 | 108 | 109 | 110 | 111 | 112 | 119 | 120 | 129 | 130 | 136 | 137 | 144 | 145 | 151 | 152 | 153 | 154 | 155 | 156 | 160 | 161 | 170 | 171 | 178 | 179 | 186 | 187 | 193 | 194 | 195 | 196 | 207 | 208 | 209 | 210 | 217 | 218 | 227 | 228 | 234 | 235 | 242 | 243 | 249 | 250 | 251 | 252 | 253 | 254 | 260 | 261 | 270 | 271 | 277 | 278 | 285 | 286 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 312 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_reminder_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/menu/add.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/menu/multi_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #37474f 4 | #263238 5 | #78909c 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | IDReminder 3 | 4 | Open navigation drawer 5 | Close navigation drawer 6 | 7 | Reminder 8 | Details 9 | Date 10 | Time 11 | Repeat 12 | Off 13 | Repetition Interval 14 | Type of Repetitions 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 25 | 26 | 34 | 35 | 53 | 54 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/test/java/com/idkotlin/idreminder/TodoUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.idkotlin.idreminder 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Todo local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class TodoUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /art/ss1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/art/ss1.png -------------------------------------------------------------------------------- /art/ss2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/art/ss2.png -------------------------------------------------------------------------------- /art/ss3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/art/ss3.png -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext.kotlin_version = '1.1.51' 5 | ext.android_support_version = '26.1.0' 6 | ext.rxjava_version='2.1.5' 7 | ext.rxandroid_version='2.0.1' 8 | ext.rxrelay_version='2.0.0' 9 | ext.logging_interceptor_version='3.8.0' 10 | ext.dagger_version='2.12' 11 | ext.room_version='1.0.0-alpha9' 12 | ext.text_drawable_version='1.0.1' 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | dependencies { 18 | 19 | classpath 'com.android.tools.build:gradle:3.0.0' 20 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 21 | 22 | // NOTE: Do not place your application dependencies here; they belong 23 | // in the individual module build.gradle files 24 | } 25 | } 26 | 27 | allprojects { 28 | repositories { 29 | google() 30 | jcenter() 31 | } 32 | } 33 | 34 | task clean(type: Delete) { 35 | delete rootProject.buildDir 36 | } 37 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/idkotlinx/idreminder/6ea808e5875602da1b677299e1268a2d67e6c9c4/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Oct 26 09:21:31 WIB 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------