Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
6 changes: 5 additions & 1 deletion .github/workflows/build_sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,16 @@ jobs:
- name: Validate Gradle wrapper
uses: gradle/[email protected]


- name: Decrypt the keystore for signing
run: |
echo "${{ secrets.KEYSTORE_ENCRYPTED }}" > keystore.asc
gpg -d --passphrase "${{ secrets.KEYSTORE_PASSWORD }}" --batch keystore.asc > keystore.jks

- name: Download and extract `ark-core` JNI libs
run: |
wget https://github.com/ARK-Builders/ark-core/releases/download/v1.0.0/jniLibs.zip
unzip -d sample/src/main jniLibs.zip

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry for suddenly jumping into this, but I think implementation(libraries.core) is enough. In theory we don't have to manually download the JNI libs like this because it's already included in the synced dependency of arkcore.

Copy link
Collaborator Author

@oluiscabral oluiscabral Dec 11, 2024

Choose a reason for hiding this comment

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

Just repeating what we later discussed: implementation(libraries.core) is not currently enough, since ark-core/java is a JAR, that means JNI libs are not available for use from it. However, I'm working on transforming ark-core/java into an AAR instead (to make JNI libs available directly from the package)

- name: Build release sample APK
run: ./gradlew sample:assembleRelease

Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,39 @@ git push --tags
- Create an action build file under `.github/workflows/` folder, following any existing build script.
- Create a release build file under `.github/workflows/` folder, following any existing release script.

## Making the Storage Demo work

This section guides you through setting up and running the Storage Demo subpage.

**1. Download the `fs-storage` JNI Libraries:**

The demo requires JNI libraries (libs). Download these from the following location:

