├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── ic_menu-web.png
│ ├── java
│ └── com
│ │ └── vrgsoft
│ │ └── mygoal
│ │ ├── data
│ │ └── db
│ │ │ ├── alerts
│ │ │ └── Goal.kt
│ │ │ └── habits
│ │ │ ├── HabitJob.kt
│ │ │ └── HabitsRepositoryLocalImp.kt
│ │ ├── domain
│ │ └── habits
│ │ │ ├── HabitInteractor.kt
│ │ │ ├── HabitRepository.kt
│ │ │ ├── HabitsInteractor.kt
│ │ │ └── HabitsRepository.kt
│ │ └── presentation
│ │ ├── common
│ │ ├── BaseActivity.kt
│ │ ├── BaseFragment.kt
│ │ ├── BasePresenter.kt
│ │ ├── BaseView.kt
│ │ ├── CachedValue.kt
│ │ ├── Layout.kt
│ │ ├── SettingsHelper.kt
│ │ └── view
│ │ │ ├── CheckableButton.kt
│ │ │ └── CheckableUtils.kt
│ │ ├── events
│ │ └── BaseEvent.kt
│ │ ├── injection
│ │ ├── AddHabitComponent.kt
│ │ ├── App.kt
│ │ ├── ApplicationComponent.kt
│ │ ├── ApplicationModule.kt
│ │ ├── DataModule.kt
│ │ ├── DomainModule.kt
│ │ ├── HabitsComponent.kt
│ │ ├── HasComponent.kt
│ │ └── PerActivity.kt
│ │ ├── main
│ │ ├── SplashActivity.kt
│ │ ├── addhabit
│ │ │ ├── AddHabitActivity.kt
│ │ │ ├── AddHabitFragment.kt
│ │ │ ├── AddHabitPresenter.kt
│ │ │ └── AddHabitView.kt
│ │ ├── habits
│ │ │ ├── HabitsActivity.kt
│ │ │ ├── HabitsFragment.kt
│ │ │ ├── HabitsPresenter.kt
│ │ │ ├── HabitsRouter.kt
│ │ │ ├── HabitsView.kt
│ │ │ └── common
│ │ │ │ ├── GoalClickListener.kt
│ │ │ │ ├── HabitsAdapter.kt
│ │ │ │ ├── resultdialogs
│ │ │ │ └── ResultDialog.kt
│ │ │ │ └── themedialog
│ │ │ │ ├── OnThemeChooseCallBack.kt
│ │ │ │ ├── ThemeAdapter.kt
│ │ │ │ ├── ThemeDialogFragment.kt
│ │ │ │ └── ThemeViewModel.kt
│ │ └── showhabit
│ │ │ ├── ShowHabbitView.kt
│ │ │ ├── ShowHabitFragment.kt
│ │ │ └── ShowHabitPresenter.kt
│ │ └── receivers
│ │ ├── AlarmReceiver.kt
│ │ └── TimeChangeReceiver.kt
│ └── res
│ ├── anim
│ └── move_anim.xml
│ ├── drawable
│ ├── actionbar_shadow.xml
│ ├── arts_icon.png
│ ├── bt_drawable.xml
│ ├── dialog_background.png
│ ├── healthy_icon.png
│ ├── home_icon.png
│ ├── ic_add.xml
│ ├── ic_collections.xml
│ ├── ic_mode_edit_black_24dp.xml
│ ├── icon.png
│ ├── main_back.png
│ ├── main_splash.png
│ ├── money_icon.png
│ ├── move_back.png
│ ├── other_icon.png
│ ├── rounded_white_rect.xml
│ ├── self_improvment_icon.png
│ ├── sex_dating_icon.png
│ ├── social_icon.png
│ └── work_and_study_icon.png
│ ├── layout
│ ├── activity_add_habit.xml
│ ├── activity_habits.xml
│ ├── activity_splash.xml
│ ├── dialog_failed.xml
│ ├── dialog_success.xml
│ ├── fragment_add_habit.xml
│ ├── fragment_dialog_theme.xml
│ ├── fragment_habits.xml
│ ├── fragment_show_habit.xml
│ ├── item.xml
│ ├── item_habit.xml
│ └── recycler_dialog.xml
│ ├── menu
│ └── main_menu.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_menu.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_menu.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_menu.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_menu.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ ├── ic_launcher_round.png
│ └── ic_menu.png
│ ├── values-it
│ └── strings.xml
│ ├── values-ru
│ └── strings.xml
│ ├── values-uk
│ └── strings.xml
│ ├── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── integers.xml
│ ├── strings.xml
│ └── styles.xml
│ └── xml
│ ├── analytics.xml
│ └── filepaths.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
└── settings.gradle
/README.md:
--------------------------------------------------------------------------------
1 | #### Get a new goal
2 | 
3 | #### We are VRG SOFT
4 | Our professionals know how to compose Cloud technologies and Internet of Things in one perfect structure. During the last 5 years we gathered strong native mobile app development tools in order to make product development process run smoothly. In our way to becoming the partner you can rely on, we are working hard and rapidly improving our product development process. Following the user’s needs we create easy-to-use and user-friendly mobile apps to deliver much more traffic to your business.
5 |
6 | First open source simple project to get your own goal
7 |
8 | Stack technology:
9 | Dagger2 + Rx2 + Realm using Clean architecture
10 |
11 | #### [HIRE US](http://vrgsoft.net/)
12 | #### Download
13 | * [Download APK from here](https://play.google.com/store/apps/details?id=com.vrgsoft.mygoal)
14 | #### Contributing
15 | * Contributions are always welcome
16 | * If you want a feature and can code, feel free to fork and add the change yourself and make a pull request
17 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'realm-android'
4 | apply plugin: 'kotlin-kapt'
5 |
6 |
7 | android {
8 | compileSdkVersion 25
9 | buildToolsVersion "25.0.2"
10 | defaultConfig {
11 | applicationId "com.vrgsoft.mygoal"
12 | minSdkVersion 16
13 | targetSdkVersion 25
14 | versionCode 1
15 | versionName "1.0"
16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
17 | vectorDrawables.useSupportLibrary = true
18 | multiDexEnabled true
19 |
20 | }
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | dataBinding
28 | {
29 | enabled = true;
30 | }
31 | }
32 |
33 | dependencies {
34 | compile fileTree(dir: 'libs', include: ['*.jar'])
35 |
36 |
37 |
38 | def supportVersion = '25.2.0'
39 |
40 | compile("com.android.support:support-v4:$supportVersion") {
41 | force = true;
42 | }
43 | compile("com.android.support:appcompat-v7:$supportVersion") {
44 | force = true;
45 | }
46 | compile("com.android.support:design:$supportVersion") {
47 | force = true;
48 | }
49 | compile("com.android.support:cardview-v7:$supportVersion") {
50 | force = true;
51 | }
52 | compile("com.android.support:recyclerview-v7:$supportVersion") {
53 | force = true;
54 | }
55 |
56 |
57 |
58 |
59 |
60 | compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
61 | // sdk19, sdk21, sdk23 are also available
62 | // In case you need support-v4 bindings
63 | //
64 |
65 |
66 | compile('com.philliphsu:bottomsheetpickers:2.3.2') {
67 | exclude group: 'com.android.support', module: 'appcompat-v7'
68 | exclude group: 'com.android.support', module: 'design'
69 | }
70 | compile 'com.google.dagger:dagger:2.9'
71 | compile 'com.github.bumptech.glide:glide:3.7.0'
72 | compile 'com.google.code.gson:gson:2.7'
73 | compile 'io.reactivex.rxjava2:rxjava:2.0.7'
74 | compile 'org.greenrobot:eventbus:3.0.0'
75 | compile 'com.android.support.constraint:constraint-layout:1.0.2'
76 | compile 'com.evernote:android-job:1.1.9'
77 | compile 'com.android.support:support-v4:25.2.0'
78 | compile 'org.jetbrains.anko:anko-sdk23:0.10.0-beta-1'
79 | compile 'org.jetbrains.anko:anko-support-v4:0.10.0-beta-1'
80 | compile 'org.jetbrains.anko:anko-appcompat-v7:0.10.0-beta-1'
81 | compile 'com.squareup.picasso:picasso:2.5.2'
82 | kapt 'com.android.databinding:compiler:2.3.2'
83 | kapt 'com.google.dagger:dagger-compiler:2.9'
84 | provided 'javax.annotation:jsr250-api:1.0'
85 | provided 'org.glassfish:javax.annotation:10.0-b28'
86 | compile 'com.github.zurche:plain-pie:v0.2.2'
87 | compile 'com.android.support:multidex:1.0.1'
88 | }
89 | repositories {
90 | mavenCentral()
91 | }
92 |
--------------------------------------------------------------------------------
/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 D:\AndroidSDK/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/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
13 |
15 |
16 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/ic_menu-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/ic_menu-web.png
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/data/db/alerts/Goal.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.data.db.alerts
2 |
3 |
4 | import io.realm.RealmObject
5 | import io.realm.annotations.PrimaryKey
6 | import java.util.concurrent.TimeUnit
7 |
8 | open class Goal : RealmObject() {
9 | @PrimaryKey
10 | var mId: Long = 0
11 | var mTime: Long = 0
12 | var mDescr: String = ""
13 | var mName: String = ""
14 | var mImage: Int = 0
15 | var mLatsDays:Long = System.currentTimeMillis()
16 | var mTwentyOne:Long = TimeUnit.DAYS.toMillis(21)
17 | var lastCheck:Long = System.currentTimeMillis()
18 |
19 |
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/data/db/habits/HabitJob.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.data.db.habits
2 |
3 | import com.evernote.android.job.Job
4 | import com.evernote.android.job.JobRequest
5 |
6 | class HabitJob : Job() {
7 | override fun onRunJob(params: Params?): Result {
8 | return Result.SUCCESS
9 | }
10 |
11 | companion object {
12 | val TAG: String = "habit_job_tag"
13 | fun scheduleJob() {
14 | JobRequest.Builder(TAG)
15 | .setExact(System.currentTimeMillis()+3000)
16 | .build()
17 | .schedule()
18 | }
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/data/db/habits/HabitsRepositoryLocalImp.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.data.db.habits
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import com.vrgsoft.mygoal.domain.habits.HabitsRepository
5 | import com.vrgsoft.mygoal.presentation.receivers.AlarmReceiver
6 | import io.reactivex.Observable
7 | import io.realm.Realm
8 | import java.util.concurrent.TimeUnit
9 | import javax.inject.Inject
10 |
11 |
12 | class HabitsRepositoryLocalImp() : HabitsRepository {
13 | lateinit private var mRealm: Realm
14 |
15 | @Inject
16 | constructor(mRealm: Realm) : this() {
17 | this.mRealm = mRealm
18 | }
19 |
20 | override fun saveHabit(goal: Goal) {
21 | mRealm.executeTransaction {
22 |
23 | if(goal.mId == 0.toLong()){
24 | val currentIdNum = mRealm.where(Goal::class.java).max("mId")
25 | val nextId: Long
26 | if (currentIdNum == null) {
27 | nextId = 1
28 | } else {
29 | nextId = currentIdNum.toLong() + 1
30 | }
31 | goal.mId = nextId
32 | }
33 |
34 | mRealm.copyToRealmOrUpdate(goal)
35 | }
36 | }
37 |
38 |
39 | override fun getGoal(id: Long): Observable {
40 | var goal:Goal = Realm.getDefaultInstance().where(Goal::class.java).equalTo("mId", id).findFirst();
41 | if(goal == null){
42 | return Observable.empty();
43 | }else{
44 | return Observable.just(Realm.getDefaultInstance().copyFromRealm(goal))
45 | }
46 |
47 | }
48 |
49 | override fun getGoals(): Observable< List> {
50 | return Observable.just(mRealm.copyFromRealm(mRealm.where(Goal::class.java).findAll()))
51 | }
52 |
53 | fun getGoalById(id : Long): Goal {
54 | return mRealm.where(Goal::class.java).equalTo("mId", id).findFirst()
55 | }
56 |
57 | fun getAllHabits():List{
58 | var castRealm : Realm = Realm.getDefaultInstance()
59 | return castRealm.where(Goal::class.java).findAll()
60 | }
61 |
62 | fun check(goal: Goal){
63 | mRealm.beginTransaction()
64 | goal.lastCheck=System.currentTimeMillis()
65 | goal.mTime = goal.mTime+TimeUnit.DAYS.toMillis(1)
66 | mRealm.copyToRealmOrUpdate(goal)
67 | mRealm.commitTransaction()
68 |
69 |
70 | }
71 |
72 |
73 | fun deleteGoalById(goal: Goal){
74 | mRealm.beginTransaction()
75 | var goalToDel:Goal = mRealm.where(Goal::class.java).equalTo("mId", goal.mId).findFirst()
76 | goalToDel.deleteFromRealm()
77 | mRealm.commitTransaction()
78 | }
79 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/domain/habits/HabitInteractor.kt:
--------------------------------------------------------------------------------
1 |
2 | package com.vrgsoft.mygoal.domain.habits
3 |
4 | import com.vrgsoft.mygoal.data.db.alerts.Goal
5 | import com.vrgsoft.mygoal.data.db.habits.HabitsRepositoryLocalImp
6 | import io.reactivex.Observable
7 | import javax.inject.Inject
8 |
9 | class HabitInteractor @Inject constructor(habitsRepositoryLocalImp: HabitsRepositoryLocalImp) {
10 | private val mHabitsRepository: HabitsRepositoryLocalImp = habitsRepositoryLocalImp
11 |
12 | fun saveHabit(habit: Goal) {
13 | mHabitsRepository.saveHabit(habit)
14 | }
15 |
16 | fun getGoal(mId:Long): Observable {
17 | return mHabitsRepository.getGoal(mId)
18 | }
19 |
20 | fun getGoalById(id:Long):Goal{
21 | return mHabitsRepository.getGoalById(id)
22 | }
23 |
24 | fun getAllHabits():List{
25 | return mHabitsRepository.getAllHabits()
26 | }
27 |
28 | fun check(goal: Goal){
29 | mHabitsRepository.check(goal)
30 | }
31 |
32 | fun deleteGoalById(goal: Goal){
33 | mHabitsRepository.deleteGoalById(goal)
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/domain/habits/HabitRepository.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.domain.habits
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import io.reactivex.Observable
5 |
6 | interface HabitRepository {
7 | fun saveHabit(goal: Goal)
8 | fun getGoal(id: Int): Observable
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/domain/habits/HabitsInteractor.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.domain.habits
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import com.vrgsoft.mygoal.data.db.habits.HabitsRepositoryLocalImp
5 | import io.reactivex.Observable
6 | import javax.inject.Inject
7 |
8 | class HabitsInteractor @Inject constructor(habitsRepositoryLocalImp: HabitsRepositoryLocalImp) {
9 | private val mHabitsRepository: HabitsRepositoryLocalImp = habitsRepositoryLocalImp
10 |
11 | fun getGoals(): Observable> {
12 | return mHabitsRepository.getGoals()
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/domain/habits/HabitsRepository.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.domain.habits
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import io.reactivex.Observable
5 |
6 | interface HabitsRepository {
7 | fun saveHabit(goal: Goal)
8 | fun getGoal(id: Long): Observable
9 | fun getGoals(): Observable< List>
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common
2 |
3 | import android.app.Activity
4 | import android.databinding.DataBindingUtil
5 | import android.databinding.ViewDataBinding
6 | import android.os.Bundle
7 | import android.support.v7.app.AppCompatActivity
8 | import android.support.v7.widget.Toolbar
9 |
10 | import com.vrgsoft.mygoal.presentation.injection.App
11 | import com.vrgsoft.mygoal.presentation.injection.ApplicationComponent
12 |
13 | abstract class BaseActivity : AppCompatActivity(), BaseView {
14 | protected var dataBinding: B? = null
15 | private set
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 | val cls = javaClass
20 | if (!cls.isAnnotationPresent(Layout::class.java)) {
21 | return
22 | }
23 | val annotation = cls.getAnnotation(Layout::class.java)
24 | dataBinding = DataBindingUtil.setContentView(activity, annotation.id)
25 | initComponent()
26 | }
27 |
28 | fun resolveToolbar(fragment: BaseFragment<*>) {
29 | val toolbar = fragment.toolbar
30 | setSupportActionBar(toolbar)
31 | supportActionBar!!.setDisplayShowTitleEnabled(false)
32 |
33 | }
34 |
35 | fun addFragment(viewGroupId: Int, fragment: BaseFragment<*>) {
36 | supportFragmentManager
37 | .beginTransaction()
38 | .replace(viewGroupId, fragment)
39 | .commit()
40 | }
41 |
42 | abstract fun initComponent()
43 |
44 | abstract val activity: A
45 | override fun onNetworkFailure() {
46 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
47 | }
48 |
49 | override fun onRequestFailure() {
50 | TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
51 | }
52 | protected val applicationComponent: ApplicationComponent
53 | get() = App.applicationComponent
54 | }
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common
2 |
3 | import android.content.DialogInterface
4 | import android.databinding.DataBindingUtil
5 | import android.databinding.ViewDataBinding
6 | import android.os.Bundle
7 | import android.support.v4.app.Fragment
8 | import android.support.v7.app.AlertDialog
9 | import android.support.v7.widget.Toolbar
10 | import android.view.LayoutInflater
11 | import android.view.View
12 | import android.view.ViewGroup
13 | import com.vrgsoft.mygoal.data.db.alerts.Goal
14 |
15 |
16 | import com.vrgsoft.mygoal.presentation.events.BaseEvent
17 |
18 | import org.greenrobot.eventbus.EventBus
19 | import org.greenrobot.eventbus.Subscribe
20 |
21 | abstract class BaseFragment : Fragment(), BaseView {
22 | private var mIsInjected = false
23 | protected var binding: B? = null
24 | private set
25 |
26 | override fun onCreate(savedInstanceState: Bundle?) {
27 | super.onCreate(savedInstanceState)
28 | try {
29 | mIsInjected = onInjectView()
30 | } catch (e: IllegalStateException) {
31 | mIsInjected = false
32 | }
33 |
34 | }
35 |
36 | override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
37 | super.onViewCreated(view, savedInstanceState)
38 | if (mIsInjected) {
39 | onViewInjected(savedInstanceState)
40 | }
41 | }
42 |
43 | override fun onCreateView(inflater: LayoutInflater?,
44 | container: ViewGroup?,
45 | savedInstanceState: Bundle?): View? {
46 | val cls = javaClass
47 | if (!cls.isAnnotationPresent(Layout::class.java)) {
48 | return null
49 | }
50 | val annotation = cls.getAnnotation(Layout::class.java)
51 | binding = DataBindingUtil.inflate(inflater, annotation.id, container, false)
52 |
53 | return binding!!.root
54 | }
55 |
56 | override fun onActivityCreated(savedInstanceState: Bundle?) {
57 | super.onActivityCreated(savedInstanceState)
58 | if (!mIsInjected) {
59 | mIsInjected = onInjectView()
60 | if (mIsInjected) {
61 | onViewInjected(savedInstanceState)
62 | }
63 | }
64 | initView()
65 | }
66 |
67 | abstract val toolbar: Toolbar?
68 |
69 | abstract fun toolbarNavigationActive(): Boolean
70 |
71 | protected abstract val presenter: BasePresenter
72 |
73 | protected abstract fun initView()
74 |
75 | @Throws(IllegalStateException::class)
76 | protected abstract fun inject()
77 |
78 | @Throws(IllegalStateException::class)
79 | protected fun onInjectView(): Boolean {
80 | inject()
81 | return true
82 | }
83 |
84 | protected fun onViewInjected(savedInstanceState: Bundle?) {
85 | presenter.view = this
86 | }
87 |
88 | override fun onStart() {
89 | super.onStart()
90 | presenter.onStart()
91 | EventBus.getDefault().register(this)
92 | }
93 |
94 |
95 | override fun onStop() {
96 | super.onStop()
97 | presenter.onStop()
98 | EventBus.getDefault().unregister(this)
99 | }
100 |
101 | @Subscribe
102 | fun onEvent(event: BaseEvent) {
103 |
104 | }
105 |
106 | override fun onNetworkFailure() {
107 | //showAlertDialog(getString(R.string.network_failure));
108 | }
109 |
110 | override fun onRequestFailure() {
111 | //showAlertDialog(getString(R.string.request_error));
112 | }
113 |
114 | protected fun showAlertDialog(message: String) {
115 | AlertDialog.Builder(context)
116 | .setMessage(message)
117 | .setCancelable(false)
118 | .show()
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/BasePresenter.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common
2 |
3 | abstract class BasePresenter {
4 | var view: View? = null
5 | var router: Router? = null
6 |
7 | abstract fun onStart()
8 |
9 | abstract fun onStop()
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/BaseView.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common
2 |
3 | interface BaseView {
4 | fun onNetworkFailure()
5 |
6 | fun onRequestFailure()
7 | }
8 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/CachedValue.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common
2 |
3 | import android.annotation.SuppressLint
4 | import android.content.SharedPreferences
5 |
6 | class CachedValue(val name: String, private var value: T?, private val defValue: T?, private val type: Class<*>) {
7 |
8 | private var sp: SharedPreferences? = null
9 | private var loaded = false
10 |
11 | constructor(name: String, type: Class<*>) : this(name, null, null, type) {}
12 |
13 | constructor(name: String, defValue: T, type: Class<*>) : this(name, null, defValue, type) {}
14 |
15 | init {
16 | this.sp = sharedPref
17 | this.loaded = value != null
18 | }
19 |
20 | fun setValue(value: T) {
21 | synchronized(lock) {
22 | loaded = true
23 | write(value)
24 | }
25 | }
26 |
27 | fun getValue(): T? {
28 | synchronized(lock) {
29 | if (!loaded) {
30 | this.value = load()
31 | loaded = true
32 | }
33 | return this.value
34 | }
35 | }
36 |
37 | private fun write(value: T) {
38 | val editor = sp!!.edit()
39 |
40 | if (value is String) {
41 |
42 | editor.putString(name, value)
43 |
44 | } else if (value is Int) {
45 |
46 | editor.putInt(name, value)
47 |
48 | } else if (value is Float) {
49 |
50 | editor.putFloat(name, value)
51 |
52 | } else if (value is Long) {
53 |
54 | editor.putLong(name, value)
55 |
56 | } else if (value is Boolean) {
57 |
58 | editor.putBoolean(name, value)
59 |
60 | }
61 |
62 | editor.apply()
63 | }
64 |
65 | @SuppressLint("unchecked")
66 | private fun load(): T? {
67 |
68 | if (type == String::class.java) {
69 |
70 | return sp!!.getString(name, defValue as String?) as T
71 |
72 | } else if (type == Int::class.java) {
73 |
74 | return Integer.valueOf(sp!!.getInt(name, if (defValue != null) (defValue as Int?)!! else 0)) as T
75 |
76 | } else if (type == Float::class.java) {
77 |
78 | return java.lang.Float.valueOf(sp!!.getFloat(name, if (defValue != null) (defValue as Float?)!! else 0F)) as T
79 |
80 | } else if (type == Long::class.java) {
81 |
82 | return java.lang.Long.valueOf(sp!!.getLong(name, if (defValue != null) (defValue as Long?)!! else 0)) as T
83 |
84 | } else if (type == Boolean::class.java) {
85 |
86 | return java.lang.Boolean.valueOf(sp!!.getBoolean(name, if (defValue != null) (defValue as Boolean?)!! else false)) as T
87 |
88 | }
89 |
90 | return null
91 | }
92 |
93 | fun delete() {
94 | synchronized(lock) {
95 | sp!!.edit().remove(name).commit()
96 | clear()
97 | }
98 | }
99 |
100 | fun setSharedPreferences(sp: SharedPreferences) {
101 | this.sp = sp
102 | }
103 |
104 | fun clear() {
105 | synchronized(lock) {
106 | loaded = false
107 | this.value = null
108 | }
109 | }
110 |
111 | companion object {
112 |
113 | private val lock = Any()
114 |
115 | private var sharedPref: SharedPreferences? = null
116 |
117 | fun initialize(sp: SharedPreferences) {
118 | CachedValue.sharedPref = sp
119 | }
120 | }
121 |
122 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/Layout.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common
2 |
3 | import android.support.annotation.LayoutRes
4 | import java.lang.annotation.Retention
5 | import java.lang.annotation.RetentionPolicy
6 |
7 | @Retention(RetentionPolicy.RUNTIME)
8 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FILE)
9 | annotation class Layout(@LayoutRes val id: Int)
10 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/SettingsHelper.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common
2 |
3 | import android.content.Context
4 |
5 |
6 | class SettingsHelper {
7 |
8 |
9 | var adsDisabled: CachedValue? = null
10 | var dateReminder: CachedValue? = null
11 |
12 | fun init(context: Context) {
13 | CachedValue.initialize(context.getSharedPreferences(APP_PREFERENCES, Context.MODE_PRIVATE))
14 | adsDisabled = CachedValue(ADS_DISABLED, false, Boolean::class.java)
15 | dateReminder = CachedValue(REMINDER, 0.toLong(), Long::class.java)
16 | }
17 |
18 | val isAdsDisabled: Boolean
19 | get() = adsDisabled!!.getValue()!!
20 |
21 | fun setDisabledAds(disabled: Boolean) {
22 | adsDisabled!!.setValue(disabled)
23 | }
24 |
25 |
26 |
27 |
28 | fun setReminder(now: Long) {
29 | dateReminder!!.setValue(now)
30 | }
31 |
32 |
33 |
34 |
35 | companion object {
36 | private val APP_PREFERENCES = "DailyBibleInspirations"
37 | private val ADS_DISABLED = "removeAds"
38 | private val REMINDER = "reminder"
39 |
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/view/CheckableButton.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common.view
2 |
3 | import android.annotation.TargetApi
4 | import android.content.Context
5 | import android.content.res.ColorStateList
6 | import android.content.res.TypedArray
7 | import android.graphics.Canvas
8 | import android.graphics.Color
9 | import android.graphics.Typeface
10 | import android.graphics.drawable.Drawable
11 | import android.graphics.drawable.GradientDrawable
12 | import android.graphics.drawable.RippleDrawable
13 | import android.graphics.drawable.StateListDrawable
14 | import android.os.Build
15 | import android.util.AttributeSet
16 | import android.view.Gravity
17 | import android.view.View
18 | import android.widget.Checkable
19 | import android.widget.LinearLayout
20 | import android.widget.TextView
21 | import com.vrgsoft.mygoal.R
22 |
23 | class CheckableButton : LinearLayout, Checkable {
24 |
25 |
26 | private var mContext: Context? = null
27 |
28 | // # Background Style Attributes
29 | private var checkedBackgroundColor = Color.BLACK
30 | private var uncheckedBackgroundColor = Color.BLACK
31 | /**
32 | * Right Now this is disabled
33 |
34 | * @param mFocusBackgroundColor
35 | */
36 | var focusBackgroundColor = Color.TRANSPARENT
37 | set(mFocusBackgroundColor) {
38 | field = mFocusBackgroundColor
39 | setupBackground()
40 | }
41 | private var mDisabledBackgroundColor = Color.parseColor("#f6f7f9")
42 | var disabledTextColor = Color.parseColor("#bec2c9")
43 | private var mDisabledBorderColor = Color.parseColor("#dddfe2")
44 |
45 | // # Text Style Attributes
46 | var checkedTextColor = Color.WHITE
47 | private var uncheckedTextColor = Color.WHITE
48 | private val mTextPosition = 1
49 | private var mDefaultTextSize = CheckableUtils.spToPx(context, 15f)
50 | var defaultTextGravity = 0x11 // Gravity.CENTER
51 | private lateinit var mText: String
52 | private val mDefaultTextFont = ""
53 |
54 | private var mBorderColor = Color.TRANSPARENT
55 | private var checkedBorderColor = Color.TRANSPARENT
56 | private var mBorderWidth = 0
57 | private var checkedBorderWidth = 0
58 | private var mTextTypeFace: Typeface?=null
59 | private val disableClick: Boolean = false
60 |
61 | private var mRadius = 0
62 |
63 | private var mTextAllCaps = false
64 | private val isRippleEffect = false
65 | var textView: TextView? = null
66 | private var mListener: OnCheckedChangeListener? = null
67 | private var isChecked: Boolean = false
68 |
69 | constructor(context: Context) : super(context) {
70 | this.mContext = context
71 | mTextTypeFace = CheckableUtils.findFont(context, mDefaultTextFont, null)
72 | init()
73 | }
74 |
75 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
76 | this.mContext = context
77 | val attrsArray = context.obtainStyledAttributes(attrs, R.styleable.CheckableButton, 0, 0)
78 | initAttributesArray(attrs, attrsArray)
79 | attrsArray.recycle()
80 | init()
81 | }
82 |
83 | /**
84 | * Initialize CheckableButton View
85 | */
86 | private fun init() {
87 |
88 | //Init The container view: LinearLayout
89 | this.orientation = VERTICAL
90 | val containerParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
91 | this.layoutParams = containerParams
92 | this.gravity = Gravity.CENTER
93 | this.isClickable = true
94 | this.isFocusable = true
95 | if (paddingLeft == 0 && paddingRight == 0 && paddingTop == 0 && paddingBottom == 0) {
96 | this.setPadding(10, 10, 10, 10)
97 | }
98 |
99 | //init the Textview:
100 | setUpTextView()
101 | setUpTextColorStates()
102 |
103 | setupBackground()
104 |
105 | // for (View view : views) {
106 | //this.addView(mTextView);
107 | //}
108 | setOnClickListener { toggle() }
109 |
110 | if (isChecked) {
111 | setChecked(true)
112 | }
113 |
114 |
115 | }
116 |
117 | private fun setUpTextView() {
118 | if (true) {
119 | textView = TextView(mContext)
120 | textView!!.text = mText
121 | textView!!.gravity = defaultTextGravity
122 | textView!!.setTextColor(if (isChecked()) checkedTextColor else uncheckedTextColor)
123 | textView!!.textSize = CheckableUtils.pxToSp(context, mDefaultTextSize.toFloat()).toFloat()
124 |
125 | textView!!.layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
126 | if (!isInEditMode && mTextTypeFace != null) {
127 | textView!!.typeface = mTextTypeFace
128 | }
129 | }
130 | }
131 |
132 | private fun setUpTextColorStates() {
133 | val states = arrayOf(intArrayOf(android.R.attr.state_enabled), // enabled
134 | intArrayOf(-android.R.attr.state_enabled), // disabled
135 | intArrayOf(-android.R.attr.state_checked), // unchecked
136 | intArrayOf(android.R.attr.state_checked), // checked
137 | intArrayOf(android.R.attr.state_pressed) // pressed
138 | )
139 |
140 | val colors = intArrayOf(checkedTextColor, disabledTextColor, uncheckedTextColor, checkedTextColor, uncheckedTextColor)
141 |
142 | val myList = ColorStateList(states, colors)
143 |
144 | if (textView != null) {
145 | this.addView(textView)
146 | }
147 | }
148 |
149 | private fun initAttributesArray(attrs: AttributeSet, attrsArray: TypedArray) {
150 |
151 | checkedBackgroundColor = attrsArray.getColor(R.styleable.CheckableButton_cb_checkedColor, checkedBackgroundColor)
152 | uncheckedBackgroundColor = attrsArray.getColor(R.styleable.CheckableButton_cb_unCheckColor, uncheckedBackgroundColor)
153 | mDisabledBackgroundColor = attrsArray.getColor(R.styleable.CheckableButton_cb_disabledColor, mDisabledBackgroundColor)
154 |
155 | this.isEnabled = attrs.getAttributeBooleanValue("http://schemas.android.com/apk/res/android", "enabled", true)
156 |
157 | disabledTextColor = attrsArray.getColor(R.styleable.CheckableButton_cb_disabledTextColor, disabledTextColor)
158 | mDisabledBorderColor = attrsArray.getColor(R.styleable.CheckableButton_cb_disabledBorderColor, mDisabledBorderColor)
159 | checkedTextColor = attrsArray.getColor(R.styleable.CheckableButton_cb_checkedTextColor, checkedTextColor)
160 | uncheckedTextColor = attrsArray.getColor(R.styleable.CheckableButton_cb_uncheckedTextColor, uncheckedTextColor)
161 | // if default color is set then the icon's color is the same (the default for icon's color)
162 | isChecked = attrsArray.getBoolean(R.styleable.CheckableButton_cb_isChecked, false)
163 | mDefaultTextSize = attrsArray.getDimension(R.styleable.CheckableButton_cb_textSize, mDefaultTextSize.toFloat()).toInt()
164 | defaultTextGravity = attrsArray.getInt(R.styleable.CheckableButton_cb_textGravity, defaultTextGravity)
165 |
166 | mBorderColor = attrsArray.getColor(R.styleable.CheckableButton_cb_unCheckBorderColor, mBorderColor)
167 | checkedBorderColor = attrsArray.getColor(R.styleable.CheckableButton_cb_checkedBorderColor, checkedBorderColor)
168 | mBorderWidth = attrsArray.getDimension(R.styleable.CheckableButton_cb_borderWidth, mBorderWidth.toFloat()).toInt()
169 | checkedBorderWidth = attrsArray.getDimension(R.styleable.CheckableButton_cb_checkedborderWidth, checkedBorderWidth.toFloat()).toInt()
170 |
171 | mRadius = attrsArray.getDimension(R.styleable.CheckableButton_cb_radius, mRadius.toFloat()).toInt()
172 |
173 | mTextAllCaps = attrsArray.getBoolean(R.styleable.CheckableButton_cb_textAllCaps, false)
174 |
175 | val text = attrsArray.getString(R.styleable.CheckableButton_cb_text)
176 | if (text != null)
177 | mText = if (mTextAllCaps) text.toUpperCase() else text
178 | }
179 |
180 | /**
181 | * Uses the backgroud color of the unchecked state to create a lighter color
182 | * to be used for the focusable drawable
183 |
184 | * @param color
185 | * *
186 | * @return
187 | */
188 | private fun lightenColor(color: Int): Int {
189 | val hsv = FloatArray(3)
190 | val mColor: Int
191 | Color.colorToHSV(color, hsv)
192 |
193 | hsv[2] = 1.0f - 0.8f * (1.0f - hsv[2])
194 | mColor = Color.HSVToColor(hsv)
195 | return mColor
196 | }
197 |
198 | /**
199 | * SETup container's background
200 | * assign drawable states
201 | */
202 | private fun setupBackground() {
203 |
204 | // Default Drawable
205 | val defaultDrawable = GradientDrawable()
206 | defaultDrawable.cornerRadius = mRadius.toFloat()
207 | defaultDrawable.setColor(uncheckedBackgroundColor)
208 |
209 | //Focus Drawable
210 | lightenColor(uncheckedBackgroundColor)
211 | val focusDrawable = GradientDrawable()
212 | focusDrawable.cornerRadius = mRadius.toFloat()
213 | focusDrawable.setColor(focusBackgroundColor)
214 |
215 | // Disabled Drawable
216 | val disabledDrawable = GradientDrawable()
217 | disabledDrawable.cornerRadius = mRadius.toFloat()
218 | disabledDrawable.setColor(mDisabledBackgroundColor)
219 | disabledDrawable.setStroke(mBorderWidth, mDisabledBorderColor)
220 |
221 | // Disabled Drawable disabled
222 | val disabledDrawable2 = GradientDrawable()
223 | disabledDrawable2.cornerRadius = mRadius.toFloat()
224 | disabledDrawable2.setColor(mDisabledBackgroundColor)
225 | disabledDrawable2.setStroke(mBorderWidth, mDisabledBorderColor)
226 |
227 | // checked Drawable
228 | val drawable3 = GradientDrawable()
229 | drawable3.cornerRadius = mRadius.toFloat()
230 | drawable3.setColor(checkedBackgroundColor)
231 |
232 |
233 | // Handle Border
234 | if (mBorderColor != 0) {
235 | defaultDrawable.setStroke(mBorderWidth, mBorderColor)
236 | disabledDrawable.setStroke(mBorderWidth, mBorderColor)
237 | }
238 | if (checkedBorderColor != 0) {
239 | drawable3.setStroke(checkedBorderWidth, checkedBorderColor)
240 | disabledDrawable2.setStroke(mBorderWidth, checkedBorderColor)
241 | }
242 |
243 | // Handle disabled border color
244 | if (!isEnabled) {
245 | defaultDrawable.setStroke(mBorderWidth, mDisabledBorderColor)
246 | }
247 |
248 |
249 | if (isRippleEffect && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
250 | this.background = getRippleDrawable(defaultDrawable, focusDrawable, disabledDrawable)
251 |
252 | } else {
253 |
254 | val states = StateListDrawable()
255 | // Focus/Pressed Drawable
256 | val drawable2 = GradientDrawable()
257 | drawable2.cornerRadius = mRadius.toFloat()
258 | drawable2.setColor(focusBackgroundColor)
259 |
260 | // Handle Button Border
261 | if (mBorderColor != 0) {
262 | drawable2.setStroke(mBorderWidth, mBorderColor)
263 | }
264 |
265 | if (!isEnabled) {
266 | drawable2.setStroke(mBorderWidth, mDisabledBorderColor)
267 | }
268 |
269 | if (focusBackgroundColor != 0) {
270 | states.addState(intArrayOf(android.R.attr.state_pressed), drawable2)
271 | states.addState(intArrayOf(android.R.attr.state_focused), drawable2)
272 | states.addState(intArrayOf(-android.R.attr.state_enabled), disabledDrawable)
273 | states.addState(intArrayOf(-android.R.attr.state_enabled, -android.R.attr.state_checked), disabledDrawable2)
274 | }
275 | if (checkedBackgroundColor != 0) {
276 | states.addState(intArrayOf(android.R.attr.state_checked), drawable3)
277 | states.addState(intArrayOf(-android.R.attr.state_checked), defaultDrawable)
278 | }
279 | states.addState(intArrayOf(), defaultDrawable)
280 |
281 |
282 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
283 | this.setBackgroundDrawable(states)
284 | } else {
285 | this.background = states
286 | }
287 |
288 | }
289 | }
290 |
291 |
292 | @TargetApi(Build.VERSION_CODES.LOLLIPOP)
293 | private fun getRippleDrawable(defaultDrawable: Drawable, focusDrawable: Drawable, disabledDrawable: Drawable): Drawable {
294 | if (!isEnabled) {
295 | return disabledDrawable
296 | } else {
297 | return RippleDrawable(ColorStateList.valueOf(focusBackgroundColor), defaultDrawable, focusDrawable)
298 | }
299 |
300 | }
301 |
302 | override fun setChecked(checked: Boolean) {
303 | if (isChecked && !checked) {
304 | switchToHide()
305 | isChecked = false
306 | } else if (!isChecked && checked) {
307 | switchToCheck()
308 | isChecked = true
309 | }
310 | textView!!.setTextColor(if (checked) checkedTextColor else uncheckedTextColor)
311 | refreshDrawableState()
312 | if (mListener != null) {
313 | mListener!!.onCheckedChanged(this, checked)
314 | }
315 | }
316 |
317 | private fun switchToCheck() {
318 | //Might apply checked animations in the future
319 | //invalidate();
320 | }
321 |
322 | private fun switchToHide() {
323 | //Might apply checked animations in the future
324 | // invalidate();
325 | }
326 |
327 |
328 | override fun onDraw(canvas: Canvas) {
329 | super.onDraw(canvas)
330 | }
331 |
332 | public override fun onCreateDrawableState(extraSpace: Int): IntArray {
333 | val drawableState = super.onCreateDrawableState(extraSpace + 1)
334 | if (isChecked()) {
335 | View.mergeDrawableStates(drawableState, CHECKED_STATE_SET)
336 | }
337 | return drawableState
338 | }
339 |
340 | override fun isChecked(): Boolean {
341 | return isChecked
342 | }
343 |
344 | override fun toggle() {
345 | this.setChecked(!isChecked())
346 | }
347 |
348 | fun setOnCheckChangeLisnter(onCheckChangeListener: OnCheckedChangeListener) {
349 | mListener = onCheckChangeListener
350 | }
351 |
352 | interface OnCheckedChangeListener {
353 | fun onCheckedChanged(buttonView: View, isChecked: Boolean)
354 | }
355 |
356 | fun getCheckedBackgroundColor(): Int {
357 | return checkedBackgroundColor
358 | }
359 |
360 | fun setCheckedBackgroundColor(checkedBackgroundColor: Int) {
361 | this.checkedBackgroundColor = checkedBackgroundColor
362 | setupBackground()
363 | }
364 |
365 | fun getUncheckedBackgroundColor(): Int {
366 | return uncheckedBackgroundColor
367 | }
368 |
369 | fun setUncheckedBackgroundColor(uncheckedBackgroundColor: Int) {
370 | this.uncheckedBackgroundColor = uncheckedBackgroundColor
371 | setupBackground()
372 | }
373 |
374 | var disabledBackgroundColor: Int
375 | get() = mDisabledBackgroundColor
376 | set(mDisabledBackgroundColor) {
377 | this.mDisabledBackgroundColor = mDisabledBackgroundColor
378 | setupBackground()
379 | }
380 |
381 | var disabledBorderColor: Int
382 | get() = mDisabledBorderColor
383 | set(mDisabledBorderColor) {
384 | this.mDisabledBorderColor = mDisabledBorderColor
385 | setupBackground()
386 | }
387 |
388 | fun getUncheckedTextColor(): Int {
389 | return uncheckedTextColor
390 | }
391 |
392 | fun setUncheckedTextColor(uncheckedTextColor: Int) {
393 | this.uncheckedTextColor = uncheckedTextColor
394 | setupBackground()
395 | }
396 |
397 | var defaultTextSize: Int
398 | get() = mDefaultTextSize
399 | set(mDefaultTextSize) {
400 | this.mDefaultTextSize = CheckableUtils.spToPx(context, mDefaultTextSize.toFloat())
401 | }
402 |
403 | var text: String
404 | get() = mText
405 | set(text) = if (textView != null)
406 | this.textView!!.text = text
407 | else
408 | mText = text
409 |
410 | var borderColor: Int
411 | get() = mBorderColor
412 | set(mBorderColor) {
413 | this.mBorderColor = mBorderColor
414 | setupBackground()
415 | }
416 |
417 | fun getCheckedBorderColor(): Int {
418 | return checkedBorderColor
419 | }
420 |
421 | fun setCheckedBorderColor(checkedBorderColor: Int) {
422 | this.checkedBorderColor = checkedBorderColor
423 | setupBackground()
424 | }
425 |
426 | var borderWidth: Int
427 | get() = mBorderWidth
428 | set(mBorderWidth) {
429 | this.mBorderWidth = mBorderWidth
430 | setupBackground()
431 | }
432 |
433 | fun getCheckedBorderWidth(): Int {
434 | return checkedBorderWidth
435 | }
436 |
437 | fun setCheckedBorderWidth(checkedBorderWidth: Int) {
438 | this.checkedBorderWidth = checkedBorderWidth
439 | setupBackground()
440 | }
441 |
442 | var radius: Int
443 | get() = mRadius
444 | set(mRadius) {
445 | this.mRadius = mRadius
446 | setupBackground()
447 | }
448 |
449 | companion object {
450 | private val CHECKED_STATE_SET = intArrayOf(android.R.attr.state_checked)
451 | }
452 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/common/view/CheckableUtils.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.common.view
2 |
3 | import android.content.Context
4 | import android.content.res.AssetManager
5 | import android.graphics.Typeface
6 | import android.text.TextUtils
7 |
8 | import java.io.File
9 | import java.util.Arrays
10 | import java.util.HashMap
11 |
12 | object CheckableUtils {
13 | private val cachedFontMap = HashMap()
14 |
15 | fun pxToSp(context: Context, px: Float): Int {
16 | return Math.round(px / context.resources.displayMetrics.scaledDensity)
17 | }
18 |
19 | fun spToPx(context: Context, sp: Float): Int {
20 | return Math.round(sp * context.resources.displayMetrics.scaledDensity)
21 | }
22 |
23 | fun findFont(context: Context, fontPath: String?, defaultFontPath: String?): Typeface? {
24 |
25 | if (fontPath == null) {
26 | return Typeface.DEFAULT
27 | }
28 |
29 | val fontName = File(fontPath).name
30 | var defaultFontName = ""
31 | if (!TextUtils.isEmpty(defaultFontPath)) {
32 | defaultFontName = File(defaultFontPath).name
33 | }
34 |
35 | if (cachedFontMap.containsKey(fontName)) {
36 | return cachedFontMap[fontName]
37 | } else {
38 | try {
39 | val assets = context.resources.assets
40 |
41 | if (Arrays.asList(*assets.list("")).contains(fontPath)) {
42 | val typeface = Typeface.createFromAsset(context.assets, fontName)
43 | cachedFontMap.put(fontName, typeface)
44 | return typeface
45 | } else if (Arrays.asList(*assets.list("fonts")).contains(fontName)) {
46 | val typeface = Typeface.createFromAsset(context.assets, String.format("fonts/%s", fontName))
47 | cachedFontMap.put(fontName, typeface)
48 | return typeface
49 | } else if (Arrays.asList(*assets.list("iconfonts")).contains(fontName)) {
50 | val typeface = Typeface.createFromAsset(context.assets, String.format("iconfonts/%s", fontName))
51 | cachedFontMap.put(fontName, typeface)
52 | return typeface
53 | } else if (!TextUtils.isEmpty(defaultFontPath) && Arrays.asList(*assets.list("")).contains(defaultFontPath)) {
54 | val typeface = Typeface.createFromAsset(context.assets, defaultFontPath)
55 | cachedFontMap.put(defaultFontName, typeface)
56 | return typeface
57 | } else {
58 | throw Exception("Font not Found")
59 | }
60 |
61 | } catch (e: Exception) {
62 | return Typeface.DEFAULT
63 | }
64 |
65 | }
66 |
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/events/BaseEvent.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.events
2 |
3 | interface BaseEvent
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/AddHabitComponent.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitActivity
4 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitFragment
5 | import com.vrgsoft.mygoal.presentation.main.habits.HabitsActivity
6 | import com.vrgsoft.mygoal.presentation.main.showhabit.ShowHabitFragment
7 | import dagger.Component
8 |
9 | @PerActivity
10 | @Component(dependencies = arrayOf(ApplicationComponent::class))
11 | interface AddHabitComponent {
12 | fun inject(habitsActivity: AddHabitActivity)
13 | fun inject(habitsActivity: AddHabitFragment)
14 | fun inject(habitsActivity: ShowHabitFragment)
15 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/App.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | import android.content.Context
4 | import android.support.multidex.MultiDex
5 | import android.support.multidex.MultiDexApplication
6 | import com.vrgsoft.mygoal.presentation.common.SettingsHelper
7 | import io.realm.Realm
8 | import io.realm.RealmConfiguration
9 |
10 |
11 |
12 |
13 | class App : MultiDexApplication(), HasComponent {
14 |
15 |
16 | companion object {
17 | lateinit var applicationComponent: ApplicationComponent
18 | var settings: SettingsHelper = SettingsHelper()
19 |
20 | }
21 |
22 | override fun onCreate() {
23 | super.onCreate()
24 | settings.init(this)
25 | Realm.init(applicationContext)
26 | initializeInjector()
27 | initRealmConfiguration()
28 | // settings.setDisabledAds(false)//disable ads
29 | }
30 |
31 |
32 |
33 |
34 | private fun initializeInjector() {
35 | applicationComponent = DaggerApplicationComponent.builder()
36 | .applicationModule(ApplicationModule(this))
37 | .dataModule(DataModule())
38 | .domainModule(DomainModule()).build();
39 | }
40 |
41 | private fun initRealmConfiguration() {
42 | val realmConfiguration = RealmConfiguration.Builder()
43 | .deleteRealmIfMigrationNeeded()
44 | .build()
45 | Realm.setDefaultConfiguration(realmConfiguration)
46 | }
47 |
48 | override val component: ApplicationComponent
49 | get() = applicationComponent
50 |
51 | override fun attachBaseContext(base: Context) {
52 | super.attachBaseContext(base)
53 | MultiDex.install(this)
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/ApplicationComponent.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | import javax.inject.Singleton
4 |
5 | import dagger.Component
6 | import io.realm.Realm
7 |
8 | @Singleton
9 | @Component(modules = arrayOf(ApplicationModule::class, DataModule::class, DomainModule::class))
10 | interface ApplicationComponent {
11 | fun provideRealm(): Realm
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/ApplicationModule.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import android.content.SharedPreferences
6 | import android.preference.PreferenceManager
7 | import com.vrgsoft.mygoal.data.db.habits.HabitsRepositoryLocalImp
8 | import com.vrgsoft.mygoal.domain.habits.HabitsRepository
9 |
10 | import javax.inject.Singleton
11 |
12 | import dagger.Module
13 | import dagger.Provides
14 |
15 | @Module
16 | class ApplicationModule(private val mApplication: Application) {
17 |
18 | @Provides
19 | @Singleton
20 | fun provideContext(): Context {
21 | return mApplication.applicationContext
22 | }
23 |
24 | @Provides
25 | @Singleton
26 | fun provideSharedPreferences(context: Context): SharedPreferences {
27 | return PreferenceManager.getDefaultSharedPreferences(context)
28 | }
29 |
30 | @Provides
31 | @Singleton
32 | fun provideHabitRepositoryLocal(): HabitsRepository {
33 | return HabitsRepositoryLocalImp()
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/DataModule.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | import dagger.Module
4 | import dagger.Provides
5 | import io.realm.Realm
6 |
7 | @Module
8 | class DataModule {
9 | @Provides
10 | fun provideRealm(): Realm {
11 | return Realm.getDefaultInstance()
12 | }
13 |
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/DomainModule.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | import dagger.Module
4 |
5 | @Module
6 | class DomainModule
7 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/HabitsComponent.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | import com.vrgsoft.mygoal.presentation.main.habits.HabitsActivity
4 | import com.vrgsoft.mygoal.presentation.main.habits.HabitsFragment
5 | import dagger.Component
6 | import javax.inject.Singleton
7 |
8 | @PerActivity
9 | @Component(dependencies = arrayOf(ApplicationComponent::class))
10 | interface HabitsComponent {
11 | fun inject(habitsActivity: HabitsActivity)
12 | fun inject(fragment: HabitsFragment)
13 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/HasComponent.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | interface HasComponent {
4 | val component: C
5 | }
6 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/injection/PerActivity.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.injection
2 |
3 | import java.lang.annotation.Retention
4 | import java.lang.annotation.RetentionPolicy
5 |
6 | import javax.inject.Scope
7 |
8 | @Scope
9 | @Retention(RetentionPolicy.RUNTIME)
10 | annotation class PerActivity
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/SplashActivity.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main
2 |
3 | import android.content.Intent
4 | import android.support.v7.app.AppCompatActivity
5 | import android.os.Bundle
6 | import android.view.View
7 | import android.view.Window
8 | import android.view.WindowManager
9 | import android.view.animation.Animation
10 | import android.view.animation.AnimationUtils
11 | import android.widget.ImageView
12 |
13 | import com.vrgsoft.mygoal.R
14 | import com.vrgsoft.mygoal.presentation.main.habits.HabitsActivity
15 |
16 | class SplashActivity : AppCompatActivity() {
17 |
18 | lateinit var ivSplashCircle:ImageView
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | requestWindowFeature(Window.FEATURE_NO_TITLE)
23 | window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
24 | WindowManager.LayoutParams.FLAG_FULLSCREEN)
25 | setContentView(R.layout.activity_splash)
26 | setContentView(R.layout.activity_splash)
27 | window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
28 |
29 | ivSplashCircle = findViewById(R.id.iv_cirlce) as ImageView
30 |
31 | val animation = AnimationUtils.loadAnimation(this, R.anim.move_anim)
32 | animation.setAnimationListener(object : Animation.AnimationListener {
33 | override fun onAnimationStart(animation: Animation) {
34 |
35 | }
36 |
37 | override fun onAnimationEnd(animation: Animation) {
38 | startActivity(Intent(this@SplashActivity, HabitsActivity::class.java))
39 | finish()
40 | }
41 |
42 | override fun onAnimationRepeat(animation: Animation) {
43 |
44 | }
45 | })
46 | ivSplashCircle.startAnimation(animation)
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/addhabit/AddHabitActivity.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.addhabit
2 |
3 | import android.os.Bundle
4 |
5 | import com.vrgsoft.mygoal.R
6 | import com.vrgsoft.mygoal.databinding.ActivityAddHabitBinding
7 | import com.vrgsoft.mygoal.presentation.common.BaseActivity
8 | import com.vrgsoft.mygoal.presentation.common.Layout
9 | import com.vrgsoft.mygoal.presentation.injection.AddHabitComponent
10 | import com.vrgsoft.mygoal.presentation.injection.DaggerAddHabitComponent
11 | import com.vrgsoft.mygoal.presentation.main.habits.common.themedialog.OnThemeChooseCallBack
12 | import com.vrgsoft.mygoal.presentation.main.habits.common.themedialog.ThemeViewModel
13 | import com.vrgsoft.mygoal.presentation.main.showhabit.ShowHabitFragment
14 |
15 | @Layout(id = R.layout.activity_add_habit)
16 | class AddHabitActivity : BaseActivity(), OnThemeChooseCallBack {
17 | lateinit var addHabitComponent: AddHabitComponent
18 | lateinit var addHabitFragment: AddHabitFragment
19 |
20 | lateinit var showHabitFragment: ShowHabitFragment
21 | val NEW_EXTRA: String = "new_extra"
22 | val ID_EXTRA: String = "id_extra"
23 | override fun initComponent() {
24 | addHabitComponent = DaggerAddHabitComponent.builder()
25 | .applicationComponent(applicationComponent)
26 | .build()
27 | }
28 |
29 | override val activity: AddHabitActivity
30 | get() = this
31 |
32 | override fun onCreate(savedInstanceState: Bundle?) {
33 | super.onCreate(savedInstanceState)
34 | if (intent.getBooleanExtra(NEW_EXTRA, true)) {
35 | addHabitFragment = AddHabitFragment.newInstance(intent.getLongExtra(ID_EXTRA, 0))
36 | supportFragmentManager.beginTransaction().replace(R.id.container, addHabitFragment).commit()
37 | } else {
38 | showHabitFragment = ShowHabitFragment.newInstance(intent.getLongExtra(ID_EXTRA, 0))
39 | supportFragmentManager.beginTransaction().replace(R.id.container, showHabitFragment).commit()
40 | }
41 | }
42 |
43 | override fun onThemeClick(themeViewModel: ThemeViewModel) {
44 | addHabitFragment.setThemeImage(themeViewModel)
45 | }
46 |
47 | fun showEditFragment() {
48 | addHabitFragment = AddHabitFragment.newInstance(intent.getLongExtra(ID_EXTRA, 0))
49 | supportFragmentManager.beginTransaction().replace(R.id.container, addHabitFragment).commit()
50 | }
51 |
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/addhabit/AddHabitFragment.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.addhabit
2 |
3 |
4 | import android.annotation.SuppressLint
5 | import android.app.DialogFragment
6 | import android.os.Bundle
7 |
8 | import android.support.v7.widget.Toolbar
9 | import com.vrgsoft.mygoal.R
10 | import com.vrgsoft.mygoal.data.db.alerts.Goal
11 | import com.vrgsoft.mygoal.databinding.FragmentAddHabitBinding
12 | import com.vrgsoft.mygoal.presentation.common.BaseFragment
13 | import com.vrgsoft.mygoal.presentation.common.BasePresenter
14 | import com.vrgsoft.mygoal.presentation.common.BaseView
15 | import com.vrgsoft.mygoal.presentation.common.Layout
16 | import org.jetbrains.anko.onClick
17 | import javax.inject.Inject
18 | import android.text.format.DateFormat
19 | import android.view.ViewGroup
20 | import com.philliphsu.bottomsheetpickers.time.BottomSheetTimePickerDialog
21 | import com.philliphsu.bottomsheetpickers.time.grid.GridTimePickerDialog
22 | import com.squareup.picasso.Picasso
23 | import com.vrgsoft.mygoal.presentation.main.habits.common.themedialog.ThemeDialogFragment
24 | import com.vrgsoft.mygoal.presentation.main.habits.common.themedialog.ThemeViewModel
25 | import com.vrgsoft.mygoal.presentation.receivers.AlarmReceiver
26 | import org.jetbrains.anko.imageResource
27 | import java.text.SimpleDateFormat
28 |
29 | import java.util.*
30 | import java.util.concurrent.TimeUnit
31 |
32 |
33 | @Layout(id = R.layout.fragment_add_habit)
34 | class AddHabitFragment : BaseFragment(), AddHabitView, BottomSheetTimePickerDialog.OnTimeSetListener {
35 |
36 |
37 | lateinit var themeDialog: DialogFragment
38 | var chosenTime: Long = Calendar.getInstance().timeInMillis
39 | var chosenTheme: Int = R.drawable.other_icon
40 | val EMOJI_TAG: String = "EmojiDialog"
41 | val DIALOG_TAG: String = "Dialog"
42 | override fun onTimeSet(viewGroup: ViewGroup?, hourOfDay: Int, minute: Int) {
43 | val cal: GregorianCalendar = GregorianCalendar()
44 | cal.set(Calendar.HOUR_OF_DAY, hourOfDay)
45 | cal.set(Calendar.MINUTE, minute)
46 | binding!!.notifyTime.text = DateFormat.getTimeFormat(context).format(cal.time)
47 | chosenTime = if (cal.timeInMillis <= System.currentTimeMillis()) cal.timeInMillis + TimeUnit.DAYS.toMillis(1) else cal.timeInMillis
48 |
49 | }
50 |
51 | companion object {
52 | val ID_EXTRA: String = "id_extra"
53 | fun newInstance(mId: Long): AddHabitFragment {
54 | val mBundl: Bundle = Bundle()
55 | mBundl.putLong(ID_EXTRA, mId)
56 | val fragment: AddHabitFragment = AddHabitFragment()
57 | fragment.arguments = mBundl
58 | return fragment
59 | }
60 | }
61 |
62 | @Inject
63 | lateinit var mHabitPresenter: AddHabitPresenter
64 | override val toolbar: Toolbar?
65 | get() = null
66 |
67 | override fun onActivityCreated(savedInstanceState: Bundle?) {
68 | super.onActivityCreated(savedInstanceState)
69 | if (this.arguments.getLong(ID_EXTRA, 0) == 0.toLong()) {
70 | initView()
71 | } else {
72 | mHabitPresenter.getGoal(this.arguments.getLong(ID_EXTRA, 0))
73 | }
74 | }
75 |
76 | override fun toolbarNavigationActive(): Boolean {
77 | return false
78 | }
79 |
80 | override val presenter: BasePresenter
81 | get() = mHabitPresenter as BasePresenter
82 |
83 | override fun initView() {
84 |
85 | val currentTime: String = SimpleDateFormat("HH:mm").format(Calendar.getInstance().time)
86 | binding!!.notifyTime.text = currentTime
87 | if (binding!!.checkBox.isChecked) {
88 | chosenTime = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)
89 | } else {
90 | chosenTime = 0
91 | }
92 | binding!!.saveHabit.onClick {
93 |
94 | mHabitPresenter.saveHabit(binding!!.habitName.editText!!.text.toString(),
95 | binding!!.habitDescription.editText!!.text.toString(), chosenTime, chosenTheme, this.arguments.getLong(ID_EXTRA, 0))
96 |
97 | if (binding!!.checkBox.isChecked) {
98 | AlarmReceiver.updateDailyReminder(context)
99 | }
100 |
101 | activity.finish()
102 | }
103 |
104 |
105 | binding!!.notifyTime.onClick {
106 | GridTimePickerDialog.newInstance(this, Calendar.getInstance().get(Calendar.HOUR_OF_DAY),
107 | Calendar.getInstance().get(Calendar.MINUTE), DateFormat.is24HourFormat(context)).show(activity.supportFragmentManager, DIALOG_TAG)
108 |
109 | }
110 |
111 |
112 | binding!!.emoji.onClick {
113 |
114 | themeDialog = ThemeDialogFragment().newInstance()
115 | themeDialog.show(activity.fragmentManager, EMOJI_TAG)
116 | }
117 |
118 |
119 | }
120 |
121 | override fun setGoal(goal: Goal) {
122 |
123 | binding!!.goal = goal
124 | Picasso.with(context).load(goal.mImage).into(binding!!.emoji)
125 | if (goal.mTime != 0.toLong()) {
126 | val currentTime: String = SimpleDateFormat("HH:mm").format(goal.mTime)
127 | binding!!.notifyTime.text = currentTime
128 | }
129 |
130 | }
131 |
132 | override fun inject() {
133 | val habitsComponent = (activity as AddHabitActivity).addHabitComponent
134 | habitsComponent.inject(this)
135 | }
136 |
137 | fun setThemeImage(themeViewModel: ThemeViewModel) {
138 | binding!!.emoji.imageResource = themeViewModel.ivTheme
139 | chosenTheme = themeViewModel.ivTheme
140 | themeDialog.dismiss()
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/addhabit/AddHabitPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.addhabit
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import com.vrgsoft.mygoal.domain.habits.HabitInteractor
5 | import com.vrgsoft.mygoal.presentation.common.BasePresenter
6 | import com.vrgsoft.mygoal.presentation.main.habits.HabitsRouter
7 | import javax.inject.Inject
8 |
9 | class AddHabitPresenter @Inject constructor(habitsInteractor: HabitInteractor) : BasePresenter() {
10 | val mHabitInteractor: HabitInteractor = habitsInteractor
11 |
12 | override fun onStart() {
13 |
14 | }
15 |
16 | override fun onStop() {
17 | }
18 |
19 | fun saveHabit(habitName: String, habitDescr: String, time:Long, theme:Int, id :Long) {
20 | val goal: Goal = Goal()
21 | goal.mId = id
22 | goal.mDescr = habitDescr
23 | goal.mName = habitName
24 | goal.mTime = time
25 | goal.mImage = theme
26 | mHabitInteractor.saveHabit(goal)
27 | }
28 |
29 | fun getGoal(mId: Long) {
30 | mHabitInteractor.getGoal(mId).subscribe({ goal: Goal -> view!!.setGoal(goal) }, Throwable::printStackTrace)
31 | }
32 |
33 | fun getGoalBuId(id:Long):Goal{
34 | return mHabitInteractor.getGoalById(id)
35 | }
36 |
37 | fun getAllHabits():List{
38 | return mHabitInteractor.getAllHabits()
39 | }
40 |
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/addhabit/AddHabitView.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.addhabit
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import com.vrgsoft.mygoal.presentation.common.BaseView
5 |
6 | interface AddHabitView : BaseView {
7 | fun setGoal(goal: Goal)
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/HabitsActivity.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import com.vrgsoft.mygoal.R
6 | import com.vrgsoft.mygoal.databinding.ActivityHabitsBinding
7 | import com.vrgsoft.mygoal.presentation.common.BaseActivity
8 | import com.vrgsoft.mygoal.presentation.common.Layout
9 | import com.vrgsoft.mygoal.presentation.injection.DaggerHabitsComponent
10 | import com.vrgsoft.mygoal.presentation.injection.HabitsComponent
11 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitActivity
12 | import org.jetbrains.anko.intentFor
13 | import org.jetbrains.anko.support.v4.intentFor
14 |
15 |
16 | @Layout(id = R.layout.activity_habits)
17 | class HabitsActivity : BaseActivity(), HabitsRouter {
18 | val NEW_EXTRA: String = "new_extra"
19 | val ID_EXTRA: String = "id_extra"
20 | lateinit var habitsComponent: HabitsComponent
21 |
22 | override fun initComponent() {
23 | habitsComponent = DaggerHabitsComponent.builder()
24 | .applicationComponent(applicationComponent)
25 | .build()
26 | }
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | supportFragmentManager.beginTransaction().replace(R.id.container, HabitsFragment.newInstance()).commit()
31 |
32 |
33 | }
34 |
35 |
36 | override fun onBackPressed() {
37 | finishAffinity()
38 |
39 | }
40 |
41 | override val activity: HabitsActivity
42 | get() = this
43 |
44 | override fun openGoal(isNew: Boolean, id: Long) {
45 | val intent: Intent = intentFor()
46 | intent.putExtra(ID_EXTRA, id)
47 | intent.putExtra(NEW_EXTRA, isNew)
48 | startActivity(intent)
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/HabitsFragment.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits
2 |
3 |
4 | import android.content.Intent
5 | import android.support.v4.app.Fragment
6 | import android.support.v7.widget.LinearLayoutManager
7 | import android.support.v7.widget.PopupMenu
8 | import android.support.v7.widget.Toolbar
9 | import android.view.View
10 | import com.vrgsoft.mygoal.R
11 | import com.vrgsoft.mygoal.data.db.alerts.Goal
12 | import com.vrgsoft.mygoal.databinding.FragmentHabitsBinding
13 | import com.vrgsoft.mygoal.presentation.common.BaseFragment
14 | import com.vrgsoft.mygoal.presentation.common.BasePresenter
15 | import com.vrgsoft.mygoal.presentation.common.BaseView
16 | import com.vrgsoft.mygoal.presentation.common.Layout
17 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitActivity
18 | import com.vrgsoft.mygoal.presentation.main.habits.common.GoalClickListener
19 | import com.vrgsoft.mygoal.presentation.main.habits.common.HabitsAdapter
20 | import org.jetbrains.anko.onClick
21 | import org.jetbrains.anko.support.v4.intentFor
22 | import javax.inject.Inject
23 |
24 |
25 | /**
26 | * A simple [Fragment] subclass.
27 | */
28 | @Layout(id = R.layout.fragment_habits)
29 | open class HabitsFragment : BaseFragment(), HabitsView, GoalClickListener {
30 | val NEW_EXTRA: String = "isNew"
31 |
32 | companion object {
33 | fun newInstance(): Fragment {
34 | val habitsFragment: HabitsFragment = HabitsFragment()
35 | return habitsFragment
36 | }
37 | }
38 |
39 |
40 | override fun setList(goals: List, mListener: GoalClickListener) {
41 |
42 | val mAdapter: HabitsAdapter = HabitsAdapter(goals, mListener, activity)
43 |
44 | binding!!.habbitsContainer.adapter = mAdapter
45 | binding!!.habbitsContainer.layoutManager = LinearLayoutManager(context)
46 |
47 | }
48 |
49 |
50 | @Inject
51 | lateinit var habitsPresenter: HabitsPresenter
52 |
53 | override val presenter: BasePresenter
54 | get() = habitsPresenter as BasePresenter
55 |
56 | override val toolbar: Toolbar?
57 | get() = null
58 |
59 | override fun toolbarNavigationActive(): Boolean {
60 | return false
61 | }
62 |
63 | override fun initView() {
64 |
65 | binding!!.addHabbit.onClick {
66 | habitsPresenter.openGoal()
67 | }
68 | binding!!.menuButton.onClick {
69 | showPopupMenu(binding!!.menuButton)
70 | }
71 | habitsPresenter.router = activity as HabitsActivity
72 |
73 |
74 | }
75 |
76 | override fun onGoalClick(mGoal: Goal) {
77 | val intent: Intent = intentFor()
78 | intent.putExtra(NEW_EXTRA, false)
79 | activity.startActivity(intent)
80 | }
81 |
82 | override fun inject() {
83 | val habitsComponent = (activity as HabitsActivity).habitsComponent
84 | habitsComponent.inject(this)
85 |
86 | }
87 |
88 |
89 | private fun showPopupMenu(v: View) {
90 | val popupMenu = PopupMenu(context, v)
91 | popupMenu.inflate(R.menu.main_menu)
92 | popupMenu
93 | .setOnMenuItemClickListener { item ->
94 | when (item.itemId) {
95 | else -> false
96 | }
97 | }
98 | popupMenu.show()
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/HabitsPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import com.vrgsoft.mygoal.domain.habits.HabitsInteractor
5 | import com.vrgsoft.mygoal.presentation.common.BasePresenter
6 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitActivity
7 | import com.vrgsoft.mygoal.presentation.main.habits.common.GoalClickListener
8 | import org.jetbrains.anko.support.v4.intentFor
9 | import javax.inject.Inject
10 |
11 | class HabitsPresenter @Inject constructor(habitsInteractor: HabitsInteractor) : BasePresenter(), GoalClickListener {
12 |
13 |
14 | override fun onGoalClick(mGoal: Goal) {
15 | router!!.openGoal(false, mGoal.mId);
16 | }
17 |
18 | val mHabitInteractor: HabitsInteractor = habitsInteractor
19 |
20 | override fun onStart() {
21 |
22 | mHabitInteractor.getGoals().subscribe({ goal: List -> view?.setList(goal, this) },
23 | { t: Throwable? -> t!!.printStackTrace() })
24 | }
25 |
26 | override fun onStop() {
27 | }
28 |
29 | fun openGoal() {
30 | router!!.openGoal(true, 0)
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/HabitsRouter.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits
2 |
3 | interface HabitsRouter {
4 | fun openGoal(isNew: Boolean, id: Long)
5 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/HabitsView.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import com.vrgsoft.mygoal.presentation.common.BaseView
5 | import com.vrgsoft.mygoal.presentation.main.habits.common.GoalClickListener
6 |
7 | interface HabitsView : BaseView {
8 |
9 | fun setList(goals: List,mListener:GoalClickListener)
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/common/GoalClickListener.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits.common
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 |
5 |
6 | interface GoalClickListener {
7 |
8 | fun onGoalClick (mGoal: Goal)
9 |
10 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/common/HabitsAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits.common
2 |
3 | import android.content.Context
4 | import android.databinding.DataBindingUtil
5 | import android.support.v7.widget.RecyclerView
6 | import android.view.LayoutInflater
7 | import android.view.View
8 | import android.view.ViewGroup
9 | import com.squareup.picasso.Picasso
10 | import com.vrgsoft.mygoal.R
11 | import com.vrgsoft.mygoal.data.db.alerts.Goal
12 | import com.vrgsoft.mygoal.databinding.ItemHabitBinding
13 | import java.util.concurrent.TimeUnit
14 |
15 | /**
16 | * Created by pavlonikitin on 3/21/17.
17 | */
18 |
19 | class HabitsAdapter(private val mItems: List,private val listener: GoalClickListener, val context : Context) : RecyclerView.Adapter() {
20 |
21 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
22 | holder.binding.goal = mItems[position]
23 | Picasso.with(context).load(mItems[position].mImage).into(holder.binding.imageView)
24 |
25 | val leftDays:String = (((mItems[position].lastCheck-mItems[position].mLatsDays)/ TimeUnit.DAYS.toMillis(1))*100/21).toString()+" %"
26 | holder.binding.tvDayLeft.text = leftDays
27 | holder.binding.listener = listener
28 | }
29 |
30 | override fun getItemCount(): Int {
31 | return mItems.size
32 | }
33 |
34 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
35 | val layoutInflater = LayoutInflater.from(parent.context)
36 | return ViewHolder(layoutInflater.inflate(R.layout.item_habit, parent, false))
37 | }
38 |
39 |
40 | class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
41 | var binding: ItemHabitBinding = DataBindingUtil.bind(view)
42 |
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/common/resultdialogs/ResultDialog.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits.common.resultdialogs
2 |
3 | import android.content.Intent
4 | import android.databinding.generated.callback.OnClickListener
5 | import android.graphics.Color
6 | import android.os.Bundle
7 | import android.graphics.drawable.ColorDrawable
8 | import android.support.v4.app.DialogFragment
9 | import android.view.ViewGroup
10 | import android.view.LayoutInflater
11 | import android.view.View
12 | import com.vrgsoft.mygoal.R
13 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitActivity
14 | import com.vrgsoft.mygoal.presentation.main.habits.common.themedialog.ThemeDialogFragment
15 |
16 | class ResultDialog : DialogFragment(), View.OnClickListener {
17 | val NEW_EXTRA: String = "new_extra"
18 | companion object {
19 | val FAILED_EXTRA = "failed_extra"
20 | fun newInstance(idFailed: Boolean): DialogFragment {
21 | val resultDialog: ResultDialog = ResultDialog()
22 | val bundle: Bundle = Bundle()
23 | bundle.putBoolean(FAILED_EXTRA, idFailed)
24 | resultDialog.arguments = bundle
25 | return resultDialog
26 | }
27 | }
28 |
29 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
30 | val layout = if (arguments.getBoolean(FAILED_EXTRA)) R.layout.dialog_failed else R.layout.dialog_success
31 | val v = inflater!!.inflate(layout, null)
32 | v.findViewById(R.id.ok).setOnClickListener(this)
33 | dialog.window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
34 | return v
35 | }
36 |
37 |
38 | override fun onCreate(savedInstanceState: Bundle?) {
39 | super.onCreate(savedInstanceState)
40 | setStyle(DialogFragment.STYLE_NO_TITLE, 0)
41 | }
42 |
43 | override fun onClick(view: View) {
44 | val intentLaunchApp = Intent(activity, AddHabitActivity::class.java)
45 | intentLaunchApp.putExtra(NEW_EXTRA, true)
46 | activity.startActivity(intentLaunchApp)
47 | dismiss()
48 | activity.finish()
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/common/themedialog/OnThemeChooseCallBack.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits.common.themedialog
2 |
3 |
4 | interface OnThemeChooseCallBack {
5 |
6 | fun onThemeClick(themeViewModel: ThemeViewModel)
7 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/common/themedialog/ThemeAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits.common.themedialog
2 |
3 | import android.content.Context
4 | import android.support.v7.widget.RecyclerView
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.ImageView
9 | import android.widget.TextView
10 | import com.vrgsoft.mygoal.R
11 |
12 | import com.squareup.picasso.Picasso
13 | import org.jetbrains.anko.onClick
14 |
15 |
16 |
17 | class ThemeAdapter constructor(private val themeViewModel: List, val context: Context) : RecyclerView.Adapter() {
18 |
19 | override fun onBindViewHolder(holder: ThemeViewHolder?, position: Int) {
20 | Picasso.with(context).load(themeViewModel[position].ivTheme).into(holder!!.ivImageTheme)
21 | holder.tvTextTheme.text = themeViewModel[position].tvTheme
22 |
23 | holder.itemView.onClick {
24 | context as OnThemeChooseCallBack
25 | context.onThemeClick(themeViewModel[position])
26 | }
27 |
28 | }
29 |
30 | override fun getItemCount(): Int {
31 | return themeViewModel.size
32 | }
33 |
34 | override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ThemeViewHolder {
35 | val layoutInflater: View = LayoutInflater.from(parent!!.context).inflate(R.layout.item, parent, false)
36 | return ThemeViewHolder(layoutInflater)
37 | }
38 |
39 | class ThemeViewHolder(v: View) : RecyclerView.ViewHolder(v) {
40 |
41 | var ivImageTheme: ImageView = v.findViewById(R.id.theme_icon) as ImageView
42 | var tvTextTheme: TextView = v.findViewById(R.id.theme_name) as TextView
43 |
44 |
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/common/themedialog/ThemeDialogFragment.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits.common.themedialog
2 |
3 | import android.app.DialogFragment
4 | import android.databinding.DataBindingUtil
5 | import android.databinding.ViewDataBinding
6 | import android.os.Bundle
7 | import android.support.v4.app.Fragment
8 | import android.support.v7.widget.LinearLayoutManager
9 | import android.view.LayoutInflater
10 | import android.view.View
11 | import android.view.ViewGroup
12 | import com.bumptech.glide.load.model.stream.StreamStringLoader
13 | import com.vrgsoft.mygoal.R
14 | import com.vrgsoft.mygoal.databinding.FragmentDialogThemeBinding
15 | import com.vrgsoft.mygoal.databinding.ItemBinding
16 | import org.jetbrains.anko.imageResource
17 |
18 |
19 | class ThemeDialogFragment : DialogFragment() {
20 |
21 |
22 | lateinit var binding:FragmentDialogThemeBinding
23 |
24 | fun newInstance(): DialogFragment {
25 | val themeDialogFragment: ThemeDialogFragment = ThemeDialogFragment()
26 | return themeDialogFragment
27 | }
28 |
29 | override fun onCreate(savedInstanceState: Bundle?) {
30 | super.onCreate(savedInstanceState)
31 | setStyle(STYLE_NO_TITLE, 0)
32 |
33 | }
34 |
35 | override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View {
36 | binding = DataBindingUtil.inflate(inflater, R.layout.fragment_dialog_theme, container, false)
37 | binding.recyclerTheme.layoutManager = LinearLayoutManager(activity)
38 | binding.recyclerTheme.adapter=ThemeAdapter(createListViewModels(), activity)
39 | return binding.root
40 |
41 | }
42 |
43 |
44 | fun createListViewModels():ArrayList{
45 | val themeListModel:ArrayList = ArrayList()
46 |
47 | val themeIcon:IntArray = intArrayOf(R.drawable.healthy_icon, R.drawable.money_icon,
48 | R.drawable.self_improvment_icon, R.drawable.sex_dating_icon, R.drawable.work_and_study_icon,
49 | R.drawable.arts_icon, R.drawable.social_icon, R.drawable.home_icon, R.drawable.other_icon)
50 | val themeNames:Array = activity.resources.getStringArray(R.array.themesNames)
51 |
52 | (0..8).mapTo(themeListModel) { ThemeViewModel(themeIcon[it], themeNames[it]) }
53 |
54 | return themeListModel
55 | }
56 |
57 |
58 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/habits/common/themedialog/ThemeViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.habits.common.themedialog
2 |
3 |
4 | class ThemeViewModel(var ivTheme: Int, var tvTheme: String)
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/showhabit/ShowHabbitView.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.showhabit
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 |
5 | interface ShowHabbitView {
6 |
7 | fun setGoal(goal: Goal)
8 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/showhabit/ShowHabitFragment.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.showhabit
2 |
3 |
4 | import android.os.Bundle
5 | import android.support.v4.app.DialogFragment
6 | import android.support.v7.widget.Toolbar
7 | import com.squareup.picasso.Picasso
8 | import com.vrgsoft.mygoal.R
9 | import com.vrgsoft.mygoal.data.db.alerts.Goal
10 | import com.vrgsoft.mygoal.databinding.FragmentShowHabitBinding
11 | import com.vrgsoft.mygoal.presentation.common.BaseFragment
12 | import com.vrgsoft.mygoal.presentation.common.BasePresenter
13 | import com.vrgsoft.mygoal.presentation.common.BaseView
14 | import com.vrgsoft.mygoal.presentation.common.Layout
15 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitActivity
16 | import com.vrgsoft.mygoal.presentation.main.habits.common.resultdialogs.ResultDialog
17 | import com.vrgsoft.mygoal.presentation.receivers.AlarmReceiver
18 | import org.jetbrains.anko.onClick
19 | import java.text.SimpleDateFormat
20 | import java.util.*
21 | import java.util.concurrent.TimeUnit
22 | import javax.inject.Inject
23 | import az.plainpie.animation.PieAngleAnimation
24 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitFragment.Companion.ID_EXTRA
25 |
26 |
27 | @Layout(id = R.layout.fragment_show_habit)
28 | class ShowHabitFragment : BaseFragment(), ShowHabbitView {
29 | val TAG_FAILED = "Failed"
30 | override fun setGoal(goal: Goal) {
31 | binding!!.goal = goal
32 | if (goal.mTime != 0.toLong()) {
33 | val currentTime: String = SimpleDateFormat("HH:mm").format(goal.mTime)
34 | binding!!.notifyTimeToShow.text = currentTime
35 | } else {
36 | binding!!.notifyTimeToShow.text = getString(R.string.none)
37 | }
38 |
39 | Picasso.with(context).load(goal.mImage).into(binding!!.emojiShow)
40 |
41 |
42 | var percentage: Float = (((goal.lastCheck - goal.mLatsDays) / TimeUnit.DAYS.toMillis(1)) * 100 / 21).toFloat()
43 | if (percentage == 0.toFloat()) {
44 | percentage = 0.1.toFloat()
45 | }
46 | binding!!.pieView.percentage = percentage
47 |
48 | val animation = PieAngleAnimation(binding!!.pieView)
49 | animation.duration = 1500
50 | binding!!.pieView.startAnimation(animation)
51 |
52 | val calLastCheck: Calendar = Calendar.getInstance()
53 | calLastCheck.timeInMillis = goal.lastCheck
54 | calLastCheck.set(Calendar.HOUR_OF_DAY, 0)
55 | calLastCheck.set(Calendar.MINUTE, 1)
56 |
57 | if ((System.currentTimeMillis() - calLastCheck.timeInMillis) > TimeUnit.DAYS.toMillis(2)) {
58 |
59 | val failedDialog: DialogFragment = ResultDialog.newInstance(true)
60 | failedDialog.show(fragmentManager, TAG_FAILED)
61 | mHabitPresenter.deleteGoalById(goal)
62 | } else {
63 | if ((calLastCheck.timeInMillis + TimeUnit.DAYS.toMillis(1)) <= System.currentTimeMillis()) {
64 | binding!!.checkHabbit.isEnabled = true
65 | binding!!.checkHabbit.onClick {
66 | mHabitPresenter.check(goal)
67 | AlarmReceiver.updateDailyReminder(context)
68 | if ((goal.mLatsDays + goal.mTwentyOne) <= System.currentTimeMillis()) {
69 | val failedDialog: DialogFragment = ResultDialog.newInstance(false)
70 | failedDialog.show(fragmentManager, TAG_FAILED)
71 | mHabitPresenter.deleteGoalById(goal)
72 | }
73 | binding!!.checkHabbit.isEnabled = false
74 | activity.finish()
75 | }
76 | } else {
77 | binding!!.checkHabbit.isEnabled = false
78 | }
79 | }
80 |
81 | }
82 |
83 | override val toolbar: Toolbar?
84 | get() = null
85 |
86 | companion object {
87 | fun newInstance(mId: Long): ShowHabitFragment {
88 | val mBundl: Bundle = Bundle()
89 | mBundl.putLong(ID_EXTRA, mId)
90 | val fragment: ShowHabitFragment = ShowHabitFragment()
91 | fragment.arguments = mBundl
92 | return fragment
93 | }
94 | }
95 |
96 | @Inject
97 | lateinit var mHabitPresenter: ShowHabitPresenter
98 |
99 | override fun toolbarNavigationActive(): Boolean {
100 | return false
101 | }
102 |
103 | override fun initView() {
104 | binding!!.ivEdit.onClick {
105 | val tmp: AddHabitActivity = activity as AddHabitActivity
106 | tmp.showEditFragment()
107 | }
108 | }
109 |
110 | override fun inject() {
111 | val habitsComponent = (activity as AddHabitActivity).addHabitComponent
112 | habitsComponent.inject(this)
113 | }
114 |
115 | override val presenter: BasePresenter
116 | get() = mHabitPresenter as BasePresenter
117 |
118 | override fun onActivityCreated(savedInstanceState: Bundle?) {
119 | super.onActivityCreated(savedInstanceState)
120 |
121 | mHabitPresenter.getGoal(this.arguments.getLong(ID_EXTRA, 0))
122 |
123 | initView()
124 | }
125 |
126 |
127 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/main/showhabit/ShowHabitPresenter.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.main.showhabit
2 |
3 | import com.vrgsoft.mygoal.data.db.alerts.Goal
4 | import com.vrgsoft.mygoal.domain.habits.HabitInteractor
5 | import com.vrgsoft.mygoal.presentation.common.BasePresenter
6 | import com.vrgsoft.mygoal.presentation.main.habits.HabitsRouter
7 | import javax.inject.Inject
8 |
9 | /**
10 | * Created by Павел on 04.04.2017.
11 | */
12 | class ShowHabitPresenter @Inject constructor(habitsInteractor: HabitInteractor) : BasePresenter(){
13 |
14 | val mHabitInteractor: HabitInteractor = habitsInteractor
15 |
16 |
17 | override fun onStart() {
18 |
19 | }
20 |
21 | override fun onStop() {
22 |
23 | }
24 |
25 | fun showHabit() {
26 |
27 | }
28 |
29 | fun getGoal(mId: Long) {
30 | mHabitInteractor.getGoal(mId).subscribe({ goal: Goal -> view!!.setGoal(goal) }, Throwable::printStackTrace)
31 |
32 | }
33 |
34 | fun check(goal: Goal){
35 | mHabitInteractor.check(goal)
36 | }
37 |
38 | fun deleteGoalById(goal: Goal){
39 | mHabitInteractor.deleteGoalById(goal)
40 | }
41 |
42 | fun getGoalById(id:Long){
43 | mHabitInteractor.getGoalById(id)
44 | }
45 |
46 |
47 |
48 |
49 |
50 |
51 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/receivers/AlarmReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.receivers
2 |
3 | import android.annotation.TargetApi
4 | import android.app.AlarmManager
5 | import android.app.Notification
6 | import android.app.NotificationManager
7 | import android.app.PendingIntent
8 | import android.content.BroadcastReceiver
9 | import android.content.Context
10 | import android.content.Intent
11 | import android.graphics.BitmapFactory
12 | import android.os.Build
13 | import android.support.annotation.RequiresApi
14 | import android.support.v4.app.NotificationCompat
15 | import com.vrgsoft.mygoal.R
16 | import com.vrgsoft.mygoal.data.db.alerts.Goal
17 | import com.vrgsoft.mygoal.data.db.habits.HabitsRepositoryLocalImp
18 | import com.vrgsoft.mygoal.domain.habits.HabitInteractor
19 | import com.vrgsoft.mygoal.domain.habits.HabitsInteractor
20 | import com.vrgsoft.mygoal.presentation.common.SettingsHelper
21 | import com.vrgsoft.mygoal.presentation.injection.App
22 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitActivity
23 | import com.vrgsoft.mygoal.presentation.main.addhabit.AddHabitPresenter
24 | import com.vrgsoft.mygoal.presentation.main.habits.HabitsActivity
25 | import com.vrgsoft.mygoal.presentation.main.habits.HabitsPresenter
26 | import java.util.*
27 | import java.util.concurrent.TimeUnit
28 | import javax.inject.Inject
29 |
30 |
31 | class AlarmReceiver : BroadcastReceiver() {
32 |
33 |
34 | override fun onReceive(context: Context, intent: Intent?) {
35 | var context = context
36 | if (intent == null || intent.action == null) {
37 | return
38 | }
39 |
40 | // When device boots, need to reschedule alarm
41 | context = context.applicationContext
42 | when (intent.action) {
43 | Intent.ACTION_DATE_CHANGED -> updateReminder(context)
44 | UPDATE_REMINDER -> updateReminder(context)
45 | UPDATE_RANDOM_REMINDER -> updateRandomReminder(context)
46 | ACTION_SHOW_DAILY_REMINDER ->
47 | showDailyReminderNotification(context, intent)
48 |
49 | }
50 | }
51 |
52 | private fun updateReminder(context: Context) {
53 | scheduleDailyReminderAlarm(context)
54 | }
55 |
56 | private fun updateRandomReminder(context: Context) {
57 | scheduleRandomReminderAlarms(context)
58 | }
59 |
60 |
61 | private fun scheduleDailyReminderAlarm(context: Context) {
62 |
63 | val habitsRepository: HabitsRepositoryLocalImp = HabitsRepositoryLocalImp()
64 | val habitInteractor: HabitInteractor = HabitInteractor(habitsRepository)
65 | val mHabitPresenter: AddHabitPresenter = AddHabitPresenter(habitInteractor)
66 | val listAlarm: List = mHabitPresenter.getAllHabits()
67 | listAlarm
68 | .filter { it.mTime != 0.toLong() }
69 | .forEach {
70 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
71 | makeMarshMallowNotif(it, context)
72 | } else {
73 | scheduleAlarm(context, createDailyReminderIntent(context, it), it.mTime)
74 | }
75 | }
76 | }
77 |
78 | @RequiresApi(api = 23)
79 | fun makeMarshMallowNotif(goal: Goal, context: Context) {
80 | for (i in 1..22) {
81 | val pendingIntent = createDailyReminderIntentMarshmalow(context, goal, i)
82 | val timeToCall: Long = goal.mTime + TimeUnit.DAYS.toMillis(i.toLong())
83 | val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
84 | alarmManager.cancel(pendingIntent)
85 | alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeToCall, pendingIntent);
86 | }
87 |
88 | }
89 |
90 | private fun scheduleRandomReminderAlarms(context: Context) {
91 | val hour = 8
92 | val minute = 30
93 | scheduleAlarmTwoDays(context, createRandomReminderIntent(context), hour, minute)
94 |
95 | }
96 |
97 | private fun scheduleAlarm(context: Context, intent: PendingIntent, reminderTime: Long) {
98 | //var nextTime : Long = reminderTime+TimeUnit.DAYS.toMillis(1);
99 | // Will override existing alarm if necessary.
100 | val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
101 | alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, reminderTime, AlarmManager.INTERVAL_DAY, intent)
102 |
103 | }
104 |
105 | private fun scheduleAlarmTwoDays(context: Context, intent: PendingIntent, hourOfDay: Int, minute: Int) {
106 | // get a calendar instance, which defaults to "now"
107 | val calendar = Calendar.getInstance()
108 | // get a date to represent "today"
109 | val today = calendar.time
110 | println("today: " + today)
111 | // add one day to the date/calendar
112 | calendar.add(Calendar.DAY_OF_YEAR, 2)
113 | // now get "tomorrow"
114 | val tomorrow = calendar.time
115 |
116 | val reminderTime = Calendar.getInstance() // Start with right now.
117 | reminderTime.set(Calendar.DATE, tomorrow.date)
118 | reminderTime.set(Calendar.HOUR_OF_DAY, hourOfDay)
119 | reminderTime.set(Calendar.MINUTE, minute)
120 | reminderTime.set(Calendar.SECOND, 0)
121 | // Start from tomorrow if today's alarm time has already passed.
122 | if (reminderTime.before(Calendar.getInstance())) {
123 | reminderTime.add(Calendar.DAY_OF_MONTH, 1)
124 | }
125 | // Will override existing alarm if necessary.
126 | val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
127 | alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, reminderTime.timeInMillis, AlarmManager.INTERVAL_DAY, intent)
128 | App.settings.setReminder(System.currentTimeMillis() + 1000 * 60 * 60 * 24)
129 | }
130 |
131 | private fun createDailyReminderIntentMarshmalow(context: Context, goal: Goal, counter: Int): PendingIntent {
132 | val intent = Intent(context, AlarmReceiver::class.java)
133 | intent.action = ACTION_SHOW_DAILY_REMINDER
134 | intent.putExtra("theme", goal.mName)
135 | intent.putExtra("question", goal.mDescr)
136 | intent.putExtra("id", goal.mId)
137 | intent.putExtra("time", goal.mTime)
138 | intent.putExtra("startTime", goal.mLatsDays)
139 |
140 | return PendingIntent.getBroadcast(context, goal.mId.toInt() * 1000 + counter, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT)
141 | }
142 |
143 | // Use same pending intent for all queries to AlarmManager to ensure only one is being updated/cancelled.
144 | private fun createDailyReminderIntent(context: Context, goal: Goal): PendingIntent {
145 | val intent = Intent(context, AlarmReceiver::class.java)
146 | intent.action = ACTION_SHOW_DAILY_REMINDER
147 | intent.putExtra("theme", goal.mName)
148 | intent.putExtra("question", goal.mDescr)
149 | intent.putExtra("id", goal.mId)
150 | intent.putExtra("time", goal.mTime)
151 | intent.putExtra("startTime", goal.mLatsDays)
152 |
153 | return PendingIntent.getBroadcast(context, goal.mId.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT)
154 | }
155 |
156 | private fun createRandomReminderIntent(context: Context): PendingIntent {
157 | val intent = Intent(context, AlarmReceiver::class.java)
158 | intent.action = ACTION_SHOW_DAILY_RANDOM_REMINDER
159 | return PendingIntent.getBroadcast(context, RANDOM_ALARM_BASE_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT)
160 | }
161 |
162 | companion object {
163 |
164 | val UPDATE_REMINDER = ".UPDATE_REMINDER"
165 | val UPDATE_RANDOM_REMINDER = ".UPDATE_RANDOM_REMINDER"
166 | private val ACTION_SHOW_DAILY_REMINDER = ".ACTION_SHOW_DAILY_REMINDER"
167 | private val ACTION_SHOW_DAILY_RANDOM_REMINDER = ".ACTION_SHOW_RANDOM_DAILY_REMINDER"
168 |
169 | private val ALARM_ID = 100218
170 | private val RANDOM_ALARM_BASE_ID = 210223
171 |
172 | fun updateDailyReminder(context: Context) {
173 | val intent = Intent(context, AlarmReceiver::class.java)
174 | intent.action = UPDATE_REMINDER
175 | context.sendBroadcast(intent)
176 | }
177 |
178 | fun updateRandomDailyReminder(context: Context) {
179 | val intent = Intent(context, AlarmReceiver::class.java)
180 | intent.action = UPDATE_RANDOM_REMINDER
181 | context.sendBroadcast(intent)
182 | }
183 |
184 | fun showDailyReminderNotification(context: Context, intent: Intent) {
185 | // Show daily reminder notification to user.
186 | val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
187 | val intentLaunchApp = Intent(context, AddHabitActivity::class.java)
188 | intentLaunchApp.putExtra("isNew", false)
189 | intentLaunchApp.putExtra("id", intent.getLongExtra("id", 0))
190 | val pendingIntent = PendingIntent.getActivity(context, ALARM_ID, intentLaunchApp, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT)
191 | val notification = createNotification(context, intent.getStringExtra("question"), intent.getStringExtra("theme"), pendingIntent)
192 | // Sets an ID for the notification, so it can be updated
193 | notificationManager.notify(ALARM_ID, notification)
194 |
195 | }
196 |
197 |
198 | private fun createNotification(context: Context, text: String, textTheme: String, pendingIntent: PendingIntent): Notification {
199 | val builder = NotificationCompat.Builder(context)
200 | builder.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.icon))
201 | builder.setContentTitle(textTheme)
202 | builder.setSmallIcon(R.drawable.icon)
203 | builder.setDefaults(Notification.DEFAULT_SOUND)
204 | builder.setWhen(System.currentTimeMillis())
205 | builder.setContentIntent(pendingIntent)
206 | builder.setContentText(text)
207 | builder.setAutoCancel(true)
208 | return builder.build()
209 | }
210 | }
211 |
212 |
213 | }
214 |
215 |
--------------------------------------------------------------------------------
/app/src/main/java/com/vrgsoft/mygoal/presentation/receivers/TimeChangeReceiver.kt:
--------------------------------------------------------------------------------
1 | package com.vrgsoft.mygoal.presentation.receivers
2 |
3 | import android.app.AlarmManager
4 | import android.app.PendingIntent
5 | import android.content.BroadcastReceiver
6 | import android.content.Context
7 | import android.content.Intent
8 | import java.util.*
9 |
10 | /**
11 | * Created by pavlonikitin on 4/4/17.
12 | */
13 |
14 | class TimeChangeReceiver : BroadcastReceiver() {
15 | val DAY_CHANGE_ALARM_ID:Int = 100220
16 |
17 |
18 | override fun onReceive(context: Context?, intent: Intent?) {
19 | AlarmReceiver.updateRandomDailyReminder(context!!)
20 |
21 | }
22 |
23 | fun scheduleDayChangeAlarm(context: Context?){
24 | val calendar:Calendar = Calendar.getInstance()
25 | calendar.set(Calendar.HOUR_OF_DAY, 0)
26 | calendar.set(Calendar.MINUTE, 0)
27 | calendar.set(Calendar.SECOND, 0)
28 | calendar.add(Calendar.DAY_OF_YEAR, 1)
29 |
30 | val am:AlarmManager = context!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
31 | val intent = Intent(context, TimeChangeReceiver::class.java)
32 | val pendingIntent = PendingIntent.getBroadcast(context, DAY_CHANGE_ALARM_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT)
33 | // Don't need this to fire exactly on the dot.
34 | am.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, AlarmManager.INTERVAL_DAY, pendingIntent)
35 |
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/res/anim/move_anim.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/actionbar_shadow.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/arts_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/arts_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bt_drawable.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/dialog_background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/dialog_background.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/healthy_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/healthy_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/home_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/home_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_collections.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_mode_edit_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/main_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/main_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/main_splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/main_splash.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/money_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/money_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/move_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/move_back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/other_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/other_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/rounded_white_rect.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/self_improvment_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/self_improvment_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/sex_dating_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/sex_dating_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/social_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/social_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/work_and_study_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/drawable/work_and_study_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_add_habit.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
9 |
10 |
15 |
16 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_habits.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_splash.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
20 |
21 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_failed.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
25 |
26 |
30 |
31 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_success.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
25 |
26 |
30 |
31 |
37 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_add_habit.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
11 |
12 |
13 |
16 |
17 |
22 |
23 |
28 |
29 |
45 |
46 |
50 |
51 |
63 |
64 |
70 |
71 |
72 |
84 |
85 |
90 |
91 |
92 |
93 |
108 |
109 |
110 |
128 |
129 |
145 |
146 |
164 |
165 |
166 |
167 |
168 |
182 |
183 |
190 |
191 |
192 |
210 |
211 |
212 |
213 |
214 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_dialog_theme.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
13 |
14 |
15 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_habits.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
17 |
18 |
28 |
29 |
32 |
33 |
42 |
43 |
55 |
56 |
57 |
58 |
59 |
60 |
66 |
67 |
68 |
69 |
78 |
79 |
80 |
81 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_show_habit.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
17 |
18 |
23 |
24 |
29 |
30 |
46 |
47 |
51 |
52 |
53 |
69 |
70 |
84 |
85 |
86 |
101 |
102 |
119 |
120 |
136 |
137 |
152 |
153 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
185 |
186 |
193 |
194 |
195 |
213 |
214 |
215 |
216 |
217 |
218 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
15 |
16 |
21 |
22 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_habit.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
12 |
13 |
16 |
17 |
18 |
19 |
23 |
38 |
39 |
56 |
57 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-hdpi/ic_menu.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-mdpi/ic_menu.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xhdpi/ic_menu.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xxhdpi/ic_menu.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VRGsoftUA/GetGoal/888eb311bfe6f999a6cfd4e6c9a13c415da71f37/app/src/main/res/mipmap-xxxhdpi/ic_menu.png
--------------------------------------------------------------------------------
/app/src/main/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Get Habit
3 |
4 |
5 | Hello blank fragment
6 | Purtroppo, tu sei perso il giorno
7 | L\'abitudine è formata in 21 giorno ,e che richiesto sforzi in precedenza diventa facile e familiare. Solo performance giornaliera esecuzione creerà un\'abitudine forte. Creare un nuovo obiettivo è possibile per fare un clic sul pulsante sotto.
8 | Creare una nuova abitudine
9 | Complimenti per la tua nuova abitudine
10 | Ricordate che è necessario creare buone abitudini: prima di tutto a se stessi, e in secondo luogo - per gli altri, su cui si può influenzare.
11 | Nome di abitudine
12 | Domanda (hai fatto ... oggi?)
13 | Salvare
14 | Tempo di notifica:
15 | NUOVA ABITUDINE
16 | I miei obiettivi
17 | Si
18 | VERIFICARE Abitudine
19 | Rimuovere gli annunci
20 |
21 |
22 | - Salute e fitness
23 | - I soldi
24 | - Auto-miglioramento
25 | - Sesso e incontri
26 | - Lavoro e studio
27 | - Arts
28 | - Sociale
29 | - Faccende domestiche
30 | - Altre
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Get Habit
3 |
4 |
5 | Hello blank fragment
6 | К сожалению, Вы пропустили день
7 | Привычка формируется за 21 день и то, что ранее требовало усилий, становится уже легким и знакомым. Только ежедненое выполнени создаст крепкую привычку. Создать новую цель Вы можете нажав на кнопку ниже.
8 | Создать новую привычку
9 | Поздравляем, у Вас новая привычка
10 | Помните, что вам нужно создавать хорошие привычки: в первую очередь для себя, а во-вторых - для других, на которые вы можете влиять.
11 | Название привычки
12 | Вопрос (Сделали ли Вы ... сегодня ?)
13 | Сохранить
14 | Время уведомений:
15 | НОВАЯ ПРИВЫЧКА
16 | Мои цели
17 | Да
18 | Отметить достижение
19 | Отключить рекламу
20 |
21 |
22 | - Здоровье и Фитнес
23 | - Деньги
24 | - Саморазвитие
25 | - Секс и свидания
26 | - Работа и учеба
27 | - Искуство
28 | - Социальное
29 | - Домашнее хозяйство
30 | - Другое
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/values-uk/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Get Habit
3 |
4 |
5 | Hello blank fragment
6 | На жаль, Ви пропустили день
7 | Звичка формується за 21 день і те що раніше викликало труднощі, стає легким та знайомим. Тільки щоденне виконання формує сильну звичку. Сворити нову ціль Ви можете натиснувши на кнопку нижче.
8 | Створити нову звичку
9 | Вітаємо, у Вас нова звичка
10 | Пам\'ятайте, що потрібно створювати тільки хороші звички: перш за все для себе, потім - для інших людей, на яких Ви можете впливати.
11 | Назва звички
12 | Питання (Чи ...сьогодні?
13 | Зберегти
14 | Час оповіщення:
15 | НОВА ЗВИЧКА
16 | Мої цілі
17 | Так
18 | Відзначити досягнення
19 | Вимкнути рекламу
20 |
21 |
22 | - Здоров\'я і фітнес
23 | - Гроші
24 | - Саморозвиток
25 | - Секс і побачення
26 | - Робота і навчання
27 | - Мистецтво
28 | - Соціальне
29 | - Домогосподарство
30 | - Інше
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #82ffda
4 | #82ffda
5 | #ffd927
6 |
7 | #9e000000
8 | #000000
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 200dp
4 | 40dp
5 | 16dp
6 | 20sp
7 | 24sp
8 | 32dp
9 | -200dp
10 | 1dp
11 | 40dp
12 | 32dp
13 | 64dp
14 | 16dp
15 | 8dp
16 | 56dp
17 | 10dp
18 | 28dp
19 | 48dp
20 | 24dp
21 | 64dp
22 | 26dp
23 | 26sp
24 | 4dp
25 | 4dp
26 | 258dp
27 | 130dp
28 | 28sp
29 | 18dp
30 | 37dp
31 | 77dp
32 | 78dp
33 | 20dp
34 | 20sp
35 | 50dp
36 | 40dp
37 | 161dp
38 |
--------------------------------------------------------------------------------
/app/src/main/res/values/integers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @drawable/healthy_icon
5 | - @drawable/money_icon
6 | - @drawable/self_improvment_icon
7 | - @drawable/sex_dating_icon
8 | - @drawable/work_and_study_icon
9 | - @drawable/arts_icon
10 | - @drawable/social_icon
11 | - @drawable/home_icon
12 | - @drawable/other_icon
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Get Habit
3 |
4 |
5 | Hello blank fragment
6 | Unfortunately, you missed the day
7 | The habit is formed on day 21, and what previously required the effort becomes already easy and familiar. Only daily performance will create a strong habit. Create a new habit by clicking on the button below
8 | Create a new habit
9 | Congratulations on your new habit
10 | Remember that you need to create good habits: first of all to yourself, and secondly - to others, on which you can influence.
11 | Habit name
12 | Question (Did you...today?
13 | Save
14 | Notification time:
15 | NEW HABIT
16 | My Goals
17 | Yes
18 | CHECK YOUR HABBIT
19 | Remove ads
20 | none
21 |
22 |
23 | - Health and Fitness
24 | - Money
25 | - Self Improvement
26 | - Sex and dating
27 | - Work and Study
28 | - Arts
29 | - Social
30 | - Housekeeping
31 | - Other
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/analytics.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UA-48042958-2
6 |
7 |
8 | true
9 |
10 |
11 | true
12 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/filepaths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.1.0'
5 | repositories {
6 | jcenter()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:2.3.1'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | classpath "io.realm:realm-gradle-plugin:3.0.0"
12 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | jcenter()
22 | maven { url "https://jitpack.io" }
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Mar 14 17:39:16 EET 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------