Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.woocommerce.android.ui.woopos.util.datastore

import com.woocommerce.android.ui.woopos.common.util.WooPosLogWrapper
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException
import java.util.Locale
import javax.inject.Inject

class WooPosSyncTimestampManager @Inject constructor(
private val timestampRepository: WooPosSyncTimestampRepository,
private val logger: WooPosLogWrapper
) {
private val gmtFormatter = DateTimeFormatter.ofPattern(GMT_DATE_FORMAT, Locale.US).withZone(ZoneOffset.UTC)

suspend fun storeProductsLastSyncTimestamp(timestamp: Long) {
timestampRepository.storeProductsLastSyncTimestamp(timestamp)
}

suspend fun getProductsLastSyncTimestamp(): Long? = timestampRepository.getProductsLastSyncTimestamp()

suspend fun clearProductsLastSyncTimestamp() = timestampRepository.clearProductsLastSyncTimestamp()

suspend fun storeVariationsLastSyncTimestamp(timestamp: Long) =
timestampRepository.storeVariationsLastSyncTimestamp(timestamp)

suspend fun getVariationsLastSyncTimestamp(): Long? = timestampRepository.getVariationsLastSyncTimestamp()

suspend fun clearVariationsLastSyncTimestamp() {
timestampRepository.clearVariationsLastSyncTimestamp()
}

suspend fun clearAllSyncTimestamps() {
timestampRepository.clearAllSyncTimestamps()
}

fun formatTimestampForApi(timestamp: Long): String {
return gmtFormatter.format(Instant.ofEpochMilli(timestamp))
}

fun parseTimestampFromApi(dateFromApi: String): Long? {
return parseGmtTimestamp(dateFromApi)
}

private fun parseGmtTimestamp(dateFromApi: String): Long? {
return try {
val localDateTime = LocalDateTime.parse(dateFromApi, gmtFormatter)
return localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli()
} catch (e: DateTimeParseException) {
logger.e("Failed to parse GMT timestamp: '$dateFromApi'", e)
null
}
}

private companion object {
const val GMT_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.woocommerce.android.ui.woopos.util.datastore

import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.woopos.common.util.WooPosLogWrapper
import kotlinx.coroutines.flow.first
import javax.inject.Inject

class WooPosSyncTimestampRepository @Inject constructor(
private val selectedSite: SelectedSite,
private val dataStore: DataStore<Preferences>,
private val logger: WooPosLogWrapper
) {

suspend fun storeProductsLastSyncTimestamp(timestamp: Long) {
val key = buildSiteSpecificKey(PRODUCTS_TIMESTAMP_KEY)
if (key != null) {
dataStore.edit { preferences ->
preferences[key] = timestamp.toString()
}
}
}

suspend fun getProductsLastSyncTimestamp(): Long? {
val key = buildSiteSpecificKey(PRODUCTS_TIMESTAMP_KEY)
return if (key != null) {
dataStore.data.first()[key]?.toLong()
} else {
null
}
}

suspend fun clearProductsLastSyncTimestamp() {
val key = buildSiteSpecificKey(PRODUCTS_TIMESTAMP_KEY)
if (key != null) {
dataStore.edit { preferences ->
preferences.remove(key)
}
}
}

suspend fun storeVariationsLastSyncTimestamp(timestamp: Long) {
val key = buildSiteSpecificKey(VARIATIONS_TIMESTAMP_KEY)
if (key != null) {
dataStore.edit { preferences ->
preferences[key] = timestamp.toString()
}
}
}

suspend fun getVariationsLastSyncTimestamp(): Long? {
val key = buildSiteSpecificKey(VARIATIONS_TIMESTAMP_KEY)
return if (key != null) {
dataStore.data.first()[key]?.toLong()
} else {
null
}
}

suspend fun clearVariationsLastSyncTimestamp() {
val key = buildSiteSpecificKey(VARIATIONS_TIMESTAMP_KEY)
if (key != null) {
dataStore.edit { preferences ->
preferences.remove(key)
}
}
}

suspend fun clearAllSyncTimestamps() {
val productsKey = buildSiteSpecificKey(PRODUCTS_TIMESTAMP_KEY)
val variationsKey = buildSiteSpecificKey(VARIATIONS_TIMESTAMP_KEY)

if (productsKey != null && variationsKey != null) {
dataStore.edit { preferences ->
preferences.remove(productsKey)
preferences.remove(variationsKey)
}
}
}

private fun buildSiteSpecificKey(key: String): Preferences.Key<String>? {
val site = selectedSite.getOrNull()
return if (site != null) {
stringPreferencesKey("${site.siteId}-$key")
} else {
logger.e("Cannot build site-specific key '$key': no site selected")
null
}
}

private companion object {
const val PRODUCTS_TIMESTAMP_KEY = "pos_products_sync_timestamp"
const val VARIATIONS_TIMESTAMP_KEY = "pos_variations_sync_timestamp"
}
}
Loading