Skip to content

Commit

Permalink
Merge pull request #68 from appwrite/dev
Browse files Browse the repository at this point in the history
fix: pong response & chunked upload
  • Loading branch information
abnegate authored Jan 29, 2025
2 parents 19bb779 + 645f2a2 commit bb6671d
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 33 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2024 Appwrite (https://appwrite.io) and individual contributors.
Copyright (c) 2025 Appwrite (https://appwrite.io) and individual contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

![Maven Central](https://img.shields.io/maven-central/v/io.appwrite/sdk-for-android.svg?color=green&style=flat-square)
![License](https://img.shields.io/github/license/appwrite/sdk-for-android.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.6.0-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.6.1-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
Expand Down Expand Up @@ -38,7 +38,7 @@ repositories {
Next, add the dependency to your project's `build.gradle(.kts)` file:

```groovy
implementation("io.appwrite:sdk-for-android:6.1.0")
implementation("io.appwrite:sdk-for-android:7.0.0")
```

### Maven
Expand All @@ -49,7 +49,7 @@ Add this to your project's `pom.xml` file:
<dependency>
<groupId>io.appwrite</groupId>
<artifactId>sdk-for-android</artifactId>
<version>6.1.0</version>
<version>7.0.0</version>
</dependency>
</dependencies>
```
Expand Down
65 changes: 46 additions & 19 deletions library/src/main/java/io/appwrite/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Client @JvmOverloads constructor(
internal lateinit var http: OkHttpClient

internal val headers: MutableMap<String, String>

val config: MutableMap<String, String>

internal val cookieJar = ListenableCookieJar(CookieManager(
Expand All @@ -86,11 +86,11 @@ class Client @JvmOverloads constructor(
"x-sdk-name" to "Android",
"x-sdk-platform" to "client",
"x-sdk-language" to "android",
"x-sdk-version" to "6.1.0",
"x-sdk-version" to "7.0.0",
"x-appwrite-response-format" to "1.6.0"
)
config = mutableMapOf()

setSelfSigned(selfSigned)
}

Expand Down Expand Up @@ -154,10 +154,10 @@ class Client @JvmOverloads constructor(

/**
* Set self Signed
*
*
* @param status
*
* @return this
* @return this
*/
fun setSelfSigned(status: Boolean): Client {
selfSigned = status
Expand Down Expand Up @@ -206,10 +206,10 @@ class Client @JvmOverloads constructor(

/**
* Set endpoint and realtime endpoint.
*
*
* @param endpoint
*
* @return this
* @return this
*/
fun setEndpoint(endpoint: String): Client {
this.endpoint = endpoint
Expand All @@ -235,32 +235,51 @@ class Client @JvmOverloads constructor(

/**
* Add Header
*
*
* @param key
* @param value
*
* @return this
* @return this
*/
fun addHeader(key: String, value: String): Client {
headers[key] = value
return this
}

/**
* Sends a "ping" request to Appwrite to verify connectivity.
*
* @return String
*/
suspend fun ping(): String {
val apiPath = "/ping"
val apiParams = mutableMapOf<String, Any?>()
val apiHeaders = mutableMapOf("content-type" to "application/json")

return call(
"GET",
apiPath,
apiHeaders,
apiParams,
responseType = String::class.java
)
}

/**
* Send the HTTP request
*
*
* @param method
* @param path
* @param headers
* @param params
*
* @return [T]
* @return [T]
*/
@Throws(AppwriteException::class)
suspend fun <T> call(
method: String,
path: String,
headers: Map<String, String> = mapOf(),
method: String,
path: String,
headers: Map<String, String> = mapOf(),
params: Map<String, Any?> = mapOf(),
responseType: Class<T>,
converter: ((Any) -> T)? = null
Expand Down Expand Up @@ -398,7 +417,7 @@ class Client @JvmOverloads constructor(
var offset = 0L
var result: Map<*, *>? = null

if (idParamName?.isNotEmpty() == true && params[idParamName] != "unique()") {
if (idParamName?.isNotEmpty() == true) {
// Make a request to check if a file already exists
val current = call(
method = "GET",
Expand Down Expand Up @@ -495,14 +514,14 @@ class Client @JvmOverloads constructor(
.charStream()
.buffered()
.use(BufferedReader::readText)

val error = if (response.headers["content-type"]?.contains("application/json") == true) {
val map = body.fromJson<Map<String, Any>>()

AppwriteException(
map["message"] as? String ?: "",
map["message"] as? String ?: "",
(map["code"] as Number).toInt(),
map["type"] as? String ?: "",
map["type"] as? String ?: "",
body
)
} else {
Expand All @@ -524,6 +543,14 @@ class Client @JvmOverloads constructor(
it.resume(true as T)
return
}
responseType == String::class.java -> {
val body = response.body!!
.charStream()
.buffered()
.use(BufferedReader::readText)
it.resume(body as T)
return
}
responseType == ByteArray::class.java -> {
it.resume(response.body!!
.byteStream()
Expand Down Expand Up @@ -554,4 +581,4 @@ class Client @JvmOverloads constructor(
}
})
}
}
}
2 changes: 2 additions & 0 deletions library/src/main/java/io/appwrite/enums/ImageFormat.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ enum class ImageFormat(val value: String) {
PNG("png"),
@SerializedName("webp")
WEBP("webp"),
@SerializedName("heic")
HEIC("heic"),
@SerializedName("avif")
AVIF("avif");

Expand Down
2 changes: 1 addition & 1 deletion library/src/main/java/io/appwrite/models/RealtimeModels.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ data class RealtimeCallback(

open class RealtimeResponse(
val type: String,
val data: Any
val data: Any?
)

data class RealtimeResponseEvent<T>(
Expand Down
19 changes: 12 additions & 7 deletions library/src/main/java/io/appwrite/services/Account.kt
Original file line number Diff line number Diff line change
Expand Up @@ -529,12 +529,12 @@ class Account(client: Client) : Service(client) {
*
* @param challengeId ID of the challenge.
* @param otp Valid verification token.
* @return [Any]
* @return [io.appwrite.models.Session]
*/
suspend fun updateMfaChallenge(
challengeId: String,
otp: String,
): Any {
): io.appwrite.models.Session {
val apiPath = "/account/mfa/challenge"

val apiParams = mutableMapOf<String, Any?>(
Expand All @@ -544,12 +544,17 @@ class Account(client: Client) : Service(client) {
val apiHeaders = mutableMapOf(
"content-type" to "application/json",
)
val converter: (Any) -> io.appwrite.models.Session = {
@Suppress("UNCHECKED_CAST")
io.appwrite.models.Session.from(map = it as Map<String, Any>)
}
return client.call(
"PUT",
apiPath,
apiHeaders,
apiParams,
responseType = Any::class.java,
responseType = io.appwrite.models.Session::class.java,
converter,
)
}

Expand Down Expand Up @@ -1467,7 +1472,7 @@ class Account(client: Client) : Service(client) {
/**
* Create push target
*
*
* Use this endpoint to register a device for push notifications. Provide a target ID (custom or generated using ID.unique()), a device identifier (usually a device token), and optionally specify which provider should send notifications to this target. The target is automatically linked to the current session and includes device information like brand and model.
*
* @param targetId Target ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.
* @param identifier The target identifier (token, email, phone etc.)
Expand Down Expand Up @@ -1508,7 +1513,7 @@ class Account(client: Client) : Service(client) {
/**
* Update push target
*
*
* Update the currently logged in user&#039;s push notification target. You can modify the target&#039;s identifier (device token) and provider ID (token, email, phone etc.). The target must exist and belong to the current user. If you change the provider ID, notifications will be sent through the new messaging provider instead.
*
* @param targetId Target ID.
* @param identifier The target identifier (token, email, phone etc.)
Expand Down Expand Up @@ -1545,7 +1550,7 @@ class Account(client: Client) : Service(client) {
/**
* Delete push target
*
*
* Delete a push notification target for the currently logged in user. After deletion, the device will no longer receive push notifications. The target must exist and belong to the current user.
*
* @param targetId Target ID.
* @return [Any]
Expand Down Expand Up @@ -1615,7 +1620,7 @@ class Account(client: Client) : Service(client) {
/**
* Create magic URL token
*
* Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The link sent to the user&#039;s email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits).
* Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to submit a request to the [POST /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process. The link sent to the user&#039;s email address is valid for 1 hour.A user is limited to 10 active sessions at a time by default. [Learn more about session limits](https://appwrite.io/docs/authentication-security#limits).
*
* @param userId Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.
* @param email User email.
Expand Down
5 changes: 3 additions & 2 deletions library/src/main/java/io/appwrite/services/Realtime.kt
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,17 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
when (message.type) {
TYPE_ERROR -> handleResponseError(message)
TYPE_EVENT -> handleResponseEvent(message)
TYPE_PONG -> {}
}
}
}

private fun handleResponseError(message: RealtimeResponse) {
throw message.data.jsonCast<AppwriteException>()
throw message.data?.jsonCast<AppwriteException>() ?: RuntimeException("Data is not present")
}

private suspend fun handleResponseEvent(message: RealtimeResponse) {
val event = message.data.jsonCast<RealtimeResponseEvent<Any>>()
val event = message.data?.jsonCast<RealtimeResponseEvent<Any>>() ?: return
if (event.channels.isEmpty()) {
return
}
Expand Down

0 comments on commit bb6671d

Please sign in to comment.