Skip to content

Commit

Permalink
Merge pull request #19 from mrtry/develop
Browse files Browse the repository at this point in the history
Ver 1.1.0
  • Loading branch information
mrtry committed Oct 11, 2020
2 parents c7d0480 + 3ce1264 commit e839ec9
Show file tree
Hide file tree
Showing 49 changed files with 901 additions and 65 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.fragment:fragment-ktx:1.2.5"
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation 'com.google.android.material:material:1.2.1'
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/io/github/mrtry/todolist/MainApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import android.app.Application
import android.content.Context
import io.github.mrtry.todolist.di.component.AppComponent
import io.github.mrtry.todolist.di.component.DaggerAppComponent
import io.github.mrtry.todolist.misc.ui.WholeActivityDelegate
import timber.log.Timber
import javax.inject.Inject


class MainApplication : Application() {
Expand All @@ -14,6 +16,9 @@ class MainApplication : Application() {
}
}

@Inject
lateinit var wholeActivityDelegate: WholeActivityDelegate

private val appComponent: AppComponent by lazy {
DaggerAppComponent.builder().build().also {
it.inject(this)
Expand All @@ -23,5 +28,8 @@ class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
Timber.plant(Timber.DebugTree())

appComponent
registerActivityLifecycleCallbacks(wholeActivityDelegate)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.github.mrtry.todolist.app.splash.ui

import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
Expand All @@ -17,6 +18,10 @@ import io.github.mrtry.todolist.misc.ui.binding.Bindable
import javax.inject.Inject

class SplashActivity : AppCompatActivity(), Injectable<LoginComponent>, Bindable<ActivitySplashBinding> {
companion object {
fun createIntent(context: Context): Intent =
Intent(context, SplashActivity::class.java)
}

@Inject
internal lateinit var viewModel: SplashViewModel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.mrtry.todolist.app.splash.ui.navigator

import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import com.firebase.ui.auth.AuthUI
import io.github.mrtry.todolist.app.splash.ui.result.SplashActivityResult
import io.github.mrtry.todolist.app.todo.ui.ToDoActivity
Expand All @@ -11,7 +11,7 @@ import javax.inject.Inject
@ActivityScope
class SplashNavigator
@Inject constructor(
private val activity: Activity
private val activity: AppCompatActivity
) : AbsNavigator(activity) {
fun navigateToToDo() {
val intent = ToDoActivity.createIntent(activity)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package io.github.mrtry.todolist.app.splash.viewmodel

import io.github.mrtry.todolist.app.splash.ui.navigator.SplashNavigator
import io.github.mrtry.todolist.auth.AuthenticationClient
import io.github.mrtry.todolist.auth.repository.AccountRepository
import io.github.mrtry.todolist.di.scope.ActivityScope
import io.github.mrtry.todolist.misc.ui.viewmodel.ViewModel
import javax.inject.Inject

@ActivityScope
class SplashViewModel
@Inject constructor(
private val authenticationClient: AuthenticationClient,
private val authenticationClient: AccountRepository,
private val navigator: SplashNavigator
) {
) : ViewModel {
fun ensuredLoggedIn() {
when (authenticationClient.isLoggedIn()) {
true -> navigator.navigateToToDo()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package io.github.mrtry.todolist.app.todo.ui

import android.os.Bundle
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.addCallback
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import io.github.mrtry.todolist.R
import io.github.mrtry.todolist.app.todo.ui.navigator.EditTaskNavigator
import io.github.mrtry.todolist.app.todo.viewmodel.EditTaskViewModel
import io.github.mrtry.todolist.databinding.FragmentEditTaskBinding
import io.github.mrtry.todolist.di.Injectable
import io.github.mrtry.todolist.di.component.EditTaskComponent
import io.github.mrtry.todolist.di.component.ToDoComponent
import io.github.mrtry.todolist.di.module.FragmentModule
import io.github.mrtry.todolist.di.scope.FragmentScope
import io.github.mrtry.todolist.di.utils.ComponentUtils
import io.github.mrtry.todolist.misc.extension.observeNonNull
import io.github.mrtry.todolist.misc.ui.binding.Bindable
import io.github.mrtry.todolist.task.entity.Task
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancelChildren
import javax.inject.Inject


private const val KEY_TASK = "KEY_TASK"

class EditTaskDialogFragment : DialogFragment(), Injectable<EditTaskComponent>, Bindable<FragmentEditTaskBinding> {
companion object {
val TAG: String = EditTaskDialogFragment::class.java.simpleName

fun newInstance(task: Task): EditTaskDialogFragment {
val fragment = EditTaskDialogFragment()
val args = Bundle()
args.putParcelable(KEY_TASK, task)
fragment.arguments = args
return fragment
}
}

override val viewBinding: FragmentEditTaskBinding by lazy {
FragmentEditTaskBinding.inflate(layoutInflater)
}

override lateinit var component: EditTaskComponent

@Inject
lateinit var viewModel: EditTaskViewModel

@Inject
lateinit var navigator: EditTaskNavigator

@Inject
lateinit var coroutineScope: CoroutineScope

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.Widget_FullScreenDialog)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
super.onCreateView(inflater, container, savedInstanceState)
return viewBinding.root
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
component = ComponentUtils.getComponent<ToDoComponent>(requireActivity())
.plusEditTaskComponent(FragmentModule(this))
component.inject(this)

savedInstanceState?.let {
viewModel.onRestoreInstanceState(it)
}

with(viewBinding) {
viewModel = this@EditTaskDialogFragment.viewModel
lifecycleOwner = this@EditTaskDialogFragment
}

requireActivity().onBackPressedDispatcher.addCallback(this) {
navigator.showSavingAlert()
}

// DialogFragmentのcancel()を無効にして、back pressをハンドリングする
// see: https://stackoverflow.com/a/7622065
isCancelable = false
dialog?.setOnKeyListener { _, keyCode, event ->
if (keyCode == KeyEvent.KEYCODE_BACK && event.action === KeyEvent.ACTION_UP) {
navigator.onBackPressed()
true
} else false
}

viewModel.title.observeNonNull(this@EditTaskDialogFragment) {
with(viewBinding.toolbar) {
menu.getItem(0).isEnabled = it.isNotEmpty()
invalidate()
}
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(viewBinding.toolbar) {
setNavigationOnClickListener {
navigator.onBackPressed()
}

inflateMenu(R.menu.menu_fragment_edit_task)
setOnMenuItemClickListener {
this@EditTaskDialogFragment.viewModel.onSaveClick()
true
}
}
}

override fun onStart() {
super.onStart()
dialog?.window?.setLayout(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
viewModel.onSaveInstanceState(outState)
}

override fun onStop() {
super.onStop()
coroutineScope.coroutineContext.cancelChildren()
}
}

@FragmentScope
class EditTaskDialogFragmentValueHolder
@Inject constructor(fragment: Fragment) {
val task: Task = fragment.requireArguments().getParcelable(KEY_TASK)!!
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ package io.github.mrtry.todolist.app.todo.ui
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.mrtry.todolist.MainApplication
import io.github.mrtry.todolist.R
import io.github.mrtry.todolist.app.todo.ui.adapter.ToDoAdapter
import io.github.mrtry.todolist.app.todo.ui.menu.ToDoMenuAction
import io.github.mrtry.todolist.app.todo.ui.navigator.ToDoNavigator
import io.github.mrtry.todolist.app.todo.viewmodel.ToDoViewModel
import io.github.mrtry.todolist.databinding.ActivityToDoBinding
Expand Down Expand Up @@ -67,6 +71,17 @@ class ToDoActivity : AppCompatActivity(), Injectable<ToDoComponent>, Bindable<Ac
viewModel.load()
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.menu_activity_to_do, menu)
return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean = ToDoMenuAction
.valueOf(item.itemId)
.getActionHandler(component)
.handleAction() || super.onOptionsItemSelected(item)

override fun onStop() {
super.onStop()
coroutineScope.coroutineContext.cancelChildren()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.mrtry.todolist.app.todo.ui.menu

import io.github.mrtry.todolist.R
import io.github.mrtry.todolist.di.component.ToDoComponent
import io.github.mrtry.todolist.misc.ui.menu.MenuAction

enum class ToDoMenuAction(override val menuId: Int) : MenuAction<ToDoMenuActionHandler, ToDoComponent> {
LOGOUT(R.id.menu_logout) {
override fun getActionHandler(component: ToDoComponent): ToDoMenuActionHandler =
component.toDoMenuLogoutActionHandler
};

companion object {
fun valueOf(menuId: Int) =
values().first { it.menuId == menuId }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.github.mrtry.todolist.app.todo.ui.menu

import io.github.mrtry.todolist.misc.ui.menu.ActionHandler

interface ToDoMenuActionHandler : ActionHandler
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.github.mrtry.todolist.app.todo.ui.menu

import io.github.mrtry.todolist.app.todo.ui.navigator.ToDoNavigator
import io.github.mrtry.todolist.auth.repository.AccountRepository
import io.github.mrtry.todolist.di.scope.ActivityScope
import javax.inject.Inject

@ActivityScope
class ToDoMenuLogoutActionHandler
@Inject constructor(
private val repository: AccountRepository,
private val navigator: ToDoNavigator
) : ToDoMenuActionHandler {
override fun handleAction(): Boolean {
navigator.showLogoutAlert() {
repository.logout()
navigator.navigateToSplash()
}
return true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.github.mrtry.todolist.app.todo.ui.navigator

import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import com.google.android.material.snackbar.Snackbar
import io.github.mrtry.todolist.R
import io.github.mrtry.todolist.databinding.FragmentEditTaskBinding
import io.github.mrtry.todolist.di.scope.FragmentScope
import io.github.mrtry.todolist.misc.ui.navigator.AbsFragmentNavigator
import javax.inject.Inject

@FragmentScope
class EditTaskNavigator
@Inject constructor(
activity: AppCompatActivity,
private val fragment: Fragment
) : AbsFragmentNavigator(activity, fragment) {
fun dismissDialog() {
(fragment as DialogFragment).dismiss()
}

fun showSavingAlert() {
showAlert(
R.string.edit_task_fragment_alert_confirm,
R.string.edit_task_fragment_alert_label_positive,
{ _, _ -> dismissDialog() }
)
}

override fun showSnackBar(messageId: Int, length: Int) {
Snackbar.make(getFragmentBindingAs<FragmentEditTaskBinding>().container, messageId, length).show()
}
}

0 comments on commit e839ec9

Please sign in to comment.