-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add profile and contacts fetching from pubky #824
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
Open
ben-kaufman
wants to merge
36
commits into
master
Choose a base branch
from
feat/pubky-profile
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+3,118
−162
Open
Changes from all commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
5983a73
feat: add profile fetching from pubky
ben-kaufman b5f211c
Merge branch 'master' into feat/pubky-profile
ben-kaufman 8d5bac7
fix build
ben-kaufman 1bdd233
Merge branch 'feat/pubky-profile' of https://github.com/synonymdev/bi…
ben-kaufman 1484f26
fix paykit version
ben-kaufman 06a618d
fixes
ben-kaufman 7ff4b1e
fixes
ben-kaufman 13bd697
fixes
ben-kaufman 359eddc
fixes
ben-kaufman ec754c1
detekt fix
ben-kaufman 9ede70f
fixes
ben-kaufman ea2a78e
fix comment
ben-kaufman fcb20c9
Merge branch 'master' into feat/pubky-profile
ovitrif 5100c97
fix feedback comments
ben-kaufman 1985f9e
Merge branch 'master' into feat/pubky-profile
ben-kaufman 8656cb7
claude fixes
ben-kaufman 9b3a0e8
feat: migrate pubky profile fetching from paykit to bitkitcore
ben-kaufman 97b8e70
feat: add Pubky contacts screen with intro flow and contact detail view
ben-kaufman 4be2306
fixes
ben-kaufman 6634eca
Merge branch 'master' into feat/pubky-profile
ben-kaufman c3b548c
Merge branch 'master' into feat/pubky-profile
ovitrif e0527c7
fixes
ben-kaufman 63cfa6e
Merge remote-tracking branch 'origin/master' into feat/pubky-profile
ben-kaufman 78d16f7
fixes
ben-kaufman 1f0bba0
fixes
ben-kaufman 7c4fdad
fix detekt
ben-kaufman e52430d
feat: add coil with pubky image fetcher
ovitrif b0383b4
refactor: migrate pubky images to coil
ovitrif ae06f53
feat: add crossfade and spring pop to pubky images
ovitrif d16bbe1
refactor: remove modifiers trailing comma
ovitrif 6ae1a82
refactor: use AsyncImage vs. SubcomposeAsyncImage
ovitrif 94b2b5a
fix: address PR review remarks
ovitrif 9a07040
refactor: extract ActionButton and LinkRow into shared components, fi…
ben-kaufman a3ac562
Merge branch 'master' into feat/pubky-profile
ben-kaufman 64e8017
Merge branch 'feat/pubky-profile' into feat/pubky-async-image
ben-kaufman 0ce5b99
Merge pull request #846 from synonymdev/feat/pubky-async-image
ben-kaufman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| package to.bitkit.data | ||
|
|
||
| import coil3.ImageLoader | ||
| import coil3.Uri | ||
| import coil3.decode.DataSource | ||
| import coil3.decode.ImageSource | ||
| import coil3.fetch.FetchResult | ||
| import coil3.fetch.Fetcher | ||
| import coil3.fetch.SourceFetchResult | ||
| import coil3.request.Options | ||
| import okio.Buffer | ||
| import org.json.JSONObject | ||
| import to.bitkit.services.PubkyService | ||
| import to.bitkit.utils.Logger | ||
|
|
||
| private const val TAG = "PubkyImageFetcher" | ||
| private const val PUBKY_SCHEME = "pubky://" | ||
|
|
||
| class PubkyImageFetcher( | ||
| private val uri: String, | ||
| private val options: Options, | ||
| private val pubkyService: PubkyService, | ||
| ) : Fetcher { | ||
|
|
||
| override suspend fun fetch(): FetchResult { | ||
| val data = pubkyService.fetchFile(uri) | ||
| val blobData = resolveImageData(data) | ||
| val source = ImageSource(Buffer().apply { write(blobData) }, options.fileSystem) | ||
| return SourceFetchResult(source, null, dataSource = DataSource.NETWORK) | ||
| } | ||
|
|
||
| private suspend fun resolveImageData(data: ByteArray): ByteArray = runCatching { | ||
| val json = JSONObject(String(data)) | ||
| val src = json.optString("src", "") | ||
| if (src.isNotEmpty() && src.startsWith(PUBKY_SCHEME)) { | ||
| Logger.debug("File descriptor found, fetching blob from '$src'", context = TAG) | ||
| pubkyService.fetchFile(src) | ||
| } else { | ||
| data | ||
| } | ||
| }.getOrDefault(data) | ||
|
|
||
| class Factory(private val pubkyService: PubkyService) : Fetcher.Factory<Uri> { | ||
| override fun create(data: Uri, options: Options, imageLoader: ImageLoader): Fetcher? { | ||
| val uri = data.toString() | ||
| if (!uri.startsWith(PUBKY_SCHEME)) return null | ||
| return PubkyImageFetcher(uri, options, pubkyService) | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package to.bitkit.data | ||
|
|
||
| import android.content.Context | ||
| import androidx.datastore.core.DataStore | ||
| import androidx.datastore.dataStore | ||
| import dagger.hilt.android.qualifiers.ApplicationContext | ||
| import kotlinx.coroutines.flow.Flow | ||
| import kotlinx.serialization.Serializable | ||
| import to.bitkit.data.serializers.PubkyStoreSerializer | ||
| import javax.inject.Inject | ||
| import javax.inject.Singleton | ||
|
|
||
| private val Context.pubkyDataStore: DataStore<PubkyStoreData> by dataStore( | ||
| fileName = "pubky.json", | ||
| serializer = PubkyStoreSerializer, | ||
| ) | ||
|
|
||
| @Singleton | ||
| class PubkyStore @Inject constructor( | ||
| @ApplicationContext private val context: Context, | ||
| ) { | ||
| private val store = context.pubkyDataStore | ||
|
|
||
| val data: Flow<PubkyStoreData> = store.data | ||
|
|
||
| suspend fun update(transform: (PubkyStoreData) -> PubkyStoreData) { | ||
| store.updateData(transform) | ||
| } | ||
|
|
||
| suspend fun reset() { | ||
| store.updateData { PubkyStoreData() } | ||
| } | ||
| } | ||
|
|
||
| @Serializable | ||
| data class PubkyStoreData( | ||
| val cachedName: String? = null, | ||
| val cachedImageUri: String? = null, | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
app/src/main/java/to/bitkit/data/serializers/PubkyStoreSerializer.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| package to.bitkit.data.serializers | ||
|
|
||
| import androidx.datastore.core.Serializer | ||
| import to.bitkit.data.PubkyStoreData | ||
| import to.bitkit.di.json | ||
| import to.bitkit.utils.Logger | ||
| import java.io.InputStream | ||
| import java.io.OutputStream | ||
|
|
||
| object PubkyStoreSerializer : Serializer<PubkyStoreData> { | ||
| private const val TAG = "PubkyStoreSerializer" | ||
|
|
||
| override val defaultValue: PubkyStoreData = PubkyStoreData() | ||
|
|
||
| override suspend fun readFrom(input: InputStream): PubkyStoreData { | ||
| return runCatching { | ||
| json.decodeFromString<PubkyStoreData>(input.readBytes().decodeToString()) | ||
| }.getOrElse { | ||
| Logger.error("Failed to deserialize PubkyStoreData", it, context = TAG) | ||
| defaultValue | ||
| } | ||
| } | ||
|
|
||
| override suspend fun writeTo(t: PubkyStoreData, output: OutputStream) { | ||
| output.write(json.encodeToString(t).encodeToByteArray()) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| package to.bitkit.di | ||
|
|
||
| import android.content.Context | ||
| import coil3.ImageLoader | ||
| import coil3.disk.DiskCache | ||
| import coil3.disk.directory | ||
| import coil3.memory.MemoryCache | ||
| import coil3.request.crossfade | ||
| import dagger.Module | ||
| import dagger.Provides | ||
| import dagger.hilt.InstallIn | ||
| import dagger.hilt.android.qualifiers.ApplicationContext | ||
| import dagger.hilt.components.SingletonComponent | ||
| import to.bitkit.data.PubkyImageFetcher | ||
| import to.bitkit.services.PubkyService | ||
| import javax.inject.Singleton | ||
|
|
||
| @Module | ||
| @InstallIn(SingletonComponent::class) | ||
| object ImageModule { | ||
|
|
||
| @Provides | ||
| @Singleton | ||
| fun provideImageLoader( | ||
| @ApplicationContext context: Context, | ||
| pubkyService: PubkyService, | ||
| ): ImageLoader = ImageLoader.Builder(context) | ||
| .crossfade(true) | ||
| .components { add(PubkyImageFetcher.Factory(pubkyService)) } | ||
| .memoryCache { | ||
| MemoryCache.Builder() | ||
| .maxSizePercent(context, percent = 0.15) | ||
| .build() | ||
| } | ||
| .diskCache { | ||
| DiskCache.Builder() | ||
| .directory(context.cacheDir.resolve("pubky-images")) | ||
| .build() | ||
| } | ||
| .build() | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| package to.bitkit.models | ||
|
|
||
| import to.bitkit.ext.ellipsisMiddle | ||
| import com.synonym.bitkitcore.PubkyProfile as CorePubkyProfile | ||
|
|
||
| data class PubkyProfileLink(val label: String, val url: String) | ||
|
|
||
| data class PubkyProfile( | ||
| val publicKey: String, | ||
| val name: String, | ||
| val bio: String, | ||
| val imageUrl: String?, | ||
| val links: List<PubkyProfileLink>, | ||
| val status: String?, | ||
| ) { | ||
| companion object { | ||
| private const val TRUNCATED_PK_LENGTH = 11 | ||
|
|
||
| fun fromFfi(publicKey: String, ffiProfile: CorePubkyProfile): PubkyProfile { | ||
| return PubkyProfile( | ||
| publicKey = publicKey, | ||
| name = ffiProfile.name, | ||
| bio = ffiProfile.bio ?: "", | ||
| imageUrl = ffiProfile.image, | ||
| links = ffiProfile.links.orEmpty().map { PubkyProfileLink(label = it.title, url = it.url) }, | ||
| status = ffiProfile.status, | ||
| ) | ||
| } | ||
|
|
||
| fun placeholder(publicKey: String) = PubkyProfile( | ||
| publicKey = publicKey, | ||
| name = publicKey.ellipsisMiddle(TRUNCATED_PK_LENGTH), | ||
| bio = "", | ||
| imageUrl = null, | ||
| links = emptyList(), | ||
| status = null, | ||
| ) | ||
|
|
||
| fun forDisplay( | ||
| publicKey: String, | ||
| name: String?, | ||
| imageUrl: String?, | ||
| ) = PubkyProfile( | ||
| publicKey = publicKey, | ||
| name = name ?: publicKey.ellipsisMiddle(TRUNCATED_PK_LENGTH), | ||
| bio = "", | ||
| imageUrl = imageUrl, | ||
| links = emptyList(), | ||
| status = null, | ||
| ) | ||
| } | ||
|
|
||
| val truncatedPublicKey: String | ||
| get() = publicKey.ellipsisMiddle(TRUNCATED_PK_LENGTH) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.