From 6140e6c409e3b62e6d5ddaaae75e5f971424d868 Mon Sep 17 00:00:00 2001 From: Mike Mazzola Date: Wed, 19 Sep 2018 13:44:28 -0400 Subject: [PATCH] Convert TaskDetail views to Kotlin --- .../todoapp/taskdetail/domain/domain.kt | 3 - ...age-info.java => TaskDetailViewActions.kt} | 13 +- .../taskdetail/view/TaskDetailViewData.java | 57 -------- ...ViewActions.java => TaskDetailViewData.kt} | 13 +- .../view/TaskDetailViewDataMapper.java | 43 ------ .../view/TaskDetailViewDataMapper.kt | 33 +++++ .../taskdetail/view/TaskDetailViews.java | 135 ------------------ .../taskdetail/view/TaskDetailViews.kt | 103 +++++++++++++ 8 files changed, 149 insertions(+), 251 deletions(-) rename todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/{package-info.java => TaskDetailViewActions.kt} (79%) delete mode 100644 todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewData.java rename todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/{TaskDetailViewActions.java => TaskDetailViewData.kt} (78%) delete mode 100755 todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewDataMapper.java create mode 100644 todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewDataMapper.kt delete mode 100644 todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViews.java create mode 100644 todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViews.kt diff --git a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/domain/domain.kt b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/domain/domain.kt index ca6acad..f214727 100644 --- a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/domain/domain.kt +++ b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/domain/domain.kt @@ -24,9 +24,6 @@ import com.example.android.architecture.blueprints.todoapp.data.Task sealed class TaskDetailEvent { companion object { @JvmStatic fun deleteTaskRequested() = DeleteTaskRequested - @JvmStatic fun completeTaskRequested() = CompleteTaskRequested - @JvmStatic fun activateTaskRequested() = ActivateTaskRequested - @JvmStatic fun editTaskRequested() = EditTaskRequested } } object DeleteTaskRequested : TaskDetailEvent() diff --git a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/package-info.java b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewActions.kt similarity index 79% rename from todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/package-info.java rename to todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewActions.kt index b0dc72d..21336d7 100644 --- a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/package-info.java +++ b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewActions.kt @@ -16,8 +16,15 @@ * limitations under the License. * -/-/- */ +package com.example.android.architecture.blueprints.todoapp.taskdetail.view -@ParametersAreNonnullByDefault -package com.example.android.architecture.blueprints.todoapp.taskdetail.view; +interface TaskDetailViewActions { -import javax.annotation.ParametersAreNonnullByDefault; + fun showTaskMarkedComplete() + + fun showTaskMarkedActive() + + fun showTaskSavingFailed() + + fun showTaskDeletionFailed() +} diff --git a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewData.java b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewData.java deleted file mode 100644 index 0129db5..0000000 --- a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewData.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * -\-\- - * -- - * Copyright (c) 2017-2018 Spotify AB - * -- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -/-/- - */ -package com.example.android.architecture.blueprints.todoapp.taskdetail.view; - -import com.google.auto.value.AutoValue; - -@AutoValue -public abstract class TaskDetailViewData { - public abstract TextViewData title(); - - public abstract TextViewData description(); - - public abstract boolean completedChecked(); - - public static Builder builder() { - return new AutoValue_TaskDetailViewData.Builder(); - } - - @AutoValue.Builder - public abstract static class Builder { - - public abstract Builder title(TextViewData title); - - public abstract Builder description(TextViewData description); - - public abstract Builder completedChecked(boolean completedChecked); - - public abstract TaskDetailViewData build(); - } - - @AutoValue - public abstract static class TextViewData { - public abstract int visibility(); - - public abstract String text(); - - public static TextViewData create(int visibility, String text) { - return new AutoValue_TaskDetailViewData_TextViewData(visibility, text); - } - } -} diff --git a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewActions.java b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewData.kt similarity index 78% rename from todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewActions.java rename to todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewData.kt index 34c1a46..ddf2147 100644 --- a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewActions.java +++ b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewData.kt @@ -16,15 +16,8 @@ * limitations under the License. * -/-/- */ -package com.example.android.architecture.blueprints.todoapp.taskdetail.view; +package com.example.android.architecture.blueprints.todoapp.taskdetail.view -public interface TaskDetailViewActions { +data class TaskDetailViewData(val title: TextViewData, val description: TextViewData, val completedChecked: Boolean) - void showTaskMarkedComplete(); - - void showTaskMarkedActive(); - - void showTaskSavingFailed(); - - void showTaskDeletionFailed(); -} +data class TextViewData(val visibility: Int, val text: String) diff --git a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewDataMapper.java b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewDataMapper.java deleted file mode 100755 index 680cf2c..0000000 --- a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewDataMapper.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * -\-\- - * -- - * Copyright (c) 2017-2018 Spotify AB - * -- - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * -/-/- - */ -package com.example.android.architecture.blueprints.todoapp.taskdetail.view; - -import static com.google.common.base.Strings.isNullOrEmpty; - -import android.view.View; -import com.example.android.architecture.blueprints.todoapp.data.Task; -import com.example.android.architecture.blueprints.todoapp.data.TaskDetails; -import com.example.android.architecture.blueprints.todoapp.taskdetail.view.TaskDetailViewData.TextViewData; - -/** Maps instances of {@link Task} to {@link TaskDetailViewData} */ -public class TaskDetailViewDataMapper { - - public static TaskDetailViewData taskToTaskViewData(Task task) { - TaskDetails details = task.details(); - String title = details.title(); - String description = details.description(); - - return TaskDetailViewData.builder() - .title(TextViewData.create(isNullOrEmpty(title) ? View.GONE : View.VISIBLE, title)) - .description( - TextViewData.create(isNullOrEmpty(description) ? View.GONE : View.VISIBLE, description)) - .completedChecked(details.completed()) - .build(); - } -} diff --git a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewDataMapper.kt b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewDataMapper.kt new file mode 100644 index 0000000..71856fe --- /dev/null +++ b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViewDataMapper.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2016, The Android Open Source Project + * Copyright (c) 2017-2018 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +@file:JvmName("TaskDetailViewDataMapper") + +package com.example.android.architecture.blueprints.todoapp.taskdetail.view + +import android.view.View +import com.example.android.architecture.blueprints.todoapp.data.Task + +fun taskToTaskViewData(task: Task): TaskDetailViewData { + val details = task.details + val title = details.title + val description = details.description + + return TaskDetailViewData( + title = TextViewData(if (title.isEmpty()) View.GONE else View.VISIBLE, title), + description = TextViewData(if (description.isEmpty()) View.GONE else View.VISIBLE, description), + completedChecked = details.completed) +} \ No newline at end of file diff --git a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViews.java b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViews.java deleted file mode 100644 index bd232b2..0000000 --- a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViews.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2016, The Android Open Source Project - * Copyright (c) 2017-2018 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.example.android.architecture.blueprints.todoapp.taskdetail.view; - -import static com.example.android.architecture.blueprints.todoapp.taskdetail.domain.TaskDetailEvent.activateTaskRequested; -import static com.example.android.architecture.blueprints.todoapp.taskdetail.domain.TaskDetailEvent.completeTaskRequested; - -import android.support.design.widget.FloatingActionButton; -import android.support.design.widget.Snackbar; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.TextView; -import com.example.android.architecture.blueprints.todoapp.R; -import com.example.android.architecture.blueprints.todoapp.taskdetail.domain.TaskDetailEvent; -import com.spotify.mobius.Connectable; -import com.spotify.mobius.Connection; -import com.spotify.mobius.functions.Consumer; -import io.reactivex.Observable; -import io.reactivex.disposables.Disposable; -import javax.annotation.Nonnull; - -public class TaskDetailViews - implements TaskDetailViewActions, Connectable { - private final FloatingActionButton mFab; - private final Observable mMenuEvents; - - private TextView mDetailTitle; - - private TextView mDetailDescription; - - private CheckBox mDetailCompleteStatus; - - private final View mRootView; - - public TaskDetailViews( - LayoutInflater inflater, - ViewGroup container, - FloatingActionButton fab, - Observable menuEvents) { - mRootView = inflater.inflate(R.layout.taskdetail_frag, container, false); - mMenuEvents = menuEvents; - mDetailTitle = mRootView.findViewById(R.id.task_detail_title); - mDetailDescription = mRootView.findViewById(R.id.task_detail_description); - mDetailCompleteStatus = mRootView.findViewById(R.id.task_detail_complete); - mFab = fab; - } - - public View getRootView() { - return mRootView; - } - - @Override - public void showTaskMarkedComplete() { - Snackbar.make(mRootView, R.string.task_marked_complete, Snackbar.LENGTH_LONG).show(); - } - - @Override - public void showTaskMarkedActive() { - Snackbar.make(mRootView, R.string.task_marked_active, Snackbar.LENGTH_LONG).show(); - } - - @Override - public void showTaskDeletionFailed() { - Snackbar.make(mRootView, "Failed to delete task", Snackbar.LENGTH_LONG).show(); - } - - @Override - public void showTaskSavingFailed() { - Snackbar.make(mRootView, "Failed to save change", Snackbar.LENGTH_LONG).show(); - } - - private void render(TaskDetailViewData viewData) { - mDetailCompleteStatus.setChecked(viewData.completedChecked()); - bindTextViewData(mDetailTitle, viewData.title()); - bindTextViewData(mDetailDescription, viewData.description()); - } - - private void bindTextViewData(TextView textView, TaskDetailViewData.TextViewData viewData) { - textView.setVisibility(viewData.visibility()); - textView.setText(viewData.text()); - } - - @Nonnull - @Override - public Connection connect(Consumer output) { - mFab.setOnClickListener(__ -> output.accept(TaskDetailEvent.editTaskRequested())); - - mDetailCompleteStatus.setOnCheckedChangeListener( - (buttonView, isChecked) -> { - if (isChecked) { - output.accept(completeTaskRequested()); - } else { - output.accept(activateTaskRequested()); - } - }); - - Disposable disposable = - mMenuEvents - .retry() - .subscribe( - output::accept, - t -> Log.e(TaskDetailViews.class.getSimpleName(), "Menu events seem to fail", t)); - - return new Connection() { - @Override - public void accept(TaskDetailViewData value) { - render(value); - } - - @Override - public void dispose() { - disposable.dispose(); - mFab.setOnClickListener(null); - mDetailCompleteStatus.setOnCheckedChangeListener(null); - } - }; - } -} diff --git a/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViews.kt b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViews.kt new file mode 100644 index 0000000..b0755e1 --- /dev/null +++ b/todoapp/app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/view/TaskDetailViews.kt @@ -0,0 +1,103 @@ +/* + * Copyright 2016, The Android Open Source Project + * Copyright (c) 2017-2018 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.example.android.architecture.blueprints.todoapp.taskdetail.view + +import android.support.design.widget.FloatingActionButton +import android.support.design.widget.Snackbar +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.CheckBox +import android.widget.TextView +import com.example.android.architecture.blueprints.todoapp.R +import com.example.android.architecture.blueprints.todoapp.taskdetail.domain.ActivateTaskRequested +import com.example.android.architecture.blueprints.todoapp.taskdetail.domain.CompleteTaskRequested +import com.example.android.architecture.blueprints.todoapp.taskdetail.domain.EditTaskRequested +import com.example.android.architecture.blueprints.todoapp.taskdetail.domain.TaskDetailEvent +import com.example.android.architecture.blueprints.todoapp.util.onAccept +import com.spotify.mobius.Connectable +import com.spotify.mobius.Connection +import com.spotify.mobius.functions.Consumer +import io.reactivex.Observable + +class TaskDetailViews( + inflater: LayoutInflater, + container: ViewGroup, + private val mFab: FloatingActionButton, + private val mMenuEvents: Observable) : TaskDetailViewActions, Connectable { + + val rootView: View = inflater.inflate(R.layout.taskdetail_frag, container, false) + + private val mDetailTitle: TextView = rootView.findViewById(R.id.task_detail_title) + + private val mDetailDescription: TextView = rootView.findViewById(R.id.task_detail_description) + + private val mDetailCompleteStatus: CheckBox = rootView.findViewById(R.id.task_detail_complete) + + override fun showTaskMarkedComplete() { + Snackbar.make(rootView, R.string.task_marked_complete, Snackbar.LENGTH_LONG).show() + } + + override fun showTaskMarkedActive() { + Snackbar.make(rootView, R.string.task_marked_active, Snackbar.LENGTH_LONG).show() + } + + override fun showTaskDeletionFailed() { + Snackbar.make(rootView, "Failed to delete task", Snackbar.LENGTH_LONG).show() + } + + override fun showTaskSavingFailed() { + Snackbar.make(rootView, "Failed to save change", Snackbar.LENGTH_LONG).show() + } + + private fun render(viewData: TaskDetailViewData) { + mDetailCompleteStatus.isChecked = viewData.completedChecked + bindTextViewData(mDetailTitle, viewData.title) + bindTextViewData(mDetailDescription, viewData.description) + } + + private fun bindTextViewData(textView: TextView, viewData: TextViewData) { + textView.visibility = viewData.visibility + textView.text = viewData.text + } + + override fun connect(output: Consumer): Connection { + mFab.setOnClickListener { _ -> output.accept(EditTaskRequested) } + + mDetailCompleteStatus.setOnCheckedChangeListener { _, isChecked -> + if (isChecked) { + output.accept(CompleteTaskRequested) + } else { + output.accept(ActivateTaskRequested) + } + } + + val disposable = mMenuEvents + .retry() + .subscribe( + { output.accept(it) }, + { Log.e(TaskDetailViews::class.java.simpleName, "Menu events seem to fail", it) }) + + return onAccept { render(it) } + .onDispose { + disposable.dispose() + mFab.setOnClickListener(null) + mDetailCompleteStatus.setOnCheckedChangeListener(null) + } + } +}