Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add image caching to SmallImageCard #319

Conversation

ishita-gambhir-adobe
Copy link

Description

Previously the images were always downloaded from the url, added cache functionality. Now, the image will be fetched from cache if present, otherwise it will be downloaded and cached for future use.

Related Issue

Motivation and Context

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Copy link

codecov bot commented Jan 7, 2025

Codecov Report

Attention: Patch coverage is 56.92308% with 28 lines in your changes missing coverage. Please review.

Project coverage is 82.23%. Comparing base (f1c6246) to head (e5398ed).

Files with missing lines Patch % Lines
...keting/mobile/messaging/ContentCardImageManager.kt 56.25% 22 Missing and 6 partials ⚠️
Additional details and impacted files
@@                     Coverage Diff                     @@
##             feature/content-cards     #319      +/-   ##
===========================================================
- Coverage                    82.78%   82.23%   -0.56%     
  Complexity                     800      800              
===========================================================
  Files                           78       79       +1     
  Lines                         3701     3765      +64     
  Branches                       572      583      +11     
===========================================================
+ Hits                          3064     3096      +32     
- Misses                         459      483      +24     
- Partials                       178      186       +8     
Flag Coverage Δ
functional-tests 30.17% <0.00%> (-0.61%) ⬇️
unit-tests 81.91% <56.92%> (-0.56%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

UIUtils.downloadImage(imageUrl) {
val contentCardImageManager = ContentCardImageManager()

contentCardImageManager.getContentCardImageBitmap(imageUrl) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we define the getContentCardImageBitmap function in a companion object within ContentCardImageManager so there is no need to create a ContentCardImageManager object just to call getContentCardImageBitmap?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

import java.io.InputStream
import java.nio.ByteBuffer

class ContentCardImageManager() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the () can be removed after the class name

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

it.onSuccess { bitmap ->
imageBitmap = bitmap
isLoading = false
}
it.onFailure {
// TODO once we have a default image, we can use that here
// todo - confirm default image bitmap to be used here
// imageBitmap = contentCardManager.getDefaultImageBitmap()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function can also be added to the companion object so it can be called statically.

byteArray.inputStream() // Create InputStream from byte array
}

val cacheEntry = CacheEntry(imageInputStream, CacheExpiry.never(), null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should set a cache expiry here as content cards will be refreshed often. @navratan-soni and @PravinPK what do you guys think is the ideal expiry time we should set? i'm thinking a 7 day expiry would be fine.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to this

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Log.warning(
MessagingConstants.LOG_TAG,
SELF_TAG,
"getImageBitmapFromCache: Unable to read cached data into a bitmap due to error: $e"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we usually use a - between the function name tag and the log message

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Log.warning(
MessagingConstants.LOG_TAG,
SELF_TAG,
"getImageBitmapFromCache: Unable to read cached data as the inputStream is null"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we usually use a - between the function name tag and the log message

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

cacheService?.set(cacheName, imageName, cacheEntry)

return true
} catch (ex: java.lang.Exception) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no need to provide the full Exception package path here:

} catch (e: Exception) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Log.warning(
MessagingConstants.LOG_TAG,
SELF_TAG,
"cacheImage - An unexpected error occurred while caching the downloaded image: \n %s",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's use the kotlin string interpolation format:

 Log.warning(
                MessagingConstants.LOG_TAG,
                SELF_TAG,
                "cacheImage - An unexpected error occurred while caching the downloaded image: $e"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -21,6 +21,8 @@ public final class MessagingConstants {
static final String CACHE_BASE_DIR = "messaging";
static final String PROPOSITIONS_CACHE_SUBDIRECTORY = "propositions";
static final String IMAGES_CACHE_SUBDIRECTORY = "images";
static final String CONTENT_CARD_CACHE_SUBDIRECTORY = "contentCardImages";
static final String CONTENT_CARD_TEST_CACHE_SUBDIRECTORY = "contentCardTestImages";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add these constants to MessagingTestConstants instead of here

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

@Test
fun get_image_first_time_when_not_in_cache() {
Copy link
Contributor

@rymorale rymorale Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we name the tests with more readable names like try getting an image when it is not in the cache? back ticks can be used to add spaces to test method names: https://kotlinlang.org/docs/coding-conventions.html#names-for-test-methods

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

import java.io.InputStream
import java.nio.ByteBuffer

class ContentCardImageManager {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whole class can be made as an object instead of class, and we can remove the companion object.

Copy link

@navratan-soni navratan-soni left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two points here.

  1. If all the methods are in companion object, can we remove the companion object and just create the whole class as Object.
  2. My preferred approach would be to create instance of this Manager class, which takes the input of cache name in constructor itself. That way we will not need to pass the name of cache in all the methods.

@rymorale
Copy link
Contributor

rymorale commented Jan 9, 2025

the Verify UI testing screenshots / verify-screenshots error can be resolved later

@ishita-gambhir-adobe ishita-gambhir-adobe merged commit ff6d1b5 into adobe:feature/content-cards Jan 9, 2025
6 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants