Skip to content

Commit

Permalink
RefreshVersions and ViewBinding
Browse files Browse the repository at this point in the history
- Replace com.github.ben-manes:gradle-versions-plugin with de.fayard.refreshVersions:refreshVersions
- Replace synthetics with ViewBindings
  • Loading branch information
SimonMarquis committed Jan 30, 2021
1 parent 9cd2118 commit 66a00b0
Show file tree
Hide file tree
Showing 12 changed files with 201 additions and 136 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:

steps:
- uses: actions/checkout@v2
- name: set up JDK 1.8
- name: set up JDK 11
uses: actions/setup-java@v1
with:
java-version: 1.8
java-version: 11
- name: Fix gradlew permission
run: chmod +x gradlew
- name: Check
Expand Down
25 changes: 25 additions & 0 deletions .run/Github.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Github" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="clean" />
<option value="check" />
<option value="app:assembleDebug" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>
70 changes: 40 additions & 30 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import java.util.*

plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
kotlin("kapt")
}

Expand Down Expand Up @@ -29,12 +30,19 @@ android {
}
}
}
buildFeatures {
viewBinding = true
}
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
testOptions {
unitTests.isIncludeAndroidResources = true
unitTests.isReturnDefaultValues = true
Expand All @@ -49,27 +57,27 @@ tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.10")
implementation(Kotlin.stdlib.jdk7)

/* AndroidX */
implementation("androidx.appcompat:appcompat:1.3.0-alpha02")
implementation("androidx.constraintlayout:constraintlayout:2.0.2")
implementation("androidx.core:core-ktx:1.5.0-alpha04")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.2.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0")
implementation("androidx.preference:preference-ktx:1.1.1")
implementation("androidx.recyclerview:recyclerview:1.2.0-alpha06")
implementation("androidx.transition:transition:1.3.1")
androidTestImplementation("androidx.test.espresso:espresso-core:3.3.0")
androidTestImplementation("androidx.test.ext:junit:1.1.2")
implementation(AndroidX.appCompat)
implementation(AndroidX.constraintLayout)
implementation(AndroidX.core.ktx)
implementation(AndroidX.lifecycle.liveDataKtx)
implementation(AndroidX.lifecycle.viewModelKtx)
implementation(AndroidX.preferenceKtx)
implementation(AndroidX.recyclerView)
implementation(AndroidX.transition)
androidTestImplementation(AndroidX.test.espresso.core)
androidTestImplementation(AndroidX.test.ext.junit)

/* Material Design */
implementation("com.google.android.material:material:1.3.0-alpha03")
implementation(Google.Android.material)

/* Firebase */
implementation("com.google.firebase:firebase-core:17.5.1")
implementation("com.google.firebase:firebase-messaging:20.3.0")
implementation("com.google.firebase:firebase-database:19.5.1")
implementation(platform(Firebase.bom))
implementation(Firebase.cloudMessaging)
implementation(Firebase.realtimeDatabase)

/* Koin: Dependency Injection */
val koin = "2.1.6"
Expand All @@ -80,26 +88,28 @@ dependencies {
androidTestImplementation("org.koin:koin-test:$koin")

/* Moshi: JSON parsing */
val moshi = "1.11.0"
implementation("com.squareup.moshi:moshi-adapters:$moshi")
implementation("com.squareup.moshi:moshi-kotlin:$moshi")
kapt("com.squareup.moshi:moshi-kotlin-codegen:$moshi")
implementation(Square.moshi)
implementation(Square.moshi.kotlinReflect)
kapt(Square.moshi.kotlinCodegen)
implementation("com.squareup.moshi:moshi-adapters:${
file("${rootDir}/versions.properties").inputStream().use {
Properties().apply { load(it) }.getProperty("version.moshi")
}
}")

/* Room: SQLite persistence */
val room = "2.2.5"
implementation("androidx.room:room-runtime:$room")
kapt("androidx.room:room-compiler:$room")
implementation("androidx.room:room-ktx:$room")
testImplementation("androidx.room:room-testing:$room")
implementation(AndroidX.room.runtime)
kapt(AndroidX.room.compiler)
implementation(AndroidX.room.ktx)
testImplementation(AndroidX.room.testing)

/* Kotlin Coroutines */
val coroutines = "1.4.0-M1"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:$coroutines")
implementation(KotlinX.coroutines.core)
implementation(KotlinX.coroutines.android)
implementation(KotlinX.coroutines.playServices)

/* JUnit */
testImplementation("junit:junit:4.13.1")
testImplementation(Testing.junit4)

}

Expand Down
87 changes: 37 additions & 50 deletions app/src/main/java/fr/smarquis/fcm/view/adapter/MessagesAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,18 @@ package fr.smarquis.fcm.view.adapter

import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.squareup.moshi.Moshi
import fr.smarquis.fcm.R
import fr.smarquis.fcm.data.model.Message
import fr.smarquis.fcm.data.model.Payload
import fr.smarquis.fcm.databinding.ItemPayloadBinding
import fr.smarquis.fcm.utils.copyToClipboard
import fr.smarquis.fcm.utils.safeStartActivity
import fr.smarquis.fcm.view.adapter.MessagesAdapter.Action.PRIMARY
Expand All @@ -48,11 +46,8 @@ class MessagesAdapter(private val moshi: Moshi) : ListAdapter<Message, MessagesA
private val selection: androidx.collection.ArrayMap<String, Boolean> = androidx.collection.ArrayMap()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val view = inflater.inflate(R.layout.item_payload, parent, false)
return ViewHolder(view, ::toggle)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
ViewHolder(ItemPayloadBinding.inflate(LayoutInflater.from(parent.context), parent, false), ::toggle)

private fun toggle(message: Message, viewHolder: ViewHolder) {
selection[message.messageId] = !(selection[message.messageId] ?: false)
Expand All @@ -61,32 +56,27 @@ class MessagesAdapter(private val moshi: Moshi) : ListAdapter<Message, MessagesA

public override fun getItem(position: Int): Message = super.getItem(position)

override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) = viewHolder.onBind(getItem(position), selection[getItem(position).messageId] ?: false)
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) = viewHolder.onBind(getItem(position), selection[getItem(position).messageId]
?: false)

