<commit_before>package fr.smarquis.fcm.data.model

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.Intent.*
import android.content.pm.PackageManager
import android.net.Uri
import android.text.TextUtils
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.Builder
import androidx.core.text.bold
import androidx.core.text.buildSpannedString
import com.google.firebase.messaging.RemoteMessage
import com.squareup.moshi.Json
import com.squareup.moshi.Moshi
import fr.smarquis.fcm.R
import fr.smarquis.fcm.view.ui.CopyToClipboardActivity
import org.koin.core.KoinComponent
import org.koin.core.inject
import java.io.IOException

sealed class Payload {

    @IdRes
    abstract fun notificationId(): Int

    @DrawableRes
    abstract fun icon(): Int

    abstract fun display(): CharSequence?

    abstract fun configure(builder: Builder): Builder

    data class App(
            @Json(name = "title")
            private val title: String? = null,
            @Json(name = "package")
            private val packageName: String? = null
    ) : Payload() {

        override fun notificationId(): Int = R.id.notification_id_app

        override fun icon(): Int = R.drawable.ic_shop_24dp

        private val display: CharSequence by lazy {
            buildSpannedString {
                bold { append("title: ") }
                append("$title\n")
                bold { append("package: ") }
                append(packageName)
            }
        }

        override fun display(): CharSequence? = display

        @SuppressLint("RestrictedApi")
        override fun configure(builder: Builder): Builder = builder.apply {
            builder.setContentTitle(if (TextUtils.isEmpty(title)) mContext.getString(R.string.payload_app) else title)
                    .setContentText(packageName)
                    .addAction(0, mContext.getString(R.string.payload_app_store), PendingIntent.getActivity(mContext, 0, playStore(), 0))
            if (isInstalled(mContext)) {
                builder.addAction(0, mContext.getString(R.string.payload_app_uninstall), PendingIntent.getActivity(mContext, 0, uninstall(), 0))
            }
        }

        fun playStore(): Intent = Intent(ACTION_VIEW, Uri.parse("market://details?id=$packageName")).apply {
            addFlags(FLAG_ACTIVITY_NEW_TASK)
        }

        fun uninstall(): Intent = Intent(ACTION_DELETE, Uri.parse("package:$packageName")).apply {
            addFlags(FLAG_ACTIVITY_NEW_TASK)
        }

        fun isInstalled(context: Context): Boolean = try {
            context.packageManager.getPackageInfo(packageName.orEmpty(), 0) != null
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }

    }

    data class Link(
            @Json(name = "title")
            private val title: String? = null,
            @Json(name = "url")
            private val url: String? = null,
            @Json(name = "open")
            @Deprecated(message = "Since Android 10, starting an Activity from background has been disabled https://developer.android.com/guide/components/activities/background-starts")
            val open: Boolean = false
    ) : Payload() {

        override fun notificationId(): Int = R.id.notification_id_link

        override fun icon(): Int = R.drawable.ic_link_24dp

        private val display: CharSequence by lazy {
            buildSpannedString {
                bold { append("title: ") }
                append("$title\n")
                bold { append("url: ") }
                append("$url")
            }
        }

        override fun display(): CharSequence? = display

        @SuppressLint("RestrictedApi")
        override fun configure(builder: Builder): Builder = builder.apply {
            setContentTitle(if (TextUtils.isEmpty(title)) mContext.getString(R.string.payload_link) else title).setContentText(url)
            if (!TextUtils.isEmpty(url)) {
                addAction(0, mContext.getString(R.string.payload_link_open), PendingIntent.getActivity(mContext, 0, intent(), 0))
            }
        }

        fun intent(): Intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
            addFlags(FLAG_ACTIVITY_NEW_TASK)
        }

    }

    @Suppress("CanSealedSubClassBeObject")
    class Ping : Payload() {

        override fun notificationId(): Int = R.id.notification_id_ping

        override fun icon(): Int = R.drawable.ic_notifications_none_24dp

        override fun display(): CharSequence? = null

        @SuppressLint("RestrictedApi")
        override fun configure(builder: Builder): Builder = builder.apply { setContentTitle(mContext.getString(R.string.payload_ping)) }
    }
<commit_msg>Fix RecyclerView animations for Ping Payload.Ping (non-data class) objects were treated all not-equals by ListAdapter's DiffUtil<commit_after>package fr.smarquis.fcm.data.model

