Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
TousAntiCovid sources
TousAntiCovid Android
Commits
009bbd4c
Commit
009bbd4c
authored
Aug 05, 2020
by
stopcovid@lunabee.com
Browse files
Update to 1.1.3
parent
9bc304da
Changes
23
Expand all
Hide whitespace changes
Inline
Side-by-side
ble/build.gradle
View file @
009bbd4c
...
...
@@ -17,8 +17,8 @@ android {
defaultConfig
{
minSdkVersion
21
targetSdkVersion
29
versionCode
1
2
versionName
"1.
3
.0"
versionCode
1
3
versionName
"1.
4
.0"
}
compileOptions
{
...
...
@@ -64,7 +64,7 @@ dependencies {
def
androidXTestJUnitVersion
=
'1.1.2-rc01'
testImplementation
"androidx.test.ext:junit:${androidXTestJUnitVersion}"
def
coroutines_version
=
"1.3.
7
"
def
coroutines_version
=
"1.3.
8
"
implementation
"org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
testImplementation
"org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines_version"
...
...
ble/src/main/java/com/orange/proximitynotification/ble/BleProximityNotification.kt
View file @
009bbd4c
...
...
@@ -43,6 +43,7 @@ class BleProximityNotification(
private
val
bleRecordProviderForScanWithoutPayload
=
RecordProviderForScanWithoutPayload
(
settings
)
private
val
bleRecordMapper
=
BleRecordMapper
(
settings
)
private
val
bleScannedDeviceFilter
=
BleScannedDeviceFilter
()
private
lateinit
var
proximityPayloadProvider
:
ProximityPayloadProvider
private
lateinit
var
callback
:
ProximityNotificationCallback
...
...
@@ -121,7 +122,7 @@ class BleProximityNotification(
bleGattManager
.
requestRemoteRssi
(
device
,
false
)
?.
let
{
rssi
->
val
scannedDevice
=
BleScannedDevice
(
device
=
device
,
rssi
=
rssi
)
bleRecordProviderForScanWith
out
Payload
.
fromScan
(
bleRecordProviderForScanWithPayload
.
fromScan
(
scannedDevice
,
payload
)
...
...
@@ -149,26 +150,9 @@ class BleProximityNotification(
private
fun
startScanner
()
{
val
status
=
bleScanner
.
start
(
callback
=
object
:
BleScanner
.
Callback
{
override
fun
onResult
(
results
:
List
<
BleScannedDevice
>)
{
if
(
results
.
isNotEmpty
())
{
coroutineScope
.
launch
(
coroutineContextProvider
.
default
)
{
results
.
mapNotNull
{
scannedDevice
->
val
serviceData
=
scannedDevice
.
serviceData
if
(
serviceData
!=
null
)
{
// Android case
decodePayload
(
serviceData
)
?.
let
{
bleRecordProviderForScanWithPayload
.
fromScan
(
scannedDevice
,
it
)
}
}
else
{
// iOS case
bleRecordProviderForScanWithoutPayload
.
fromScan
(
scannedDevice
,
null
)
}
}.
forEach
{
notifyProximity
(
it
)
}
handleScanResults
(
bleScannedDeviceFilter
.
filter
(
results
))
}
}
}
...
...
@@ -213,6 +197,24 @@ class BleProximityNotification(
callback
.
onProximity
(
proximityInfo
)
}
private
suspend
fun
handleScanResults
(
results
:
List
<
BleScannedDevice
>)
=
withContext
(
coroutineContextProvider
.
default
)
{
results
.
mapNotNull
{
scannedDevice
->
val
serviceData
=
scannedDevice
.
serviceData
if
(
serviceData
!=
null
)
{
// Android case
decodePayload
(
serviceData
)
?.
let
{
bleRecordProviderForScanWithPayload
.
fromScan
(
scannedDevice
,
it
)
}
}
else
{
// iOS case
bleRecordProviderForScanWithoutPayload
.
fromScan
(
scannedDevice
,
null
)
}
}.
forEach
{
notifyProximity
(
it
)
}
}
private
fun
decodePayload
(
value
:
ByteArray
)
=
BlePayload
.
fromOrNull
(
value
)
private
fun
buildPayload
()
=
BlePayload
(
...
...
ble/src/main/java/com/orange/proximitynotification/ble/BleScannedDeviceFilter.kt
0 → 100644
View file @
009bbd4c
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Authors
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Created by Orange / Date - 2020/06/30 - for the STOP-COVID project
*/
package
com.orange.proximitynotification.ble
import
com.orange.proximitynotification.ble.scanner.BleScannedDevice
import
java.util.Date
internal
class
BleScannedDeviceFilter
{
private
var
mostRecentScanTimestamp
=
Date
(
0
)
fun
filter
(
scannedDevices
:
List
<
BleScannedDevice
>):
List
<
BleScannedDevice
>
{
val
results
=
scannedDevices
.
sortedByDescending
{
it
.
timestamp
}
.
distinctBy
{
it
.
serviceData
?.
contentHashCode
()
?:
run
{
it
.
device
.
address
}
}
.
filter
{
it
.
timestamp
>
mostRecentScanTimestamp
}
results
.
firstOrNull
()
?.
let
{
this
.
mostRecentScanTimestamp
=
it
.
timestamp
}
return
results
}
}
\ No newline at end of file
ble/src/main/java/com/orange/proximitynotification/ble/scanner/BleScannerImpl.kt
View file @
009bbd4c
...
...
@@ -98,7 +98,6 @@ class BleScannerImpl(
super
.
onBatchScanResults
(
results
)
results
.
distinctBy
{
it
.
device
}
.
toBleScannedDevices
(
settings
.
serviceUuid
)
.
takeIf
{
it
.
isNotEmpty
()
}
?.
let
{
callback
.
onResult
(
it
)
}
...
...
ble/src/main/java/com/orange/proximitynotification/ble/scanner/ScanResultExt.kt
View file @
009bbd4c
...
...
@@ -11,14 +11,16 @@
package
com.orange.proximitynotification.ble.scanner
import
android.os.ParcelUuid
import
com.orange.proximitynotification.tools.nanosTimestampToDate
import
no.nordicsemi.android.support.v18.scanner.ScanResult
import
java.util.UUID
internal
fun
ScanResult
.
toBleScannedDevice
(
serviceUuid
:
UUID
):
BleScannedDevice
=
BleScannedDevice
(
device
=
device
,
rssi
=
rssi
,
serviceData
=
scanRecord
?.
serviceData
?.
get
(
ParcelUuid
(
serviceUuid
)),
rssi
=
rssi
timestamp
=
timestampNanos
.
nanosTimestampToDate
()
)
internal
fun
List
<
ScanResult
>.
toBleScannedDevices
(
serviceUuid
:
UUID
):
List
<
BleScannedDevice
>
=
...
...
ble/src/main/java/com/orange/proximitynotification/tools/TimeUtils.kt
0 → 100644
View file @
009bbd4c
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Authors
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Created by Orange / Date - 2020/06/30 - for the STOP-COVID project
*/
package
com.orange.proximitynotification.tools
import
android.os.SystemClock
import
java.util.Date
internal
fun
Long
.
nanosTimestampToDate
():
Date
=
Date
(
System
.
currentTimeMillis
()
-
SystemClock
.
elapsedRealtime
()
+
(
this
/
1000000
))
\ No newline at end of file
ble/src/test/java/com/orange/proximitynotification/ble/BleScannedDeviceFilterTest.kt
0 → 100644
View file @
009bbd4c
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Authors
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Created by Orange / Date - 2020/06/30 - for the STOP-COVID project
*/
package
com.orange.proximitynotification.ble
import
com.google.common.truth.Truth.assertThat
import
com.orange.proximitynotification.ble.scanner.BleScannedDevice
import
org.junit.Test
import
java.util.Date
class
BleScannedDeviceFilterTest
{
private
val
filter
=
BleScannedDeviceFilter
()
@Test
fun
filter_with_empty_should_return_empty
()
{
// Given
val
scans
:
List
<
BleScannedDevice
>
=
emptyList
()
// When
val
result
=
filter
.
filter
(
scans
)
// Then
assertThat
(
result
).
isEmpty
()
}
@Test
fun
filter_with_different_device_scans_should_return_same_device_scans
()
{
// Given
val
now
=
Date
()
val
scans
:
List
<
BleScannedDevice
>
=
listOf
(
bleScannedDevice
(
bluetoothDevice
(
"Device1"
),
timestamp
=
now
,
serviceData
=
null
),
bleScannedDevice
(
bluetoothDevice
(
"Device2"
),
timestamp
=
now
,
serviceData
=
null
),
bleScannedDevice
(
bluetoothDevice
(
"Device3"
),
timestamp
=
now
,
serviceData
=
byteArrayOf
(
1
)),
bleScannedDevice
(
bluetoothDevice
(
"Device4"
),
timestamp
=
now
,
serviceData
=
byteArrayOf
(
2
))
)
// When
val
result
=
filter
.
filter
(
scans
)
// Then
assertThat
(
result
).
isEqualTo
(
scans
)
}
@Test
fun
filter_with_different_device_scans_but_same_service_data_should_squash
()
{
// Given
val
now
=
Date
()
val
device1
=
bluetoothDevice
(
"Device1"
)
val
device2
=
bluetoothDevice
(
"Device2"
)
val
device3
=
bluetoothDevice
(
"Device3"
)
val
device4
=
bluetoothDevice
(
"Device4"
)
val
scans
:
List
<
BleScannedDevice
>
=
listOf
(
bleScannedDevice
(
device1
,
timestamp
=
now
,
serviceData
=
null
),
bleScannedDevice
(
device2
,
timestamp
=
now
,
serviceData
=
null
),
bleScannedDevice
(
device3
,
timestamp
=
now
.
minus
(
2
),
serviceData
=
byteArrayOf
(
1
)),
bleScannedDevice
(
device4
,
timestamp
=
now
,
serviceData
=
byteArrayOf
(
1
))
)
// When
val
result
=
filter
.
filter
(
scans
)
// Then
assertThat
(
result
).
containsExactly
(
bleScannedDevice
(
device1
,
timestamp
=
now
,
serviceData
=
null
),
bleScannedDevice
(
device2
,
timestamp
=
now
,
serviceData
=
null
),
bleScannedDevice
(
device4
,
timestamp
=
now
,
serviceData
=
byteArrayOf
(
1
))
)
}
@Test
fun
filter_with_same_devices_scans_should_keep_most_recent_scans_and_order_them_by_timestamp
()
{
// Given
val
device1
=
bluetoothDevice
(
"Device1"
)
val
device2
=
bluetoothDevice
(
"Device2"
)
val
serviceData
=
byteArrayOf
(
1
)
val
now
=
Date
()
val
scans
:
List
<
BleScannedDevice
>
=
listOf
(
bleScannedDevice
(
device
=
device2
,
serviceData
=
null
,
timestamp
=
now
.
minus
(
5
)),
bleScannedDevice
(
device
=
device2
,
serviceData
=
null
,
timestamp
=
now
.
minus
(
4
)),
bleScannedDevice
(
device
=
device1
,
serviceData
=
serviceData
,
timestamp
=
now
.
minus
(
3
)),
bleScannedDevice
(
device
=
device1
,
serviceData
=
serviceData
,
timestamp
=
now
.
minus
(
2
)),
bleScannedDevice
(
device
=
device1
,
serviceData
=
serviceData
,
timestamp
=
now
.
minus
(
1
))
)
// When
val
result
=
filter
.
filter
(
scans
)
// Then
assertThat
(
result
).
containsExactly
(
bleScannedDevice
(
device
=
device1
,
serviceData
=
serviceData
,
timestamp
=
now
.
minus
(
1
)),
bleScannedDevice
(
device
=
device2
,
serviceData
=
null
,
timestamp
=
now
.
minus
(
4
))
)
}
@Test
fun
filter_with_old_scans_should_only_keep_most_recent_ones
()
{
// Given
val
now
=
Date
()
val
scansBefore
:
List
<
BleScannedDevice
>
=
listOf
(
bleScannedDevice
(
bluetoothDevice
(
"Device-skipped-1"
),
timestamp
=
now
.
minus
(
1_001
),
serviceData
=
null
),
bleScannedDevice
(
bluetoothDevice
(
"Device-skipped-2"
),
timestamp
=
now
.
minus
(
1_000
),
serviceData
=
null
)
)
filter
.
filter
(
scansBefore
)
val
device1
=
bluetoothDevice
(
"Device1"
)
val
device2
=
bluetoothDevice
(
"Device2"
)
val
device3
=
bluetoothDevice
(
"Device3"
)
val
scans
:
List
<
BleScannedDevice
>
=
listOf
(
bleScannedDevice
(
device1
,
timestamp
=
now
.
minus
(
1_001
),
serviceData
=
null
),
bleScannedDevice
(
device2
,
timestamp
=
now
.
minus
(
1_000
),
serviceData
=
null
),
bleScannedDevice
(
device3
,
timestamp
=
now
.
minus
(
999
),
serviceData
=
null
)
)
// When
val
result
=
filter
.
filter
(
scans
)
// Then
assertThat
(
result
).
containsExactly
(
bleScannedDevice
(
device3
,
timestamp
=
now
.
minus
(
999
),
serviceData
=
null
)
)
}
private
fun
Date
.
minus
(
millis
:
Long
)
=
Date
(
time
-
millis
)
}
\ No newline at end of file
ble/src/test/java/com/orange/proximitynotification/ble/BleTestHelper.kt
View file @
009bbd4c
...
...
@@ -45,11 +45,13 @@ internal fun payload(
internal
fun
bleScannedDevice
(
device
:
BluetoothDevice
=
bluetoothDevice
(),
rssi
:
Int
=
0
,
serviceData
:
ByteArray
?
=
null
serviceData
:
ByteArray
?
=
null
,
timestamp
:
Date
=
Date
()
)
=
BleScannedDevice
(
device
=
device
,
rssi
=
rssi
,
serviceData
=
serviceData
serviceData
=
serviceData
,
timestamp
=
timestamp
)
internal
fun
bluetoothDevice
(
address
:
String
=
"address"
):
BluetoothDevice
{
...
...
ble/src/test/java/com/orange/proximitynotification/ble/scanner/ScanResultExtKtTest.kt
View file @
009bbd4c
...
...
@@ -58,13 +58,15 @@ class ScanResultExtKtTest {
private
fun
givenScanResult
(
device
:
BluetoothDevice
=
mock
(),
rssi
:
Int
=
0
,
scanRecord
:
ScanRecord
?
=
null
scanRecord
:
ScanRecord
?
=
null
,
timestampNanos
:
Long
=
0L
):
ScanResult
{
val
scanResult
=
mock
<
ScanResult
>()
whenever
(
scanResult
.
device
).
thenReturn
(
device
)
whenever
(
scanResult
.
rssi
).
thenReturn
(
rssi
)
whenever
(
scanResult
.
scanRecord
).
thenReturn
(
scanRecord
)
whenever
(
scanResult
.
timestampNanos
).
thenReturn
(
timestampNanos
)
return
scanResult
}
...
...
build.gradle
View file @
009bbd4c
...
...
@@ -16,11 +16,16 @@ buildscript {
jcenter
()
}
dependencies
{
classpath
"androidx.navigation:navigation-safe-args-gradle-plugin:2.
2.2
"
classpath
'com.android.tools.build:gradle:4.0.
0
'
classpath
"androidx.navigation:navigation-safe-args-gradle-plugin:2.
3.0
"
classpath
'com.android.tools.build:gradle:4.0.
1
'
classpath
"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath
"com.karumi:shot:4.3.0"
classpath
'com.google.protobuf:protobuf-gradle-plugin:0.8.12'
// https://issuetracker.google.com/issues/159151549#comment3
classpath
'org.ow2.asm:asm:8.0.1'
classpath
'org.ow2.asm:asm-util:8.0.1'
classpath
'org.ow2.asm:asm-commons:8.0.1'
}
}
...
...
coreui/build.gradle
View file @
009bbd4c
...
...
@@ -39,15 +39,13 @@ android {
}
kotlinOptions
.
jvmTarget
=
JavaVersion
.
VERSION_1_8
.
toString
()
viewBinding
{
enabled
=
true
}
buildFeatures
.
viewBinding
=
true
}
dependencies
{
// Fix https://stackoverflow.com/questions/41025200/android-view-inflateexception-error-inflating-class-android-webkit-webview/58131421#58131421
api
'androidx.appcompat:appcompat:1.2.0-rc01'
api
'androidx.constraintlayout:constraintlayout:2.0.0-beta
7
'
api
'androidx.constraintlayout:constraintlayout:2.0.0-beta
8
'
api
'androidx.core:core-ktx:1.3.0'
api
'androidx.lifecycle:lifecycle-extensions:2.2.0'
api
'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
...
...
@@ -60,19 +58,19 @@ dependencies {
api
'androidx.emoji:emoji-appcompat:1.1.0'
api
'androidx.emoji:emoji-bundled:1.1.0'
api
'com.google.android.material:material:1.2.0-
beta
01'
api
'com.google.android.material:material:1.2.0-
rc
01'
api
'com.google.code.gson:gson:2.8.6'
api
'com.jakewharton.timber:timber:4.7.1'
api
'com.mikepenz:fastadapter:5.
1.0
'
api
'com.mikepenz:fastadapter-extensions-utils:5.
1.0
'
api
'com.mikepenz:fastadapter:5.
2.2
'
api
'com.mikepenz:fastadapter-extensions-utils:5.
2.2
'
implementation
'com.squareup.okhttp3:logging-interceptor:4.
7.2
'
implementation
"com.squareup.okhttp3:okhttp-tls:4.
7.2
"
implementation
'com.squareup.okhttp3:logging-interceptor:4.
8.0
'
implementation
"com.squareup.okhttp3:okhttp-tls:4.
8.0
"
implementation
"com.squareup.retrofit2:converter-gson:2.9.0"
api
"com.squareup.retrofit2:retrofit:2.9.0"
api
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
api
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.
7
'
api
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.
8
'
}
coreui/src/main/java/com/lunabeestudio/stopcovid/coreui/fragment/FastAdapterFragment.kt
View file @
009bbd4c
...
...
@@ -42,11 +42,6 @@ abstract class FastAdapterFragment : BaseFragment() {
return
binding
?.
root
}
override
fun
onViewCreated
(
view
:
View
,
savedInstanceState
:
Bundle
?)
{
super
.
onViewCreated
(
view
,
savedInstanceState
)
refreshScreen
()
}
override
fun
refreshScreen
()
{
adapter
.
setNewList
(
getItems
())
}
...
...
framework/build.gradle
View file @
009bbd4c
...
...
@@ -57,19 +57,19 @@ android {
dependencies
{
implementation
"androidx.annotation:annotation:1.1.0"
implementation
"com.squareup.okhttp3:logging-interceptor:4.
7.2
"
implementation
"com.squareup.okhttp3:okhttp-tls:4.
7.2
"
implementation
"com.squareup.okhttp3:logging-interceptor:4.
8.0
"
implementation
"com.squareup.okhttp3:okhttp-tls:4.
8.0
"
implementation
"com.squareup.retrofit2:converter-gson:2.9.0"
api
"com.squareup.retrofit2:retrofit:2.9.0"
implementation
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.
7
'
implementation
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.
8
'
implementation
'com.jakewharton.timber:timber:4.7.1'
implementation
'com.google.code.gson:gson:2.8.6'
implementation
'com.google.protobuf:protobuf-javalite:3.12.2'
implementation
'org.bouncycastle:bcprov-jdk15on:1.6
5.01
'
implementation
'org.bouncycastle:bcprov-jdk15on:1.6
6
'
implementation
project
(
path:
':domain'
)
implementation
project
(
path:
':robert'
)
...
...
@@ -78,6 +78,6 @@ dependencies {
androidTestImplementation
"androidx.test:runner:1.2.0"
androidTestImplementation
"androidx.test:rules:1.2.0"
androidTestImplementation
"androidx.test.ext:truth:1.3.0-rc01"
androidTestImplementation
"com.squareup.okhttp3:mockwebserver:4.
7.2
"
androidTestImplementation
"org.apache.commons:commons-text:1.
8
"
androidTestImplementation
"com.squareup.okhttp3:mockwebserver:4.
8.0
"
androidTestImplementation
"org.apache.commons:commons-text:1.
9
"
}
robert/build.gradle
View file @
009bbd4c
...
...
@@ -26,9 +26,9 @@ android {
dependencies
{
implementation
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.
7
'
implementation
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.
8
'
implementation
'androidx.work:work-runtime-ktx:2.
3.4
'
implementation
'androidx.work:work-runtime-ktx:2.
4.0
'
implementation
'com.google.code.gson:gson:2.8.6'
...
...
stopcovid/build.gradle
View file @
009bbd4c
...
...
@@ -42,8 +42,8 @@ android {
applicationId
"fr.gouv.android.stopcovid"
minSdkVersion
21
targetSdkVersion
29
versionCode
4
1
versionName
"1.1.
2
"
versionCode
4
3
versionName
"1.1.
3
"
testInstrumentationRunner
=
'com.lunabeestudio.stopcovid.TestRunner'
...
...
@@ -64,15 +64,15 @@ android {
animationsDisabled
true
}
viewBinding
{
enabled
=
true
}
buildFeatures
.
viewBinding
=
true
}
dependencies
{
implementation
'androidx.documentfile:documentfile:1.0.1'
implementation
'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation
'androidx.work:work-runtime-ktx:2.3.4'
implementation
'androidx.work:work-runtime-ktx:2.4.0'
implementation
'com.airbnb.android:lottie:3.4.1'
implementation
(
'com.journeyapps:zxing-android-embedded:4.1.0'
)
{
transitive
=
false
}
//noinspection NewerVersionAvailable,GradleDependency (New version require minSdk 24)
...
...
stopcovid/src/main/java/com/lunabeestudio/stopcovid/fastitem/LottieItem.kt
0 → 100644
View file @
009bbd4c
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Authors
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Created by Lunabee Studio / Date - 2020/04/05 - for the STOP-COVID project
*/
package
com.lunabeestudio.stopcovid.fastitem
import
android.animation.Animator
import
android.view.View
import
androidx.core.view.isInvisible
import
androidx.core.view.isVisible
import
androidx.recyclerview.widget.RecyclerView
import
com.airbnb.lottie.LottieAnimationView
import
com.airbnb.lottie.LottieCompositionFactory
import
com.airbnb.lottie.LottieDrawable
import
com.lunabeestudio.stopcovid.R
import
com.lunabeestudio.stopcovid.coreui.fastitem.BaseItem
class
LottieItem
:
BaseItem
<
LottieItem
.
ViewHolder
>(
R
.
layout
.
item_lottie
,
::
ViewHolder
,
R
.
id
.
item_lottie
)
{
var
state
:
State
=
State
.
OFF
override
fun
bindView
(
holder
:
ViewHolder
,
payloads
:
List
<
Any
>)
{
super
.
bindView
(
holder
,
payloads
)
holder
.
onView
.
removeAllAnimatorListeners
()
holder
.
offView
.
removeAllAnimatorListeners
()
holder
.
offView
.
setMinFrame
(
1
)
holder
.
offView
.
addLottieOnCompositionLoadedListener
{
holder
.
onView
.
addLottieOnCompositionLoadedListener
{
when
(
state
)
{
State
.
ON
->
onCase
(
holder
)
State
.
OFF
->
offCase
(
holder
)
State
.
OFF_TO_ON
->
offToOnCase
(
holder
)
State
.
ON_TO_OFF
->
onToOffCase
(
holder
)
}
}
}
}
private
fun
onToOffCase
(
holder
:
ViewHolder
)
{
holder
.
onView
.
speed
=
-
5f
holder
.
onView
.
repeatCount
=
0
holder
.
offView
.
progress
=
1f
holder
.
offView
.
repeatCount
=
0
holder
.
offView
.
speed
=
-
1f
holder
.
onView
.
addAnimatorListener
(
object
:
EndAnimatorListener
{
override
fun
onAnimationEnd
(
animation
:
Animator
?)
{
holder
.
onView
.
removeAnimatorListener
(
this
)
holder
.
offView
.
addAnimatorListener
(
object
:
EndAnimatorListener
{
override
fun
onAnimationEnd
(
animation
:
Animator
?)
{
holder
.
offView
.
removeAnimatorListener
(
this
)
state
=
State
.
OFF
offCase
(
holder
)
}
})
holder
.
offView
.
isVisible
=
true
holder
.
onView
.
isInvisible
=
true
holder
.
offView
.
post
{
holder
.
offView
.
playAnimation
()
}
}
})
holder
.
onView
.
isVisible
=
true
holder
.
offView
.
isInvisible
=
true
}
private
fun
offToOnCase
(
holder
:
ViewHolder
)
{
holder
.
offView
.
frame
=
1
holder
.
offView
.
speed
=
1f
holder
.
offView
.
repeatCount
=
0
holder
.
offView
.
addAnimatorListener
(
object
:
EndAnimatorListener
{
override
fun
onAnimationEnd
(
animation
:
Animator
?)
{
holder
.
offView
.
removeAnimatorListener
(
this
)
state
=
State
.
ON
onCase
(
holder
)
}
})
holder
.
offView
.
isVisible
=
true