mirror of
https://github.com/AdrianKuta/Unbound-Drag-Drop.git
synced 2025-04-19 22:49:02 +02:00
Cleanup
This commit is contained in:
parent
6f93d0c234
commit
ee9000b98a
21
.idea/deploymentTargetSelector.xml
generated
Normal file
21
.idea/deploymentTargetSelector.xml
generated
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="deploymentTargetSelector">
|
||||||
|
<selectionStates>
|
||||||
|
<SelectionState runConfigName="unbounddragdrop">
|
||||||
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
|
</SelectionState>
|
||||||
|
<SelectionState runConfigName="app">
|
||||||
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
|
<DropdownSelection timestamp="2024-06-25T21:25:19.314095Z">
|
||||||
|
<Target type="DEFAULT_BOOT">
|
||||||
|
<handle>
|
||||||
|
<DeviceId pluginId="LocalEmulator" identifier="path=/Users/adriankuta/.android/avd/Pixel_8_API_34.avd" />
|
||||||
|
</handle>
|
||||||
|
</Target>
|
||||||
|
</DropdownSelection>
|
||||||
|
<DialogSelection />
|
||||||
|
</SelectionState>
|
||||||
|
</selectionStates>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,147 @@
|
|||||||
|
package com.github.adriankuta.unbounddragdrop
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.activity.viewModels
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.github.adriankuta.unbounddragdrop.databinding.ActivityMainBinding
|
||||||
|
import com.github.adriankuta.unbounddragdrop.model.TaskStatus
|
||||||
|
import dev.adriankuta.unbounddragdrop.DragDropHelper
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private val viewModel: MainViewModel by viewModels()
|
||||||
|
private lateinit var binding: ActivityMainBinding
|
||||||
|
private lateinit var todoAdapter: SimpleGridPageAdapter
|
||||||
|
private lateinit var inProgressAdapter: SimpleGridPageAdapter
|
||||||
|
private val callback = object : DragDropHelper.Callback() {
|
||||||
|
override fun onMove(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
|
targetRecyclerView: RecyclerView,
|
||||||
|
targetViewHolder: RecyclerView.ViewHolder?
|
||||||
|
): Boolean {
|
||||||
|
return onMove(
|
||||||
|
recyclerView,
|
||||||
|
viewHolder.adapterPosition,
|
||||||
|
targetRecyclerView,
|
||||||
|
targetViewHolder?.adapterPosition
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMoved(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
|
targetRecyclerView: RecyclerView,
|
||||||
|
targetViewHolder: RecyclerView.ViewHolder?
|
||||||
|
) = Unit
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
setContentView(binding.root)
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(binding.main) { v, insets ->
|
||||||
|
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||||
|
insets
|
||||||
|
}
|
||||||
|
|
||||||
|
setupRecyclerViews()
|
||||||
|
setObservers()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupRecyclerViews() {
|
||||||
|
todoAdapter = SimpleGridPageAdapter()
|
||||||
|
inProgressAdapter = SimpleGridPageAdapter()
|
||||||
|
|
||||||
|
with(binding) {
|
||||||
|
setupRecyclerView(toDoRecyclerView, todoAdapter)
|
||||||
|
setupRecyclerView(inProgressRecyclerView, inProgressAdapter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setObservers() {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
viewModel.uiState.collect(::render)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun render(uiState: MainUiState) {
|
||||||
|
todoAdapter.submitList(uiState.todo)
|
||||||
|
inProgressAdapter.submitList(uiState.inProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupRecyclerView(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
adapter: RecyclerView.Adapter<*>
|
||||||
|
) {
|
||||||
|
recyclerView.adapter = adapter
|
||||||
|
recyclerView.layoutManager =
|
||||||
|
GridLayoutManager(this, GRID_ROWS, GridLayoutManager.HORIZONTAL, false)
|
||||||
|
DragDropHelper(callback).attachToRecyclerView(recyclerView)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onMove(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
sourcePosition: Int,
|
||||||
|
targetRecyclerView: RecyclerView,
|
||||||
|
targetPosition: Int?
|
||||||
|
): Boolean {
|
||||||
|
if (recyclerView == targetRecyclerView) {
|
||||||
|
onChangeOrder(recyclerView, sourcePosition, targetPosition)
|
||||||
|
} else {
|
||||||
|
onChangeStatus(recyclerView, sourcePosition, targetRecyclerView, targetPosition)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onChangeOrder(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
sourcePosition: Int,
|
||||||
|
targetPosition: Int?
|
||||||
|
) {
|
||||||
|
targetPosition ?: return
|
||||||
|
val taskStatus = when (recyclerView.id) {
|
||||||
|
R.id.to_do_recycler_view -> TaskStatus.TODO
|
||||||
|
R.id.in_progress_recycler_view -> TaskStatus.IN_PROGRESS
|
||||||
|
else -> null
|
||||||
|
} ?: return
|
||||||
|
|
||||||
|
viewModel.onChangeOrder(taskStatus, sourcePosition, targetPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onChangeStatus(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
sourcePosition: Int,
|
||||||
|
targetRecyclerView: RecyclerView,
|
||||||
|
targetPosition: Int?
|
||||||
|
) {
|
||||||
|
val fromStatus = when (recyclerView.id) {
|
||||||
|
R.id.to_do_recycler_view -> TaskStatus.TODO
|
||||||
|
R.id.in_progress_recycler_view -> TaskStatus.IN_PROGRESS
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
val toStatus = when (targetRecyclerView.id) {
|
||||||
|
R.id.to_do_recycler_view -> TaskStatus.TODO
|
||||||
|
R.id.in_progress_recycler_view -> TaskStatus.IN_PROGRESS
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
if (fromStatus != null && toStatus != null) {
|
||||||
|
viewModel.onChangeStatus(fromStatus, toStatus, sourcePosition, targetPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val GRID_ROWS = 2
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package com.github.adriankuta.unbounddragdrop
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.github.adriankuta.unbounddragdrop.model.Task
|
||||||
|
import com.github.adriankuta.unbounddragdrop.model.TaskStatus
|
||||||
|
import com.github.adriankuta.unbounddragdrop.model.TaskStatus.IN_PROGRESS
|
||||||
|
import com.github.adriankuta.unbounddragdrop.model.TaskStatus.TODO
|
||||||
|
import com.github.adriankuta.unbounddragdrop.util.WhileUiSubscribed
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import java.util.Collections
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
data class MainUiState(
|
||||||
|
val todo: List<Task> = emptyList(),
|
||||||
|
val inProgress: List<Task> = emptyList(),
|
||||||
|
)
|
||||||
|
|
||||||
|
class MainViewModel : ViewModel() {
|
||||||
|
|
||||||
|
|
||||||
|
private val _todoTasks = MutableStateFlow<List<Task>>(emptyList())
|
||||||
|
private val _inProgressTasks = MutableStateFlow<List<Task>>(emptyList())
|
||||||
|
|
||||||
|
init {
|
||||||
|
_todoTasks.value =
|
||||||
|
List(30) { Task(UUID.randomUUID().toString(), "Task $it", TODO) }
|
||||||
|
_inProgressTasks.value =
|
||||||
|
List(4) { Task(UUID.randomUUID().toString(), "Task $it", IN_PROGRESS) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val uiState: StateFlow<MainUiState> = combine(_todoTasks, _inProgressTasks) { listA, listB ->
|
||||||
|
MainUiState(listA, listB)
|
||||||
|
}.stateIn(
|
||||||
|
scope = viewModelScope,
|
||||||
|
started = WhileUiSubscribed,
|
||||||
|
initialValue = MainUiState()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun onChangeOrder(status: TaskStatus, sourcePosition: Int, targetPosition: Int) {
|
||||||
|
when (status) {
|
||||||
|
TODO -> _todoTasks.swapElements(sourcePosition, targetPosition)
|
||||||
|
IN_PROGRESS -> _inProgressTasks.swapElements(sourcePosition, targetPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onChangeStatus(
|
||||||
|
fromStatus: TaskStatus,
|
||||||
|
toStatus: TaskStatus,
|
||||||
|
fromPosition: Int,
|
||||||
|
toPosition: Int?
|
||||||
|
) {
|
||||||
|
val itemToMove = when (fromStatus) {
|
||||||
|
TODO -> _todoTasks.removeAt(fromPosition)
|
||||||
|
IN_PROGRESS -> _inProgressTasks.removeAt(fromPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
when (toStatus) {
|
||||||
|
TODO -> _todoTasks.add(toPosition ?: _todoTasks.size(), itemToMove)
|
||||||
|
IN_PROGRESS -> _inProgressTasks.add(toPosition ?: _inProgressTasks.size(), itemToMove)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> MutableStateFlow<List<T>>.swapElements(
|
||||||
|
sourcePosition: Int,
|
||||||
|
targetPosition: Int
|
||||||
|
) {
|
||||||
|
val newList = value.toMutableList()
|
||||||
|
Collections.swap(newList, sourcePosition, targetPosition)
|
||||||
|
value = newList
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> MutableStateFlow<List<T>>.removeAt(index: Int): T {
|
||||||
|
val newList = value.toMutableList()
|
||||||
|
val removedItem = newList.removeAt(index)
|
||||||
|
value = newList
|
||||||
|
return removedItem
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> MutableStateFlow<List<T>>.add(index: Int, item: T) {
|
||||||
|
val newList = value.toMutableList()
|
||||||
|
newList.add(index, item)
|
||||||
|
value = newList
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> MutableStateFlow<List<T>>.size(): Int {
|
||||||
|
return value.size
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.github.adriankuta.unbounddragdrop
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import timber.log.Timber
|
||||||
|
import timber.log.Timber.DebugTree
|
||||||
|
|
||||||
|
class MyApplication : Application() {
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
Timber.plant(DebugTree())
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package com.github.adriankuta.unbounddragdrop
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.AsyncListDiffer
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.github.adriankuta.unbounddragdrop.databinding.TextItemBinding
|
||||||
|
import com.github.adriankuta.unbounddragdrop.model.Task
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleGridPageAdapter :
|
||||||
|
RecyclerView.Adapter<SimpleGridPageAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
private val diffUtil = object : DiffUtil.ItemCallback<Task>() {
|
||||||
|
override fun areItemsTheSame(oldItem: Task, newItem: Task): Boolean {
|
||||||
|
return oldItem.id == newItem.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(
|
||||||
|
oldItem: Task,
|
||||||
|
newItem: Task
|
||||||
|
): Boolean {
|
||||||
|
return oldItem == newItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val asyncListDiffer = AsyncListDiffer(this, diffUtil)
|
||||||
|
|
||||||
|
fun submitList(list: List<Task>) {
|
||||||
|
asyncListDiffer.submitList(list)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
|
||||||
|
return ViewHolder(viewGroup.inflate())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
|
||||||
|
val data = asyncListDiffer.currentList[position]
|
||||||
|
viewHolder.bind(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount() = asyncListDiffer.currentList.size
|
||||||
|
|
||||||
|
class ViewHolder(private val binding: TextItemBinding) : RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
fun bind(task: Task) {
|
||||||
|
binding.textView.text = task.title
|
||||||
|
binding.root.isLongClickable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ViewGroup.inflate() =
|
||||||
|
TextItemBinding.inflate(LayoutInflater.from(context), this, false)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.github.adriankuta.unbounddragdrop.model
|
||||||
|
|
||||||
|
data class Task(
|
||||||
|
val id: String,
|
||||||
|
val title: String,
|
||||||
|
val taskStatus: TaskStatus
|
||||||
|
)
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.github.adriankuta.unbounddragdrop.model
|
||||||
|
|
||||||
|
enum class TaskStatus {
|
||||||
|
TODO,
|
||||||
|
IN_PROGRESS
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.github.adriankuta.unbounddragdrop.util
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
|
||||||
|
private const val StopTimeoutMillis: Long = 5000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A [SharingStarted] meant to be used with a [StateFlow] to expose data to the UI.
|
||||||
|
*
|
||||||
|
* When the UI stops observing, upstream flows stay active for some time to allow the system to
|
||||||
|
* come back from a short-lived configuration change (such as rotations). If the UI stops
|
||||||
|
* observing for longer, the cache is kept but the upstream flows are stopped. When the UI comes
|
||||||
|
* back, the latest value is replayed and the upstream flows are executed again. This is done to
|
||||||
|
* save resources when the app is in the background but let users switch between apps quickly.
|
||||||
|
*/
|
||||||
|
val WhileUiSubscribed: SharingStarted = SharingStarted.WhileSubscribed(StopTimeoutMillis)
|
57
app/src/main/res/layout/activity_main.xml
Normal file
57
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="#33aaaaaa"
|
||||||
|
android:padding="16dp"
|
||||||
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/header"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Sprint 1"
|
||||||
|
android:textSize="22sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/todo_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="To Do"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/header" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/to_do_recycler_view"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/todo_label" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/in_progress_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingVertical="12dp"
|
||||||
|
android:text="In Progress"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/to_do_recycler_view" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/in_progress_recycler_view"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/in_progress_label" />
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
21
app/src/main/res/layout/text_item.xml
Normal file
21
app/src/main/res/layout/text_item.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="12dp"
|
||||||
|
app:cardCornerRadius="4dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="30dp"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import org.gradle.api.Plugin
|
||||||
|
import org.gradle.api.Project
|
||||||
|
|
||||||
|
class AndroidLibraryPublishConventionPlugin : Plugin<Project> {
|
||||||
|
override fun apply(target: Project) {
|
||||||
|
with(target) {
|
||||||
|
with(pluginManager) {
|
||||||
|
apply("com.vanniktech.maven.publish")
|
||||||
|
apply("com.gradleup.nmcp")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user