override fun onViewRecycled(holder: ViewHolder) = holder.onUnbind()

enum class Action {
PRIMARY, SECONDARY
}

inner class ViewHolder(itemView: View, private val listener: (Message, ViewHolder) -> Unit) : RecyclerView.ViewHolder(itemView) {
inner class ViewHolder(private val binding: ItemPayloadBinding, private val listener: (Message, ViewHolder) -> Unit) : RecyclerView.ViewHolder(binding.root) {

private var message: Message? = null
private var selected = false

private val icon: ImageView = itemView.findViewById(R.id.item_icon)
private val timestamp: TimeAgoTextView = itemView.findViewById(R.id.item_timestamp)
private val raw: TextView = itemView.findViewById(R.id.item_raw)
private val text: TextView = itemView.findViewById(R.id.item_text)
private val button1: Button = itemView.findViewById(R.id.item_btn_1)
private val button2: Button = itemView.findViewById(R.id.item_btn_2)
private val selector: View = itemView.findViewById(R.id.item_selector)

init {
button1.setOnClickListener { execute(PRIMARY, payload()) }
button2.setOnClickListener { execute(SECONDARY, payload()) }
itemView.setOnClickListener { message?.let { listener(it, this) } }
itemView.setOnLongClickListener { message?.let { listener(it, this) }.let { true } }
with(binding) {
buttonPrimary.setOnClickListener { execute(PRIMARY, payload()) }
buttonSecondary.setOnClickListener { execute(SECONDARY, payload()) }
root.setOnClickListener { message?.let { listener(it, this@ViewHolder) } }
root.setOnLongClickListener { message?.let { listener(it, this@ViewHolder) }.let { true } }
}
}

private fun payload(): Payload? = message?.payload
Expand All @@ -100,29 +90,27 @@ class MessagesAdapter(private val moshi: Moshi) : ListAdapter<Message, MessagesA
SECONDARY -> context.safeStartActivity(payload.uninstall())
}
}
is Payload.Link -> {
if (action == PRIMARY) {
context.safeStartActivity(payload.intent())
}
is Payload.Link -> if (action == PRIMARY) context.safeStartActivity(payload.intent())
is Payload.Text -> if (action == PRIMARY) context.copyToClipboard(payload.text)
is Payload.Ping -> {
}
is Payload.Text -> {
if (action == PRIMARY) {
context.copyToClipboard(payload.text)
}
is Payload.Raw -> {
}
null -> {
}
}
}

fun onBind(message: Message, selected: Boolean) {
this.message = message
this.selected = selected
fun onBind(message: Message, selected: Boolean) = with(binding) {
this@ViewHolder.message = message
this@ViewHolder.selected = selected
icon.setImageResource(message.payload?.icon() ?: 0)
timestamp.timestamp = min(message.sentTime, System.currentTimeMillis())
renderContent()
renderButtons()
}

private fun renderContent() {
private fun renderContent() = with(binding) {
selector.isActivated = selected
if (selected) {
text.text = null
Expand All @@ -141,10 +129,10 @@ class MessagesAdapter(private val moshi: Moshi) : ListAdapter<Message, MessagesA
}
}

private fun renderButtons() {
private fun renderButtons() = with(binding) {
mapOf(
PRIMARY to button1,
SECONDARY to button2
PRIMARY to buttonPrimary,
SECONDARY to buttonSecondary
).forEach { (action, button) ->
render(action, button, message?.payload)
}
Expand All @@ -170,28 +158,27 @@ class MessagesAdapter(private val moshi: Moshi) : ListAdapter<Message, MessagesA
}
}
}
is Payload.Link -> {
if (action == PRIMARY) {
button.visibility = VISIBLE
button.setText(R.string.payload_link_open)
return
}
is Payload.Link -> if (action == PRIMARY) {
button.visibility = VISIBLE
button.setText(R.string.payload_link_open)
return
}
is Payload.Text -> {
if (action == PRIMARY) {
button.visibility = VISIBLE
button.setText(R.string.payload_text_copy)
return
}
is Payload.Text -> if (action == PRIMARY) {
button.visibility = VISIBLE
button.setText(R.string.payload_text_copy)
return
}
is Payload.Ping -> {}
is Payload.Raw -> {}
null -> {}
}
button.visibility = GONE
button.text = null
}

fun onUnbind() {
message = null
timestamp.timestamp = TimeAgoTextView.NO_TIMESTAMP
binding.timestamp.timestamp = TimeAgoTextView.NO_TIMESTAMP
}
}

Expand Down
Loading

0 comments on commit 66a00b0

Please sign in to comment.