Merge pull request 'Issue 2: Add config' (#7) from ms/issues-2/add-config-db into master
@ -27,7 +27,8 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
buildConfigField "Integer", "DB_VERSION", "1"
|
buildConfigField "Integer", "DB_VERSION", "1"
|
||||||
buildConfigField "Boolean", "TEST", "false"
|
buildConfigField "Boolean", "TEST", "false"
|
||||||
|
@ -8,12 +8,6 @@
|
|||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.CAMERA"
|
android:name="android.permission.CAMERA"
|
||||||
tools:node="remove" />
|
tools:node="remove" />
|
||||||
<uses-permission
|
|
||||||
android:name="android.permission.READ_PHONE_STATE"
|
|
||||||
tools:node="remove" />
|
|
||||||
<uses-permission
|
|
||||||
android:name="android.permission.INTERNET"
|
|
||||||
tools:node="remove" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
|
@ -2,18 +2,22 @@ package fr.sanchezm.attestationsCovid19.data.db
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.dao.AttestationDao
|
import fr.sanchezm.attestationsCovid19.data.db.dao.AttestationDao
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.db.dao.ConfigDao
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.dao.ProfileDao
|
import fr.sanchezm.attestationsCovid19.data.db.dao.ProfileDao
|
||||||
|
|
||||||
class MyDatabase private constructor(private val savePath: String, private val filesPath: String) {
|
class MyDatabase private constructor(private val savePath: String, private val filesPath: String) {
|
||||||
|
|
||||||
private var _profileDao: ProfileDao? = null
|
private var _profileDao: ProfileDao? = null
|
||||||
private var _attestationDao: AttestationDao? = null
|
private var _attestationDao: AttestationDao? = null
|
||||||
|
private var _configDao: ConfigDao? = null
|
||||||
|
|
||||||
fun profileDao(): ProfileDao = _profileDao ?: ProfileDao(savePath).also { _profileDao = it }
|
fun profileDao(): ProfileDao = _profileDao ?: ProfileDao(savePath).also { _profileDao = it }
|
||||||
|
|
||||||
fun attestationDao(): AttestationDao =
|
fun attestationDao(): AttestationDao =
|
||||||
_attestationDao ?: AttestationDao(savePath, filesPath).also { _attestationDao = it }
|
_attestationDao ?: AttestationDao(savePath, filesPath).also { _attestationDao = it }
|
||||||
|
|
||||||
|
fun configDao(): ConfigDao = _configDao ?: ConfigDao(savePath).also { _configDao = it }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Volatile
|
@Volatile
|
||||||
private var instance: MyDatabase? = null
|
private var instance: MyDatabase? = null
|
||||||
|
@ -11,8 +11,8 @@ import java.io.File
|
|||||||
|
|
||||||
class AttestationDao(private val savePath: String, private val filesPath: String) {
|
class AttestationDao(private val savePath: String, private val filesPath: String) {
|
||||||
|
|
||||||
private var _attestations = MutableLiveData<ArrayList<Attestation>>()
|
private val _attestations = MutableLiveData<ArrayList<Attestation>>()
|
||||||
private var fileName = "attestation.db"
|
private val fileName = "attestation.db"
|
||||||
private val type = object : TypeToken<ArrayList<Attestation>>() {}.type
|
private val type = object : TypeToken<ArrayList<Attestation>>() {}.type
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package fr.sanchezm.attestationsCovid19.data.db.dao
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import fr.sanchezm.attestationsCovid19.BuildConfig
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.db.entity.Config
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class ConfigDao(private val savePath: String) {
|
||||||
|
|
||||||
|
private val _config = MutableLiveData<Config>()
|
||||||
|
private val fileName = "config.db"
|
||||||
|
|
||||||
|
fun getConfig(): LiveData<Config> =
|
||||||
|
_config
|
||||||
|
|
||||||
|
fun updateConfig(config: Config) {
|
||||||
|
_config.value = config
|
||||||
|
save()
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
load()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun load() {
|
||||||
|
val file = File("$savePath/$fileName")
|
||||||
|
|
||||||
|
if (file.exists()) {
|
||||||
|
_config.value = Gson().fromJson(file.readText(Charsets.UTF_8), Config::class.java)
|
||||||
|
_config.value?.versionCode = BuildConfig.VERSION_CODE
|
||||||
|
_config.value?.versionName = BuildConfig.VERSION_NAME
|
||||||
|
} else {
|
||||||
|
_config.value =
|
||||||
|
Config(BuildConfig.DB_VERSION, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
|
||||||
|
save()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun save() {
|
||||||
|
File("$savePath/$fileName").writeText(Gson().toJson(_config.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,8 +8,8 @@ import java.io.File
|
|||||||
|
|
||||||
class ProfileDao(private val path: String) {
|
class ProfileDao(private val path: String) {
|
||||||
|
|
||||||
private var _profile = MutableLiveData<Profile>()
|
private val _profile = MutableLiveData<Profile>()
|
||||||
private var fileName = "profile.db"
|
private val fileName = "profile.db"
|
||||||
|
|
||||||
fun getProfile(): LiveData<Profile> =
|
fun getProfile(): LiveData<Profile> =
|
||||||
_profile
|
_profile
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package fr.sanchezm.attestationsCovid19.data.db.entity
|
||||||
|
|
||||||
|
data class Config(
|
||||||
|
val dbVersion: Int,
|
||||||
|
var versionName: String,
|
||||||
|
var versionCode: Int
|
||||||
|
)
|
@ -0,0 +1,21 @@
|
|||||||
|
package fr.sanchezm.attestationsCovid19.data.repository
|
||||||
|
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.db.dao.ConfigDao
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.db.entity.Config
|
||||||
|
|
||||||
|
class ConfigRepository private constructor(private val configDao: ConfigDao) {
|
||||||
|
|
||||||
|
fun getConfig() = configDao.getConfig()
|
||||||
|
|
||||||
|
fun updateConfig(config: Config) = configDao.updateConfig(config)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
private var instance: ConfigRepository? = null
|
||||||
|
|
||||||
|
fun getInstance(configDao: ConfigDao) =
|
||||||
|
instance ?: synchronized(this) {
|
||||||
|
instance ?: ConfigRepository(configDao).also { instance = it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import fr.sanchezm.attestationsCovid19.R
|
|||||||
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.entity.Profile
|
import fr.sanchezm.attestationsCovid19.data.db.entity.Profile
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.repository.ConfigRepository
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository
|
||||||
import fr.sanchezm.attestationsCovid19.utilities.Event
|
import fr.sanchezm.attestationsCovid19.utilities.Event
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@ -18,6 +19,7 @@ import java.time.format.DateTimeFormatter
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class AddViewModel(
|
class AddViewModel(
|
||||||
|
private val configRepository: ConfigRepository,
|
||||||
private val profileRepository: ProfileRepository,
|
private val profileRepository: ProfileRepository,
|
||||||
private val attestationRepository: AttestationRepository
|
private val attestationRepository: AttestationRepository
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
@ -3,9 +3,11 @@ package fr.sanchezm.attestationsCovid19.ui.add
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.repository.ConfigRepository
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository
|
||||||
|
|
||||||
class AddViewModelFactory(
|
class AddViewModelFactory(
|
||||||
|
private val configRepository: ConfigRepository,
|
||||||
private val profileRepository: ProfileRepository,
|
private val profileRepository: ProfileRepository,
|
||||||
private val attestationRepository: AttestationRepository
|
private val attestationRepository: AttestationRepository
|
||||||
) :
|
) :
|
||||||
@ -13,6 +15,6 @@ class AddViewModelFactory(
|
|||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||||
return AddViewModel(profileRepository, attestationRepository) as T
|
return AddViewModel(configRepository, profileRepository, attestationRepository) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,9 +5,14 @@ import androidx.lifecycle.LiveData
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.repository.ConfigRepository
|
||||||
import fr.sanchezm.attestationsCovid19.utilities.Event
|
import fr.sanchezm.attestationsCovid19.utilities.Event
|
||||||
|
|
||||||
class AttestationsViewModel(attestationRepository: AttestationRepository) : ViewModel() {
|
class AttestationsViewModel(
|
||||||
|
private val configRepository: ConfigRepository,
|
||||||
|
attestationRepository: AttestationRepository
|
||||||
|
) :
|
||||||
|
ViewModel() {
|
||||||
|
|
||||||
private val _startActivity = MutableLiveData<Event<Long>>()
|
private val _startActivity = MutableLiveData<Event<Long>>()
|
||||||
private var _displayNoAttestation = MutableLiveData<Int>()
|
private var _displayNoAttestation = MutableLiveData<Int>()
|
||||||
|
@ -3,13 +3,16 @@ package fr.sanchezm.attestationsCovid19.ui.attestations
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.ConfigRepository
|
||||||
|
|
||||||
class AttestationsViewModelFactory(private val attestationRepository: AttestationRepository) :
|
class AttestationsViewModelFactory(
|
||||||
|
private val configRepository: ConfigRepository,
|
||||||
|
private val attestationRepository: AttestationRepository
|
||||||
|
) :
|
||||||
ViewModelProvider.NewInstanceFactory() {
|
ViewModelProvider.NewInstanceFactory() {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||||
return AttestationsViewModel(attestationRepository) as T
|
return AttestationsViewModel(configRepository, attestationRepository) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,10 +7,15 @@ import androidx.lifecycle.MutableLiveData
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
import fr.sanchezm.attestationsCovid19.data.db.entity.Attestation
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.repository.ConfigRepository
|
||||||
import fr.sanchezm.attestationsCovid19.utilities.Event
|
import fr.sanchezm.attestationsCovid19.utilities.Event
|
||||||
import fr.sanchezm.attestationsCovid19.utilities.QRCodeUtils
|
import fr.sanchezm.attestationsCovid19.utilities.QRCodeUtils
|
||||||
|
|
||||||
class QrCodeViewModel(private val attestationRepository: AttestationRepository) : ViewModel() {
|
class QrCodeViewModel(
|
||||||
|
private val configRepository: ConfigRepository,
|
||||||
|
private val attestationRepository: AttestationRepository
|
||||||
|
) :
|
||||||
|
ViewModel() {
|
||||||
|
|
||||||
private val _attestation = MutableLiveData<Attestation>()
|
private val _attestation = MutableLiveData<Attestation>()
|
||||||
|
|
||||||
|
@ -3,12 +3,16 @@ package fr.sanchezm.attestationsCovid19.ui.qrcode
|
|||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.repository.ConfigRepository
|
||||||
|
|
||||||
class QrCodeViewModelFactory(private val attestationRepository: AttestationRepository) :
|
class QrCodeViewModelFactory(
|
||||||
|
private val configRepository: ConfigRepository,
|
||||||
|
private val attestationRepository: AttestationRepository
|
||||||
|
) :
|
||||||
ViewModelProvider.NewInstanceFactory() {
|
ViewModelProvider.NewInstanceFactory() {
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
|
||||||
return QrCodeViewModel(attestationRepository) as T
|
return QrCodeViewModel(configRepository, attestationRepository) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import fr.sanchezm.attestationsCovid19.data.db.MyDatabase
|
import fr.sanchezm.attestationsCovid19.data.db.MyDatabase
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.AttestationRepository
|
||||||
|
import fr.sanchezm.attestationsCovid19.data.repository.ConfigRepository
|
||||||
import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository
|
import fr.sanchezm.attestationsCovid19.data.repository.ProfileRepository
|
||||||
import fr.sanchezm.attestationsCovid19.ui.add.AddViewModelFactory
|
import fr.sanchezm.attestationsCovid19.ui.add.AddViewModelFactory
|
||||||
import fr.sanchezm.attestationsCovid19.ui.attestations.AttestationsViewModelFactory
|
import fr.sanchezm.attestationsCovid19.ui.attestations.AttestationsViewModelFactory
|
||||||
@ -11,41 +12,42 @@ import fr.sanchezm.attestationsCovid19.ui.qrcode.QrCodeViewModelFactory
|
|||||||
|
|
||||||
object InjectorUtils {
|
object InjectorUtils {
|
||||||
|
|
||||||
fun provideAddViewModelFactory(context: Context): AddViewModelFactory {
|
fun provideAddViewModelFactory(context: Context): AddViewModelFactory =
|
||||||
val profileRepository =
|
AddViewModelFactory(
|
||||||
ProfileRepository.getInstance(
|
getConfigRepo(context),
|
||||||
MyDatabase.invoke(context, getMyFilesDir(context)).profileDao()
|
getProfileRepo(context),
|
||||||
)
|
getAttestationRepo(context)
|
||||||
val attestationRepository =
|
)
|
||||||
AttestationRepository.getInstance(
|
|
||||||
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
|
|
||||||
)
|
|
||||||
|
|
||||||
return AddViewModelFactory(profileRepository, attestationRepository)
|
fun provideAttestationViewModel(context: Context): AttestationsViewModelFactory =
|
||||||
}
|
AttestationsViewModelFactory(
|
||||||
|
getConfigRepo(context),
|
||||||
|
getAttestationRepo(context)
|
||||||
|
)
|
||||||
|
|
||||||
fun provideAttestationViewModel(context: Context): AttestationsViewModelFactory {
|
fun provideQrCodeViewModel(context: Context): QrCodeViewModelFactory =
|
||||||
val attestationRepository =
|
QrCodeViewModelFactory(
|
||||||
AttestationRepository.getInstance(
|
getConfigRepo(context),
|
||||||
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
|
getAttestationRepo(context)
|
||||||
)
|
)
|
||||||
|
|
||||||
return AttestationsViewModelFactory(attestationRepository)
|
fun providePdfUtils(context: Context): PdfUtils =
|
||||||
}
|
PdfUtils.getInstance(context.assets, getMyFilesDir(context))
|
||||||
|
|
||||||
fun provideQrCodeViewModel(context: Context): QrCodeViewModelFactory {
|
private fun getMyFilesDir(context: Context): String =
|
||||||
val attestationRepository =
|
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.path!!
|
||||||
AttestationRepository.getInstance(
|
|
||||||
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
|
|
||||||
)
|
|
||||||
|
|
||||||
return QrCodeViewModelFactory(attestationRepository)
|
private fun getAttestationRepo(context: Context): AttestationRepository =
|
||||||
}
|
AttestationRepository.getInstance(
|
||||||
|
MyDatabase.invoke(context, getMyFilesDir(context)).attestationDao()
|
||||||
|
)
|
||||||
|
|
||||||
fun providePdfUtils(context: Context): PdfUtils {
|
private fun getProfileRepo(context: Context): ProfileRepository = ProfileRepository.getInstance(
|
||||||
return PdfUtils.getInstance(context.assets, getMyFilesDir(context))
|
MyDatabase.invoke(context, getMyFilesDir(context)).profileDao()
|
||||||
}
|
)
|
||||||
|
|
||||||
private fun getMyFilesDir(context: Context): String = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.path!!
|
private fun getConfigRepo(context: Context): ConfigRepository = ConfigRepository.getInstance(
|
||||||
|
MyDatabase.invoke(context, getMyFilesDir(context)).configDao()
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
Before Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
Normal file
After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 4.5 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
Normal file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.6 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 5.3 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
Normal file
After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 6.4 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 5.7 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
Normal file
After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 10 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 8.1 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
Normal file
After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
After Width: | Height: | Size: 11 KiB |