* **[ark-core repository](https://github.com/ARK-Builders/ark-core)**

- If you can't find them in the "Releases" section, check the latest successful build actions for artifacts.

**2. Place the Libraries:**

After downloading, move the JNI library files into your project's `sample/src/main/jniLibs` directory. **If the path doesn't exist, create it**

Your project structure should resemble this:

```
...
sample/
...
src/
main/
...
jniLibs/
arm64-v8a/
armeabi-v7a/
x86/
x86_64/
...
...
...
```

With the `fs-storage` JNI libraries in place, you're ready to build, run the project and use the Storage Demo subpage.
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ fastadapter = { group = "com.mikepenz", name = "fastadapter", version.ref = "fas
fastadapter-extensions-binding = { group = "com.mikepenz", name = "fastadapter-extensions-binding", version.ref = "fastadapter" }
fastadapter-extensions-diff = { group = "com.mikepenz", name = "fastadapter-extensions-diff", version.ref = "fastadapter" }
arklib = { group = "dev.arkbuilders", name = "arklib", version.ref = "arkLib" }
core = {group = "dev.arkbuilders.core", name = "lib", version = "1.0-SNAPSHOT"}
orbit-mvi-viewmodel = { group = "org.orbit-mvi", name = "orbit-viewmodel", version.ref = "orbitMvi" }
viewbinding-property-delegate = { group = "com.github.kirich1409", name = "viewbindingpropertydelegate-noreflection", version.ref = "viewbindingPropertyDelegate" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidXCore" }
Expand Down
4 changes: 2 additions & 2 deletions sample/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ android {
dependencies {
implementation(project(":filepicker"))
implementation(project(":about"))

implementation(libraries.core)
implementation(libraries.arklib)
implementation("androidx.core:core-ktx:1.12.0")
implementation(libraries.androidx.appcompat)
implementation(libraries.android.material)
testImplementation(libraries.junit)
androidTestImplementation(libraries.androidx.test.junit)
androidTestImplementation(libraries.androidx.test.espresso)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,32 @@ import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.DialogFragment
import dev.arkbuilders.core.FileStorage
import dev.arkbuilders.sample.R
import dev.arkbuilders.sample.databinding.FragmentStorageDemoBinding
import dev.arkbuilders.sample.extension.getAbsolutePath
import java.io.File
import java.util.UUID

class StorageDemoFragment: DialogFragment() {

private val TAG = StorageDemoFragment::class.java.name

private lateinit var binding: FragmentStorageDemoBinding
private val map by lazy { mutableMapOf<String, String>() }
private var workingDir: String = "/"
private var storage: FileStorage? = null

private val selectDirRequest = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
uri?.let {
// call this to persist permission across device reboots
context?.contentResolver?.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
workingDir = uri.getAbsolutePath()
refreshFilesTree()
val initialStorageFile = UUID.randomUUID().toString()
binding.edtStoragePath.setText(initialStorageFile)
storage = FileStorage(initialStorageFile,
"$workingDir/$initialStorageFile"
)
}
}

Expand Down Expand Up @@ -61,29 +68,39 @@ class StorageDemoFragment: DialogFragment() {

binding.edtStoragePath.setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
refreshFilesTree()
val relativeStoragePath = v.text.toString()
storage = FileStorage(relativeStoragePath,
"$workingDir/$relativeStoragePath"
)
binding.tvCurrentAbsolutePath.text = String.format("%s/%s", workingDir, relativeStoragePath)
return@setOnEditorActionListener true
}
false
}

binding.btnNewMapEntry.setOnClickListener {
MapEntryDialog(isDelete = false, onDone = { key, value ->
map[key] = value ?: ""
refreshMap()
if (storage != null) {
storage!!.set(key, value)
}
refreshStorage()
}).show(parentFragmentManager, MapEntryDialog::class.java.name)
}

binding.btnDeleteEntry.setOnClickListener {
MapEntryDialog(isDelete = true, onDone = { key, value ->
map.remove(key)
refreshMap()
MapEntryDialog(isDelete = true, onDone = { key, _ ->
if (storage != null) {
storage!!.remove(key)
}
refreshStorage()
}).show(parentFragmentManager, MapEntryDialog::class.java.name)
}

binding.btnClearMap.setOnClickListener {
map.clear()
refreshMap()
if (storage != null) {
storage!!.erase()
}
refreshStorage()
}
}

Expand All @@ -105,13 +122,14 @@ class StorageDemoFragment: DialogFragment() {
}
}

private fun refreshMap() {
if (map.isEmpty()) {
private fun refreshStorage() {
if (storage == null) {
binding.tvMapValues.text = getString(R.string.empty_map)
return
}
storage!!.writeFS()
Copy link
Member

Choose a reason for hiding this comment

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

I should check with the crate implementation, but do we really need flushing? That isn't handled by the crate?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

From what I tested, no

Copy link
Member

Choose a reason for hiding this comment

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

storage.set and storage.remove do not write to fs, only storage.erase deletes file

val mapEntries = StringBuilder()
for (entry in map) {
for (entry in storage!!) {
mapEntries.append(entry.key).append(" -> ").append(entry.value).append("\n")
}
binding.tvMapValues.text = mapEntries.toString()
Expand Down
10 changes: 9 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,21 @@ dependencyResolutionManagement {
url = URI("https://jitpack.io")
}
maven {
name = "GitHubPackages"
name = "arklib-android GitHub Packages"
url = URI("https://maven.pkg.github.com/ARK-Builders/arklib-android")
Copy link
Member

Choose a reason for hiding this comment

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

Let's use ark-android to avoid confusion with the archived repo.

It was just a fat lib when we were prototyping, now we moved to the next level with modular framework 😁

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. I don't know if I understood it correctly. This is indeed a reference to arklib-android archive, it is not a name for the current repo. Should we use another repo instead?

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I didn't notice the link leads to the archived repo.

We certainly should not use archived repos.

Copy link
Member

Choose a reason for hiding this comment

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

But what do we use from arklib-android?

Copy link
Collaborator Author

@oluiscabral oluiscabral Dec 12, 2024

Choose a reason for hiding this comment

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

@kirillt It's being used in at least 23 places, just search for dev.arkbuilders.arklib and you'll realize it too. Here's an example on the sample package

import dev.arkbuilders.arklib.data.folders.FoldersRepo
import dev.arkbuilders.arklib.initArkLib
import dev.arkbuilders.arklib.initRustLogger

Copy link
Member

Choose a reason for hiding this comment

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

But what do we use from arklib-android?

TagSelector and ScoreWidget dependent on arklib, they need ResourceIndex, TagStorage, ScoreStorage and so on

Copy link
Member

Choose a reason for hiding this comment

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

Thanks guys, I wasn't realizing it.. I'll come up with plan for the upgrade later.

credentials {
username = "token"
password = "\u0037\u0066\u0066\u0036\u0030\u0039\u0033\u0066\u0032\u0037\u0033\u0036\u0033\u0037\u0064\u0036\u0037\u0066\u0038\u0030\u0034\u0039\u0062\u0030\u0039\u0038\u0039\u0038\u0066\u0034\u0066\u0034\u0031\u0064\u0062\u0033\u0064\u0033\u0038\u0065"
}
}
maven {
name = "ark-core GitHub Packages"
url = URI("https://maven.pkg.github.com/ARK-Builders/ark-core")
credentials {
username = "token"
password = "\u0037\u0066\u0066\u0036\u0030\u0039\u0033\u0066\u0032\u0037\u0033\u0036\u0033\u0037\u0064\u0036\u0037\u0066\u0038\u0030\u0034\u0039\u0062\u0030\u0039\u0038\u0039\u0038\u0066\u0034\u0066\u0034\u0031\u0064\u0062\u0033\u0064\u0033\u0038\u0065"
}
}
}

versionCatalogs {
Expand Down