Removed unused classes
Using dagger for Retrofit2, OkHttp and Gson
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
sealed class Answer<out R> {
|
||||
data class Success<out T>(val data: T) : Answer<T>()
|
||||
data class Error(val errorString: String) : Answer<Nothing>()
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
data class Resource<out T> constructor(
|
||||
val status: Status,
|
||||
val responseData: T?,
|
||||
val message: String?
|
||||
) {
|
||||
|
||||
enum class Status {
|
||||
SUCCESS,
|
||||
ERROR,
|
||||
LOADING
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun <T> success(responseData: T?): Resource<T> =
|
||||
Resource(Status.SUCCESS, responseData, null)
|
||||
|
||||
fun <T> error(message: String?, responseBody: T? = null): Resource<T> =
|
||||
Resource(Status.ERROR, responseBody, message)
|
||||
|
||||
fun <T> loading(responseData: T? = null): Resource<T> =
|
||||
Resource(Status.LOADING, responseData, null)
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.meloda.fast.BuildConfig
|
||||
import com.meloda.fast.api.method.MessageMethodSetter
|
||||
import com.meloda.fast.api.method.MethodSetter
|
||||
import com.meloda.fast.api.method.UserMethodSetter
|
||||
import com.meloda.fast.api.network.ErrorCodes
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.asFlow
|
||||
import org.json.JSONArray
|
||||
@@ -55,13 +56,14 @@ object VKApi {
|
||||
try {
|
||||
checkError(json, url)
|
||||
} catch (ex: VKException) {
|
||||
if (ex.code == ErrorCodes.TOO_MANY_REQUESTS) {
|
||||
Timer().schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
execute(url, cls)
|
||||
}
|
||||
}, 1000)
|
||||
} else throw ex
|
||||
throw ex
|
||||
// if (ex.code == ErrorCodes.TOO_MANY_REQUESTS) {
|
||||
// Timer().schedule(object : TimerTask() {
|
||||
// override fun run() {
|
||||
// execute(url, cls)
|
||||
// }
|
||||
// }, 1000)
|
||||
// } else throw ex
|
||||
}
|
||||
|
||||
when (cls) {
|
||||
@@ -282,7 +284,7 @@ object VKApi {
|
||||
|
||||
val code = error.optInt("error_code", -1)
|
||||
val message = error.optString("error_msg", "")
|
||||
val e = VKException(url, message, code)
|
||||
// val e = VKException(url, message, code)
|
||||
|
||||
//TODO: add checking invalid session
|
||||
if (code == 5 && message.contains("invalid session")) {
|
||||
@@ -291,16 +293,16 @@ object VKApi {
|
||||
// })
|
||||
}
|
||||
|
||||
if (code == ErrorCodes.CAPTCHA_NEEDED) {
|
||||
e.captchaImg = error.optString("captcha_img")
|
||||
e.captchaSid = error.optString("captcha_sid")
|
||||
}
|
||||
// if (code == ErrorCodes.CAPTCHA_NEEDED) {
|
||||
// e.captchaImg = error.optString("captcha_img")
|
||||
// e.captchaSid = error.optString("captcha_sid")
|
||||
// }
|
||||
//
|
||||
// if (code == ErrorCodes.VALIDATION_REQUIRED) {
|
||||
// e.redirectUri = error.optString("redirect_uri")
|
||||
// }
|
||||
|
||||
if (code == ErrorCodes.VALIDATION_REQUIRED) {
|
||||
e.redirectUri = error.optString("redirect_uri")
|
||||
}
|
||||
|
||||
throw e
|
||||
// throw e
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,17 @@ package com.meloda.fast.api
|
||||
import android.util.Log
|
||||
import com.meloda.fast.BuildConfig
|
||||
import com.meloda.fast.UserConfig
|
||||
import com.meloda.fast.api.util.VKUtil
|
||||
import java.net.URLEncoder
|
||||
|
||||
object VKAuth {
|
||||
|
||||
private const val TAG = "VKM.VKAuth"
|
||||
|
||||
private const val settings = "notify," +
|
||||
object GrantType {
|
||||
const val PASSWORD = "password"
|
||||
}
|
||||
|
||||
const val scope = "notify," +
|
||||
"friends," +
|
||||
"photos," +
|
||||
"audio," +
|
||||
@@ -30,17 +33,25 @@ object VKAuth {
|
||||
fun getDirectAuthUrl(
|
||||
login: String,
|
||||
password: String,
|
||||
captchaSid: String? = null,
|
||||
captchaKey: String? = null
|
||||
) = "https://oauth.vk.com/token?grant_type=password&" +
|
||||
twoFa: Boolean = false,
|
||||
twoFaCode: String = "",
|
||||
captcha: Pair<String, String>? = null
|
||||
) = "https://oauth.vk.com/token?" +
|
||||
"grant_type=password&" +
|
||||
"client_id=${VKConstants.VK_APP_ID}&" +
|
||||
"scope=$settings&" +
|
||||
"client_secret=${VKConstants.VK_SECRET}&" +
|
||||
"username=$login&" +
|
||||
"password=$password" +
|
||||
(if (captchaSid == null || captchaKey == null) "" else "&captcha_sid=$captchaSid&captcha_key=$captchaKey") +
|
||||
"password=$password&" +
|
||||
"scope=$scope&" +
|
||||
"2fa_supported=1&" +
|
||||
"force_sms=${if (twoFa) "1" else "0"}" +
|
||||
(if (twoFa) "code=$twoFaCode" else "") +
|
||||
(if (captcha == null) "" else "&captcha_sid=${captcha.first}&captcha_key=${captcha.second}") +
|
||||
"&v=${URLEncoder.encode(VKApi.API_VERSION, "utf-8")}"
|
||||
|
||||
fun getSendSmsCodeUrl(sid: String) = "https://api.vk.com/method/auth.validatePhone?" +
|
||||
"sid=$sid&" +
|
||||
"&v=${URLEncoder.encode(VKApi.API_VERSION, "utf-8")}"
|
||||
|
||||
fun getOAuthUrl(settings: String) = "https://oauth.vk.com/authorize?" +
|
||||
"client_id=${UserConfig.FAST_APP_ID}&" +
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
import org.json.JSONObject
|
||||
import java.io.IOException
|
||||
|
||||
class VKException(var url: String = "", override var message: String = "", var code: Int) :
|
||||
IOException(message) {
|
||||
var captchaSid: String? = null
|
||||
var captchaImg: String? = null
|
||||
class VKException(var url: String = "", var description: String = "", var error: String) :
|
||||
IOException(description) {
|
||||
|
||||
var captcha: Pair<String, String>? = null
|
||||
var redirectUri: String? = null
|
||||
|
||||
var validationSid: String? = null
|
||||
|
||||
var json: JSONObject? = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "code: $code, message: $message"
|
||||
return "url: $url;\n\nerror: $error; description: $description;"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
import com.meloda.fast.api.model.response.GetConversationsResponse
|
||||
import retrofit2.http.Field
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface VKRepo {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(VKUrls.getConversations)
|
||||
suspend fun getAllChats(
|
||||
@Field("user_id") chatId: Int,
|
||||
@Field("token") token: String
|
||||
): Answer<GetConversationsResponse>
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
object VKUrls {
|
||||
|
||||
const val getConversations = "messages.getConversations"
|
||||
|
||||
}
|
||||
+17
-1
@@ -1,7 +1,8 @@
|
||||
package com.meloda.fast.api.util
|
||||
package com.meloda.fast.api
|
||||
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.api.model.*
|
||||
import com.meloda.fast.api.network.VKErrors
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.text.SimpleDateFormat
|
||||
@@ -12,6 +13,21 @@ object VKUtil {
|
||||
|
||||
private const val TAG = "VKUtil"
|
||||
|
||||
fun isValidationRequired(throwable: Throwable): Boolean {
|
||||
if (throwable !is VKException) return false
|
||||
return throwable.error == VKErrors.NEED_VALIDATION
|
||||
}
|
||||
|
||||
fun isCaptchaRequired(throwable: Throwable): Boolean {
|
||||
if (throwable !is VKException) return false
|
||||
return throwable.error == VKErrors.NEED_CAPTCHA
|
||||
}
|
||||
|
||||
fun extractValidationSid(throwable: Throwable): String? {
|
||||
if (throwable !is VKException) return null
|
||||
return throwable.json?.optString("validation_sid")
|
||||
}
|
||||
|
||||
fun extractPattern(string: String, pattern: String): String? {
|
||||
val p = Pattern.compile(pattern)
|
||||
val m = p.matcher(string)
|
||||
@@ -1,4 +0,0 @@
|
||||
package com.meloda.fast.api.datasource
|
||||
|
||||
class MessagesDataSource constructor() {
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package com.meloda.fast.api.datasource.base
|
||||
|
||||
import android.util.Log
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import com.meloda.fast.api.Resource
|
||||
import com.meloda.fast.api.model.ApiResponse
|
||||
import com.meloda.fast.api.ErrorCodes
|
||||
import com.meloda.fast.api.VKException
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.HttpException
|
||||
|
||||
class BaseDataSource {
|
||||
|
||||
private val TAG = BaseDataSource::class.simpleName
|
||||
|
||||
//TODO: move to resources
|
||||
private val DEFAULT_ERROR = "Internal server error"
|
||||
|
||||
protected suspend fun <T> getResult(apiCall: suspend () -> ApiResponse<T>): Resource<T> {
|
||||
try {
|
||||
val response = apiCall()
|
||||
return if (response.isSuccessful) {
|
||||
Resource.success(response.response)
|
||||
} else {
|
||||
Log.d(TAG, "Server response unsuccessful")
|
||||
if (response.error != null) {
|
||||
Log.w(TAG, "Unsuccessful response with code 2XX")
|
||||
Resource.error(response.error.message, response.response)
|
||||
} else {
|
||||
Log.e(TAG, "Unsuccessful result without error!")
|
||||
Resource.error(DEFAULT_ERROR)
|
||||
}
|
||||
}
|
||||
} catch (e: HttpException) {
|
||||
Log.e(TAG, "Error while executing request ${e.message}")
|
||||
val errorBody = e.response()?.errorBody() ?: return Resource.error(DEFAULT_ERROR)
|
||||
val errorResponse = parseErrorBody<T>(errorBody) ?: return Resource.error(DEFAULT_ERROR)
|
||||
|
||||
return Resource.error(errorResponse.message)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Error while executing request ${e.message}")
|
||||
|
||||
return Resource.error(DEFAULT_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> parseErrorBody(responseBody: ResponseBody?): Exception? {
|
||||
if (responseBody == null) return null
|
||||
|
||||
val jsonResponse: JsonObject?
|
||||
try {
|
||||
jsonResponse = JsonParser.parseString(responseBody.string()) as? JsonObject
|
||||
if (jsonResponse == null) {
|
||||
Log.d(TAG, "Response body is empty while parsing error body.")
|
||||
return null
|
||||
}
|
||||
} catch (e: JsonSyntaxException) {
|
||||
Log.e(TAG, "Error while parsing json ${e.message}")
|
||||
return null
|
||||
} catch (e: java.lang.Exception) {
|
||||
Log.e(TAG, "Unknown error ${e.message}")
|
||||
return null
|
||||
}
|
||||
|
||||
if (jsonResponse.has("error")) {
|
||||
val error = jsonResponse["error"].asJsonObject
|
||||
|
||||
val message = error["error_msg"].asString
|
||||
val code = error["error_code"].asInt
|
||||
|
||||
val e = VKException("", message, code)
|
||||
|
||||
//TODO: add checking invalid session
|
||||
if (code == 5 && message.contains("invalid session")) {
|
||||
// context?.startActivity(Intent(context, DropUserDataActivity::class.java).apply {
|
||||
// addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
// })
|
||||
}
|
||||
|
||||
if (code == ErrorCodes.CAPTCHA_NEEDED) {
|
||||
e.captchaImg = error["captcha_img"].asString
|
||||
e.captchaSid = error["captcha_sid"].asString
|
||||
}
|
||||
|
||||
if (code == ErrorCodes.VALIDATION_REQUIRED) {
|
||||
e.redirectUri = error["redirect_uri"].asString
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.meloda.fast.api.model
|
||||
|
||||
data class ApiResponse<T> constructor(
|
||||
val isSuccessful: Boolean,
|
||||
val error: Error?,
|
||||
val response: T?
|
||||
)
|
||||
|
||||
data class Error constructor(
|
||||
val code: Long,
|
||||
val message: String
|
||||
)
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.meloda.fast.api.model
|
||||
|
||||
import android.util.ArrayMap
|
||||
import com.meloda.fast.api.util.VKUtil
|
||||
import com.meloda.fast.api.VKUtil
|
||||
import org.json.JSONObject
|
||||
|
||||
open class VKMessage() : VKModel() {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.meloda.fast.api.network
|
||||
|
||||
import com.meloda.fast.api.VKApi
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import java.net.URLEncoder
|
||||
|
||||
class AuthInterceptor : Interceptor {
|
||||
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val builder = chain.request().url.newBuilder()
|
||||
.addQueryParameter("v", URLEncoder.encode(VKApi.API_VERSION, "utf-8"))
|
||||
return chain.proceed(chain.request().newBuilder().apply { url(builder.build()) }.build())
|
||||
|
||||
}
|
||||
}
|
||||
+10
-1
@@ -1,4 +1,4 @@
|
||||
package com.meloda.fast.api
|
||||
package com.meloda.fast.api.network
|
||||
|
||||
object ErrorCodes {
|
||||
const val UNKNOWN_ERROR = 1
|
||||
@@ -39,4 +39,13 @@ object ErrorCodes {
|
||||
const val INVALID_DOC_ID = 1150
|
||||
const val INVALID_DOC_TITLE = 1152
|
||||
const val ACCESS_TO_DOC_DENIED = 1153
|
||||
}
|
||||
|
||||
object VKErrors {
|
||||
const val UNKNOWN = "unknown_error"
|
||||
|
||||
const val NEED_VALIDATION = "need_validation"
|
||||
const val NEED_CAPTCHA = "need_captcha"
|
||||
const val INVALID_REQUEST = "invalid_request"
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package com.meloda.fast.api.network
|
||||
|
||||
import android.util.Log
|
||||
import com.meloda.fast.api.VKException
|
||||
import okhttp3.Request
|
||||
import okio.IOException
|
||||
import okio.Timeout
|
||||
import org.json.JSONObject
|
||||
import retrofit2.*
|
||||
import java.lang.reflect.ParameterizedType
|
||||
import java.lang.reflect.Type
|
||||
|
||||
class ResultCallFactory : CallAdapter.Factory() {
|
||||
override fun get(
|
||||
returnType: Type,
|
||||
annotations: Array<out Annotation>,
|
||||
retrofit: Retrofit
|
||||
): CallAdapter<*, *>? {
|
||||
val rawReturnType: Class<*> = getRawType(returnType)
|
||||
if (rawReturnType == Call::class.java) {
|
||||
if (returnType is ParameterizedType) {
|
||||
val callInnerType: Type = getParameterUpperBound(0, returnType)
|
||||
if (getRawType(callInnerType) == Answer::class.java) {
|
||||
if (callInnerType is ParameterizedType) {
|
||||
val resultInnerType = getParameterUpperBound(0, callInnerType)
|
||||
return ResultCallAdapter<Any?>(resultInnerType)
|
||||
}
|
||||
return ResultCallAdapter<Nothing>(Nothing::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class CallDelegate<In, Out>(protected val proxy: Call<In>) : Call<Out> {
|
||||
|
||||
override fun execute(): Response<Out> = throw NotImplementedError()
|
||||
|
||||
final override fun enqueue(callback: Callback<Out>) = enqueueImpl(callback)
|
||||
|
||||
final override fun clone(): Call<Out> = cloneImpl()
|
||||
|
||||
override fun cancel() = proxy.cancel()
|
||||
|
||||
override fun request(): Request = proxy.request()
|
||||
|
||||
override fun isExecuted() = proxy.isExecuted
|
||||
|
||||
override fun isCanceled() = proxy.isCanceled
|
||||
|
||||
abstract fun enqueueImpl(callback: Callback<Out>)
|
||||
|
||||
abstract fun cloneImpl(): Call<Out>
|
||||
}
|
||||
|
||||
private class ResultCallAdapter<R>(private val type: Type) : CallAdapter<R, Call<Answer<R>>> {
|
||||
|
||||
override fun responseType() = type
|
||||
|
||||
override fun adapt(call: Call<R>): Call<Answer<R>> = ResultCall(call)
|
||||
}
|
||||
|
||||
internal class ResultCall<T>(proxy: Call<T>) : CallDelegate<T, Answer<T>>(proxy) {
|
||||
|
||||
override fun enqueueImpl(callback: Callback<Answer<T>>) {
|
||||
proxy.enqueue(ResultCallback(this, callback))
|
||||
}
|
||||
|
||||
override fun cloneImpl(): ResultCall<T> {
|
||||
return ResultCall(proxy.clone())
|
||||
}
|
||||
|
||||
private class ResultCallback<T>(
|
||||
private val proxy: ResultCall<T>,
|
||||
private val callback: Callback<Answer<T>>
|
||||
) : Callback<T> {
|
||||
|
||||
// TODO: 8/31/2021 parse VK errors
|
||||
override fun onResponse(call: Call<T>, response: Response<T>) {
|
||||
val result: Answer<T> = if (response.isSuccessful)
|
||||
Answer.Success(response.body() as T)
|
||||
else Answer.Error(IOException(response.errorBody()?.string() ?: ""))
|
||||
|
||||
if (result is Answer.Error) if (checkErrors(call, result)) return
|
||||
|
||||
callback.onResponse(proxy, Response.success(result))
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<T>, error: Throwable) {
|
||||
callback.onResponse(
|
||||
proxy,
|
||||
Response.success(Answer.Error(throwable = error))
|
||||
)
|
||||
}
|
||||
|
||||
private fun checkErrors(call: Call<T>, result: Answer.Error): Boolean {
|
||||
val json = JSONObject(result.throwable.message ?: "{}")
|
||||
|
||||
return if (json.has("error")) {
|
||||
val error = json.optString("error", "")
|
||||
val description = json.optString("error_description", "")
|
||||
|
||||
val exception = VKException(
|
||||
error = error,
|
||||
description = description,
|
||||
).also { it.json = json }
|
||||
|
||||
onFailure(call, exception)
|
||||
true
|
||||
} else false
|
||||
}
|
||||
}
|
||||
|
||||
override fun timeout(): Timeout {
|
||||
return proxy.timeout()
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Answer<out R> {
|
||||
|
||||
data class Success<out T>(val data: T) : Answer<T>()
|
||||
data class Error(val throwable: Throwable) : Answer<Nothing>()
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.meloda.fast.api.network
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.meloda.fast.api.network.datasource.AuthDataSource
|
||||
import com.meloda.fast.api.network.repo.AuthRepo
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Singleton
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
class VKModules {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideOkHttpClient(authInterceptor: AuthInterceptor): OkHttpClient = OkHttpClient.Builder()
|
||||
.connectTimeout(20, TimeUnit.SECONDS)
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.writeTimeout(20, TimeUnit.SECONDS)
|
||||
.addInterceptor(authInterceptor)
|
||||
.followRedirects(true)
|
||||
.followSslRedirects(true)
|
||||
.addInterceptor(HttpLoggingInterceptor().apply {
|
||||
level = HttpLoggingInterceptor.Level.BODY
|
||||
}).build()
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGson(): Gson = GsonBuilder()
|
||||
.setLenient()
|
||||
.create()
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideRetrofit(
|
||||
client: OkHttpClient,
|
||||
gson: Gson
|
||||
): Retrofit = Retrofit.Builder()
|
||||
.baseUrl("https://api.vk.com/")
|
||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||
.addCallAdapterFactory(ResultCallFactory())
|
||||
.client(client)
|
||||
.build()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideAuthInterceptor(): AuthInterceptor = AuthInterceptor()
|
||||
|
||||
@Provides
|
||||
fun provideAuthRepo(retrofit: Retrofit): AuthRepo =
|
||||
retrofit.create(AuthRepo::class.java)
|
||||
|
||||
@Provides
|
||||
fun provideAuthDataSource(repo: AuthRepo): AuthDataSource =
|
||||
AuthDataSource(repo)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.meloda.fast.api.network
|
||||
|
||||
object VKUrls {
|
||||
|
||||
object Auth {
|
||||
const val directAuth = "https://oauth.vk.com/token"
|
||||
}
|
||||
|
||||
object Conversations {
|
||||
const val get = "messages.getConversations"
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.meloda.fast.api.network.datasource
|
||||
|
||||
import com.meloda.fast.api.network.repo.AuthRepo
|
||||
import javax.inject.Inject
|
||||
|
||||
class AuthDataSource @Inject constructor(
|
||||
private val repo: AuthRepo
|
||||
) : AuthRepo {
|
||||
override suspend fun auth(param: Map<String, String?>) = repo.auth(param)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.meloda.fast.api.network.repo
|
||||
|
||||
import com.meloda.fast.api.network.VKUrls
|
||||
import com.meloda.fast.api.network.response.ResponseAuthDirect
|
||||
import com.meloda.fast.api.network.Answer
|
||||
import retrofit2.http.*
|
||||
|
||||
interface AuthRepo {
|
||||
|
||||
@GET(VKUrls.Auth.directAuth)
|
||||
suspend fun auth(@QueryMap param: Map<String, String?>): Answer<ResponseAuthDirect>
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.meloda.fast.api.network.repo
|
||||
|
||||
import com.meloda.fast.api.network.Answer
|
||||
import com.meloda.fast.api.network.VKUrls
|
||||
import com.meloda.fast.api.network.response.GetConversationsResponse
|
||||
import retrofit2.http.*
|
||||
|
||||
interface ConversationsRepo {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST(VKUrls.Conversations.get)
|
||||
suspend fun getAllChats(
|
||||
@Field("user_id") chatId: Int,
|
||||
@Field("token") token: String
|
||||
): Answer<GetConversationsResponse>
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.meloda.fast.api.network.request
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class RequestAuthDirect(
|
||||
@SerializedName("grant_type") val grantType: String,
|
||||
@SerializedName("client_id") val clientId: String,
|
||||
@SerializedName("client_secret") val clientSecret: String,
|
||||
@SerializedName("username") val username: String,
|
||||
@SerializedName("password") val password: String,
|
||||
@SerializedName("scope") val scope: String,
|
||||
@SerializedName("2fa_supported") val twoFaSupported: Boolean = true,
|
||||
@SerializedName("force_sms") val twoFaForceSms: Boolean = false,
|
||||
@SerializedName("code") val twoFaCode: String? = null,
|
||||
@SerializedName("captcha_sid") val captchaSid: String? = null,
|
||||
@SerializedName("captcha_key") val captchaKey: String? = null,
|
||||
) : Parcelable {
|
||||
val map
|
||||
get() = mutableMapOf(
|
||||
"grant_type" to grantType,
|
||||
"client_id" to clientId,
|
||||
"client_secret" to clientSecret,
|
||||
"username" to username,
|
||||
"password" to password,
|
||||
"scope" to scope,
|
||||
"2fa_supported" to if (twoFaSupported) "1" else "0",
|
||||
"force_sms" to if (twoFaForceSms) "1" else "0"
|
||||
)
|
||||
.apply {
|
||||
twoFaCode?.let { this["code"] = it }
|
||||
captchaSid?.let { this["captcha_sid"] = it }
|
||||
captchaKey?.let { this["captcha_key"] = it }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
package com.meloda.fast.api.network.request
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.meloda.fast.api.model.request
|
||||
package com.meloda.fast.api.network.request
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.meloda.fast.api.network.response
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class ResponseAuthDirect(
|
||||
@SerializedName("access_token") val accessToken: String? = null,
|
||||
@SerializedName("user_id") val userId: Int? = null,
|
||||
@SerializedName("trusted_hash") val twoFaHash: String? = null,
|
||||
@SerializedName("validation_sid") val validationSid: String? = null
|
||||
) : Parcelable
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.meloda.fast.api.model.response
|
||||
package com.meloda.fast.api.network.response
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.meloda.fast.api.service
|
||||
|
||||
import com.meloda.fast.api.model.ApiResponse
|
||||
import com.meloda.fast.api.model.request.RequestMessagesGetConversations
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.QueryMap
|
||||
|
||||
interface MessagesService {
|
||||
|
||||
@GET("messages.getConversations")
|
||||
suspend fun getConversations(@QueryMap params: RequestMessagesGetConversations): ApiResponse<Map<String, Any>>
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user