Tp 37447 Theme change for employment icons and clickstream events for ap upload data action (#7602)
Co-authored-by: Sangaraboina Rishvik Vardhan <rishvik.vardhan@navi.com>
This commit is contained in:
@@ -35,7 +35,6 @@ import com.navi.common.uitron.model.action.GetScreenDefinitionApiAction
|
||||
import com.navi.common.uitron.model.action.LambdaApiAction
|
||||
import com.navi.common.uitron.model.action.PartialFillCallAction
|
||||
import com.navi.common.uitron.model.action.SourceType
|
||||
import com.navi.common.uitron.util.ApActionType
|
||||
import com.navi.common.utils.Constants
|
||||
import com.navi.common.utils.getDeviceData
|
||||
import getInputId
|
||||
@@ -166,6 +165,9 @@ fun getFillApplicationRequestBody(
|
||||
SourceType.CURRENT_TIMESTAMP.name -> {
|
||||
Field(item.name.orEmpty(), Timestamp(System.currentTimeMillis()).toString())
|
||||
}
|
||||
SourceType.ZERO_TIMESTAMP.name -> {
|
||||
Field(item.name.orEmpty(), Timestamp(0).toString())
|
||||
}
|
||||
SourceType.SDK_OUTPUT.name -> {
|
||||
val output: String? = viewModel.handle[item.sourceProperty.orEmpty()]
|
||||
output?.let { Field(item.name.orEmpty(), output) }
|
||||
|
||||
@@ -22,13 +22,13 @@ import com.navi.common.uitron.model.action.UploadDeviceDataType
|
||||
import com.navi.common.uitron.model.action.UploadLocationDataConfig
|
||||
import com.navi.common.useruploaddata.model.IngestionStatusType
|
||||
import com.navi.common.useruploaddata.viewmodel.UserDataViewModel
|
||||
import com.navi.common.utils.CommonNaviAnalytics
|
||||
import com.navi.common.utils.getDeviceDetails
|
||||
import com.navi.common.utils.getScreenRefreshRate
|
||||
import com.navi.uitron.viewmodel.UiTronViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import orTrue
|
||||
import timber.log.Timber
|
||||
|
||||
@Composable
|
||||
@@ -38,6 +38,7 @@ fun HandleUploadDataAction(
|
||||
userDataViewModel: UserDataViewModel = hiltViewModel(),
|
||||
activity: ApplicationPlatformActivity
|
||||
) {
|
||||
val analyticsTracker = remember { CommonNaviAnalytics.naviAnalytics.HandleUploadDataAction() }
|
||||
val action = remember { mutableStateOf(UploadDataAction()) }
|
||||
val needToUploadDataToS3 = remember { mutableStateOf(true) }
|
||||
val uploadedDataToS3 = remember { mutableStateOf(false) }
|
||||
@@ -53,119 +54,119 @@ fun HandleUploadDataAction(
|
||||
viewModel.getActionCallback().collect { uiTronAction ->
|
||||
if (uiTronAction is UploadDataAction) {
|
||||
action.value = uiTronAction
|
||||
if (uiTronAction.shouldUpload.orTrue()) {
|
||||
(uiTronAction.data)?.let { data ->
|
||||
val uploadSmsToS3: Boolean =
|
||||
data.any { it?.uploadType == UploadDeviceDataType.UploadSmsToS3.name }
|
||||
(uiTronAction.data)?.let { data ->
|
||||
val uploadSmsToS3: Boolean =
|
||||
data.any { it?.uploadType == UploadDeviceDataType.UploadSmsToS3.name }
|
||||
|
||||
val uploadContactsToS3: Boolean =
|
||||
data.any {
|
||||
it?.uploadType == UploadDeviceDataType.UploadContactsToS3.name
|
||||
}
|
||||
|
||||
val uploadAppsDataToS3: Boolean =
|
||||
data.any {
|
||||
it?.uploadType == UploadDeviceDataType.UploadAppsDataToS3.name
|
||||
}
|
||||
|
||||
val uploadSmsToFinoramic: Boolean =
|
||||
data.any {
|
||||
it?.uploadType == UploadDeviceDataType.UploadSmsToFinoramic.name
|
||||
}
|
||||
|
||||
val uploadDeviceData: Boolean =
|
||||
data.any {
|
||||
it?.uploadType == UploadDeviceDataType.UploadDeviceData.name
|
||||
}
|
||||
|
||||
val uploadSmsContactsBatchData: Boolean =
|
||||
data.any {
|
||||
it?.uploadType ==
|
||||
UploadDeviceDataType.UploadSmsContactsBatchData.name
|
||||
}
|
||||
|
||||
val businessVertical: String? = data.firstOrNull()?.businessVertical
|
||||
val screenName: String = data.firstOrNull()?.screenName.orEmpty()
|
||||
val numberOfRetriesLeft: Int =
|
||||
data.firstOrNull()?.numberOfRetries.orZero()
|
||||
|
||||
needToUploadDataToS3.value =
|
||||
uploadSmsToS3 || uploadContactsToS3 || uploadAppsDataToS3
|
||||
needToUploadDeviceDataToS3.value = uploadDeviceData
|
||||
needToUploadBatchesDataToS3.value = uploadSmsContactsBatchData
|
||||
|
||||
if (uploadSmsContactsBatchData) {
|
||||
viewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||
val smsTask = async {
|
||||
activity.utilsHandler.commonSmsUtil.readSms(
|
||||
CommonLibManager.application
|
||||
)
|
||||
}
|
||||
val contactsTask = async {
|
||||
CommonContactsUtil.readContacts(CommonLibManager.application)
|
||||
}
|
||||
smsTask.await()
|
||||
contactsTask.await()
|
||||
Timber.d(
|
||||
"SmsTask, ContactsTask and Device Details Task Done (in batches)"
|
||||
)
|
||||
uploadedBatchesData.value = true
|
||||
}
|
||||
val uploadContactsToS3: Boolean =
|
||||
data.any {
|
||||
it?.uploadType == UploadDeviceDataType.UploadContactsToS3.name
|
||||
}
|
||||
|
||||
if (uploadSmsToS3 || uploadContactsToS3 || uploadAppsDataToS3) {
|
||||
userDataViewModel.sendUserDataToAwsWithRetries(
|
||||
uploadSmsToS3,
|
||||
uploadContactsToS3,
|
||||
uploadAppsDataToS3,
|
||||
businessVertical.orEmpty(),
|
||||
numberOfRetriesLeft
|
||||
) { _, userDataUploadCallbackResponse ->
|
||||
if (
|
||||
val uploadAppsDataToS3: Boolean =
|
||||
data.any {
|
||||
it?.uploadType == UploadDeviceDataType.UploadAppsDataToS3.name
|
||||
}
|
||||
|
||||
val uploadSmsToFinoramic: Boolean =
|
||||
data.any {
|
||||
it?.uploadType == UploadDeviceDataType.UploadSmsToFinoramic.name
|
||||
}
|
||||
|
||||
val uploadDeviceData: Boolean =
|
||||
data.any {
|
||||
it?.uploadType == UploadDeviceDataType.UploadDeviceData.name
|
||||
}
|
||||
|
||||
val uploadSmsContactsBatchData: Boolean =
|
||||
data.any {
|
||||
it?.uploadType ==
|
||||
UploadDeviceDataType.UploadSmsContactsBatchData.name
|
||||
}
|
||||
|
||||
val businessVertical: String? = data.firstOrNull()?.businessVertical
|
||||
val screenName: String = data.firstOrNull()?.screenName.orEmpty()
|
||||
val numberOfRetriesLeft: Int = data.firstOrNull()?.numberOfRetries.orZero()
|
||||
|
||||
needToUploadDataToS3.value =
|
||||
uploadSmsToS3 || uploadContactsToS3 || uploadAppsDataToS3
|
||||
needToUploadDeviceDataToS3.value = uploadDeviceData
|
||||
needToUploadBatchesDataToS3.value = uploadSmsContactsBatchData
|
||||
|
||||
if (uploadSmsContactsBatchData) {
|
||||
viewModel.viewModelScope.launch(Dispatchers.IO) {
|
||||
val smsTask = async {
|
||||
activity.utilsHandler.commonSmsUtil.readSms(
|
||||
CommonLibManager.application
|
||||
)
|
||||
}
|
||||
val contactsTask = async {
|
||||
CommonContactsUtil.readContacts(CommonLibManager.application)
|
||||
}
|
||||
smsTask.await()
|
||||
contactsTask.await()
|
||||
Timber.d(
|
||||
"SmsTask, ContactsTask and Device Details Task Done (in batches)"
|
||||
)
|
||||
uploadedBatchesData.value = true
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadSmsToS3 || uploadContactsToS3 || uploadAppsDataToS3) {
|
||||
userDataViewModel.sendUserDataToAwsWithRetries(
|
||||
uploadSmsToS3,
|
||||
uploadContactsToS3,
|
||||
uploadAppsDataToS3,
|
||||
businessVertical.orEmpty(),
|
||||
numberOfRetriesLeft
|
||||
) { _, userDataUploadCallbackResponse ->
|
||||
if (
|
||||
userDataUploadCallbackResponse.ingestionStatusList
|
||||
?.ingestionStatusList
|
||||
?.any { it.status == IngestionStatusType.FAILED }
|
||||
.orFalse()
|
||||
) {
|
||||
analyticsTracker.onUploadToS3Failed(
|
||||
userDataUploadCallbackResponse.ingestionStatusList
|
||||
?.ingestionStatusList
|
||||
?.any { it.status == IngestionStatusType.FAILED }
|
||||
.orFalse()
|
||||
) {
|
||||
viewModel.handleActions(uiTronAction.onFailure)
|
||||
} else {
|
||||
uploadedDataToS3.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uploadSmsToFinoramic) {
|
||||
activity.sdkHandler.finoramicHandler
|
||||
.getFinoramicHelper(activity = activity)
|
||||
?.sendSms(context)
|
||||
}
|
||||
|
||||
if (uploadDeviceData) {
|
||||
val deviceDetails =
|
||||
getDeviceDetails(
|
||||
getScreenRefreshRate(
|
||||
context,
|
||||
(context as? BaseActivity)?.windowManager
|
||||
)
|
||||
.toString()
|
||||
)
|
||||
userDataViewModel.sendDeviceDetails(deviceDetails) {
|
||||
uploadedDeviceData.value = true
|
||||
viewModel.handleActions(uiTronAction.onFailure)
|
||||
} else {
|
||||
uploadedDataToS3.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(data.firstOrNull {
|
||||
if (uploadSmsToFinoramic) {
|
||||
activity.sdkHandler.finoramicHandler
|
||||
.getFinoramicHelper(activity = activity)
|
||||
?.sendSms(context)
|
||||
}
|
||||
|
||||
if (uploadDeviceData) {
|
||||
val deviceDetails =
|
||||
getDeviceDetails(
|
||||
getScreenRefreshRate(
|
||||
context,
|
||||
(context as? BaseActivity)?.windowManager
|
||||
)
|
||||
)
|
||||
userDataViewModel.sendDeviceDetails(deviceDetails) {
|
||||
uploadedDeviceData.value = true
|
||||
}
|
||||
}
|
||||
|
||||
(data.firstOrNull {
|
||||
it?.uploadType == UploadDeviceDataType.UploadLocationData.name
|
||||
} as? UploadLocationDataConfig)
|
||||
?.let {
|
||||
(context as? BaseActivity)?.updateLocation(
|
||||
it.eventName,
|
||||
businessVertical,
|
||||
screenName
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
viewModel.handleActions(uiTronAction.onFailure)
|
||||
?.let {
|
||||
(context as? BaseActivity)?.updateLocation(
|
||||
it.eventName,
|
||||
businessVertical,
|
||||
screenName
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,8 +175,8 @@ fun HandleUploadDataAction(
|
||||
|
||||
if (
|
||||
(uploadedDataToS3.value || !needToUploadDataToS3.value) &&
|
||||
(uploadedDeviceData.value || !needToUploadDeviceDataToS3.value) &&
|
||||
(uploadedBatchesData.value || !needToUploadBatchesDataToS3.value)
|
||||
(uploadedDeviceData.value || !needToUploadDeviceDataToS3.value) &&
|
||||
(uploadedBatchesData.value || !needToUploadBatchesDataToS3.value)
|
||||
) {
|
||||
needToUploadDataToS3.value = true
|
||||
uploadedDataToS3.value = false
|
||||
@@ -186,6 +187,7 @@ fun HandleUploadDataAction(
|
||||
needToUploadBatchesDataToS3.value = true
|
||||
uploadedBatchesData.value = false
|
||||
|
||||
analyticsTracker.onDataUploadSuccess()
|
||||
viewModel.handleActions(action.value.onSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,14 +42,14 @@ class CollapsableItemsWithTitleWidget {
|
||||
fun Render(viewModel: ApplicationPlatformVM, widget: WidgetModelDefinition<UiTronResponse>) {
|
||||
val titleDescriptionListWidgetData =
|
||||
widget.widgetData?.data?.get("widget_data_${widget.widgetId}")
|
||||
as? CollapsableItemsWithTitleWidgetData
|
||||
as? CollapsableItemsWithTitleWidgetData
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(
|
||||
titleDescriptionListWidgetData?.backgroundColor?.hexToComposeColor
|
||||
?: Color.White
|
||||
)
|
||||
.padding(20.dp, 24.dp)
|
||||
modifier =
|
||||
Modifier.background(
|
||||
titleDescriptionListWidgetData?.backgroundColor?.hexToComposeColor
|
||||
?: Color.White
|
||||
)
|
||||
.padding(20.dp, 24.dp)
|
||||
) {
|
||||
widget.widgetData?.parentComposeView?.let {
|
||||
UiTronRenderer(widget.widgetData.data, viewModel).Render(composeViews = it)
|
||||
@@ -59,48 +59,52 @@ class CollapsableItemsWithTitleWidget {
|
||||
val rotation = remember { mutableStateOf(0f) }
|
||||
Column(modifier = Modifier.padding(top = 24.dp)) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
modifier =
|
||||
Modifier.fillMaxWidth().clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
expand.value = expand.value.not()
|
||||
rotation.value = rotation.value + 180
|
||||
},
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
TextRenderer().Render(
|
||||
property = titleDescriptionListWidgetData.itemTitleProperty
|
||||
?: TextProperty(),
|
||||
uiTronData = titleDescriptionListWidgetData.itemTitleData?.apply {
|
||||
text = it.title
|
||||
} ?: TextData(text = it.title),
|
||||
uiTronViewModel = viewModel,
|
||||
modifier = null
|
||||
)
|
||||
TextRenderer()
|
||||
.Render(
|
||||
property = titleDescriptionListWidgetData.itemTitleProperty
|
||||
?: TextProperty(),
|
||||
uiTronData =
|
||||
titleDescriptionListWidgetData.itemTitleData?.apply {
|
||||
text = it.title
|
||||
}
|
||||
?: TextData(text = it.title),
|
||||
uiTronViewModel = viewModel,
|
||||
modifier = null
|
||||
)
|
||||
AsyncImage(
|
||||
contentDescription = "",
|
||||
model =
|
||||
ImageRequest.Builder(LocalContext.current)
|
||||
.data(titleDescriptionListWidgetData.dropDownIconUrl)
|
||||
.size(Size.ORIGINAL)
|
||||
.allowHardware(false)
|
||||
.build(),
|
||||
modifier =
|
||||
Modifier
|
||||
.rotate(rotation.value)
|
||||
.clickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() }
|
||||
) {
|
||||
expand.value = expand.value.not()
|
||||
rotation.value = rotation.value + 180
|
||||
}
|
||||
ImageRequest.Builder(LocalContext.current)
|
||||
.data(titleDescriptionListWidgetData.dropDownIconUrl)
|
||||
.size(Size.ORIGINAL)
|
||||
.allowHardware(false)
|
||||
.build(),
|
||||
modifier = Modifier.rotate(rotation.value)
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(visible = expand.value) {
|
||||
TextRenderer().Render(
|
||||
property = titleDescriptionListWidgetData.itemDescriptionProperty
|
||||
?: TextProperty(),
|
||||
uiTronData = titleDescriptionListWidgetData.itemTitleData?.apply {
|
||||
text = it.description
|
||||
} ?: TextData(text = it.description),
|
||||
uiTronViewModel = viewModel,
|
||||
modifier = null
|
||||
)
|
||||
TextRenderer()
|
||||
.Render(
|
||||
property = titleDescriptionListWidgetData.itemDescriptionProperty
|
||||
?: TextProperty(),
|
||||
uiTronData =
|
||||
titleDescriptionListWidgetData.itemTitleData?.apply {
|
||||
text = it.description
|
||||
}
|
||||
?: TextData(text = it.description),
|
||||
uiTronViewModel = viewModel,
|
||||
modifier = null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
"size": 100
|
||||
},
|
||||
"colors": {
|
||||
"backgroundColor": "#FF5732"
|
||||
"backgroundColor": "#1F002A"
|
||||
}
|
||||
},
|
||||
"childrenViews": [
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.navi.common.useruploaddata.model.UserContact
|
||||
import com.navi.common.useruploaddata.model.UserPhone
|
||||
import com.navi.common.useruploaddata.repository.UserDataRepository
|
||||
import com.navi.common.useruploaddata.utils.PermissionUtil.hasPermissions
|
||||
import com.navi.common.utils.CommonNaviAnalytics
|
||||
import com.navi.common.utils.Constants
|
||||
import com.navi.common.utils.Constants.QUESTION_MARK
|
||||
import com.navi.common.utils.Constants.UNDERSCORE
|
||||
@@ -36,6 +37,8 @@ import retrofit2.Response
|
||||
|
||||
object CommonContactsUtil {
|
||||
|
||||
private val analyticsTracker = CommonNaviAnalytics.naviAnalytics.CommonContactsUtil()
|
||||
|
||||
suspend fun readContacts(applicationContext: Context) {
|
||||
try {
|
||||
val cursor = executeQueryToReadContacts(applicationContext)
|
||||
@@ -44,14 +47,18 @@ object CommonContactsUtil {
|
||||
if (!moveToFirst()) return
|
||||
var pageNumber = 1
|
||||
val contacts = mutableListOf<UserContact>()
|
||||
analyticsTracker.contactReadStartTime(pageNumber)
|
||||
do {
|
||||
readContact(contacts)
|
||||
if (contacts.size == Constants.USER_DATA_PAYLOAD_SIZE) {
|
||||
analyticsTracker.contactReadEndTime(pageNumber)
|
||||
postContactsAndClearList(contacts, getTotalPages(), pageNumber)
|
||||
pageNumber += 1
|
||||
analyticsTracker.contactReadStartTime(pageNumber)
|
||||
}
|
||||
} while (moveToNext())
|
||||
if (contacts.size > 0) {
|
||||
analyticsTracker.contactReadEndTime(pageNumber)
|
||||
postContactsAndClearList(contacts, getTotalPages(), pageNumber)
|
||||
}
|
||||
}
|
||||
@@ -86,10 +93,22 @@ object CommonContactsUtil {
|
||||
totalPages: Int,
|
||||
pageNumber: Int
|
||||
) {
|
||||
analyticsTracker.contactUploadStartTime(pageNumber)
|
||||
val request = UserDataWrapper(totalPages, pageNumber, contacts)
|
||||
analyticsTracker.onContactUploadStart(totalPages, pageNumber, contacts.size)
|
||||
val response = UserDataRepository().postContacts(request)
|
||||
response.error?.let { Exception("Contact Upload Issue" + UNDERSCORE + it.statusCode).log() }
|
||||
analyticsTracker.contactUploadEndTime(pageNumber)
|
||||
response.error?.let {
|
||||
Exception("Contact Upload Issue" + UNDERSCORE + it.statusCode).log()
|
||||
analyticsTracker.onContactUploadFailure(
|
||||
totalPages,
|
||||
pageNumber,
|
||||
contacts.size,
|
||||
it.statusCode
|
||||
)
|
||||
}
|
||||
contacts.clear()
|
||||
analyticsTracker.onContactUploadSuccess(totalPages, pageNumber, contacts.size)
|
||||
}
|
||||
|
||||
suspend fun readZipAndUploadContacts(
|
||||
@@ -102,14 +121,22 @@ object CommonContactsUtil {
|
||||
val contactList = mutableListOf<UserContact>()
|
||||
var pageNumber = 1
|
||||
cursor?.apply {
|
||||
analyticsTracker.contactReadStartTime(pageNumber)
|
||||
if (!moveToFirst()) return null
|
||||
do readContact(contactList) while (moveToNext())
|
||||
close()
|
||||
if (contactList.size > 0) {
|
||||
analyticsTracker.contactReadEndTime(pageNumber)
|
||||
} else if (contactList.isEmpty()) {
|
||||
analyticsTracker.onFoundEmptyContactsList()
|
||||
}
|
||||
}
|
||||
val contactData = ContactData(contactList)
|
||||
analyticsTracker.onZippingSuccess(Constants.CONTACTS)
|
||||
postZippedContacts(contactData, url, referenceId, pageNumber = pageNumber)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
analyticsTracker.onZippingFailure(Constants.CONTACTS)
|
||||
IngestionStatus(
|
||||
referenceId = referenceId,
|
||||
ingestionType = IngestionType.CONTACTS,
|
||||
@@ -124,16 +151,23 @@ object CommonContactsUtil {
|
||||
referenceId: String,
|
||||
pageNumber: Int
|
||||
): IngestionStatus {
|
||||
analyticsTracker.contactUploadStartTime(pageNumber)
|
||||
val gson = Gson().toJson(contactData)
|
||||
analyticsTracker.onZippingUploadInitiated(Constants.CONTACTS)
|
||||
val response = postZippedData(gson, url)
|
||||
analyticsTracker.contactUploadEndTime(pageNumber)
|
||||
val ingestionStatus =
|
||||
IngestionStatus(
|
||||
referenceId = referenceId,
|
||||
ingestionType = IngestionType.CONTACTS,
|
||||
)
|
||||
if (response.isSuccessful) {
|
||||
analyticsTracker.onContactUploadSuccess()
|
||||
analyticsTracker.onZippingUploadSuccess(Constants.CONTACTS)
|
||||
ingestionStatus.status = IngestionStatusType.SUCCESS
|
||||
} else {
|
||||
analyticsTracker.onContactUploadFailureEvent()
|
||||
analyticsTracker.onZippingUploadFailure(Constants.CONTACTS)
|
||||
ingestionStatus.status = IngestionStatusType.FAILED
|
||||
}
|
||||
return ingestionStatus
|
||||
|
||||
@@ -17,12 +17,15 @@ import com.navi.common.useruploaddata.repository.UserDataRepository
|
||||
import com.navi.common.useruploaddata.utils.PermissionUtil.hasPermissions
|
||||
import com.navi.common.useruploaddata.utils.getSmsDataProjection
|
||||
import com.navi.common.useruploaddata.utils.getUserSmsFromCursorData
|
||||
import com.navi.common.utils.CommonNaviAnalytics
|
||||
import com.navi.common.utils.Constants
|
||||
import com.navi.common.utils.getTotalPages
|
||||
import com.navi.common.utils.log
|
||||
|
||||
class CommonSmsUtil {
|
||||
|
||||
private val analyticsTracker = CommonNaviAnalytics.naviAnalytics.CommonSmsUtil()
|
||||
|
||||
suspend fun readSms(applicationContext: Context) {
|
||||
try {
|
||||
val cursor = executeQueryToReadSms(applicationContext)
|
||||
@@ -30,14 +33,18 @@ class CommonSmsUtil {
|
||||
if (!moveToFirst()) return
|
||||
var pageNumber = 1
|
||||
val smsList = mutableListOf<UserSms>()
|
||||
analyticsTracker.smsReadStartTime(pageNumber)
|
||||
do {
|
||||
readSmsWithCursor(cursor = this, smsList = smsList)
|
||||
if (smsList.size == Constants.USER_DATA_PAYLOAD_SIZE) {
|
||||
analyticsTracker.smsReadEndTime(pageNumber)
|
||||
postSmsAndClearList(smsList, getTotalPages(), pageNumber)
|
||||
pageNumber += 1
|
||||
analyticsTracker.smsReadStartTime(pageNumber)
|
||||
}
|
||||
} while (moveToNext())
|
||||
if (smsList.size > 0) {
|
||||
analyticsTracker.smsReadEndTime(pageNumber)
|
||||
postSmsAndClearList(smsList, getTotalPages(), pageNumber)
|
||||
}
|
||||
}
|
||||
@@ -72,15 +79,32 @@ class CommonSmsUtil {
|
||||
pageNumber: Int,
|
||||
retryCount: Int = 0
|
||||
) {
|
||||
analyticsTracker.smsUploadStartTime(pageNumber)
|
||||
val request = UserDataWrapper(totalPages, pageNumber, smsList)
|
||||
analyticsTracker.onSmsUploadStart(totalPages, pageNumber, smsList.size, retryCount)
|
||||
val response = UserDataRepository().postSms(request)
|
||||
analyticsTracker.smsUploadEndTime(pageNumber, retryCount)
|
||||
response.error?.let {
|
||||
Exception("Installed App Upload Issue" + Constants.UNDERSCORE + it.statusCode).log()
|
||||
analyticsTracker.onSmsUploadFailure(
|
||||
totalPages,
|
||||
pageNumber,
|
||||
smsList.size,
|
||||
it.statusCode,
|
||||
)
|
||||
if (retryCount < 1) {
|
||||
postSmsAndClearList(smsList, totalPages, pageNumber, retryCount = retryCount + 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
?: run { smsList.clear() }
|
||||
?: run {
|
||||
smsList.clear()
|
||||
analyticsTracker.onSmsUploadSuccess(
|
||||
totalPages,
|
||||
pageNumber,
|
||||
smsList.size,
|
||||
retryCount
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,5 +54,6 @@ enum class SourceType {
|
||||
DEVICE_PROPERTY,
|
||||
SDK_OUTPUT,
|
||||
PRE_DEFINED,
|
||||
CURRENT_TIMESTAMP
|
||||
CURRENT_TIMESTAMP,
|
||||
ZERO_TIMESTAMP
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@ import kotlinx.parcelize.Parcelize
|
||||
open class UploadDataAction(
|
||||
@SerializedName("data") val data: List<UploadDataConfig?>? = null,
|
||||
@SerializedName("onSuccess") val onSuccess: UiTronActionData? = null,
|
||||
@SerializedName("onFailure") val onFailure: UiTronActionData? = null,
|
||||
@SerializedName("shouldUpload") val shouldUpload: Boolean? = null
|
||||
@SerializedName("onFailure") val onFailure: UiTronActionData? = null
|
||||
) : UiTronAction(), Parcelable {
|
||||
override suspend fun manageAction(actionDetails: ActionDetails) {
|
||||
val action = actionDetails.uiTronAction as UploadDataAction
|
||||
|
||||
@@ -17,6 +17,8 @@ import android.provider.Telephony
|
||||
import android.util.Base64
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.gson.Gson
|
||||
import com.navi.base.utils.isNotNull
|
||||
import com.navi.base.utils.orZero
|
||||
import com.navi.common.CommonLibManager.application
|
||||
import com.navi.common.managers.PermissionsManager
|
||||
import com.navi.common.model.UploadDataAsyncResponse
|
||||
@@ -26,8 +28,11 @@ import com.navi.common.network.ApiConstants
|
||||
import com.navi.common.useruploaddata.model.*
|
||||
import com.navi.common.useruploaddata.repository.UserDataRepository
|
||||
import com.navi.common.utils.COMMA
|
||||
import com.navi.common.utils.CommonNaviAnalytics
|
||||
import com.navi.common.utils.Constants
|
||||
import com.navi.common.utils.Constants.QUESTION_MARK
|
||||
import com.navi.common.utils.gzipCompress
|
||||
import com.navi.common.utils.isValidResponse
|
||||
import com.navi.common.utils.log
|
||||
import kotlinx.coroutines.*
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
@@ -36,14 +41,20 @@ import retrofit2.Response
|
||||
|
||||
object PermissionUtil {
|
||||
|
||||
private val analyticsTracker = CommonNaviAnalytics.naviAnalytics.PermissionUtil()
|
||||
|
||||
fun hasPermissions(
|
||||
context: Context,
|
||||
permissions: Array<String> = PermissionsManager.requiredPermissions
|
||||
): Boolean =
|
||||
permissions.all { permission ->
|
||||
ContextCompat.checkSelfPermission(context, permission) ==
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
): Boolean {
|
||||
val hasPermission =
|
||||
permissions.all { permission ->
|
||||
ContextCompat.checkSelfPermission(context, permission) ==
|
||||
PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
analyticsTracker.hasPermissions(hasPermission)
|
||||
return hasPermission
|
||||
}
|
||||
|
||||
suspend fun uploadAppData(
|
||||
scope: CoroutineScope,
|
||||
@@ -98,7 +109,11 @@ object PermissionUtil {
|
||||
needTohandleIngestionPolling: Boolean
|
||||
) {
|
||||
val startTimeInMillis = System.currentTimeMillis()
|
||||
analyticsTracker.postGettingPreSignedUrlInitiated()
|
||||
var response = UserDataRepository().getPreSignedUrlList(ingestionType, businessVertical)
|
||||
if (response.error != null || response.errors != null) {
|
||||
analyticsTracker.postErrorInGettingPreSignedUrl(response.error ?: response.errors)
|
||||
}
|
||||
var retryCount = 1 // retry the getPreSignedUrlList api max 3 times
|
||||
while ((response.error != null || !response.errors.isNullOrEmpty()) && retryCount <= 4) {
|
||||
if (retryCount == 4) {
|
||||
@@ -108,17 +123,30 @@ object PermissionUtil {
|
||||
return
|
||||
}
|
||||
retryCount++
|
||||
analyticsTracker.postGettingPreSignedUrlInitiated(retryCount - 1)
|
||||
response = UserDataRepository().getPreSignedUrlList(ingestionType, businessVertical)
|
||||
}
|
||||
if (response.isValidResponse()) {
|
||||
analyticsTracker.postGettingPreSignedUrlSuccess(retryCount)
|
||||
}
|
||||
var ingestionList: List<IngestionStatus?>? = null
|
||||
try {
|
||||
val taskLists = extractTasks(response.data, scope)
|
||||
ingestionList = (taskLists.awaitAll().filterNotNull())
|
||||
var uploadedResponseData: UploadDataAsyncResponse? = null
|
||||
if (ingestionList.isNotEmpty()) {
|
||||
analyticsTracker.onDataUploadAcknowledgementInitiated(ingestionList.toString())
|
||||
val uploadedResponse =
|
||||
UserDataRepository().postIngestionStatus(IngestionStatusBody(ingestionList))
|
||||
uploadedResponseData = uploadedResponse.data
|
||||
if (uploadedResponse.error != null || uploadedResponse.errors != null) {
|
||||
analyticsTracker.onErrorUploadingSms(
|
||||
error = uploadedResponse.error ?: uploadedResponse.errors
|
||||
)
|
||||
analyticsTracker.onDataUploadAcknowledgementFailure(ingestionList.toString())
|
||||
} else {
|
||||
analyticsTracker.onDataUploadAcknowledgementSuccess(ingestionList.toString())
|
||||
}
|
||||
}
|
||||
val endTimeInMillis = System.currentTimeMillis()
|
||||
val timeTakenToUploadAppData = (endTimeInMillis - startTimeInMillis)
|
||||
@@ -136,10 +164,21 @@ object PermissionUtil {
|
||||
// callback invocation means ,we are done with uploading
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
analyticsTracker.onExceptionWhileUploadingData()
|
||||
ingestionList?.filterNotNull()?.let {
|
||||
if (it.isNotEmpty()) {
|
||||
analyticsTracker.onDataUploadAcknowledgementInitiated(ingestionList.toString())
|
||||
val uploadedResponse =
|
||||
UserDataRepository().postIngestionStatus(IngestionStatusBody(it))
|
||||
if (uploadedResponse.error.isNotNull() || uploadedResponse.errors.isNotNull()) {
|
||||
analyticsTracker.onDataUploadAcknowledgementFailure(
|
||||
ingestionList.toString()
|
||||
)
|
||||
} else {
|
||||
analyticsTracker.onDataUploadAcknowledgementSuccess(
|
||||
ingestionList.toString()
|
||||
)
|
||||
}
|
||||
val userDataUploadCallbackResponse =
|
||||
UserDataUploadCallbackResponse(
|
||||
IngestionStatusBody(it),
|
||||
@@ -152,8 +191,11 @@ object PermissionUtil {
|
||||
UploadDataPollingUtil()
|
||||
.handleUploadDataResponse(userDataUploadCallbackResponse)
|
||||
}
|
||||
} else {
|
||||
analyticsTracker.onIngestionTaskListEmpty(true)
|
||||
}
|
||||
}
|
||||
?: run { analyticsTracker.onIngestionTaskListNull() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,6 +205,12 @@ object PermissionUtil {
|
||||
): MutableList<Deferred<IngestionStatus?>> {
|
||||
val taskLists = mutableListOf<Deferred<IngestionStatus?>>()
|
||||
preSignedUrlResponse?.preSignedUrlList?.forEach { preSignedModel ->
|
||||
analyticsTracker.postPreSignedIngestionStatus(
|
||||
preSignedModel.preSignedUrl,
|
||||
preSignedModel.referenceId,
|
||||
preSignedModel.ingestionType,
|
||||
preSignedModel.upload,
|
||||
)
|
||||
if (
|
||||
preSignedModel.upload == true &&
|
||||
preSignedModel.referenceId != null &&
|
||||
@@ -177,6 +225,10 @@ object PermissionUtil {
|
||||
?.let { taskLists.add(it) }
|
||||
}
|
||||
}
|
||||
analyticsTracker.numberOfUrlsReceivedAndNumberOfDataUploaded(
|
||||
preSignedUrlResponse?.preSignedUrlList?.size.orZero(),
|
||||
taskLists.size
|
||||
)
|
||||
return taskLists
|
||||
}
|
||||
|
||||
@@ -222,10 +274,15 @@ object PermissionUtil {
|
||||
if (!moveToFirst()) return null
|
||||
do readSms(smsList) while (moveToNext())
|
||||
close()
|
||||
if (smsList.isEmpty()) {
|
||||
analyticsTracker.onFoundEmptySmsList()
|
||||
}
|
||||
}
|
||||
analyticsTracker.onZippingSuccess(Constants.SMS)
|
||||
postZippedMessages(smsList, url, referenceId)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
analyticsTracker.onZippingFailure(Constants.SMS)
|
||||
IngestionStatus(
|
||||
referenceId = referenceId,
|
||||
ingestionType = IngestionType.SMS,
|
||||
@@ -248,9 +305,11 @@ object PermissionUtil {
|
||||
AppDetails(it.applicationInfo.name, it.firstInstallTime, it.lastUpdateTime)
|
||||
)
|
||||
}
|
||||
analyticsTracker.onZippingSuccess(IngestionType.APPS.name)
|
||||
postZippedApps(installedApps.toMutableList(), url, referenceId)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
analyticsTracker.onZippingFailure(IngestionType.APPS.name)
|
||||
IngestionStatus(
|
||||
referenceId = referenceId,
|
||||
ingestionType = IngestionType.APPS,
|
||||
@@ -272,11 +331,13 @@ object PermissionUtil {
|
||||
if (!moveToFirst()) return null
|
||||
do readContact(contactList) while (moveToNext())
|
||||
close()
|
||||
analyticsTracker.onZippingSuccess(IngestionType.CONTACTS.name)
|
||||
}
|
||||
val contactData = ContactData(contactList)
|
||||
postZippedContacts(contactData, url, referenceId, pageNumber = pageNumber)
|
||||
} catch (e: Exception) {
|
||||
e.log()
|
||||
analyticsTracker.onZippingFailure(IngestionType.CONTACTS.name)
|
||||
IngestionStatus(
|
||||
referenceId = referenceId,
|
||||
ingestionType = IngestionType.CONTACTS,
|
||||
@@ -352,6 +413,7 @@ object PermissionUtil {
|
||||
referenceId: String
|
||||
): IngestionStatus {
|
||||
val gson = Gson().toJson(UserSmsData(smsList.sortedBy { it.timeStamp }))
|
||||
analyticsTracker.onZippingUploadInitiated(Constants.SMS)
|
||||
val response = postZippedData(gson, url)
|
||||
|
||||
val ingestionStatus =
|
||||
@@ -363,8 +425,10 @@ object PermissionUtil {
|
||||
)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
analyticsTracker.onZippingUploadSuccess(Constants.SMS)
|
||||
ingestionStatus.status = IngestionStatusType.SUCCESS
|
||||
} else {
|
||||
analyticsTracker.onZippingUploadFailure(Constants.SMS)
|
||||
ingestionStatus.status = IngestionStatusType.FAILED
|
||||
}
|
||||
|
||||
@@ -379,6 +443,7 @@ object PermissionUtil {
|
||||
pageNumber: Int
|
||||
): IngestionStatus {
|
||||
val gson = Gson().toJson(contactData)
|
||||
analyticsTracker.onZippingUploadInitiated(IngestionType.CONTACTS.name)
|
||||
val response = postZippedData(gson, url)
|
||||
val ingestionStatus =
|
||||
IngestionStatus(
|
||||
@@ -386,8 +451,10 @@ object PermissionUtil {
|
||||
ingestionType = IngestionType.CONTACTS,
|
||||
)
|
||||
if (response.isSuccessful) {
|
||||
analyticsTracker.onZippingUploadSuccess(IngestionType.CONTACTS.name)
|
||||
ingestionStatus.status = IngestionStatusType.SUCCESS
|
||||
} else {
|
||||
analyticsTracker.onZippingUploadFailure(IngestionType.CONTACTS.name)
|
||||
ingestionStatus.status = IngestionStatusType.FAILED
|
||||
}
|
||||
return ingestionStatus
|
||||
@@ -420,6 +487,7 @@ object PermissionUtil {
|
||||
referenceId: String
|
||||
): IngestionStatus {
|
||||
val gson = Gson().toJson(UserAppData(appList))
|
||||
analyticsTracker.onZippingUploadInitiated(IngestionType.APPS.name)
|
||||
val response = postZippedData(gson, url)
|
||||
|
||||
val ingestionStatus =
|
||||
@@ -429,8 +497,10 @@ object PermissionUtil {
|
||||
)
|
||||
|
||||
if (response.isSuccessful) {
|
||||
analyticsTracker.onZippingUploadSuccess(IngestionType.APPS.name)
|
||||
ingestionStatus.status = IngestionStatusType.SUCCESS
|
||||
} else {
|
||||
analyticsTracker.onZippingUploadFailure(IngestionType.APPS.name)
|
||||
ingestionStatus.status = IngestionStatusType.FAILED
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ package com.navi.common.utils
|
||||
import androidx.annotation.Keep
|
||||
import com.navi.analytics.alfred.AlfredManager
|
||||
import com.navi.analytics.utils.NaviTrackEvent
|
||||
import com.navi.base.utils.orFalse
|
||||
import com.navi.base.model.ActionData
|
||||
import com.navi.base.model.GenericAnalyticsData
|
||||
import com.navi.base.sharedpref.CommonPrefConstants
|
||||
@@ -744,41 +743,43 @@ class CommonNaviAnalytics private constructor() {
|
||||
)
|
||||
}
|
||||
|
||||
inner class AuthenticatorEvents{
|
||||
inner class AuthenticatorEvents {
|
||||
|
||||
fun createNewSessionNeeded(apiUrl: String, isNeeded : Boolean) {
|
||||
fun createNewSessionNeeded(apiUrl: String, isNeeded: Boolean) {
|
||||
val map = mapOf(Pair("isNeeded", isNeeded.toString()), Pair("apiUrl", apiUrl))
|
||||
NaviTrackEvent.trackEvent("dev_is_new_session_needed", map)
|
||||
}
|
||||
|
||||
fun authenticateCalledForApi(apiUrl : String) {
|
||||
fun authenticateCalledForApi(apiUrl: String) {
|
||||
val map = mapOf(Pair("apiUrl", apiUrl))
|
||||
NaviTrackEvent.trackEvent("authentication_needed", map)
|
||||
}
|
||||
|
||||
fun reTriggerUnAuthApi(apiUrl: String, isSessionDataPresent: Boolean) {
|
||||
val map = mapOf(
|
||||
Pair("apiUrl", apiUrl),
|
||||
Pair("isSessionDataPresent", isSessionDataPresent.toString())
|
||||
)
|
||||
val map =
|
||||
mapOf(
|
||||
Pair("apiUrl", apiUrl),
|
||||
Pair("isSessionDataPresent", isSessionDataPresent.toString())
|
||||
)
|
||||
NaviTrackEvent.trackEvent("dev_retrigger_unauth_api", map)
|
||||
}
|
||||
|
||||
fun refreshTokenCancelled(apiUrl : String) {
|
||||
fun refreshTokenCancelled(apiUrl: String) {
|
||||
val map = mapOf(Pair("apiUrl", apiUrl))
|
||||
NaviTrackEvent.trackEvent("refresh_token_cancelled", map)
|
||||
}
|
||||
|
||||
fun onGetExistingSessionToken(apiUrl: String, isLoggedIn : Boolean) {
|
||||
fun onGetExistingSessionToken(apiUrl: String, isLoggedIn: Boolean) {
|
||||
val map = mapOf(Pair("isLoggedIn", isLoggedIn.toString()), Pair("apiUrl", apiUrl))
|
||||
NaviTrackEvent.trackEvent("dev_get_existing_session_token", map)
|
||||
}
|
||||
|
||||
fun refreshTokenApiCalled(
|
||||
unAuthApiUrl : String,
|
||||
unAuthApiUrl: String,
|
||||
isError: Boolean,
|
||||
error: GenericErrorResponse?,
|
||||
errorMessage: ErrorMessage?,
|
||||
isRefreshTokenExpired : Boolean
|
||||
isRefreshTokenExpired: Boolean
|
||||
) {
|
||||
val map =
|
||||
mapOf(
|
||||
@@ -794,10 +795,7 @@ class CommonNaviAnalytics private constructor() {
|
||||
NaviTrackEvent.trackEvent("refresh_token", map)
|
||||
}
|
||||
|
||||
fun refreshTokenApiError(
|
||||
error: GenericErrorResponse?,
|
||||
errorMessage: ErrorMessage?
|
||||
) {
|
||||
fun refreshTokenApiError(error: GenericErrorResponse?, errorMessage: ErrorMessage?) {
|
||||
val map =
|
||||
mapOf(
|
||||
Pair("error_data", error.toString()),
|
||||
@@ -809,10 +807,7 @@ class CommonNaviAnalytics private constructor() {
|
||||
NaviTrackEvent.trackEvent("refresh_token_error", map)
|
||||
}
|
||||
|
||||
fun refreshTokenExpired(
|
||||
error: GenericErrorResponse?,
|
||||
errorMessage: ErrorMessage?
|
||||
) {
|
||||
fun refreshTokenExpired(error: GenericErrorResponse?, errorMessage: ErrorMessage?) {
|
||||
val map =
|
||||
mapOf(
|
||||
Pair("error_data", error.toString()),
|
||||
@@ -824,24 +819,29 @@ class CommonNaviAnalytics private constructor() {
|
||||
NaviTrackEvent.trackEvent("refresh_token_expired", map)
|
||||
}
|
||||
|
||||
fun logout(error: GenericErrorResponse?, isRefreshTokenExpired : Boolean) {
|
||||
val map = mapOf(
|
||||
Pair("isRefreshTokenExpired", isRefreshTokenExpired.toString()),
|
||||
Pair("reason", "refresh token failed"),
|
||||
Pair("statusCode", error?.statusCode.toString())
|
||||
)
|
||||
fun logout(error: GenericErrorResponse?, isRefreshTokenExpired: Boolean) {
|
||||
val map =
|
||||
mapOf(
|
||||
Pair("isRefreshTokenExpired", isRefreshTokenExpired.toString()),
|
||||
Pair("reason", "refresh token failed"),
|
||||
Pair("statusCode", error?.statusCode.toString())
|
||||
)
|
||||
NaviTrackEvent.trackEvent("logout", map)
|
||||
}
|
||||
|
||||
fun createNewSessionResponse(isSessionTokenCreated: Boolean,
|
||||
isRefreshTokenCreated: Boolean,
|
||||
error: GenericErrorResponse?,
|
||||
errorMessage: ErrorMessage?) {
|
||||
val map = mapOf(Pair("isSessionTokenCreated", isSessionTokenCreated.toString()),
|
||||
Pair("isRefreshTokenCreated", isRefreshTokenCreated.toString()),
|
||||
Pair("error", error.toString()),
|
||||
Pair("errorMessage", errorMessage.toString())
|
||||
)
|
||||
fun createNewSessionResponse(
|
||||
isSessionTokenCreated: Boolean,
|
||||
isRefreshTokenCreated: Boolean,
|
||||
error: GenericErrorResponse?,
|
||||
errorMessage: ErrorMessage?
|
||||
) {
|
||||
val map =
|
||||
mapOf(
|
||||
Pair("isSessionTokenCreated", isSessionTokenCreated.toString()),
|
||||
Pair("isRefreshTokenCreated", isRefreshTokenCreated.toString()),
|
||||
Pair("error", error.toString()),
|
||||
Pair("errorMessage", errorMessage.toString())
|
||||
)
|
||||
NaviTrackEvent.trackEvent("dev_create_new_session_response", map)
|
||||
}
|
||||
}
|
||||
@@ -948,6 +948,404 @@ class CommonNaviAnalytics private constructor() {
|
||||
}
|
||||
}
|
||||
|
||||
inner class HandleUploadDataAction {
|
||||
|
||||
fun onUploadToS3Failed(ingestionStatusList: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
eventName = "dev_ap_on_upload_to_s3_failed",
|
||||
eventValues = mapOf(Pair("ingestionStatusList", ingestionStatusList))
|
||||
)
|
||||
}
|
||||
|
||||
fun onDataUploadSuccess() {
|
||||
NaviTrackEvent.trackEventOnClickStream(eventName = "dev_ap_on_data_upload_Success")
|
||||
}
|
||||
}
|
||||
|
||||
inner class CommonContactsUtil {
|
||||
fun onFoundEmptyContactsList() {
|
||||
NaviTrackEvent.trackEventOnClickStream("PL_DEV_CONTACT_LIST_IS_EMPTY")
|
||||
}
|
||||
|
||||
fun onContactUploadStart(totalPages: Int, pageNumber: Int, size: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"contact_upload_started",
|
||||
mapOf(
|
||||
Pair("totalPages", totalPages.toString()),
|
||||
Pair("pageNumber", pageNumber.toString()),
|
||||
Pair("size", size.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onContactUploadSuccess(totalPages: Int, pageNumber: Int, size: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"contact_upload_success",
|
||||
mapOf(
|
||||
Pair("totalPages", totalPages.toString()),
|
||||
Pair("pageNumber", pageNumber.toString()),
|
||||
Pair("size", size.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onContactUploadSuccess() {
|
||||
NaviTrackEvent.trackEventOnClickStream("pl_dev_contact_upload_success")
|
||||
}
|
||||
|
||||
fun onContactUploadFailureEvent() {
|
||||
NaviTrackEvent.trackEventOnClickStream("pl_dev_contact_upload_failure")
|
||||
}
|
||||
|
||||
fun onContactUploadFailure(totalPages: Int, pageNumber: Int, size: Int, statusCode: Int?) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"contact_upload_failure",
|
||||
mapOf(
|
||||
Pair("totalPages", totalPages.toString()),
|
||||
Pair("pageNumber", pageNumber.toString()),
|
||||
Pair("size", size.toString()),
|
||||
Pair("statusCode", statusCode.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun contactUploadStartTime(pageNumber: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"contact_number_upload_start_time",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("pageNumber", pageNumber.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun contactUploadEndTime(pageNumber: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"contact_number_upload_end_time",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("pageNumber", pageNumber.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun contactReadStartTime(pageNumber: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"contact_number_read_start_time",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("pageNumber", pageNumber.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun contactReadEndTime(pageNumber: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"contact_number_read_end_time",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("pageNumber", pageNumber.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingSuccess(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_success",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingFailure(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_failure",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingUploadInitiated(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_upload_initiated",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingUploadSuccess(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_upload_success",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingUploadFailure(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_upload_failure",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
inner class CommonSmsUtil {
|
||||
fun onSmsUploadStart(totalPages: Int, pageNumber: Int, size: Int, retryCount: Int = 0) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
if (retryCount == 0) "sms_upload_started" else "retry_sms_upload_started",
|
||||
mapOf(
|
||||
Pair("totalPages", totalPages.toString()),
|
||||
Pair("pageNumber", pageNumber.toString()),
|
||||
Pair("size", size.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onSmsUploadSuccess(totalPages: Int, pageNumber: Int, size: Int, retryCount: Int = 0) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
if (retryCount == 0) "sms_upload_success" else "retry_sms_upload_success",
|
||||
mapOf(
|
||||
Pair("totalPages", totalPages.toString()),
|
||||
Pair("pageNumber", pageNumber.toString()),
|
||||
Pair("size", size.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onSmsUploadFailure(totalPages: Int, pageNumber: Int, size: Int, statusCode: Int?) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"sms_upload_failure",
|
||||
mapOf(
|
||||
Pair("totalPages", totalPages.toString()),
|
||||
Pair("pageNumber", pageNumber.toString()),
|
||||
Pair("size", size.toString()),
|
||||
Pair("statusCode", statusCode.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun smsUploadStartTime(pageNumber: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"sms_upload_start_time",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("pageNumber", pageNumber.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun smsUploadEndTime(pageNumber: Int, retryCount: Int = 0) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
if (retryCount == 0) "sms_upload_end_time" else "retry_sms_upload_end_time",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("pageNumber", pageNumber.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun smsReadStartTime(pageNumber: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"sms_read_start_time",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("pageNumber", pageNumber.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun smsReadEndTime(pageNumber: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"sms_read_end_time",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("pageNumber", pageNumber.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
inner class PermissionUtil {
|
||||
|
||||
fun hasPermissions(hasPermissions: Boolean) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"dev_has_all_required_permissions_for_data_upload",
|
||||
mapOf(Pair("hasPermissions", hasPermissions.toString()))
|
||||
)
|
||||
}
|
||||
|
||||
fun postGettingPreSignedUrlInitiated(retryCount: Int = 0) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"PL_GET_PRE_SIGNED_URL_CALL_INITIATED",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("retryCount", retryCount.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun postGettingPreSignedUrlSuccess(retryCount: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"PL_GET_PRE_SIGNED_URL_CALL_SUCCESS",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("retryCount", retryCount.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun postErrorInGettingPreSignedUrl(error: Any?) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"PL_ERROR_IN_GETTING_PRESIGNED_URL",
|
||||
mapOf(Pair("error", error?.toString() ?: EMPTY))
|
||||
)
|
||||
}
|
||||
|
||||
fun onErrorUploadingSms(error: Any?) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"PL_AWS_SMS_UPLOADING_FAILURE",
|
||||
mapOf(Pair("error", error?.toString() ?: EMPTY))
|
||||
)
|
||||
}
|
||||
|
||||
fun onExceptionWhileUploadingData() {
|
||||
NaviTrackEvent.trackEventOnClickStream("AWS_DATA_UPLOADING_EXCEPTION")
|
||||
}
|
||||
|
||||
fun onFoundEmptySmsList() {
|
||||
NaviTrackEvent.trackEventOnClickStream("PL_SMS_IS_EMPTY")
|
||||
}
|
||||
|
||||
fun postPreSignedIngestionStatus(
|
||||
preSignedUrl: String?,
|
||||
referenceId: String?,
|
||||
ingestionType: String?,
|
||||
upload: Boolean?
|
||||
) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"PL_PRESIGNED_INGESTION_DATA",
|
||||
mapOf(
|
||||
Pair("presignedUrl", preSignedUrl.toString()),
|
||||
Pair("referenceId", referenceId.toString()),
|
||||
Pair("ingestionType", ingestionType.toString()),
|
||||
Pair("needToUpload", upload.toString()),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun numberOfUrlsReceivedAndNumberOfDataUploaded(urlsReceived: Int, uploadTypeCount: Int) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"PL_PRE_SIGNED_URLS_RECEIVED",
|
||||
mapOf(
|
||||
Pair("url_received_count", urlsReceived.toString()),
|
||||
Pair("upload_type_count", uploadTypeCount.toString())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onDataUploadAcknowledgementInitiated(ingestionList: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_data_upload_acknowledgement_initiated",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("ingestion_list", ingestionList)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onDataUploadAcknowledgementSuccess(ingestionList: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_data_upload_acknowledgement_success",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("ingestion_list", ingestionList)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onDataUploadAcknowledgementFailure(ingestionList: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_data_upload_acknowledgement_failure",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("ingestion_list", ingestionList)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onIngestionTaskListEmpty(isException: Boolean) {
|
||||
NaviTrackEvent.trackEvent(
|
||||
eventName = "PL_Ingestion_Task_List_Empty",
|
||||
eventValues = mapOf(Pair("isException", isException.toString()))
|
||||
)
|
||||
}
|
||||
|
||||
fun onIngestionTaskListNull() {
|
||||
NaviTrackEvent.trackEvent(eventName = "PL_Ingestion_Task_List_Null")
|
||||
}
|
||||
|
||||
fun onZippingSuccess(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_success",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingFailure(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_failure",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingUploadInitiated(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_upload_initiated",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingUploadSuccess(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_upload_success",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun onZippingUploadFailure(type: String) {
|
||||
NaviTrackEvent.trackEventOnClickStream(
|
||||
"on_zipping_upload_failure",
|
||||
mapOf(
|
||||
Pair("atTimeStamp", System.currentTimeMillis().toString()),
|
||||
Pair("type", type)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val OVERRIDE_EVENT = "override_event"
|
||||
const val TEXT_TRUE = "true"
|
||||
|
||||
@@ -16,9 +16,9 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
|
||||
private val LightColors =
|
||||
Colors(
|
||||
primary = FFFF5732,
|
||||
primary = FF1F002A,
|
||||
primaryVariant = Color.Black,
|
||||
secondary = FFFF5732,
|
||||
secondary = FF1F002A,
|
||||
secondaryVariant = FF018786,
|
||||
background = FF0000FF,
|
||||
surface = Color.White,
|
||||
|
||||
@@ -1398,11 +1398,11 @@ object NaviWidgetIconUtils {
|
||||
EMAIL_LOGO -> R.drawable.ic_email
|
||||
RIGHT_ARROW_DARK_BLACK -> R.drawable.ic_right_arrow_dark_black
|
||||
SALARIED_UNSELECTED_ICON -> R.drawable.ic_salaried_unselected
|
||||
SALARIED_SELECTED_ICON -> R.drawable.ic_salaried_selected
|
||||
SALARIED_SELECTED_ICON -> R.drawable.ic_salaried_selected_purple_color
|
||||
SELF_EMPLOYED_UNSELECTED_ICON -> R.drawable.ic_others_unselected
|
||||
SELF_EMPLOYED_SELECTED_ICON -> R.drawable.ic_others_selected
|
||||
SELF_EMPLOYED_SELECTED_ICON -> R.drawable.ic_self_employed_selected_purple_theme
|
||||
OTHERS_UNSELECTED_ICON -> R.drawable.ic_others_employment_unselected
|
||||
OTHERS_SELECTED_ICON -> R.drawable.ic_others_employment_selected
|
||||
OTHERS_SELECTED_ICON -> R.drawable.ic_others_selected_purple_theme
|
||||
DELAY -> R.drawable.delay
|
||||
else -> -1
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h24v24h-24z"/>
|
||||
<path
|
||||
android:pathData="M15.306,3.53C14.582,3.838 13.803,3.998 13.016,4C12.236,4.001 11.464,3.845 10.746,3.54C10.027,3.236 9.378,2.791 8.836,2.23V2.22C9.205,1.594 9.759,1.098 10.423,0.803C11.086,0.507 11.826,0.425 12.538,0.569C13.25,0.714 13.899,1.076 14.395,1.607C14.891,2.137 15.21,2.81 15.306,3.53Z"
|
||||
android:fillColor="#E6BEFF"/>
|
||||
<path
|
||||
android:pathData="M15.346,4C15.346,4.929 14.977,5.819 14.321,6.475C13.664,7.132 12.774,7.5 11.846,7.5C10.917,7.5 10.027,7.132 9.371,6.475C8.715,5.819 8.346,4.929 8.346,4C8.342,3.376 8.512,2.764 8.836,2.23C9.378,2.791 10.027,3.237 10.745,3.541C11.464,3.846 12.236,4.002 13.016,4C13.803,3.999 14.582,3.839 15.306,3.53C15.334,3.685 15.348,3.843 15.346,4Z"
|
||||
android:fillColor="#F8EDFF"/>
|
||||
<path
|
||||
android:pathData="M15.306,3.53C15.156,3.59 14.996,3.65 14.846,3.7C14.535,3.181 14.095,2.752 13.57,2.454C13.044,2.157 12.45,2 11.846,2C11.006,1.997 10.195,2.303 9.566,2.86C9.304,2.672 9.06,2.461 8.836,2.23V2.22C9.205,1.594 9.759,1.098 10.423,0.803C11.086,0.507 11.826,0.425 12.538,0.569C13.25,0.714 13.899,1.076 14.395,1.607C14.891,2.137 15.21,2.81 15.306,3.53Z"
|
||||
android:fillColor="#E6BEFF"/>
|
||||
<path
|
||||
android:pathData="M8.829,2.223C9.371,2.785 10.021,3.232 10.74,3.537C11.458,3.843 12.231,4 13.012,4C13.803,4 14.585,3.839 15.312,3.527"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="1.16667"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M11.846,7.5C13.779,7.5 15.346,5.933 15.346,4C15.346,2.067 13.779,0.5 11.846,0.5C9.913,0.5 8.346,2.067 8.346,4C8.346,5.933 9.913,7.5 11.846,7.5Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="1.16667"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M13.857,23.551L14.357,17.551H16.857V14.051C16.857,12.725 16.331,11.453 15.393,10.515C14.455,9.578 13.184,9.051 11.857,9.051C10.531,9.051 9.26,9.578 8.322,10.515C7.384,11.453 6.857,12.725 6.857,14.051V17.551H9.357L9.857,23.551H13.857Z"
|
||||
android:fillColor="#F8EDFF"/>
|
||||
<path
|
||||
android:pathData="M11.857,9.051C11.201,9.051 10.551,9.18 9.944,9.432C9.337,9.683 8.786,10.051 8.322,10.515C7.384,11.453 6.857,12.725 6.857,14.051V16.07C6.857,14.744 7.384,13.472 8.322,12.534C9.26,11.597 10.531,11.07 11.857,11.07C13.184,11.07 14.455,11.597 15.393,12.534C16.331,13.472 16.857,14.744 16.857,16.07V14.051C16.857,13.394 16.728,12.744 16.477,12.137C16.226,11.531 15.857,10.98 15.393,10.515C14.929,10.051 14.377,9.683 13.771,9.432C13.164,9.18 12.514,9.051 11.857,9.051Z"
|
||||
android:fillColor="#F8EDFF"/>
|
||||
<path
|
||||
android:pathData="M13.857,23.551L14.357,17.551H16.857V14.051C16.857,12.725 16.331,11.453 15.393,10.515C14.455,9.578 13.184,9.051 11.857,9.051C10.531,9.051 9.26,9.578 8.322,10.515C7.384,11.453 6.857,12.725 6.857,14.051V17.551H9.357L9.857,23.551H13.857Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="1.16667"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,72 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="25dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="25"
|
||||
android:viewportHeight="24">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0.5,0h24v24h-24z"/>
|
||||
<path
|
||||
android:pathData="M14,16.5C14,16.235 14.105,15.98 14.293,15.793C14.48,15.605 14.735,15.5 15,15.5H23C23.265,15.5 23.52,15.605 23.707,15.793C23.895,15.98 24,16.235 24,16.5V22.5C24,22.765 23.895,23.019 23.707,23.207C23.52,23.395 23.265,23.5 23,23.5H15C14.735,23.5 14.48,23.395 14.293,23.207C14.105,23.019 14,22.765 14,22.5V16.5Z"
|
||||
android:fillColor="#F8EDFF"/>
|
||||
<path
|
||||
android:pathData="M23,15.5H15C14.735,15.5 14.48,15.605 14.293,15.793C14.105,15.98 14,16.235 14,16.5V22.5C14,22.765 14.105,23.019 14.293,23.207C14.48,23.395 14.735,23.5 15,23.5H15.281L23.234,15.547C23.158,15.522 23.08,15.506 23,15.5Z"
|
||||
android:fillColor="#E6BEFF"/>
|
||||
<path
|
||||
android:pathData="M6,7.5C6.692,7.5 7.369,7.295 7.945,6.91C8.52,6.525 8.969,5.979 9.234,5.339C9.499,4.7 9.568,3.996 9.433,3.317C9.298,2.638 8.965,2.015 8.475,1.525C7.986,1.036 7.362,0.702 6.683,0.567C6.004,0.432 5.3,0.501 4.661,0.766C4.021,1.031 3.475,1.48 3.09,2.055C2.706,2.631 2.5,3.308 2.5,4C2.5,4.928 2.869,5.818 3.525,6.475C4.182,7.131 5.072,7.5 6,7.5Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.953488"
|
||||
android:fillColor="#F8EDFF"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M8,23.5L8.5,17.5H11V14C11,12.674 10.473,11.402 9.536,10.464C8.598,9.527 7.326,9 6,9C4.674,9 3.402,9.527 2.464,10.464C1.527,11.402 1,12.674 1,14V17.5H3.5L4,23.5H8Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.953488"
|
||||
android:fillColor="#F8EDFF"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M14,16.5C14,16.235 14.105,15.98 14.293,15.793C14.48,15.605 14.735,15.5 15,15.5H23C23.265,15.5 23.52,15.605 23.707,15.793C23.895,15.98 24,16.235 24,16.5V22.5C24,22.765 23.895,23.019 23.707,23.207C23.52,23.395 23.265,23.5 23,23.5H15C14.735,23.5 14.48,23.395 14.293,23.207C14.105,23.019 14,22.765 14,22.5V16.5Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.953488"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M16.5,15.5L17,14.5C17.109,14.194 17.314,13.931 17.584,13.751C17.855,13.571 18.176,13.483 18.5,13.5H19.5C19.825,13.483 20.146,13.571 20.416,13.751C20.686,13.931 20.891,14.194 21,14.5L21.5,15.5"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.953488"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M14,19.5H24"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.953488"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M19,19.5V21"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.953488"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M6,11V14"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.953488"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M7.167,4C7.953,4 8.73,3.841 9.453,3.533C9.36,2.812 9.044,2.138 8.548,1.606C8.053,1.074 7.403,0.71 6.69,0.567C5.977,0.423 5.237,0.507 4.574,0.806C3.911,1.105 3.359,1.604 2.994,2.233C3.536,2.792 4.184,3.236 4.901,3.54C5.618,3.843 6.389,4 7.167,4Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.953488"
|
||||
android:fillColor="#E6BEFF"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,75 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h24v24h-24z"/>
|
||||
<path
|
||||
android:pathData="M18.5,23H5.5L3.81,16.24C3.773,16.092 3.772,15.937 3.805,15.788C3.838,15.639 3.904,15.499 4,15.38C4.093,15.262 4.211,15.167 4.346,15.101C4.481,15.035 4.629,15.001 4.78,15H19.22C19.372,14.999 19.522,15.033 19.658,15.099C19.795,15.165 19.915,15.261 20.01,15.38C20.103,15.5 20.168,15.64 20.199,15.789C20.23,15.938 20.227,16.092 20.19,16.24L18.5,23Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.95"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M1,23H23"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.95"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M16.75,13.001C16.421,12.001 15.785,11.13 14.932,10.512C14.079,9.895 13.053,9.563 12,9.563C10.947,9.563 9.921,9.895 9.068,10.512C8.215,11.13 7.579,12.001 7.25,13.001"
|
||||
android:fillColor="#F8EDFF"/>
|
||||
<path
|
||||
android:pathData="M16.75,13.001C16.421,12.001 15.785,11.13 14.932,10.512C14.079,9.895 13.053,9.563 12,9.563C10.947,9.563 9.921,9.895 9.068,10.512C8.215,11.13 7.579,12.001 7.25,13.001"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.95"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M12,8C13.933,8 15.5,6.433 15.5,4.5C15.5,2.567 13.933,1 12,1C10.067,1 8.5,2.567 8.5,4.5C8.5,6.433 10.067,8 12,8Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.95"
|
||||
android:fillColor="#F8EDFF"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M12,12V13.5"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.95"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M15,3.5C15,4.605 13.881,4.5 12.5,4.5C10.5,4 9.5,3.605 9.5,2.5C9.5,1.395 11.119,1 12.5,1C13.881,1 15,2.395 15,3.5Z"
|
||||
android:fillColor="#E6BEFF"/>
|
||||
<path
|
||||
android:pathData="M12,8C13.933,8 15.5,6.433 15.5,4.5C15.5,2.567 13.933,1 12,1C10.067,1 8.5,2.567 8.5,4.5C8.5,6.433 10.067,8 12,8Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.95"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M18.5,23H5.5L3.81,16.24C3.773,16.092 3.772,15.937 3.805,15.788C3.838,15.639 3.904,15.499 4,15.38C4.093,15.262 4.211,15.167 4.346,15.101C4.481,15.035 4.629,15.001 4.78,15H19.22C19.372,14.999 19.522,15.033 19.658,15.099C19.795,15.165 19.915,15.261 20.01,15.38C20.103,15.5 20.168,15.64 20.199,15.789C20.23,15.938 20.227,16.092 20.19,16.24L18.5,23Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.95"
|
||||
android:fillColor="#F8EDFF"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M9,2.73C9.541,3.29 10.189,3.735 10.905,4.039C11.622,4.343 12.392,4.5 13.17,4.5C13.962,4.49 14.745,4.32 15.47,4"
|
||||
android:fillColor="#E6BEFF"/>
|
||||
<path
|
||||
android:pathData="M9,2.73C9.541,3.29 10.189,3.735 10.905,4.039C11.622,4.343 12.392,4.5 13.17,4.5C13.962,4.49 14.745,4.32 15.47,4"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="0.95"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#1F002A"
|
||||
android:strokeLineCap="round"/>
|
||||
</group>
|
||||
</vector>
|
||||
Reference in New Issue
Block a user