import android.annotation.SuppressLint
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.content.Intent.*
import android.content.pm.PackageManager
import android.net.Uri
import android.text.TextUtils
import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.Builder
import androidx.core.text.bold
import androidx.core.text.buildSpannedString
import com.google.firebase.messaging.RemoteMessage
import com.squareup.moshi.Json
import com.squareup.moshi.Moshi
import fr.smarquis.fcm.R
import fr.smarquis.fcm.view.ui.CopyToClipboardActivity
import org.koin.core.KoinComponent
import org.koin.core.inject
import java.io.IOException

sealed class Payload {

    @IdRes
    abstract fun notificationId(): Int

    @DrawableRes
    abstract fun icon(): Int

    abstract fun display(): CharSequence?

    abstract fun configure(builder: Builder): Builder

    data class App(
            @Json(name = "title")
            private val title: String? = null,
            @Json(name = "package")
            private val packageName: String? = null
    ) : Payload() {

        override fun notificationId(): Int = R.id.notification_id_app

        override fun icon(): Int = R.drawable.ic_shop_24dp

        private val display: CharSequence by lazy {
            buildSpannedString {
                bold { append("title: ") }
                append("$title\n")
                bold { append("package: ") }
                append(packageName)
            }
        }

        override fun display(): CharSequence? = display

        @SuppressLint("RestrictedApi")
        override fun configure(builder: Builder): Builder = builder.apply {
            builder.setContentTitle(if (TextUtils.isEmpty(title)) mContext.getString(R.string.payload_app) else title)
                    .setContentText(packageName)
                    .addAction(0, mContext.getString(R.string.payload_app_store), PendingIntent.getActivity(mContext, 0, playStore(), 0))
            if (isInstalled(mContext)) {
                builder.addAction(0, mContext.getString(R.string.payload_app_uninstall), PendingIntent.getActivity(mContext, 0, uninstall(), 0))
            }
        }

        fun playStore(): Intent = Intent(ACTION_VIEW, Uri.parse("market://details?id=$packageName")).apply {
            addFlags(FLAG_ACTIVITY_NEW_TASK)
        }

        fun uninstall(): Intent = Intent(ACTION_DELETE, Uri.parse("package:$packageName")).apply {
            addFlags(FLAG_ACTIVITY_NEW_TASK)
        }

        fun isInstalled(context: Context): Boolean = try {
            context.packageManager.getPackageInfo(packageName.orEmpty(), 0) != null
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }

    }

    data class Link(
            @Json(name = "title")
            private val title: String? = null,
            @Json(name = "url")
            private val url: String? = null,
            @Json(name = "open")
            @Deprecated(message = "Since Android 10, starting an Activity from background has been disabled https://developer.android.com/guide/components/activities/background-starts")
            val open: Boolean = false
    ) : Payload() {

        override fun notificationId(): Int = R.id.notification_id_link

        override fun icon(): Int = R.drawable.ic_link_24dp

        private val display: CharSequence by lazy {
            buildSpannedString {
                bold { append("title: ") }
                append("$title\n")
                bold { append("url: ") }
                append("$url")
            }
        }

        override fun display(): CharSequence? = display

        @SuppressLint("RestrictedApi")
        override fun configure(builder: Builder): Builder = builder.apply {
            setContentTitle(if (TextUtils.isEmpty(title)) mContext.getString(R.string.payload_link) else title).setContentText(url)
            if (!TextUtils.isEmpty(url)) {
                addAction(0, mContext.getString(R.string.payload_link_open), PendingIntent.getActivity(mContext, 0, intent(), 0))
            }
        }

        fun intent(): Intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
            addFlags(FLAG_ACTIVITY_NEW_TASK)
        }

    }

    @Suppress("CanSealedSubClassBeObject")
    class Ping : Payload() {

        override fun notificationId(): Int = R.id.notification_id_ping

        override fun icon(): Int = R.drawable.ic_notifications_none_24dp

        override fun display(): CharSequence? = null

        @SuppressLint("RestrictedApi")
        override fun configure(builder: Builder): Builder = builder.apply { setContentTitle(mContext.getString(R.string.payload_ping)) }

        override fun equals(other: Any?): Boolean = if (other is Ping) true else super.equals(other)

        override fun hashCode(): Int = 0

    }

{'fraction_non_alphanumeric': 0.10323805716570059, 'fraction_numerical': 0.0036977813312012793, 'mean_word_length': 2.6655677655677654, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6076188', 'n_tokens_mistral': 2797, 'n_tokens_neox': 2675, 'n_words': 598}