diff --git a/README.md b/README.md index 4e850bd..9567192 100644 --- a/README.md +++ b/README.md @@ -15,17 +15,17 @@ Calf stands for **C**ompose **A**daptive **L**ook & **F**eel ## Artifacts -| Artifact | Description | Platforms | Version | -|-----------------------|-------------------------------------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **calf-ui** | Adaptive UI components | Android, iOS, Desktop, Web | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-ui)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-ui%22) | -| **calf-file-picker** | Native File Picker wrapper | Android, iOS, Desktop, Web | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-file-picker)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-file-picker%22) | -| **calf-permissions** | API that allows you to handle permissions | Android, iOS | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-file-picker)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-file-picker%22) | -| **calf-geo** | API that allows you to access geolocation | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-navigation** | Native navigation wrapper | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-map** | Native Maps wrapper | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-media** | Video/Audio player | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-notification** | Notification manager | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-sf-symbols** | Apple SF Symbols icons | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| Artifact | Description | Platforms | Version | +|-----------------------|-------------------------------------------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **calf-ui** | Adaptive UI components | Android, iOS, Desktop, Web(Js, Wasm) | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-ui)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-ui%22) | +| **calf-file-picker** | Native File Picker wrapper | Android, iOS, Desktop, Web(Js, Wasm) | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-file-picker)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-file-picker%22) | +| **calf-permissions** | API that allows you to handle permissions | Android, iOS | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-file-picker)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-file-picker%22) | +| **calf-geo** | API that allows you to access geolocation | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-navigation** | Native navigation wrapper | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-map** | Native Maps wrapper | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-media** | Video/Audio player | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-notification** | Notification manager | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-sf-symbols** | Apple SF Symbols icons | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | > The main focus for now is Android and iOS, but more Desktop components are coming that allows you to create adaptive UIs for Desktop as well (Windows, macOS, Linux) @@ -33,14 +33,21 @@ Calf stands for **C**ompose **A**daptive **L**ook & **F**eel [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-ui)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-ui%22) +| Kotlin version | Compose version | Calf version | +|----------------|-----------------|--------------| +| 1.9.22 | 1.6.0 | 0.4.0 | +| 1.9.21 | 1.5.11 | 0.3.1 | +| 1.9.20 | 1.5.10 | 0.2.0 | +| 1.9.0 | 1.5.0 | 0.1.1 | + Add the following dependency to your module `build.gradle.kts` file: ```kotlin // For Adaptive UI components -api("com.mohamedrejeb.calf:calf-ui:0.3.1") +api("com.mohamedrejeb.calf:calf-ui:0.4.0") // For Adaptive FilePicker -implementation("com.mohamedrejeb.calf:calf-file-picker:0.3.1") +implementation("com.mohamedrejeb.calf:calf-file-picker:0.4.0") ``` If you are using `calf-ui` artifact, make sure to export it to binaries: @@ -56,7 +63,7 @@ kotlin { .forEach { it.binaries.framework { ... - export("com.mohamedrejeb.calf:calf-ui:0.3.1") + export("com.mohamedrejeb.calf:calf-ui:0.4.0") } } ... @@ -73,7 +80,7 @@ kotlin { ... framework { ... - export("com.mohamedrejeb.calf:calf-ui:0.3.1") + export("com.mohamedrejeb.calf:calf-ui:0.4.0") } } ... @@ -286,19 +293,28 @@ LaunchedEffect(Unit) { Calf File Picker allows you to pick files from the device storage. -| Android | iOS | -|------------------------------------------------------------|----------------------------------------------------| -| ![Web View Android](docs/images/AdaptiveFilePicker-android.png) | ![Web View iOS](docs/images/AdaptiveFilePicker-ios.png) | +| Android | iOS | +|--------------------------------------------------------------------|------------------------------------------------------------| +| ![File Picker Android](docs/images/AdaptiveFilePicker-android.png) | ![File Picker iOS](docs/images/AdaptiveFilePicker-ios.png) | + +| Desktop | Web | +|--------------------------------------------------------------------|------------------------------------------------------------| +| ![File Picker Desktop](docs/images/AdaptiveFilePicker-desktop.png) | ![File Picker Web](docs/images/AdaptiveFilePicker-web.png) | ```kotlin +val scope = rememberCoroutineScope() +val context = LocalPlatformContext.current + val pickerLauncher = rememberFilePickerLauncher( type = FilePickerFileType.Image, selectionMode = FilePickerSelectionMode.Single, onResult = { files -> - files.firstOrNull()?.let { file -> - // Do something with the selected file - // You can get the ByteArray of the file - file.readByteArray() + scope.launch { + files.firstOrNull()?.let { file -> + // Do something with the selected file + // You can get the ByteArray of the file + file.readByteArray(context) + } } } ) @@ -345,6 +361,8 @@ val type = FilePickerFileType.Custom( * `FilePickerSelectionMode.Single` - Allows you to pick a single file * `FilePickerSelectionMode.Multiple` - Allows you to pick multiple files +Read the full file picker documentation [here](docs/filepicker.md). + ## Contribution If you've found an error in this sample, please file an issue.
Feel free to help out by sending a pull request :heart:. diff --git a/docs/filepicker.md b/docs/filepicker.md index 6214e36..3b0ada8 100644 --- a/docs/filepicker.md +++ b/docs/filepicker.md @@ -7,26 +7,36 @@ Add the following dependency to your module `build.gradle.kts` file: ```kotlin -implementation("com.mohamedrejeb.calf:calf-file-picker:0.3.1") +implementation("com.mohamedrejeb.calf:calf-file-picker:0.4.0") ``` ## Usage Calf File Picker allows you to pick files from the device storage. -| Android | iOS | -|------------------------------------------------------------|----------------------------------------------------| -| ![Web View Android](images/AdaptiveFilePicker-android.png) | ![Web View iOS](images/AdaptiveFilePicker-ios.png) | + +| Android | iOS | +|---------------------------------------------------------------|-------------------------------------------------------| +| ![File Picker Android](images/AdaptiveFilePicker-android.png) | ![File Picker iOS](images/AdaptiveFilePicker-ios.png) | + +| Desktop | Web | +|---------------------------------------------------------------|-------------------------------------------------------| +| ![File Picker Desktop](images/AdaptiveFilePicker-desktop.png) | ![File Picker Web](images/AdaptiveFilePicker-web.png) | ```kotlin +val scope = rememberCoroutineScope() +val context = LocalPlatformContext.current + val pickerLauncher = rememberFilePickerLauncher( type = FilePickerFileType.Image, selectionMode = FilePickerSelectionMode.Single, onResult = { files -> - files.firstOrNull()?.let { file -> - // Do something with the selected file - // You can get the ByteArray of the file - file.readByteArray() + scope.launch { + files.firstOrNull()?.let { file -> + // Do something with the selected file + // You can get the ByteArray of the file + file.readByteArray(context) + } } } ) @@ -71,4 +81,85 @@ val type = FilePickerFileType.Custom( `FilePickerSelectionMode` allows you to specify the selection mode of the file picker: * `FilePickerSelectionMode.Single` - Allows you to pick a single file -* `FilePickerSelectionMode.Multiple` - Allows you to pick multiple files \ No newline at end of file +* `FilePickerSelectionMode.Multiple` - Allows you to pick multiple files + +#### Extensions + +* Read the `ByteArray` of the file using the `readByteArray` extension function: + +```kotlin +val context = LocalPlatformContext.current + +LaunchedEffect(file) { + val byteArray = file.readByteArray(context) +} +``` + +> The `readByteArray` extension function is a suspending function, so you need to call it from a coroutine scope. + +> It's not recommended to use `readByteArray` extension function on large files, as it reads the entire file into memory. +> For large files, it's recommended to use the platform-specific APIs to read the file. + +* Check if the file exists using the `exists` extension function: + +```kotlin +val context = LocalPlatformContext.current + +val exists = file.exists(context) +``` + +* Get the file name using the `getName` extension function: + +```kotlin +val context = LocalPlatformContext.current + +val name = file.getName(context) +``` + +* Get the file path using the `getPath` extension function: + +```kotlin +val context = LocalPlatformContext.current + +val path = file.getPath(context) +``` + +* Check if the file is a directory using the `isDirectory` extension function: + +```kotlin +val context = LocalPlatformContext.current + +val isDirectory = file.isDirectory(context) +``` + +* Check if the file is a file using the `isFile` extension function: + +```kotlin +val context = LocalPlatformContext.current + +val isFile = file.isFile(context) +``` + +#### Platform-specific APIs + +KmpFile is a wrapper around platform-specific APIs, so you can use the platform-specific APIs to read the file: + +##### Android +```kotlin +val uri: Uri = kmpFile.uri +``` + +##### iOS +```kotlin +val nsUrl: NSURL = kmpFile.nsUrl +``` + +##### Desktop +```kotlin +val file: java.io.File = kmpFile.file +``` + +##### Web +```kotlin +val file: org.w3c.files.File = kmpFile.file +``` diff --git a/docs/images/AdaptiveFilePicker-desktop.png b/docs/images/AdaptiveFilePicker-desktop.png new file mode 100644 index 0000000..6d333b9 Binary files /dev/null and b/docs/images/AdaptiveFilePicker-desktop.png differ diff --git a/docs/images/AdaptiveFilePicker-web.png b/docs/images/AdaptiveFilePicker-web.png new file mode 100644 index 0000000..ba45b8b Binary files /dev/null and b/docs/images/AdaptiveFilePicker-web.png differ diff --git a/docs/index.md b/docs/index.md index f09f1a2..50a53a0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -15,17 +15,17 @@ Calf stands for **C**ompose **A**daptive **L**ook & **F**eel ## Artifacts -| Artifact | Description | Platforms | Version | -|-----------------------|-------------------------------------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **calf-ui** | Adaptive UI components | Android, iOS, Desktop, Web | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-ui)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-ui%22) | -| **calf-file-picker** | Native File Picker wrapper | Android, iOS, Desktop, Web | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-file-picker)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-file-picker%22) | -| **calf-permissions** | API that allows you to handle permissions | Android, iOS | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-file-picker)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-file-picker%22) | -| **calf-geo** | API that allows you to access geolocation | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-navigation** | Native navigation wrapper | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-map** | Native Maps wrapper | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-media** | Video/Audio player | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-notification** | Notification manager | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | -| **calf-sf-symbols** | Apple SF Symbols icons | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| Artifact | Description | Platforms | Version | +|-----------------------|-------------------------------------------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **calf-ui** | Adaptive UI components | Android, iOS, Desktop, Web(Js, Wasm) | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-ui)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-ui%22) | +| **calf-file-picker** | Native File Picker wrapper | Android, iOS, Desktop, Web(Js, Wasm) | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-file-picker)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-file-picker%22) | +| **calf-permissions** | API that allows you to handle permissions | Android, iOS | [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-file-picker)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-file-picker%22) | +| **calf-geo** | API that allows you to access geolocation | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-navigation** | Native navigation wrapper | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-map** | Native Maps wrapper | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-media** | Video/Audio player | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-notification** | Notification manager | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | +| **calf-sf-symbols** | Apple SF Symbols icons | Coming soon... 🚧 🚧 | Coming soon... 🚧 🚧 | > The main focus for now is Android and iOS, but more Desktop components are coming that allows you to create adaptive UIs for Desktop as well (Windows, macOS, Linux) diff --git a/docs/installation.md b/docs/installation.md index 1231448..f8c57c2 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -2,17 +2,24 @@ [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-ui)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-ui%22) +| Kotlin version | Compose version | Calf version | +|----------------|-----------------|--------------| +| 1.9.22 | 1.6.0 | 0.4.0 | +| 1.9.21 | 1.5.11 | 0.3.1 | +| 1.9.20 | 1.5.10 | 0.2.0 | +| 1.9.0 | 1.5.0 | 0.1.1 | + Add the following dependencies to your module `build.gradle.kts` file: ```kotlin // For Adaptive UI components -api("com.mohamedrejeb.calf:calf-ui:0.3.1") +api("com.mohamedrejeb.calf:calf-ui:0.4.0") // For Adaptive FilePicker -implementation("com.mohamedrejeb.calf:calf-file-picker:0.3.1") +implementation("com.mohamedrejeb.calf:calf-file-picker:0.4.0") // For Permissions -implementation("com.mohamedrejeb.calf:calf-permissions:0.3.1") +implementation("com.mohamedrejeb.calf:calf-permissions:0.4.0") ``` If you are using `calf-ui` artifact, make sure to export it to binaries: @@ -28,7 +35,7 @@ kotlin { .forEach { it.binaries.framework { ... - export("com.mohamedrejeb.calf:calf-ui:0.3.1") + export("com.mohamedrejeb.calf:calf-ui:0.4.0") } } ... @@ -45,7 +52,7 @@ kotlin { ... framework { ... - export("com.mohamedrejeb.calf:calf-ui:0.3.1") + export("com.mohamedrejeb.calf:calf-ui:0.4.0") } } ... diff --git a/docs/permissions.md b/docs/permissions.md index 6f52524..a8b7651 100644 --- a/docs/permissions.md +++ b/docs/permissions.md @@ -7,7 +7,7 @@ Add the following dependency to your module `build.gradle.kts` file: ```kotlin -implementation("com.mohamedrejeb.calf:calf-permissions:0.3.1") +implementation("com.mohamedrejeb.calf:calf-permissions:0.4.0") ``` ## Usage diff --git a/docs/ui.md b/docs/ui.md index d985aad..11a1425 100644 --- a/docs/ui.md +++ b/docs/ui.md @@ -4,10 +4,17 @@ [![Maven Central](https://img.shields.io/maven-central/v/com.mohamedrejeb.calf/calf-ui)](https://search.maven.org/search?q=g:%22com.mohamedrejeb.calf%22%20AND%20a:%calf-ui%22) +| Kotlin version | Compose version | Calf version | +|----------------|-----------------|--------------| +| 1.9.22 | 1.6.0 | 0.4.0 | +| 1.9.21 | 1.5.11 | 0.3.1 | +| 1.9.20 | 1.5.10 | 0.2.0 | +| 1.9.0 | 1.5.0 | 0.1.1 | + Add the following dependency to your module `build.gradle.kts` file: ```kotlin -api("com.mohamedrejeb.calf:calf-ui:0.3.1") +api("com.mohamedrejeb.calf:calf-ui:0.4.0") ``` If you are using `calf-ui` artifact, make sure to export it to binaries: @@ -23,7 +30,7 @@ kotlin { .forEach { it.binaries.framework { ... - export("com.mohamedrejeb.calf:calf-ui:0.3.1") + export("com.mohamedrejeb.calf:calf-ui:0.4.0") } } ... @@ -40,7 +47,7 @@ kotlin { ... framework { ... - export("com.mohamedrejeb.calf:calf-ui:0.3.1") + export("com.mohamedrejeb.calf:calf-ui:0.4.0") } } ... diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d9255c4..1309a16 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,6 +7,7 @@ nexus-publish = "2.0.0-rc-1" documentfile = "1.0.1" conventionPlugin = "0.1.0" +calf = "0.4.0" # For sample compose-compiler = "1.5.4" @@ -41,6 +42,9 @@ documentfile = { module = "androidx.documentfile:documentfile", version.ref = "d # For sample activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activity-compose" } navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigation-compose" } +calf-ui = { module = "com.mohamedrejeb.calf:calf-ui", version.ref = "calf" } +calf-file-picker = { module = "com.mohamedrejeb.calf:calf-file-picker", version.ref = "calf" } +calf-permissions = { module = "com.mohamedrejeb.calf:calf-permissions", version.ref = "calf" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } diff --git a/sample/common/build.gradle.kts b/sample/common/build.gradle.kts index 62ef624..66c51a9 100644 --- a/sample/common/build.gradle.kts +++ b/sample/common/build.gradle.kts @@ -36,7 +36,7 @@ kotlin { isStatic = true // IMPORTANT: Exporting calf-ui is required for some functionalities to work - export(projects.calfUi) + export(libs.calf.ui) } } @@ -50,9 +50,9 @@ kotlin { // Calf // This is possible thanks to `enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")` // in `settings.gradle.kts - api(projects.calfUi) - implementation(projects.calfFilePicker) - implementation(projects.calfPermissions) + api(libs.calf.ui) + implementation(libs.calf.file.picker) + implementation(libs.calf.permissions) implementation(projects.calfNavigation) } } diff --git a/settings.gradle.kts b/settings.gradle.kts index dd5b3dd..16bf21c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,7 +37,7 @@ include( // Sample modules ":sample:android", ":sample:desktop", - ":sample:web", + ":sample:web-js", ":sample:web-wasm", ":sample:common", )