├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── markdown-navigator.xml ├── markdown-navigator │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── Photos ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png ├── Minitask-feature-graphic.png └── minitask_land.png ├── README.md ├── app ├── .gitignore ├── build.gradle ├── google-services.json ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── luongvo │ │ └── com │ │ └── todolistminimal │ │ ├── ExampleInstrumentedTest.java │ │ ├── Pages │ │ ├── AddTask.java │ │ └── Home.java │ │ ├── TasksTest.java │ │ └── Utils │ │ └── CustomAssertions.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ │ └── redlor │ │ │ └── it │ │ │ └── minitask │ │ │ ├── AboutActivity.java │ │ │ ├── Adapters │ │ │ └── MyFragmentPagerAdapter.java │ │ │ ├── AddTodoItem.java │ │ │ ├── DetailActivity.java │ │ │ ├── DetailFragment.java │ │ │ ├── MainActivity.java │ │ │ ├── PageFragment.java │ │ │ ├── PrivacyActivity.java │ │ │ ├── ToDoItem.java │ │ │ ├── TodayFragment.java │ │ │ ├── Utils │ │ │ ├── MyDateTimeUtils.java │ │ │ ├── NotificationPublisher.java │ │ │ ├── SimpleDividerItemDecoration.java │ │ │ └── UpdateFirebase.java │ │ │ ├── WeekFragment.java │ │ │ └── viewholder │ │ │ └── FirebaseViewHolder.java │ └── res │ │ ├── drawable-hdpi-v11 │ │ └── ic_stat_name.png │ │ ├── drawable-hdpi-v9 │ │ └── ic_stat_name.png │ │ ├── drawable-hdpi │ │ ├── ic_access_alarms_white_36dp.png │ │ ├── ic_alarm_on_black_18dp.png │ │ ├── ic_alarm_on_white_36dp.png │ │ ├── ic_delete_sweep_white_24dp.png │ │ ├── ic_done_white_36dp.png │ │ ├── ic_email_black_18dp.png │ │ ├── ic_mode_edit_white_24dp.png │ │ ├── ic_plus_white_24dp.png │ │ ├── ic_stat_name.png │ │ └── ic_warning_black_24dp.png │ │ ├── drawable-mdpi-v11 │ │ └── ic_stat_name.png │ │ ├── drawable-mdpi-v9 │ │ └── ic_stat_name.png │ │ ├── drawable-mdpi │ │ ├── ic_access_alarms_white_36dp.png │ │ ├── ic_alarm_on_black_18dp.png │ │ ├── ic_alarm_on_white_36dp.png │ │ ├── ic_delete_sweep_white_24dp.png │ │ ├── ic_done_white_36dp.png │ │ ├── ic_email_black_18dp.png │ │ ├── ic_mode_edit_white_24dp.png │ │ ├── ic_plus_white_24dp.png │ │ ├── ic_stat_name.png │ │ └── ic_warning_black_24dp.png │ │ ├── drawable-xhdpi-v11 │ │ └── ic_stat_name.png │ │ ├── drawable-xhdpi-v9 │ │ └── ic_stat_name.png │ │ ├── drawable-xhdpi │ │ ├── ic_access_alarms_white_36dp.png │ │ ├── ic_alarm_on_black_18dp.png │ │ ├── ic_alarm_on_white_36dp.png │ │ ├── ic_delete_sweep_white_24dp.png │ │ ├── ic_done_white_36dp.png │ │ ├── ic_email_black_18dp.png │ │ ├── ic_mode_edit_white_24dp.png │ │ ├── ic_plus_white_24dp.png │ │ ├── ic_stat_name.png │ │ └── ic_warning_black_24dp.png │ │ ├── drawable-xxhdpi-v11 │ │ └── ic_stat_name.png │ │ ├── drawable-xxhdpi-v9 │ │ └── ic_stat_name.png │ │ ├── drawable-xxhdpi │ │ ├── ic_access_alarms_white_36dp.png │ │ ├── ic_alarm_on_black_18dp.png │ │ ├── ic_alarm_on_white_36dp.png │ │ ├── ic_delete_sweep_white_24dp.png │ │ ├── ic_done_white_36dp.png │ │ ├── ic_email_black_18dp.png │ │ ├── ic_mode_edit_white_24dp.png │ │ ├── ic_plus_white_24dp.png │ │ ├── ic_stat_name.png │ │ └── ic_warning_black_24dp.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_access_alarms_white_36dp.png │ │ ├── ic_alarm_on_black_18dp.png │ │ ├── ic_alarm_on_white_36dp.png │ │ ├── ic_delete_sweep_white_24dp.png │ │ ├── ic_done_white_36dp.png │ │ ├── ic_email_black_18dp.png │ │ ├── ic_mode_edit_white_24dp.png │ │ ├── ic_plus_white_24dp.png │ │ └── ic_warning_black_24dp.png │ │ ├── drawable │ │ ├── ic_facebook.png │ │ ├── ic_github.png │ │ ├── ic_patreon.png │ │ ├── ic_paypal.png │ │ ├── ic_twitter.png │ │ ├── inbox.webp │ │ ├── line_divider.xml │ │ ├── selector.xml │ │ ├── seven_day.webp │ │ ├── splash.webp │ │ ├── splash_screen.xml │ │ └── today.webp │ │ ├── layout-land │ │ └── activity_add_todo_item.xml │ │ ├── layout-sw600dp │ │ └── activity_main.xml │ │ ├── layout │ │ ├── activity_about.xml │ │ ├── activity_add_todo_item.xml │ │ ├── activity_detail.xml │ │ ├── activity_main.xml │ │ ├── activity_privacy.xml │ │ ├── fragment_detail.xml │ │ ├── fragment_page.xml │ │ ├── fragment_today.xml │ │ ├── fragment_week.xml │ │ └── todo_item.xml │ │ ├── menu │ │ └── menu_main_activity.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-ldpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-fr │ │ └── strings.xml │ │ ├── values-it │ │ └── strings.xml │ │ ├── values-pl │ │ └── strings.xml │ │ ├── values-pt │ │ └── strings.xml │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── device.xml │ └── test │ └── java │ └── luongvo │ └── com │ └── todolistminimal │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/markdown-navigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 36 | 37 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Photos/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/1.png -------------------------------------------------------------------------------- /Photos/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/10.png -------------------------------------------------------------------------------- /Photos/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/11.png -------------------------------------------------------------------------------- /Photos/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/12.png -------------------------------------------------------------------------------- /Photos/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/2.png -------------------------------------------------------------------------------- /Photos/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/3.png -------------------------------------------------------------------------------- /Photos/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/4.png -------------------------------------------------------------------------------- /Photos/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/5.png -------------------------------------------------------------------------------- /Photos/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/6.png -------------------------------------------------------------------------------- /Photos/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/7.png -------------------------------------------------------------------------------- /Photos/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/8.png -------------------------------------------------------------------------------- /Photos/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/9.png -------------------------------------------------------------------------------- /Photos/Minitask-feature-graphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/Minitask-feature-graphic.png -------------------------------------------------------------------------------- /Photos/minitask_land.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/Photos/minitask_land.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Minitask 2 | [![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.png?v=103)](https://github.com/ellerbrock/open-source-badges/) 3 | 4 | ![](./app/src/main/ic_launcher-web.png) 5 | 6 | ## About 7 | Minitask is a mini, lightweight (<5MB), and simple app for reminders/ todo list/ task management. The app is simple with very basic functions like task list, date time reminder and features a beautiful, efficient UI. I made Minitask while I was learning Android Development. There has been various apps of the same function on the PlayStore, but making this app enables me to sharpen my Android skills and implement my idea. 8 | Redlor: I am taking on the development of this app from November 2017. The aim is to switch to Firebase from SQLite and make some enhancements. I need help with issues in the Issues section and translations and any kind of suggestion are very welcome. 9 | 10 | ## Download 11 | 12 | Get it on Google Play 13 | 14 | Actually on Open Beta testing. 15 | 16 | 17 | ## Screenshot 18 | Drawing Drawing Drawing Drawing Drawing Drawing Drawing Drawing Drawing Drawing Drawing Drawing Drawing 19 | 20 | ## Contributing 21 | PRs and discussions are welcomed. Translation is also appreciated. 22 | 23 | Contributors: 24 | 25 | https://github.com/LewisVo (original developer) 26 | 27 | https://github.com/danielblokus 28 | 29 | Translations: 30 | 31 | Italian: https://github.com/redlor 32 | 33 | Polish: https://github.com/danielblokus 34 | 35 | French: https://github.com/Bradzer 36 | 37 | Portuguese: https://github.com/rickpms 38 | 39 | ## App icon credit 40 | https://www.flaticon.com/free-icon/startup_341435#term=rocket&page=2&position=33 41 | https://www.flaticon.com/free-icon/rocket_122111#term=rocket&page=2&position=62 42 | 43 | ## License 44 | Apache License Ver 2.0 45 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '26.0.2' 6 | defaultConfig { 7 | applicationId "redlor.it.minitask" 8 | minSdkVersion 16 9 | targetSdkVersion 26 10 | versionCode 5 11 | versionName "Beta 1.1" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.google.firebase:firebase-database:11.4.2' 28 | compile 'com.firebaseui:firebase-ui-database:3.1.0' 29 | compile 'com.google.firebase:firebase-auth:11.4.2' 30 | compile 'com.firebaseui:firebase-ui-auth:3.1.0' 31 | // compile 'com.facebook.android:facebook-android-sdk:4.14.1' 32 | 33 | 34 | 35 | 36 | 37 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 38 | compile 'com.jpardogo.materialtabstrip:library:1.1.1' 39 | 40 | compile 'com.android.support:appcompat-v7:26+' 41 | compile 'com.android.support:support-v4:26+' 42 | compile 'com.android.support:design:26+' 43 | 44 | 45 | compile 'com.jakewharton:butterknife:8.7.0' 46 | compile 'com.rengwuxian.materialedittext:library:2.1.4' 47 | compile 'com.wdullaer:materialdatetimepicker:3.4.0' 48 | 49 | implementation 'com.facebook.android:facebook-login:4.27.0' 50 | 51 | testCompile 'junit:junit:4.12' 52 | testCompile 'com.facebook.android:facebook-login:4.27.0' 53 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.7.0' 54 | } 55 | 56 | 57 | apply plugin: 'com.google.gms.google-services' -------------------------------------------------------------------------------- /app/google-services.json: -------------------------------------------------------------------------------- 1 | { 2 | "project_info": { 3 | "project_number": "422715163795", 4 | "firebase_url": "https://minitask-ba58f.firebaseio.com", 5 | "project_id": "minitask-ba58f", 6 | "storage_bucket": "minitask-ba58f.appspot.com" 7 | }, 8 | "client": [ 9 | { 10 | "client_info": { 11 | "mobilesdk_app_id": "1:422715163795:android:4f5551902bb0e252", 12 | "android_client_info": { 13 | "package_name": "redlor.it.minitask" 14 | } 15 | }, 16 | "oauth_client": [ 17 | { 18 | "client_id": "422715163795-30p402jee2ll016js3s59k03nen67fnj.apps.googleusercontent.com", 19 | "client_type": 1, 20 | "android_info": { 21 | "package_name": "redlor.it.minitask", 22 | "certificate_hash": "d2d65ecd6b1d5686e87b306e177100acce18b8f8" 23 | } 24 | }, 25 | { 26 | "client_id": "422715163795-fkjv8fpkat634vo8b36m7ql7ljn33m93.apps.googleusercontent.com", 27 | "client_type": 1, 28 | "android_info": { 29 | "package_name": "redlor.it.minitask", 30 | "certificate_hash": "f301baf1e430fab2db5020c9f88ef94fcff86c93" 31 | } 32 | }, 33 | { 34 | "client_id": "422715163795-vbjr8p32l9qqdu2hhfpjkl58d3cu0f76.apps.googleusercontent.com", 35 | "client_type": 3 36 | } 37 | ], 38 | "api_key": [ 39 | { 40 | "current_key": "AIzaSyAyrrrGR640oc8X32GQ8pm8ZFEiumwFjbw" 41 | } 42 | ], 43 | "services": { 44 | "analytics_service": { 45 | "status": 1 46 | }, 47 | "appinvite_service": { 48 | "status": 2, 49 | "other_platform_oauth_client": [ 50 | { 51 | "client_id": "422715163795-vbjr8p32l9qqdu2hhfpjkl58d3cu0f76.apps.googleusercontent.com", 52 | "client_type": 3 53 | } 54 | ] 55 | }, 56 | "ads_service": { 57 | "status": 2 58 | } 59 | } 60 | } 61 | ], 62 | "configuration_version": "1" 63 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/luongvo/Android/Sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/luongvo/com/todolistminimal/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package luongvo.com.todolistminimal; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("luongvo.com.todolistminimal", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/androidTest/java/luongvo/com/todolistminimal/Pages/AddTask.java: -------------------------------------------------------------------------------- 1 | package luongvo.com.todolistminimal.Pages; 2 | 3 | import luongvo.com.todolistminimal.R; 4 | 5 | import static android.support.test.espresso.Espresso.onView; 6 | import static android.support.test.espresso.action.ViewActions.click; 7 | import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; 8 | import static android.support.test.espresso.action.ViewActions.replaceText; 9 | import static android.support.test.espresso.assertion.ViewAssertions.matches; 10 | import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; 11 | import static android.support.test.espresso.matcher.ViewMatchers.withId; 12 | import static org.hamcrest.Matchers.allOf; 13 | import static org.hamcrest.Matchers.notNullValue; 14 | 15 | /** 16 | * Created by Daniel Blokus on 30.09.2017. 17 | */ 18 | 19 | public class AddTask { 20 | 21 | public static final String TASK_NAME = "test"; 22 | 23 | public AddTask() { 24 | onView(allOf(withId(R.id.todoInput))) 25 | .check(matches(notNullValue())) 26 | .check(matches(isDisplayed())); 27 | } 28 | 29 | public Home addTask() { 30 | isTaskNameInputDisplayed(); 31 | fillTaskName(); 32 | closeSoftKeyboard(); 33 | isAddButtonDisplayed(); 34 | clickAddButton(); 35 | return new Home(); 36 | } 37 | 38 | private void isTaskNameInputDisplayed() { 39 | onView(allOf(withId(R.id.todoEditText), isDisplayed())); 40 | } 41 | 42 | private void fillTaskName() { 43 | onView((withId(R.id.todoEditText))) 44 | .perform(replaceText(TASK_NAME)); 45 | } 46 | 47 | private void isAddButtonDisplayed() { 48 | onView(withId(R.id.addTodoBtn)) 49 | .check(matches(notNullValue())) 50 | .check(matches(isDisplayed())); 51 | } 52 | 53 | private void clickAddButton() { 54 | onView(withId(R.id.addTodoBtn)) 55 | .perform(click()); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /app/src/androidTest/java/luongvo/com/todolistminimal/Pages/Home.java: -------------------------------------------------------------------------------- 1 | package luongvo.com.todolistminimal.Pages; 2 | 3 | import luongvo.com.todolistminimal.R; 4 | 5 | import static android.support.test.espresso.Espresso.onView; 6 | import static android.support.test.espresso.action.ViewActions.click; 7 | import static android.support.test.espresso.assertion.ViewAssertions.matches; 8 | import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; 9 | import static android.support.test.espresso.matcher.ViewMatchers.withId; 10 | import static org.hamcrest.Matchers.allOf; 11 | import static org.hamcrest.Matchers.notNullValue; 12 | 13 | /** 14 | * Created by Daniel Blokus on 30.09.2017. 15 | */ 16 | 17 | public class Home { 18 | 19 | public Home(){ 20 | onView(allOf(withId(R.id.action_bar))) 21 | .check(matches(notNullValue())).check(matches(isDisplayed())); 22 | } 23 | 24 | public AddTask navigateToAddTask() { 25 | onView(allOf(withId(R.id.actionButton))).perform(click()); 26 | return new AddTask(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/androidTest/java/luongvo/com/todolistminimal/TasksTest.java: -------------------------------------------------------------------------------- 1 | package luongvo.com.todolistminimal; 2 | 3 | import android.support.test.rule.ActivityTestRule; 4 | import android.support.test.runner.AndroidJUnit4; 5 | 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import luongvo.com.todolistminimal.Pages.Home; 11 | 12 | import static luongvo.com.todolistminimal.Pages.AddTask.TASK_NAME; 13 | import static luongvo.com.todolistminimal.Utils.CustomAssertions.shouldDisplayNewTaskInTheList; 14 | 15 | /** 16 | * Created by Daniel Blokus on 30.09.2017. 17 | */ 18 | 19 | @RunWith(AndroidJUnit4.class) 20 | public class TasksTest { 21 | @Rule 22 | public ActivityTestRule mActivityTestRule = new ActivityTestRule<>(MainActivity.class); 23 | 24 | @Test 25 | public void createDefaultTask_ShouldDisplayHomeView() { 26 | new Home().navigateToAddTask().addTask(); 27 | shouldDisplayNewTaskInTheList(TASK_NAME); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/androidTest/java/luongvo/com/todolistminimal/Utils/CustomAssertions.java: -------------------------------------------------------------------------------- 1 | package luongvo.com.todolistminimal.Utils; 2 | 3 | import android.support.test.espresso.ViewInteraction; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import android.view.ViewParent; 7 | 8 | import org.hamcrest.Description; 9 | import org.hamcrest.Matcher; 10 | import org.hamcrest.TypeSafeMatcher; 11 | 12 | import luongvo.com.todolistminimal.R; 13 | 14 | import static android.support.test.espresso.Espresso.onView; 15 | import static android.support.test.espresso.assertion.ViewAssertions.matches; 16 | import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; 17 | import static android.support.test.espresso.matcher.ViewMatchers.withId; 18 | import static android.support.test.espresso.matcher.ViewMatchers.withText; 19 | import static org.hamcrest.Matchers.allOf; 20 | 21 | /** 22 | * Created by Daniel Blokus on 30.09.2017. 23 | */ 24 | 25 | public class CustomAssertions { 26 | 27 | public static void shouldDisplayNewTaskInTheList(String taskName) { 28 | ViewInteraction textView = onView( 29 | allOf(withId(R.id.todoContent), 30 | childAtPosition( 31 | allOf(withId(R.id.taskList), 32 | childAtPosition( 33 | withId(R.id.todoList), 34 | 0)), 35 | 1), 36 | isDisplayed())); 37 | textView.check(matches(withText(taskName))); 38 | } 39 | 40 | private static Matcher childAtPosition( 41 | final Matcher parentMatcher, final int position) { 42 | 43 | return new TypeSafeMatcher() { 44 | @Override 45 | public void describeTo(Description description) { 46 | description.appendText("Child at position " + position + " in parent "); 47 | parentMatcher.describeTo(description); 48 | } 49 | 50 | @Override 51 | public boolean matchesSafely(View view) { 52 | ViewParent parent = view.getParent(); 53 | return parent instanceof ViewGroup && parentMatcher.matches(parent) 54 | && view.equals(((ViewGroup) parent).getChildAt(position)); 55 | } 56 | }; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 16 | 17 | 19 | 20 | 21 | 22 | 23 | 24 | 27 | 28 | 29 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 43 | 44 | 45 | 47 | 48 | 50 | 51 | 52 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/AboutActivity.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | 6 | public class AboutActivity extends AppCompatActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | setTheme(R.style.AppTheme); 11 | super.onCreate(savedInstanceState); 12 | setContentView(R.layout.activity_about); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/Adapters/MyFragmentPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask.Adapters; 2 | 3 | import android.app.Activity; 4 | import android.support.v4.app.Fragment; 5 | import android.support.v4.app.FragmentManager; 6 | import android.support.v4.app.FragmentStatePagerAdapter; 7 | 8 | import redlor.it.minitask.PageFragment; 9 | import redlor.it.minitask.R; 10 | import redlor.it.minitask.TodayFragment; 11 | import redlor.it.minitask.WeekFragment; 12 | 13 | /** 14 | * Created by luongvo on 18/07/2017. 15 | */ 16 | 17 | public class MyFragmentPagerAdapter extends FragmentStatePagerAdapter { 18 | private static final int PAGE_COUNT = 3; 19 | 20 | private Activity myActivity; 21 | 22 | public MyFragmentPagerAdapter(FragmentManager fm, Activity activity) { 23 | super(fm); 24 | this.myActivity = activity; 25 | } 26 | 27 | @Override 28 | public Fragment getItem(int position) { 29 | switch (position) { 30 | case 0: 31 | PageFragment pageFragment = new PageFragment(); 32 | return pageFragment; 33 | case 1: 34 | TodayFragment todayFragment = new TodayFragment(); 35 | return todayFragment; 36 | case 2: 37 | WeekFragment weekFragment = new WeekFragment(); 38 | return weekFragment; 39 | default: 40 | return null; 41 | } 42 | } 43 | 44 | @Override 45 | public int getCount() { 46 | return PAGE_COUNT; 47 | } 48 | 49 | @Override 50 | public CharSequence getPageTitle(int position) { 51 | 52 | switch (position) { 53 | case 0: 54 | return myActivity.getString(R.string.inbox); 55 | case 1: 56 | return myActivity.getString(R.string.today); 57 | case 2: 58 | return myActivity.getString(R.string.next_7_days); 59 | } 60 | return null; 61 | 62 | } 63 | 64 | @Override 65 | public int getItemPosition(Object object) { 66 | return POSITION_NONE; 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/DetailActivity.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.FragmentManager; 7 | import android.support.v7.app.AppCompatActivity; 8 | 9 | /** 10 | * Created by Redlor on 26/11/2017. 11 | * This class replaces @ DetailTodoItem in order to implement a fragment for Dual Pane mode 12 | */ 13 | 14 | public class DetailActivity extends AppCompatActivity { 15 | 16 | String content; 17 | String reminder; 18 | Boolean hasReminder; 19 | Boolean done; 20 | String mItemId; 21 | 22 | @Override 23 | protected void onCreate(@Nullable Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_detail); 26 | 27 | getSupportActionBar().setTitle(getString(R.string.detail)); 28 | 29 | if (savedInstanceState == null) { 30 | DetailFragment detailFragment = new DetailFragment(); 31 | FragmentManager fragmentManager = getSupportFragmentManager(); 32 | 33 | getDataFromIntent(); 34 | 35 | // Send data to the DetailFragment 36 | Bundle bundle = new Bundle(); 37 | bundle.putString("content", content); 38 | bundle.putString("reminder", reminder); 39 | bundle.putBoolean("hasReminder", hasReminder); 40 | bundle.putBoolean("done", done); 41 | bundle.putString("itemId", mItemId); 42 | detailFragment.setArguments(bundle); 43 | 44 | fragmentManager.beginTransaction() 45 | .add(R.id.details_container, detailFragment) 46 | .commit(); 47 | 48 | } 49 | } 50 | 51 | private void getDataFromIntent() { 52 | // because we go from main activity to here 53 | Intent intent = getIntent(); 54 | content = intent.getStringExtra("content"); 55 | reminder = intent.getStringExtra("reminder"); 56 | hasReminder = intent.getExtras().getBoolean("hasReminder"); 57 | done = intent.getExtras().getBoolean("done"); 58 | mItemId = intent.getExtras().getString("itemId"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/DetailFragment.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask; 2 | 3 | import android.app.Activity; 4 | import android.app.Dialog; 5 | import android.content.DialogInterface; 6 | import android.content.Intent; 7 | import android.os.Bundle; 8 | import android.support.annotation.Nullable; 9 | import android.support.design.widget.FloatingActionButton; 10 | import android.support.v4.app.Fragment; 11 | import android.support.v7.app.AlertDialog; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.view.WindowManager; 16 | import android.widget.TextView; 17 | 18 | import butterknife.BindView; 19 | import butterknife.ButterKnife; 20 | import redlor.it.minitask.Utils.MyDateTimeUtils; 21 | import redlor.it.minitask.Utils.UpdateFirebase; 22 | 23 | /** 24 | * Created by Redlor on 26/11/2017. 25 | * This Fragment shows the details of an item. 26 | * In dual pane it is placed next to MainActivity 27 | */ 28 | 29 | public class DetailFragment extends Fragment { 30 | 31 | @BindView(R.id.todoInfo) 32 | TextView todoInfo; 33 | @BindView(R.id.reminderInfo) 34 | TextView reminderInfo; 35 | @BindView(R.id.editTodoBtn) 36 | FloatingActionButton editTodo; 37 | @BindView(R.id.deleteTodoBtn) 38 | FloatingActionButton deleteTodo; 39 | 40 | String content; 41 | String reminder; 42 | Boolean hasReminder = true; 43 | Boolean done = false; 44 | String mItemId; 45 | 46 | MyDateTimeUtils dateTimeUtils; // util to do stuffs with notification 47 | 48 | // Declare the class with Firebase methods 49 | UpdateFirebase updateFirebase; 50 | 51 | ToDoItem currentToDoItem; 52 | private long oldRowId; 53 | 54 | /** 55 | * Mandatory empty constructor for the fragment manager to instantiate the fragment 56 | */ 57 | public DetailFragment() { 58 | } 59 | 60 | // Prevent dialog dismiss when orientation changes. 61 | private static void doKeepDialog(Dialog dialog) { 62 | WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 63 | lp.copyFrom(dialog.getWindow().getAttributes()); 64 | lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 65 | lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 66 | dialog.getWindow().setAttributes(lp); 67 | } 68 | 69 | @Nullable 70 | @Override 71 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 72 | getActivity().getSupportFragmentManager().beginTransaction().attach(this).commit(); 73 | if (container == null) { 74 | return null; 75 | } 76 | // If the is rotated, get the existing data 77 | if (savedInstanceState != null) { 78 | content = savedInstanceState.getString("currentContent"); 79 | reminder = savedInstanceState.getString("currentReminder"); 80 | hasReminder = savedInstanceState.getBoolean("currenthasReminder"); 81 | done = savedInstanceState.getBoolean("currentDone"); 82 | mItemId = savedInstanceState.getString("currentItemId"); 83 | 84 | // Otherwise get the data from the DetailActivity 85 | } else { 86 | Bundle bundle = new Bundle(); 87 | bundle = getArguments(); 88 | if (bundle != null) { 89 | content = bundle.getString("content"); 90 | reminder = bundle.getString("reminder"); 91 | hasReminder = bundle.getBoolean("hasReminder"); 92 | done = bundle.getBoolean("done"); 93 | mItemId = bundle.getString("itemId"); 94 | } 95 | } 96 | 97 | View rootView = inflater.inflate(R.layout.fragment_detail, container, false); 98 | ButterKnife.bind(this, rootView); 99 | 100 | dateTimeUtils = new MyDateTimeUtils(); 101 | assignComponents(); 102 | 103 | return rootView; 104 | } 105 | 106 | private void assignComponents() { 107 | // update UI with the content taken from intent 108 | todoInfo.setText(content); 109 | 110 | if (hasReminder) 111 | reminderInfo.setText(reminder); 112 | else reminderInfo.setText(getString(R.string.not_found)); 113 | // if edit button is press fire add activity with a little tweak 114 | 115 | if (content == null) { 116 | deleteTodo.setClickable(false); 117 | editTodo.setClickable(false); 118 | } else { 119 | // if delete is pressed then delete item in database and also remove object for notifydatsetchanged 120 | deleteTodo.setOnClickListener(new View.OnClickListener() { 121 | @Override 122 | public void onClick(View v) { 123 | AlertDialog alertDialog = new AlertDialog.Builder(getContext()) 124 | .setIcon(android.R.drawable.ic_menu_delete) 125 | .setTitle(R.string.delete) 126 | .setMessage(R.string.delete_single_task_message) 127 | .setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() { 128 | @Override 129 | public void onClick(DialogInterface dialog, int which) { 130 | // Toast.makeText(getActivity(), R.string.item_deleted, Toast.LENGTH_SHORT).show(); 131 | 132 | ToDoItem toDoItem = new ToDoItem(content, done, reminder, hasReminder, mItemId); 133 | 134 | // remove existing scheduled notification if existed 135 | if (!reminder.equals(" ")) 136 | dateTimeUtils.cancelScheduledNotification(dateTimeUtils.getNotification(content, getContext()), 137 | getContext(), (int) oldRowId); 138 | 139 | updateFirebase = new UpdateFirebase(); 140 | updateFirebase.deleteItem(toDoItem); 141 | 142 | Activity a = getActivity(); 143 | if (a != null) { 144 | // This intent is for the dual pane mode, to refresh the UI 145 | a.startActivity(new Intent(getContext(), MainActivity.class)); 146 | a.overridePendingTransition(0, 0); 147 | } else { 148 | getActivity().getSupportFragmentManager().isDestroyed(); 149 | } 150 | 151 | } 152 | }) 153 | .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 154 | @Override 155 | public void onClick(DialogInterface dialog, int which) { 156 | if (dialog != null) { 157 | dialog.dismiss(); 158 | } 159 | } 160 | }).create(); 161 | alertDialog.show(); 162 | doKeepDialog(alertDialog); 163 | } 164 | 165 | 166 | /* Toast.makeText(getActivity(), getString(R.string.item_deleted), Toast.LENGTH_SHORT).show(); 167 | ToDoItem toDoItem = new ToDoItem(content, done, reminder, hasReminder, mItemId); 168 | 169 | // remove existing scheduled notification if existed 170 | if (!reminder.equals(" ")) 171 | dateTimeUtils.cancelScheduledNotification(dateTimeUtils.getNotification(content, getContext()), 172 | getContext(), (int) oldRowId); 173 | 174 | // Instantiate a new UpdateFirebase class 175 | updateFirebase = new UpdateFirebase(); 176 | // **New** Delete the item from Firebase Database 177 | updateFirebase.deleteItem(toDoItem); 178 | getActivity().finish(); 179 | 180 | // This intent is for the dual pane mode, to refresh the UI 181 | getActivity().startActivity(new Intent(v.getContext(), MainActivity.class)); 182 | getActivity().overridePendingTransition(0, 0);*/ 183 | 184 | }); 185 | 186 | editTodo.setOnClickListener(new View.OnClickListener() { 187 | @Override 188 | public void onClick(View v) { 189 | Intent intent = new Intent(getContext(), AddTodoItem.class); 190 | intent.putExtra("item", currentToDoItem); 191 | intent.putExtra("content", content); 192 | intent.putExtra("reminder", reminder); 193 | intent.putExtra("hasReminder", hasReminder); 194 | intent.putExtra("done", done); 195 | intent.putExtra("id", mItemId); 196 | getActivity().finish(); 197 | startActivity(intent); 198 | } 199 | }); 200 | } 201 | } 202 | 203 | // Save the current state 204 | @Override 205 | public void onSaveInstanceState(Bundle currentState) { 206 | currentState.putString("currentContent", content); 207 | currentState.putString("currentReminder", reminder); 208 | currentState.putBoolean("currenthasReminder", hasReminder); 209 | currentState.putBoolean("currentDone", done); 210 | currentState.putString("currentItemId", mItemId); 211 | 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/PageFragment.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask; 2 | 3 | import android.content.Intent; 4 | import android.graphics.Paint; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v4.app.Fragment; 8 | import android.support.v4.app.FragmentManager; 9 | import android.support.v4.app.FragmentTransaction; 10 | import android.support.v7.widget.LinearLayoutManager; 11 | import android.support.v7.widget.RecyclerView; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.view.animation.Animation; 16 | import android.view.animation.LinearInterpolator; 17 | import android.view.animation.TranslateAnimation; 18 | import android.widget.CompoundButton; 19 | import android.widget.Toast; 20 | 21 | import com.firebase.ui.database.FirebaseRecyclerAdapter; 22 | import com.firebase.ui.database.FirebaseRecyclerOptions; 23 | import com.google.firebase.auth.FirebaseAuth; 24 | import com.google.firebase.auth.FirebaseUser; 25 | import com.google.firebase.database.DatabaseReference; 26 | import com.google.firebase.database.FirebaseDatabase; 27 | import com.google.firebase.database.Query; 28 | 29 | import java.text.SimpleDateFormat; 30 | import java.util.Calendar; 31 | import java.util.HashMap; 32 | 33 | import redlor.it.minitask.Utils.SimpleDividerItemDecoration; 34 | import redlor.it.minitask.viewholder.FirebaseViewHolder; 35 | 36 | import static redlor.it.minitask.MainActivity.mTwoPane; 37 | 38 | 39 | public class PageFragment extends Fragment { 40 | 41 | DatabaseReference mDatabaseReference; 42 | FirebaseRecyclerAdapter mFirebaseAdapter; 43 | private RecyclerView mRecyclerView; 44 | private View view; 45 | private Toast mToast; 46 | 47 | 48 | @Override 49 | public void onCreate(@Nullable Bundle savedInstanceState) { 50 | super.onCreate(savedInstanceState); 51 | 52 | } 53 | 54 | @Nullable 55 | @Override 56 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 57 | // inflate the tab view with these fragments 58 | view = inflater.inflate(R.layout.fragment_page, container, false); 59 | return view; 60 | } 61 | 62 | @Override 63 | public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) { 64 | super.onViewCreated(view, savedInstanceState); 65 | 66 | FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); 67 | String uid = firebaseUser.getUid(); 68 | 69 | mDatabaseReference = FirebaseDatabase.getInstance().getReference("users").child(uid).child("toDoItems"); 70 | mDatabaseReference.keepSynced(true); 71 | 72 | final Query query = FirebaseDatabase.getInstance() 73 | .getReference("users") 74 | .child(uid) 75 | .child("toDoItems") 76 | .limitToLast(50); 77 | 78 | FirebaseRecyclerOptions options = 79 | new FirebaseRecyclerOptions.Builder() 80 | .setQuery(query, ToDoItem.class) 81 | .build(); 82 | 83 | mFirebaseAdapter = new FirebaseRecyclerAdapter(options 84 | ) { 85 | 86 | @Override 87 | public FirebaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 88 | View view = LayoutInflater.from(parent.getContext()) 89 | .inflate(R.layout.todo_item, parent, false); 90 | return new FirebaseViewHolder(view); 91 | } 92 | 93 | @Override 94 | protected void onBindViewHolder(final FirebaseViewHolder viewHolder, final int position, final ToDoItem toDoItem) { 95 | // set the content of the item 96 | viewHolder.content.setText(toDoItem.getContent()); 97 | // set the checkbox status of the item 98 | viewHolder.checkDone.setChecked(toDoItem.getDone()); 99 | // check if checkbox is checked, then strike through the text 100 | // this is for the first time UI render 101 | if (viewHolder.checkDone.isChecked()) { 102 | viewHolder.content.setPaintFlags(viewHolder.content.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); 103 | } else { 104 | viewHolder.content.setPaintFlags(viewHolder.content.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG)); 105 | } 106 | // render the clock icon if the item has a reminder 107 | // and add a animation for expired item 108 | if (toDoItem.getHasReminder()) { 109 | viewHolder.clockReminder.setVisibility(View.VISIBLE); 110 | Calendar c = Calendar.getInstance(); 111 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 112 | String currentDateTime = sdf.format(c.getTime()); 113 | if (currentDateTime.compareTo(toDoItem.getReminderDate()) > 0) { 114 | TranslateAnimation animation = new TranslateAnimation(0, 0, 0, 6); 115 | animation.setDuration(400); 116 | animation.setInterpolator(new LinearInterpolator()); 117 | animation.setRepeatCount(Animation.INFINITE); 118 | viewHolder.clockReminder.setAnimation(animation); 119 | } 120 | } else { 121 | viewHolder.clockReminder.setVisibility(View.INVISIBLE); 122 | } 123 | 124 | viewHolder.checkDone.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 125 | @Override 126 | public void onCheckedChanged(CompoundButton compoundButton, final boolean b) { 127 | final String id = mFirebaseAdapter.getRef(position).getKey(); 128 | 129 | if (b) { 130 | toDoItem.setDone(true); 131 | HashMap map = new HashMap<>(); 132 | map.put("done", true); 133 | mDatabaseReference.child(id).updateChildren(map); 134 | viewHolder.checkDone.setOnCheckedChangeListener(null); 135 | 136 | } else { 137 | toDoItem.setDone(false); 138 | HashMap map = new HashMap<>(); 139 | map.put("done", false); 140 | mDatabaseReference.child(id).updateChildren(map); 141 | viewHolder.checkDone.setOnCheckedChangeListener(null); 142 | 143 | } 144 | } 145 | }); 146 | 147 | viewHolder.setOnClickListener(new FirebaseViewHolder.ClickListener() { 148 | @Override 149 | public void onItemClick(View view, int position) { 150 | final String itemId = mFirebaseAdapter.getRef(position).getKey(); 151 | if (mTwoPane) { 152 | DetailFragment newDetailFragment = new DetailFragment(); 153 | FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 154 | Bundle bundle = new Bundle(); 155 | bundle.putString("content", toDoItem.getContent()); 156 | bundle.putString("reminder", toDoItem.getReminderDate()); 157 | bundle.putBoolean("hasReminder", toDoItem.getHasReminder()); 158 | bundle.putBoolean("done", toDoItem.getDone()); 159 | bundle.putString("itemId", itemId); 160 | newDetailFragment.setArguments(bundle); 161 | 162 | fragmentManager.beginTransaction() 163 | .replace(R.id.details_container, newDetailFragment) 164 | .detach(newDetailFragment) 165 | .attach(newDetailFragment) 166 | .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) 167 | .commit(); 168 | } else { 169 | Intent intent = new Intent(getContext(), DetailActivity.class); 170 | intent.putExtra("content", toDoItem.getContent()); 171 | intent.putExtra("reminder", toDoItem.getReminderDate()); 172 | intent.putExtra("hasReminder", toDoItem.getHasReminder()); 173 | intent.putExtra("done", toDoItem.getDone()); 174 | intent.putExtra("itemId", itemId); 175 | System.out.println("id in page fragment: " + itemId); 176 | startActivity(intent); 177 | } 178 | } 179 | 180 | @Override 181 | public void onItemLongClick(View view, int position) { 182 | if (mToast != null) { 183 | mToast.cancel(); 184 | } 185 | boolean hasReminder = toDoItem.getHasReminder(); 186 | if (hasReminder) { 187 | String reminder = toDoItem.getReminderDate(); 188 | mToast = Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.reminder_info) + " " + reminder, Toast.LENGTH_SHORT); 189 | mToast.show(); 190 | } else { 191 | mToast = Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.no_reminder), Toast.LENGTH_SHORT); 192 | mToast.show(); 193 | } 194 | } 195 | }); 196 | } 197 | }; 198 | 199 | mRecyclerView = (RecyclerView) view.findViewById(R.id.to_do_list); 200 | mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 201 | mRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getContext())); 202 | mRecyclerView.setAdapter(mFirebaseAdapter); 203 | 204 | } 205 | 206 | @Override 207 | public void onStop() { 208 | super.onStop(); 209 | mFirebaseAdapter.stopListening(); 210 | 211 | } 212 | 213 | @Override 214 | public void onStart() { 215 | super.onStart(); 216 | mFirebaseAdapter.startListening(); 217 | } 218 | 219 | @Override 220 | public void onResume() { 221 | super.onResume(); 222 | } 223 | 224 | } 225 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/PrivacyActivity.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | 6 | public class PrivacyActivity extends AppCompatActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | setTheme(R.style.AppTheme); 11 | super.onCreate(savedInstanceState); 12 | setContentView(R.layout.activity_privacy); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/ToDoItem.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask; 2 | 3 | import com.google.firebase.database.Exclude; 4 | 5 | import java.io.Serializable; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /** 10 | * Created by luongvo on 19/07/2017. 11 | */ 12 | 13 | public class ToDoItem implements Serializable { 14 | public Map toDoItemsMap = new HashMap<>(); 15 | private String content; 16 | private boolean done; 17 | private String reminderDate; 18 | private boolean hasReminder; 19 | private String mItemId; 20 | 21 | // Old constructor 22 | public ToDoItem(String content, boolean done, boolean hasReminder, String reminderDate) { 23 | this.content = content; 24 | this.done = done; 25 | this.hasReminder = hasReminder; 26 | this.reminderDate = reminderDate; 27 | 28 | } 29 | 30 | public ToDoItem() { 31 | } 32 | 33 | // New constructor with Firebase Id variable 34 | public ToDoItem(String content, boolean done, String reminderDate, boolean hasReminder, String itemId) { 35 | this.content = content; 36 | this.done = done; 37 | this.reminderDate = reminderDate; 38 | this.hasReminder = hasReminder; 39 | this.mItemId = itemId; 40 | } 41 | 42 | 43 | public boolean getHasReminder() { 44 | return hasReminder; 45 | } 46 | 47 | public String getContent() { 48 | return content; 49 | } 50 | 51 | public void setContent(String content) { 52 | this.content = content; 53 | } 54 | 55 | public boolean getDone() { 56 | return done; 57 | } 58 | 59 | public void setDone(Boolean done) { 60 | this.done = done; 61 | } 62 | 63 | public String getReminderDate() { 64 | return reminderDate; 65 | } 66 | 67 | public String getItemId() { 68 | return mItemId; 69 | } 70 | 71 | public void setItemId(String mItemId) { 72 | this.mItemId = mItemId; 73 | } 74 | 75 | // compare object for remove from array list 76 | @Override 77 | public boolean equals(Object obj) { 78 | if (this == obj) 79 | return true; 80 | if (obj == null) 81 | return false; 82 | if (getClass() != obj.getClass()) 83 | return false; 84 | ToDoItem other = (ToDoItem) obj; 85 | if (!content.equals(other.content)) 86 | return false; 87 | if (!reminderDate.equals(other.reminderDate)) 88 | return false; 89 | if (hasReminder != other.hasReminder) 90 | return false; 91 | if (done != other.done) 92 | return false; 93 | return true; 94 | } 95 | 96 | @Override 97 | public String toString() { 98 | return "ToDoItem{" + 99 | "content='" + content + '\'' + 100 | ", done=" + done + 101 | ", reminderDate='" + reminderDate + '\'' + 102 | ", hasReminder=" + hasReminder + 103 | ", mItemId='" + mItemId + '\'' + 104 | '}'; 105 | } 106 | 107 | @Exclude 108 | public Map toMap() { 109 | HashMap result = new HashMap<>(); 110 | result.put("content", content); 111 | result.put("done", done); 112 | result.put("hasReminder", hasReminder); 113 | result.put("reminderDate", reminderDate); 114 | 115 | return result; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/TodayFragment.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask; 2 | 3 | import android.content.Intent; 4 | import android.graphics.Paint; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v4.app.Fragment; 8 | import android.support.v4.app.FragmentManager; 9 | import android.support.v4.app.FragmentTransaction; 10 | import android.support.v7.widget.LinearLayoutManager; 11 | import android.support.v7.widget.RecyclerView; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.widget.CompoundButton; 16 | import android.widget.Toast; 17 | 18 | import com.firebase.ui.database.FirebaseRecyclerAdapter; 19 | import com.firebase.ui.database.FirebaseRecyclerOptions; 20 | import com.google.firebase.auth.FirebaseAuth; 21 | import com.google.firebase.auth.FirebaseUser; 22 | import com.google.firebase.database.DatabaseReference; 23 | import com.google.firebase.database.FirebaseDatabase; 24 | import com.google.firebase.database.Query; 25 | 26 | import java.text.SimpleDateFormat; 27 | import java.util.Calendar; 28 | import java.util.Date; 29 | import java.util.HashMap; 30 | 31 | import redlor.it.minitask.Utils.SimpleDividerItemDecoration; 32 | import redlor.it.minitask.viewholder.FirebaseViewHolder; 33 | 34 | import static redlor.it.minitask.MainActivity.mTwoPane; 35 | 36 | 37 | public class TodayFragment extends Fragment { 38 | 39 | 40 | DatabaseReference mDatabaseReference; 41 | FirebaseRecyclerAdapter mFirebaseAdapter; 42 | Date today; 43 | String day; 44 | String myDay; 45 | private RecyclerView mRecyclerView; 46 | private View view; 47 | private Toast mToast; 48 | 49 | @Override 50 | public void onCreate(@Nullable Bundle savedInstanceState) { 51 | super.onCreate(savedInstanceState); 52 | setRetainInstance(true); 53 | } 54 | 55 | 56 | @Nullable 57 | @Override 58 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 59 | // inflate the tab view with these fragments 60 | view = inflater.inflate(R.layout.fragment_today, container, false); 61 | return view; 62 | 63 | } 64 | 65 | @Override 66 | public void setUserVisibleHint(boolean isVisibleToUser) { 67 | super.setUserVisibleHint(isVisibleToUser); 68 | if (isVisibleToUser) { 69 | 70 | firebaseLoadToday(); 71 | 72 | } 73 | } 74 | 75 | @Override 76 | public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) { 77 | super.onViewCreated(view, savedInstanceState); 78 | } 79 | 80 | 81 | @Override 82 | public void onStop() { 83 | super.onStop(); 84 | try { 85 | mFirebaseAdapter.stopListening(); 86 | } catch (Exception e) { 87 | e.getStackTrace(); 88 | } 89 | 90 | } 91 | 92 | @Override 93 | public void onStart() { 94 | super.onStart(); 95 | 96 | 97 | } 98 | 99 | @Override 100 | public void onResume() { 101 | super.onResume(); 102 | } 103 | 104 | private void firebaseLoadToday() { 105 | FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); 106 | final String uid = firebaseUser.getUid(); 107 | 108 | mDatabaseReference = FirebaseDatabase.getInstance().getReference("users").child(uid).child("toDoItems"); 109 | mDatabaseReference.keepSynced(true); 110 | 111 | final Query query = FirebaseDatabase.getInstance() 112 | .getReference("users") 113 | .child(uid) 114 | .child("toDoItems") 115 | .limitToLast(50); 116 | 117 | final FirebaseRecyclerOptions options = 118 | new FirebaseRecyclerOptions.Builder() 119 | .setQuery(query, ToDoItem.class) 120 | .build(); 121 | mFirebaseAdapter = new FirebaseRecyclerAdapter(options 122 | ) { 123 | @Override 124 | public FirebaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 125 | View view = LayoutInflater.from(parent.getContext()) 126 | .inflate(R.layout.todo_item, parent, false); 127 | return new FirebaseViewHolder(view); 128 | } 129 | 130 | 131 | @Override 132 | protected void onBindViewHolder(final FirebaseViewHolder viewHolder, final int position, final ToDoItem toDoItem) { 133 | boolean hasReminder = toDoItem.getHasReminder(); 134 | Calendar calendar = Calendar.getInstance(); 135 | today = calendar.getTime(); 136 | SimpleDateFormat myFormat = new SimpleDateFormat("yyyy-MM-dd"); 137 | myDay = myFormat.format(today); 138 | String completeTime = toDoItem.getReminderDate(); 139 | if (completeTime != null && !completeTime.equals(" ")) { 140 | String[] parts = completeTime.split(" "); 141 | day = parts[0]; 142 | } 143 | 144 | if (hasReminder && myDay.equals(day)) { 145 | boolean todayB = true; 146 | System.out.println(myDay + " " + day); 147 | // set the content of the item 148 | viewHolder.content.setText(toDoItem.getContent()); 149 | // set the checkbox status of the item 150 | viewHolder.checkDone.setChecked(toDoItem.getDone()); 151 | // check if checkbox is checked, then strike through the text 152 | // this is for the first time UI render 153 | if (viewHolder.checkDone.isChecked()) { 154 | viewHolder.content.setPaintFlags(viewHolder.content.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); 155 | } else { 156 | viewHolder.content.setPaintFlags(viewHolder.content.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG)); 157 | 158 | } 159 | // render the clock icon if the item has a reminder 160 | if (toDoItem.getHasReminder()) 161 | viewHolder.clockReminder.setVisibility(View.VISIBLE); 162 | else 163 | viewHolder.clockReminder.setVisibility(View.INVISIBLE); 164 | 165 | viewHolder.checkDone.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 166 | @Override 167 | public void onCheckedChanged(CompoundButton compoundButton, final boolean b) { 168 | final String id = mFirebaseAdapter.getRef(position).getKey(); 169 | 170 | if (b) { 171 | toDoItem.setDone(true); 172 | HashMap map = new HashMap<>(); 173 | map.put("done", true); 174 | mDatabaseReference.child(id).updateChildren(map); 175 | viewHolder.checkDone.setOnCheckedChangeListener(null); 176 | 177 | } else { 178 | toDoItem.setDone(false); 179 | HashMap map = new HashMap<>(); 180 | map.put("done", false); 181 | mDatabaseReference.child(id).updateChildren(map); 182 | viewHolder.checkDone.setOnCheckedChangeListener(null); 183 | 184 | } 185 | } 186 | }); 187 | 188 | viewHolder.setOnClickListener(new FirebaseViewHolder.ClickListener() { 189 | @Override 190 | public void onItemClick(View view, int position) { 191 | final String itemId = mFirebaseAdapter.getRef(position).getKey(); 192 | if (mTwoPane) { 193 | DetailFragment newDetailFragment = new DetailFragment(); 194 | FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 195 | Bundle bundle = new Bundle(); 196 | bundle.putString("content", toDoItem.getContent()); 197 | bundle.putString("reminder", toDoItem.getReminderDate()); 198 | bundle.putBoolean("hasReminder", toDoItem.getHasReminder()); 199 | bundle.putBoolean("done", toDoItem.getDone()); 200 | bundle.putString("itemId", itemId); 201 | newDetailFragment.setArguments(bundle); 202 | 203 | fragmentManager.beginTransaction() 204 | .replace(R.id.details_container, newDetailFragment) 205 | .detach(newDetailFragment) 206 | .attach(newDetailFragment) 207 | .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) 208 | .commit(); 209 | } else { 210 | Intent intent = new Intent(getContext(), DetailActivity.class); 211 | intent.putExtra("content", toDoItem.getContent()); 212 | intent.putExtra("reminder", toDoItem.getReminderDate()); 213 | intent.putExtra("hasReminder", toDoItem.getHasReminder()); 214 | intent.putExtra("done", toDoItem.getDone()); 215 | intent.putExtra("itemId", itemId); 216 | startActivity(intent); 217 | } 218 | } 219 | 220 | @Override 221 | public void onItemLongClick(View view, int position) { 222 | if (mToast != null) { 223 | mToast.cancel(); 224 | } 225 | String reminder = toDoItem.getReminderDate(); 226 | mToast = Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.reminder_info) + " " + reminder, Toast.LENGTH_LONG); 227 | mToast.show(); 228 | } 229 | }); 230 | 231 | 232 | } else { 233 | viewHolder.LayoutHide(); 234 | } 235 | 236 | } 237 | }; 238 | 239 | mRecyclerView = (RecyclerView) view.findViewById(R.id.to_do_list_today); 240 | mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 241 | mRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getContext())); 242 | mRecyclerView.setAdapter(mFirebaseAdapter); 243 | mFirebaseAdapter.startListening(); 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/Utils/MyDateTimeUtils.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask.Utils; 2 | 3 | import android.app.AlarmManager; 4 | import android.app.Notification; 5 | import android.app.PendingIntent; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.graphics.BitmapFactory; 9 | import android.support.v4.app.NotificationCompat; 10 | 11 | import java.text.ParseException; 12 | import java.text.SimpleDateFormat; 13 | import java.util.Calendar; 14 | import java.util.Date; 15 | 16 | import redlor.it.minitask.MainActivity; 17 | import redlor.it.minitask.R; 18 | 19 | import static redlor.it.minitask.Utils.NotificationPublisher.NOTIFICATION; 20 | import static redlor.it.minitask.Utils.NotificationPublisher.NOTIFICATION_ID; 21 | 22 | 23 | // This class includes every helper function that relates to time 24 | public class MyDateTimeUtils { 25 | 26 | // Three simpledateformat for each specific use 27 | private SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); 28 | private SimpleDateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss"); 29 | private SimpleDateFormat dateTimeFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 30 | 31 | /* This return a formatted date if the parameter passed in is empty. 32 | It is used in case the user select the "set time" option without first "set date". 33 | The default date is today. 34 | We can have a equivalent fillTimeIfEmpty but I decided not to implement that 35 | Because time range is wider so it's hard to choose 1 point of time as default.*/ 36 | public String fillDateIfEmpty(String date) { 37 | if (date.equals("")) { 38 | Calendar calendar = Calendar.getInstance(); 39 | return dateFormatter.format(calendar.getTime()); 40 | } else return date; 41 | } 42 | 43 | /*This returns a date string with passed-in integer year, months, dayofmonth.*/ 44 | public String dateToString(int year, int monthOfYear, int dayOfMonth) { 45 | Calendar calendar = Calendar.getInstance(); 46 | calendar.set(year, monthOfYear, dayOfMonth); 47 | return dateFormatter.format(calendar.getTime()); 48 | } 49 | 50 | /*This returns a time string with passed-in integer year, months, dayofmonth.*/ 51 | public String timeToString(int hourOfDay, int minute) { 52 | Calendar calendar = Calendar.getInstance(); 53 | calendar.set(0, 0, 0, hourOfDay, minute); 54 | return timeFormatter.format(calendar.getTime()); 55 | } 56 | 57 | /* this check if a date user chooses is not in the past by comparing to current date*/ 58 | public boolean checkInvalidDate(int year, int monthOfYear, int dayOfMonth) { 59 | Calendar calendar = Calendar.getInstance(); 60 | Date today = calendar.getTime(); 61 | calendar.set(year, monthOfYear, dayOfMonth); 62 | Date dateSet = calendar.getTime(); 63 | return (today.compareTo(dateSet) > 0); 64 | } 65 | 66 | /* This check if a time user chooses is not in the past by comparing to current time */ 67 | public boolean checkInvalidTime(int hourOfDay, int minute) { 68 | Calendar calendar = Calendar.getInstance(); 69 | int nowHour = calendar.get(Calendar.HOUR_OF_DAY); 70 | int nowMinute = calendar.get(Calendar.MINUTE); 71 | return (hourOfDay < nowHour || (hourOfDay == nowHour && minute <= nowMinute)); 72 | } 73 | 74 | /* this schedule notification to the time that user set*/ 75 | public void ScheduleNotification(Notification notification, 76 | Context context, int notificationID, String dateTime) { 77 | Intent notificationIntent = new Intent(context, NotificationPublisher.class); 78 | notificationIntent.putExtra(NOTIFICATION_ID, notificationID); 79 | notificationIntent.putExtra(NOTIFICATION, notification); 80 | PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); 81 | // parse string parameter to milliseconds for later alarm set 82 | Date futureInMillis = null; 83 | try { 84 | futureInMillis = dateTimeFormatter.parse(dateTime); 85 | } catch (ParseException e) { 86 | e.printStackTrace(); 87 | } 88 | AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 89 | alarmManager.set(AlarmManager.RTC_WAKEUP, futureInMillis.getTime(), pendingIntent); 90 | } 91 | 92 | /* this cancel a future notification if item is deleted or editted */ 93 | public void cancelScheduledNotification(Notification notification, 94 | Context context, int notificationID) { 95 | Intent notificationIntent = new Intent(context, NotificationPublisher.class); 96 | notificationIntent.putExtra(NOTIFICATION_ID, notificationID); 97 | notificationIntent.putExtra(NOTIFICATION, notification); 98 | PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); 99 | AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 100 | alarmManager.cancel(pendingIntent); 101 | } 102 | 103 | /* This is a helper function to build a notification object */ 104 | public Notification getNotification(String content, Context context) { 105 | Intent intent = new Intent(context, MainActivity.class); 106 | PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); 107 | 108 | NotificationCompat.Builder builder = new NotificationCompat.Builder(context); 109 | builder.setContentTitle(context.getString(R.string.task_to_be_done)); 110 | builder.setContentText(content); 111 | builder.setSmallIcon(R.drawable.ic_stat_name); 112 | builder.setDefaults(Notification.DEFAULT_ALL); 113 | builder.setPriority(Notification.PRIORITY_MAX); 114 | builder.setStyle(new NotificationCompat.BigTextStyle().bigText(content)); 115 | builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), 116 | R.mipmap.ic_launcher)); 117 | builder.setContentIntent(pendingIntent); 118 | builder.setShowWhen(false); 119 | builder.setAutoCancel(true); 120 | return builder.build(); 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/Utils/NotificationPublisher.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask.Utils; 2 | 3 | /** 4 | * Created by luongvo on 26/07/2017. 5 | */ 6 | 7 | import android.app.Notification; 8 | import android.app.NotificationManager; 9 | import android.content.BroadcastReceiver; 10 | import android.content.Context; 11 | import android.content.Intent; 12 | 13 | // This class manage notification publishing 14 | public class NotificationPublisher extends BroadcastReceiver { 15 | 16 | public static String NOTIFICATION_ID = "notification-id"; 17 | public static String NOTIFICATION = "notification"; 18 | 19 | public void onReceive(Context context, Intent intent) { 20 | 21 | NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 22 | 23 | Notification notification = intent.getParcelableExtra(NOTIFICATION); 24 | int id = intent.getIntExtra(NOTIFICATION_ID, 0); 25 | notificationManager.notify(id, notification); 26 | 27 | 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/Utils/SimpleDividerItemDecoration.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask.Utils; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.drawable.Drawable; 6 | import android.support.v4.content.ContextCompat; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.View; 9 | 10 | import redlor.it.minitask.R; 11 | 12 | 13 | /** 14 | * Created by Redlor on 25/11/2017. 15 | * This class implements a divider for the items in the RecyclerView. 16 | */ 17 | 18 | public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration { 19 | private Drawable mDivider; 20 | 21 | public SimpleDividerItemDecoration(Context context) { 22 | mDivider = ContextCompat.getDrawable(context, R.drawable.line_divider); 23 | } 24 | 25 | @Override 26 | public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { 27 | int left = parent.getPaddingLeft(); 28 | int right = parent.getWidth() - parent.getPaddingRight(); 29 | 30 | int childCount = parent.getChildCount(); 31 | for (int i = 0; i < childCount; i++) { 32 | View child = parent.getChildAt(i); 33 | 34 | RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); 35 | 36 | int top = child.getBottom() + params.bottomMargin; 37 | int bottom = top + mDivider.getIntrinsicHeight(); 38 | 39 | mDivider.setBounds(left, top, right, bottom); 40 | mDivider.draw(c); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/Utils/UpdateFirebase.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask.Utils; 2 | 3 | import android.content.Context; 4 | 5 | import com.google.firebase.auth.FirebaseAuth; 6 | import com.google.firebase.auth.FirebaseUser; 7 | import com.google.firebase.database.DataSnapshot; 8 | import com.google.firebase.database.DatabaseError; 9 | import com.google.firebase.database.DatabaseReference; 10 | import com.google.firebase.database.FirebaseDatabase; 11 | import com.google.firebase.database.Query; 12 | import com.google.firebase.database.ValueEventListener; 13 | 14 | import java.util.HashMap; 15 | 16 | import redlor.it.minitask.ToDoItem; 17 | 18 | /** 19 | * Created by Redlor on 25/11/2017. 20 | * This class contains the methods need to update the Real-Time Database on Firebase. 21 | */ 22 | 23 | public class UpdateFirebase { 24 | 25 | MyDateTimeUtils dateTimeUtils; 26 | // Get a reference to the Database 27 | private FirebaseUser firebaseUser = FirebaseAuth.getInstance().getCurrentUser(); 28 | private String uid = firebaseUser.getUid(); 29 | private DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("users").child(uid).child("toDoItems"); 30 | 31 | 32 | public UpdateFirebase() { 33 | } 34 | 35 | 36 | // This method add a new item to Firebase Database 37 | public void addItem(ToDoItem toDoItem) { 38 | databaseReference.keepSynced(true); 39 | String itemId = databaseReference.push().getKey(); 40 | System.out.println(itemId); 41 | databaseReference.child(itemId).setValue(toDoItem); 42 | toDoItem.setItemId(itemId); 43 | } 44 | 45 | public void updateItem(String newContent, boolean newHasReminder, String newReminderDate, String oldItemId) { 46 | databaseReference.keepSynced(true); 47 | 48 | HashMap map = new HashMap<>(); 49 | map.put("content", newContent); 50 | map.put("hasReminder", newHasReminder); 51 | map.put("reminderDate", newReminderDate); 52 | 53 | databaseReference.child(oldItemId).updateChildren(map); 54 | } 55 | 56 | // This method delete an item from Firebase Database 57 | public void deleteItem(final ToDoItem toDoItem) { 58 | databaseReference.keepSynced(true); 59 | 60 | String id = toDoItem.getItemId(); 61 | databaseReference.child(id).addListenerForSingleValueEvent(new ValueEventListener() { 62 | @Override 63 | public void onDataChange(DataSnapshot dataSnapshot) { 64 | for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) { 65 | dataSnapshot1.getRef().removeValue(); 66 | } 67 | } 68 | 69 | @Override 70 | public void onCancelled(DatabaseError databaseError) { 71 | 72 | } 73 | }); 74 | } 75 | 76 | // This method delete all the checked items from Firebase 77 | public void deleteChecked(final Context context) { 78 | databaseReference.keepSynced(true); 79 | dateTimeUtils = new MyDateTimeUtils(); 80 | Query query = databaseReference.orderByChild("done").equalTo(true); 81 | query.addListenerForSingleValueEvent(new ValueEventListener() { 82 | @Override 83 | public void onDataChange(DataSnapshot dataSnapshot) { 84 | for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) { 85 | ToDoItem toDoItem = dataSnapshot1.getValue(ToDoItem.class); 86 | String content = toDoItem.getContent(); 87 | boolean reminder = toDoItem.getHasReminder(); 88 | if (reminder) { 89 | dateTimeUtils.cancelScheduledNotification(dateTimeUtils.getNotification(content, context), 90 | context, (int) 0); 91 | } 92 | 93 | dataSnapshot1.getRef().removeValue(); 94 | 95 | } 96 | } 97 | 98 | @Override 99 | public void onCancelled(DatabaseError databaseError) { 100 | } 101 | }); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/redlor/it/minitask/viewholder/FirebaseViewHolder.java: -------------------------------------------------------------------------------- 1 | package redlor.it.minitask.viewholder; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | import android.widget.CheckBox; 7 | import android.widget.ImageView; 8 | import android.widget.LinearLayout; 9 | import android.widget.TextView; 10 | 11 | import butterknife.BindView; 12 | import butterknife.ButterKnife; 13 | import redlor.it.minitask.R; 14 | 15 | 16 | /** 17 | * Created by Hp on 08/12/2017. 18 | */ 19 | 20 | public class FirebaseViewHolder extends RecyclerView.ViewHolder { 21 | 22 | final LinearLayout.LayoutParams params; 23 | private final LinearLayout layout; 24 | @BindView(R.id.taskList) 25 | public LinearLayout taskList; 26 | @BindView(R.id.todoContent) 27 | public 28 | TextView content; 29 | @BindView(R.id.checkDone) 30 | public 31 | CheckBox checkDone; 32 | @BindView(R.id.clockReminder) 33 | public 34 | ImageView clockReminder; 35 | private FirebaseViewHolder.ClickListener mClickListener; 36 | 37 | public FirebaseViewHolder(final View view) { 38 | super(view); 39 | ButterKnife.bind(this, view); 40 | layout = (LinearLayout) itemView.findViewById(R.id.taskList); 41 | params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 42 | ViewGroup.LayoutParams.WRAP_CONTENT); 43 | 44 | itemView.setOnClickListener(new View.OnClickListener() { 45 | @Override 46 | public void onClick(View v) { 47 | mClickListener.onItemClick(v, getAdapterPosition()); 48 | } 49 | }); 50 | itemView.setOnLongClickListener(new View.OnLongClickListener() { 51 | @Override 52 | public boolean onLongClick(View view) { 53 | mClickListener.onItemLongClick(view, getAdapterPosition()); 54 | return true; 55 | } 56 | }); 57 | } 58 | 59 | public void setOnClickListener(FirebaseViewHolder.ClickListener clickListener) { 60 | mClickListener = clickListener; 61 | 62 | 63 | } 64 | 65 | public void LayoutHide() { 66 | params.height = 0; 67 | layout.setLayoutParams(params); 68 | } 69 | 70 | //Interface to send callbacks... 71 | public interface ClickListener { 72 | public void onItemClick(View view, int position); 73 | 74 | public void onItemLongClick(View view, int position); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi-v11/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi-v11/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi-v9/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi-v9/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_access_alarms_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_access_alarms_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_alarm_on_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_alarm_on_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_alarm_on_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_alarm_on_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_delete_sweep_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_delete_sweep_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_done_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_done_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_email_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_email_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_mode_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_plus_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_plus_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_warning_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-hdpi/ic_warning_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi-v11/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi-v11/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi-v9/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi-v9/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_access_alarms_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_access_alarms_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_alarm_on_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_alarm_on_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_alarm_on_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_alarm_on_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_delete_sweep_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_delete_sweep_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_done_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_done_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_email_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_email_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_mode_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_plus_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_plus_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_warning_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-mdpi/ic_warning_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi-v11/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi-v11/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi-v9/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi-v9/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_access_alarms_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_access_alarms_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_alarm_on_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_alarm_on_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_alarm_on_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_alarm_on_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_delete_sweep_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_delete_sweep_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_done_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_done_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_email_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_email_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_mode_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_plus_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_plus_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_warning_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xhdpi/ic_warning_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi-v11/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi-v11/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi-v9/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi-v9/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_access_alarms_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_access_alarms_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_alarm_on_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_alarm_on_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_alarm_on_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_alarm_on_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_delete_sweep_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_delete_sweep_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_done_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_done_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_email_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_email_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_mode_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_plus_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_plus_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_stat_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_stat_name.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_warning_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxhdpi/ic_warning_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_access_alarms_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_access_alarms_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_alarm_on_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_alarm_on_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_alarm_on_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_alarm_on_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_delete_sweep_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_delete_sweep_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_done_white_36dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_done_white_36dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_email_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_email_black_18dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_mode_edit_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_plus_white_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_plus_white_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_warning_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable-xxxhdpi/ic_warning_black_24dp.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/ic_facebook.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/ic_github.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_patreon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/ic_patreon.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_paypal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/ic_paypal.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/ic_twitter.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/inbox.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/inbox.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/line_divider.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/seven_day.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/seven_day.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/splash.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/splash.webp -------------------------------------------------------------------------------- /app/src/main/res/drawable/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/today.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redlor/Minitask/4b505a130c05c5e26be1ae33067d2bc1505fdcf5/app/src/main/res/drawable/today.webp -------------------------------------------------------------------------------- /app/src/main/res/layout-land/activity_add_todo_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 18 | 19 | 28 | 29 | 50 | 51 | 52 | 53 | 60 | 61 | 67 | 68 | 72 | 73 | 80 | 81 | 85 | 86 | 87 | 88 | 94 | 95 |