Removed unused resources
refactoring unread messages view unread counter avatar in toolbar
This commit is contained in:
@@ -27,10 +27,6 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".service.LongPollService"
|
||||
android:enabled="true" />
|
||||
|
||||
<receiver
|
||||
android:name=".receiver.MinuteReceiver"
|
||||
android:enabled="true"
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
import com.meloda.fast.api.loader.UsersLoader
|
||||
|
||||
object LoadManager {
|
||||
|
||||
val users = UsersLoader()
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.meloda.fast.api.model.VkUser
|
||||
import com.meloda.fast.common.AppGlobal
|
||||
|
||||
@@ -31,6 +32,6 @@ object UserConfig {
|
||||
|
||||
fun isLoggedIn() = userId > 0 && accessToken.isNotBlank()
|
||||
|
||||
var vkUser: VkUser? = null
|
||||
val vkUser = MutableLiveData<VkUser?>(null)
|
||||
|
||||
}
|
||||
@@ -1,16 +1,30 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.api.model.VkGroup
|
||||
import com.meloda.fast.api.model.VkGroupCall
|
||||
import com.meloda.fast.api.model.VkMessage
|
||||
import com.meloda.fast.api.model.VkUser
|
||||
import com.meloda.fast.api.model.attachments.*
|
||||
import com.meloda.fast.api.model.base.BaseVkMessage
|
||||
import com.meloda.fast.api.model.base.attachments.BaseVkAttachmentItem
|
||||
import com.meloda.fast.api.network.VKErrors
|
||||
|
||||
object VkUtils {
|
||||
|
||||
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 parseForwards(baseForwards: List<BaseVkMessage>?): List<VkMessage>? {
|
||||
if (baseForwards.isNullOrEmpty()) return null
|
||||
|
||||
@@ -114,6 +128,12 @@ object VkUtils {
|
||||
initiatorId = call.initiatorId
|
||||
)
|
||||
}
|
||||
BaseVkAttachmentItem.AttachmentType.GROUP_CALL_IN_PROGRESS -> {
|
||||
val groupCall = baseAttachment.groupCall ?: continue
|
||||
attachments += VkGroupCall(
|
||||
initiatorId = groupCall.initiatorId
|
||||
)
|
||||
}
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
@@ -315,6 +335,52 @@ object VkUtils {
|
||||
}
|
||||
}
|
||||
|
||||
fun getAttachmentConversationIcon(context: Context, message: VkMessage): Drawable? {
|
||||
message.geoType?.let {
|
||||
return ContextCompat.getDrawable(context, R.drawable.ic_map_marker)
|
||||
}
|
||||
|
||||
if (message.attachments.isNullOrEmpty()) return null
|
||||
|
||||
return message.attachments?.let { attachments ->
|
||||
if (attachments.size == 1 || isAttachmentsHaveOneType(attachments)) {
|
||||
getAttachmentTypeByClass(attachments[0])?.let {
|
||||
getAttachmentIconByType(
|
||||
context,
|
||||
it
|
||||
)
|
||||
}
|
||||
} else {
|
||||
ContextCompat.getDrawable(context, R.drawable.ic_baseline_attach_file_24)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAttachmentIconByType(
|
||||
context: Context,
|
||||
attachmentType: BaseVkAttachmentItem.AttachmentType
|
||||
): Drawable? {
|
||||
val resId = when (attachmentType) {
|
||||
BaseVkAttachmentItem.AttachmentType.PHOTO -> R.drawable.ic_attachment_photo
|
||||
BaseVkAttachmentItem.AttachmentType.VIDEO -> R.drawable.ic_attachment_video
|
||||
BaseVkAttachmentItem.AttachmentType.AUDIO -> R.drawable.ic_attachment_audio
|
||||
BaseVkAttachmentItem.AttachmentType.FILE -> R.drawable.ic_attachment_file
|
||||
BaseVkAttachmentItem.AttachmentType.LINK -> R.drawable.ic_attachment_link
|
||||
BaseVkAttachmentItem.AttachmentType.VOICE -> R.drawable.ic_attachment_voice
|
||||
BaseVkAttachmentItem.AttachmentType.MINI_APP -> R.drawable.ic_attachment_mini_app
|
||||
BaseVkAttachmentItem.AttachmentType.STICKER -> R.drawable.ic_attachment_sticker
|
||||
BaseVkAttachmentItem.AttachmentType.GIFT -> R.drawable.ic_attachment_gift
|
||||
BaseVkAttachmentItem.AttachmentType.WALL -> R.drawable.ic_attachment_wall
|
||||
BaseVkAttachmentItem.AttachmentType.GRAFFITI -> R.drawable.ic_attachment_graffiti
|
||||
BaseVkAttachmentItem.AttachmentType.POLL -> R.drawable.ic_attachment_poll
|
||||
BaseVkAttachmentItem.AttachmentType.WALL_REPLY -> R.drawable.ic_attachment_wall_reply
|
||||
BaseVkAttachmentItem.AttachmentType.CALL -> R.drawable.ic_attachment_call
|
||||
BaseVkAttachmentItem.AttachmentType.GROUP_CALL_IN_PROGRESS -> R.drawable.ic_attachment_group_call
|
||||
}
|
||||
|
||||
return ContextCompat.getDrawable(context, resId)
|
||||
}
|
||||
|
||||
fun isAttachmentsHaveOneType(attachments: List<VkAttachment>): Boolean {
|
||||
if (attachments.isEmpty()) return true
|
||||
if (attachments.size == 1) return true
|
||||
@@ -344,6 +410,7 @@ object VkUtils {
|
||||
is VkPoll -> BaseVkAttachmentItem.AttachmentType.POLL
|
||||
is VkWallReply -> BaseVkAttachmentItem.AttachmentType.WALL_REPLY
|
||||
is VkCall -> BaseVkAttachmentItem.AttachmentType.CALL
|
||||
is VkGroupCall -> BaseVkAttachmentItem.AttachmentType.GROUP_CALL_IN_PROGRESS
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.meloda.fast.api.loader
|
||||
|
||||
abstract class Loader<T> {
|
||||
|
||||
abstract suspend fun load(params: MutableMap<String, Any>): List<T>
|
||||
abstract suspend fun loadSingle(params: MutableMap<String, Any>): T
|
||||
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package com.meloda.fast.api.loader
|
||||
|
||||
import com.meloda.fast.api.model.VkUser
|
||||
|
||||
class UsersLoader : Loader<VkUser>() {
|
||||
|
||||
suspend fun load(
|
||||
usersIds: List<Int>,
|
||||
fields: String = ""
|
||||
) = load(
|
||||
mutableMapOf(
|
||||
"usersIds" to usersIds.joinToString { it.toString() },
|
||||
"fields" to fields
|
||||
)
|
||||
)
|
||||
|
||||
override suspend fun load(params: MutableMap<String, Any>): List<VkUser> {
|
||||
val usersIds: String = params["usersIds"] as String
|
||||
val fields: String = params["fields"] as String
|
||||
|
||||
// val users = repo.getById(
|
||||
// UsersGetRequest(
|
||||
// usersIds = usersIds.split(",").map { it.toInt() },
|
||||
// fields = fields
|
||||
// )
|
||||
// )
|
||||
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override suspend fun loadSingle(params: MutableMap<String, Any>): VkUser {
|
||||
return load(params)[0]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,14 @@ data class VkConversation(
|
||||
val title: String?,
|
||||
val photo200: String?,
|
||||
val type: String,
|
||||
val callInProgress: Boolean
|
||||
val callInProgress: Boolean,
|
||||
val isPhantom: Boolean,
|
||||
val lastConversationMessageId: Int,
|
||||
val inRead: Int,
|
||||
val outRead: Int,
|
||||
val isMarkedUnread: Boolean,
|
||||
val lastMessageId: Int,
|
||||
val unreadCount: Int?
|
||||
) {
|
||||
@Ignore
|
||||
var lastMessage: VkMessage? = null
|
||||
@@ -20,4 +27,9 @@ data class VkConversation(
|
||||
fun isUser() = type == "user"
|
||||
fun isGroup() = type == "group"
|
||||
|
||||
fun isInUnread() = inRead != lastMessageId
|
||||
fun isOutUnread() = outRead != lastMessageId
|
||||
|
||||
fun isUnread() = isInUnread() || isOutUnread()
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.meloda.fast.api.model
|
||||
|
||||
import com.meloda.fast.api.model.attachments.VkAttachment
|
||||
|
||||
data class VkGroupCall(
|
||||
val initiatorId: Int
|
||||
) : VkAttachment()
|
||||
@@ -33,7 +33,9 @@ data class BaseVkConversation(
|
||||
@SerializedName("chat_settings")
|
||||
val chatSettings: ChatSettings?,
|
||||
@SerializedName("call_in_progress")
|
||||
val callInProgress: CallInProgress?
|
||||
val callInProgress: CallInProgress?,
|
||||
@SerializedName("unread_count")
|
||||
val unreadCount: Int?
|
||||
) : Parcelable {
|
||||
|
||||
fun asVkConversation(lastMessage: VkMessage? = null) = VkConversation(
|
||||
@@ -41,7 +43,14 @@ data class BaseVkConversation(
|
||||
title = chatSettings?.title,
|
||||
photo200 = chatSettings?.photo?.photo200,
|
||||
type = peer.type,
|
||||
callInProgress = callInProgress != null
|
||||
callInProgress = callInProgress != null,
|
||||
isPhantom = chatSettings?.isDisappearing == true,
|
||||
lastConversationMessageId = lastConversationMessageId,
|
||||
inRead = inRead,
|
||||
outRead = outRead,
|
||||
isMarkedUnread = isMarkedUnread,
|
||||
lastMessageId = lastMessageId,
|
||||
unreadCount = unreadCount
|
||||
).apply { this.lastMessage = lastMessage }
|
||||
|
||||
@Parcelize
|
||||
|
||||
+5
-2
@@ -24,7 +24,9 @@ data class BaseVkAttachmentItem(
|
||||
val poll: BaseVkPoll?,
|
||||
@SerializedName("wall_reply")
|
||||
val wallReply: BaseVkWallReply?,
|
||||
val call: BaseVkCall?
|
||||
val call: BaseVkCall?,
|
||||
@SerializedName("group_call_in_progress")
|
||||
val groupCall: BaseVkGroupCall?
|
||||
) : Parcelable {
|
||||
|
||||
fun getPreparedType() = AttachmentType.parse(type)
|
||||
@@ -43,7 +45,8 @@ data class BaseVkAttachmentItem(
|
||||
GRAFFITI("graffiti"),
|
||||
POLL("poll"),
|
||||
WALL_REPLY("wall_reply"),
|
||||
CALL("call")
|
||||
CALL("call"),
|
||||
GROUP_CALL_IN_PROGRESS("group_call_in_progress")
|
||||
;
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.meloda.fast.api.model.base.attachments
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class BaseVkGroupCall(
|
||||
@SerializedName("initiator_id")
|
||||
val initiatorId: Int,
|
||||
@SerializedName("join_link")
|
||||
val joinLink: String,
|
||||
val participants: Participants
|
||||
) : Parcelable {
|
||||
|
||||
@Parcelize
|
||||
data class Participants(
|
||||
val list: List<Int>,
|
||||
val count: Int
|
||||
) : Parcelable
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONArray
|
||||
import java.util.*
|
||||
|
||||
object VKAttachments {
|
||||
|
||||
fun parse(array: JSONArray): ArrayList<VKModel> {
|
||||
val attachments = ArrayList<VKModel>(array.length())
|
||||
|
||||
for (i in 0 until array.length()) {
|
||||
var attachment = array.optJSONObject(i) ?: continue
|
||||
if (attachment.has("attachment")) {
|
||||
attachment = attachment.optJSONObject("attachment") ?: continue
|
||||
}
|
||||
|
||||
val type = Type.fromString(attachment.optString("type"))
|
||||
val jsonObject = attachment.optJSONObject(type.value) ?: continue
|
||||
|
||||
when (type) {
|
||||
// Type.PHOTO -> attachments.add(oldVKPhoto(jsonObject))
|
||||
// Type.AUDIO -> attachments.add(oldVKAudio(jsonObject))
|
||||
// Type.VIDEO -> attachments.add(oldVKVideo(jsonObject))
|
||||
// Type.DOCUMENT -> attachments.add(oldVKDocument(jsonObject))
|
||||
// Type.STICKER -> attachments.add(oldVKSticker(jsonObject))
|
||||
// Type.LINK -> attachments.add(oldVKLink(jsonObject))
|
||||
// Type.GIFT -> attachments.add(VKGift(jsonObject))
|
||||
// Type.VOICE_MESSAGE -> attachments.add(oldVKAudioMessage(jsonObject))
|
||||
// Type.GRAFFITI -> attachments.add(VKGraffiti(jsonObject))
|
||||
Type.POLL -> attachments.add(oldVKPoll(jsonObject))
|
||||
Type.CALL -> attachments.add(VKCall(jsonObject))
|
||||
// Type.WALL_POST -> attachments.add(VKWall(jsonObject))
|
||||
Type.WALL_REPLY -> attachments.add(oldVKComment(jsonObject))
|
||||
// Type.GEOLOCATION -> attachments.add(oldVKGeolocation(jsonObject))
|
||||
else -> continue
|
||||
}
|
||||
}
|
||||
|
||||
return attachments
|
||||
}
|
||||
|
||||
enum class Type(val value: String) {
|
||||
NONE("none"),
|
||||
PHOTO("photo"),
|
||||
VIDEO("video"),
|
||||
AUDIO("audio"),
|
||||
AUDIO_PLAYLIST("audio_playlist"),
|
||||
DOCUMENT("doc"),
|
||||
LINK("link"),
|
||||
STICKER("sticker"),
|
||||
GIFT("gift"),
|
||||
VOICE_MESSAGE("audio_message"),
|
||||
GRAFFITI("graffiti"),
|
||||
POLL("poll"),
|
||||
GEOLOCATION("geo"),
|
||||
WALL_POST("wall"),
|
||||
WALL_REPLY("wall_reply"),
|
||||
CALL("call"),
|
||||
STORY("story"),
|
||||
POINT("point"),
|
||||
MARKET("market"),
|
||||
ARTICLE("article"),
|
||||
PODCAST("podcast"),
|
||||
MONEY_REQUEST("money_request");
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String): Type {
|
||||
for (v in values()) {
|
||||
if (v.value == value) return v
|
||||
}
|
||||
|
||||
return NONE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKCall() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.CALL
|
||||
|
||||
var initiatorId: Int = 0
|
||||
var receiverId: Int = 0
|
||||
var state: State = State.NONE
|
||||
var time: Int = 0
|
||||
var duration: Int = 0
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
initiatorId = o.optInt("initiator_id", -1)
|
||||
receiverId = o.optInt("receiver_id", -1)
|
||||
state = State.fromString(o.optString("state"))
|
||||
time = o.optInt("time")
|
||||
duration = o.optInt("duration")
|
||||
}
|
||||
|
||||
enum class State(val value: String) {
|
||||
NONE("none"),
|
||||
REACHED("reached"),
|
||||
CANCELLED_INITIATOR("canceled_by_initiator"),
|
||||
CANCELLED_RECEIVER("canceled_by_receiver");
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String) = values().first { it.value == value }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import java.util.*
|
||||
|
||||
class VKLongPollHistory : VKModel() {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
private val lpMessages: ArrayList<oldVKMessage>? = null
|
||||
private val messages: ArrayList<oldVKMessage>? = null
|
||||
private val profiles: ArrayList<oldVKUser>? = null
|
||||
private val groups: ArrayList<oldVKGroup>? = null //TODO: использовать
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class VKLongPollServer() : VKModel() {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
var key: String = ""
|
||||
var server: String = ""
|
||||
var ts: Long = 0
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
key = o.optString("key")
|
||||
server = o.optString("server").replace("\\", "")
|
||||
ts = o.optLong("ts")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import com.meloda.fast.api.model.old.VKAttachments
|
||||
import com.meloda.fast.base.adapter.BaseItem
|
||||
import java.io.Serializable
|
||||
|
||||
abstract class VKModel : BaseItem(), Serializable {
|
||||
|
||||
abstract val attachmentType: VKAttachments.Type
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID = 1L
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKAudio() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.AUDIO
|
||||
|
||||
var id: Int = 0
|
||||
var ownerId: Int = 0
|
||||
var artist: String = ""
|
||||
var title: String = ""
|
||||
var duration: Int = 0
|
||||
var url: String = ""
|
||||
var date: Int = 0
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
ownerId = o.optInt("owner_id", -1)
|
||||
artist = o.optString("artist")
|
||||
title = o.optString("title")
|
||||
duration = o.optInt("duration")
|
||||
url = o.optString("url")
|
||||
date = o.optInt("date")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKAudioMessage() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.VOICE_MESSAGE
|
||||
|
||||
var duration: Int = 0
|
||||
var waveform: ArrayList<Int> = arrayListOf()
|
||||
var linkOgg: String = ""
|
||||
var linkMp3: String = ""
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
duration = o.optInt("duration")
|
||||
linkOgg = o.optString("link_ogg")
|
||||
linkMp3 = o.optString("link_mp3")
|
||||
|
||||
o.optJSONArray("waveform")?.let {
|
||||
val waveform = ArrayList<Int>()
|
||||
for (i in 0 until it.length()) {
|
||||
waveform.add(it.optInt(i))
|
||||
}
|
||||
this.waveform = waveform
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKComment() : VKModel() { //https://vk.com/dev/objects/comment
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.WALL_REPLY
|
||||
|
||||
constructor(o: JSONObject) : this() {}
|
||||
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKConversation() : VKModel(), Cloneable {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
|
||||
var profiles = arrayListOf<oldVKUser>()
|
||||
var groups = arrayListOf<oldVKGroup>()
|
||||
|
||||
var conversationsCount: Int = 0
|
||||
|
||||
var count: Int = 0
|
||||
}
|
||||
|
||||
var isAllowed: Boolean = false
|
||||
var notAllowedReason: Reason = Reason.NULL
|
||||
|
||||
var inReadMessageId: Int = 0
|
||||
var outReadMessageId: Int = 0
|
||||
var lastMessageId: Int = 0
|
||||
var unreadCount: Int = 0
|
||||
|
||||
var id: Int = 0
|
||||
|
||||
var intType: Int = 0
|
||||
var type: Type = Type.NULL
|
||||
|
||||
var localId: Int = 0
|
||||
|
||||
var notificationsEnabled: Boolean = false
|
||||
|
||||
var disabledUntil: Int = 0
|
||||
var isDisabledForever: Boolean = false
|
||||
var isNoSound: Boolean = false
|
||||
|
||||
var membersCount: Int = 0
|
||||
var title: String? = null
|
||||
|
||||
var pinnedMessage: oldVKMessage? = null
|
||||
|
||||
var intState: Int = 0
|
||||
var state: State = State.IN
|
||||
|
||||
var lastMessage: oldVKMessage = oldVKMessage()
|
||||
|
||||
var isGroupChannel: Boolean = false
|
||||
|
||||
var photo50: String = ""
|
||||
var photo100: String = ""
|
||||
var photo200: String = ""
|
||||
|
||||
var peerUser: oldVKUser? = null
|
||||
|
||||
var peerGroup: oldVKGroup? = null
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
inReadMessageId = o.optInt("in_read")
|
||||
outReadMessageId = o.optInt("out_read")
|
||||
lastMessageId = o.optInt("last_message_id", -1)
|
||||
unreadCount = o.optInt("unread_count", 0)
|
||||
|
||||
o.optJSONObject("peer")?.let {
|
||||
id = it.optInt("id", -1)
|
||||
type = Type.fromString(it.optString("type"))
|
||||
localId = it.optInt("local_id")
|
||||
}
|
||||
|
||||
o.optJSONObject("push_settings")?.let {
|
||||
disabledUntil = it.optInt("disabled_until")
|
||||
isDisabledForever = it.optBoolean("disabled_forever")
|
||||
isNoSound = it.optBoolean("no_sound")
|
||||
}
|
||||
|
||||
o.optJSONObject("can_write")?.let {
|
||||
isAllowed = it.optBoolean("allowed")
|
||||
notAllowedReason = Reason.fromInt(it.optInt("reason", -1))
|
||||
}
|
||||
|
||||
o.optJSONObject("chat_settings")?.let {
|
||||
membersCount = it.optInt("members_count")
|
||||
title = it.optString("title")
|
||||
if (title?.isBlank() == true) title = null
|
||||
|
||||
it.optJSONObject("pinned_message")?.let { pinned ->
|
||||
pinnedMessage = oldVKMessage(pinned)
|
||||
}
|
||||
|
||||
state = State.fromString(it.optString("state"))
|
||||
|
||||
it.optJSONObject("photo")?.let { photo ->
|
||||
photo50 = photo.optString("photo_50")
|
||||
photo100 = photo.optString("photo_100")
|
||||
photo200 = photo.optString("photo_200")
|
||||
}
|
||||
|
||||
isGroupChannel = it.optBoolean("is_group_channel")
|
||||
}
|
||||
}
|
||||
|
||||
fun isNotificationsDisabled() = (isDisabledForever || disabledUntil > 0 || isNoSound)
|
||||
|
||||
fun isChat() = type == Type.CHAT
|
||||
|
||||
fun isUser() = type == Type.USER
|
||||
|
||||
fun isGroup() = type == Type.GROUP
|
||||
|
||||
override fun toString() = title ?: ""
|
||||
|
||||
public override fun clone() = super.clone() as oldVKConversation
|
||||
|
||||
enum class Type(val value: String) {
|
||||
NULL("null"),
|
||||
USER("user"),
|
||||
CHAT("chat"),
|
||||
GROUP("group");
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String) = values().first { it.value == value }
|
||||
}
|
||||
}
|
||||
|
||||
enum class State(val value: String) {
|
||||
IN("in"),
|
||||
KICKED("kicked"),
|
||||
LEFT("left");
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String) = values().first { it.value == value }
|
||||
}
|
||||
}
|
||||
|
||||
enum class Reason(val value: Int) {
|
||||
NULL(-1),
|
||||
U(0),
|
||||
BLOCKED_DELETED(18),
|
||||
BLACKLISTED(900),
|
||||
BLOCKED_GROUP_MESSAGES(901),
|
||||
PRIVACY_SETTINGS(902),
|
||||
GROUP_DISABLED_MESSAGES(915),
|
||||
GROUP_BLOCKED_MESSAGES(916),
|
||||
NO_ACCESS_CHAT(917),
|
||||
NO_ACCESS_EMAIL(918),
|
||||
U1(925),
|
||||
NO_ACCESS_COMMUNITY(203);
|
||||
|
||||
companion object {
|
||||
fun fromInt(value: Int) = values().first { it.value == value }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
|
||||
class oldVKDocument() : VKModel() {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.DOCUMENT
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
var id: Int = 0
|
||||
var ownerId: Int = 0
|
||||
var title: String = ""
|
||||
var size: Int = 0
|
||||
var ext: String = ""
|
||||
var url: String = ""
|
||||
var date: Int = 0
|
||||
var type: Type = Type.UNKNOWN
|
||||
var preview: Preview? = null
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
ownerId = o.optInt("owner_id", -1)
|
||||
title = o.optString("title")
|
||||
size = o.optInt("size")
|
||||
ext = o.optString("ext")
|
||||
url = o.optString("url")
|
||||
date = o.optInt("date")
|
||||
type = Type.fromInt(o.optInt("type"))
|
||||
|
||||
o.optJSONObject("preview")?.let {
|
||||
preview = Preview(it)
|
||||
}
|
||||
}
|
||||
|
||||
class Preview(o: JSONObject) : Serializable {
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
var photo: Photo? = null
|
||||
var graffiti: Graffiti? = null
|
||||
|
||||
inner class Photo(o: JSONObject) : Serializable {
|
||||
|
||||
var sizes: ArrayList<oldVKPhotoSize>? = null
|
||||
|
||||
init {
|
||||
o.optJSONArray("sizes")?.let {
|
||||
val sizes = ArrayList<oldVKPhotoSize>()
|
||||
for (i in 0 until it.length()) {
|
||||
sizes.add(oldVKPhotoSize(it.optJSONObject(i)))
|
||||
}
|
||||
this.sizes = sizes
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Graffiti(o: JSONObject) : Serializable {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
var src: String = o.optString("src")
|
||||
var width: Int = o.optInt("width")
|
||||
var height: Int = o.optInt("height")
|
||||
}
|
||||
|
||||
init {
|
||||
o.optJSONObject("photo")?.let {
|
||||
photo = Photo(it)
|
||||
}
|
||||
|
||||
o.optJSONObject("graffiti")?.let {
|
||||
graffiti = Graffiti(it)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
enum class Type(val value: Int) {
|
||||
NONE(0),
|
||||
TEXT(1),
|
||||
ARCHIVE(2),
|
||||
GIF(3),
|
||||
IMAGE(4),
|
||||
AUDIO(5),
|
||||
VIDEO(6),
|
||||
BOOK(7),
|
||||
UNKNOWN(8);
|
||||
|
||||
companion object {
|
||||
fun fromInt(value: Int) = values().first { it.value == value }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKGeolocation() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.GEOLOCATION
|
||||
|
||||
constructor(o: JSONObject) : this() {}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKGift() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.GIFT
|
||||
|
||||
var id: Int = 0
|
||||
var thumb256: String = ""
|
||||
var thumb96: String = ""
|
||||
var thumb48: String = ""
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
thumb256 = o.optString("thumb_256")
|
||||
thumb96 = o.optString("thumb_96")
|
||||
thumb48 = o.optString("thumb_48")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKGraffiti() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.GRAFFITI
|
||||
|
||||
var id: Int = 0
|
||||
var ownerId: Int = 0
|
||||
var url: String = ""
|
||||
var width: Int = 0
|
||||
var height: Int = 0
|
||||
var accessKey: String = ""
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
ownerId = o.optInt("owner_id", -1)
|
||||
url = o.optString("url")
|
||||
width = o.optInt("width")
|
||||
height = o.optInt("height")
|
||||
accessKey = o.optString("access_key")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
open class oldVKGroup() : VKModel() {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
companion object {
|
||||
|
||||
const val serialVersionUID: Long = 1L
|
||||
|
||||
fun parse(array: JSONArray): ArrayList<oldVKGroup> {
|
||||
val groups = ArrayList<oldVKGroup>()
|
||||
|
||||
for (i in 0 until array.length()) {
|
||||
groups.add(oldVKGroup(array.optJSONObject(i)))
|
||||
}
|
||||
return groups
|
||||
}
|
||||
}
|
||||
|
||||
var id: Int = 0
|
||||
var name: String = ""
|
||||
var screenName: String = ""
|
||||
var isClosed: Boolean = false
|
||||
var deactivated: String = ""
|
||||
var type: Type = Type.NULL
|
||||
var photo50: String = ""
|
||||
var photo100: String = ""
|
||||
var photo200: String = ""
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
name = o.optString("name")
|
||||
screenName = o.optString("screen_name")
|
||||
isClosed = o.optInt("is_closed") == 1
|
||||
deactivated = o.optString("deactivated")
|
||||
type = Type.fromString(o.optString("type"))
|
||||
photo50 = o.optString("photo_50")
|
||||
photo100 = o.optString("photo_100")
|
||||
photo200 = o.optString("photo_200")
|
||||
}
|
||||
|
||||
enum class Type(val value: String) {
|
||||
NULL("null"),
|
||||
GROUP("group"),
|
||||
PAGE("page"),
|
||||
EVENT("event");
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String) = values().first { it.value == value }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
import java.io.Serializable
|
||||
|
||||
class oldVKLink() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.LINK
|
||||
|
||||
var url: String = ""
|
||||
var title: String = ""
|
||||
var caption: String = ""
|
||||
var description: String = ""
|
||||
var previewPage: String = ""
|
||||
var previewUrl: String = ""
|
||||
var photo: oldVKPhoto? = null
|
||||
var button: Button? = null
|
||||
|
||||
constructor(o: JSONObject): this() {
|
||||
url = o.optString("url")
|
||||
title = o.optString("title")
|
||||
caption = o.optString("caption")
|
||||
description = o.optString("description")
|
||||
previewPage = o.optString("preview_page")
|
||||
previewUrl = o.optString("preview_url")
|
||||
|
||||
o.optJSONObject("photo")?.let {
|
||||
photo = oldVKPhoto(it)
|
||||
}
|
||||
|
||||
o.optJSONObject("button")?.let {
|
||||
button = Button(it)
|
||||
}
|
||||
}
|
||||
|
||||
class Button(o: JSONObject) : Serializable {
|
||||
var title: String = o.optString("title")
|
||||
var action: Action? = null
|
||||
|
||||
init {
|
||||
o.optJSONObject("action")?.let {
|
||||
action = Action(it)
|
||||
}
|
||||
}
|
||||
|
||||
class Action(o: JSONObject) : Serializable {
|
||||
|
||||
var type: String = o.optString("type")
|
||||
var url: String = o.optString("url")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import android.util.ArrayMap
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import org.json.JSONObject
|
||||
|
||||
open class oldVKMessage() : VKModel() {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
companion object {
|
||||
|
||||
var profiles = arrayListOf<oldVKUser>()
|
||||
var groups = arrayListOf<oldVKGroup>()
|
||||
var conversations = arrayListOf<oldVKConversation>()
|
||||
|
||||
const val serialVersionUID: Long = 1L
|
||||
|
||||
var lastHistoryCount: Int = 0
|
||||
|
||||
const val UNREAD = 1 // Оно просто есть
|
||||
const val OUTBOX = 1 shl 1 // Исходящее сообщение
|
||||
const val REPLIED = 1 shl 2 // На сообщение был создан ответ
|
||||
const val IMPORTANT = 1 shl 3 // Важное сообщение
|
||||
const val FRIENDS = 1 shl 5 // Сообщение в чат друга
|
||||
const val SPAM = 1 shl 6 // Сообщение помечено как спам
|
||||
const val DELETED = 1 shl 7 // Удаление сообщения
|
||||
const val AUDIO_LISTENED = 1 shl 12 // ГС прослушано
|
||||
const val CHAT = 1 shl 13 // Сообщение отправлено в беседу
|
||||
const val CANCEL_SPAM = 1 shl 15 // Отмена пометки спама
|
||||
const val HIDDEN = 1 shl 16 // Приветственное сообщение сообщества
|
||||
const val DELETE_FOR_ALL = 1 shl 17 // Сообщение удалено для всех
|
||||
const val CHAT_IN = 1 shl 19 // Входящее сообщение в беседе
|
||||
const val REPLY_MSG = 1 shl 21 // Ответ на сообщение
|
||||
|
||||
val flags = ArrayMap<String, Int>()
|
||||
|
||||
fun isOut(flags: Int): Boolean {
|
||||
return OUTBOX and flags > 0
|
||||
}
|
||||
|
||||
fun isDeleted(flags: Int): Boolean {
|
||||
return DELETED and flags > 0
|
||||
}
|
||||
|
||||
fun isUnread(flags: Int): Boolean {
|
||||
return UNREAD and flags > 0
|
||||
}
|
||||
|
||||
fun isSpam(flags: Int): Boolean {
|
||||
return SPAM and flags > 0
|
||||
}
|
||||
|
||||
fun isCanceledSpam(flags: Int): Boolean {
|
||||
return CANCEL_SPAM and flags > 0
|
||||
}
|
||||
|
||||
fun isImportant(flags: Int): Boolean {
|
||||
return IMPORTANT and flags > 0
|
||||
}
|
||||
|
||||
fun isDeletedForAll(flags: Int): Boolean {
|
||||
return DELETE_FOR_ALL and flags > 0
|
||||
}
|
||||
|
||||
init {
|
||||
flags["unread"] = UNREAD
|
||||
flags["outbox"] = OUTBOX
|
||||
flags["replied"] = REPLIED
|
||||
flags["important"] = IMPORTANT
|
||||
flags["friends"] = FRIENDS
|
||||
flags["spam"] = SPAM
|
||||
flags["deleted"] = DELETED
|
||||
flags["audio_listened"] = AUDIO_LISTENED
|
||||
flags["chat"] = CHAT
|
||||
flags["cancel_spam"] = CANCEL_SPAM
|
||||
flags["hidden"] = HIDDEN
|
||||
flags["delete_for_all"] = DELETE_FOR_ALL
|
||||
flags["chat_in"] = CHAT_IN
|
||||
flags["reply_msg"] = REPLY_MSG
|
||||
}
|
||||
}
|
||||
|
||||
var id: Int = 0
|
||||
var date: Int = 0
|
||||
var peerId: Int = 0
|
||||
var fromId: Int = 0
|
||||
var editTime: Int = 0
|
||||
var isOut: Boolean = false
|
||||
var text: String = ""
|
||||
var randomId: Int = 0
|
||||
var conversationMessageId: Int = 0
|
||||
|
||||
var hasEmoji: Boolean = false
|
||||
var isImportant: Boolean = false
|
||||
var isRead: Boolean = false
|
||||
|
||||
var attachments: ArrayList<VKModel> = arrayListOf()
|
||||
|
||||
var fwdMessages: ArrayList<oldVKMessage> = arrayListOf()
|
||||
|
||||
var replyMessage: oldVKMessage? = null
|
||||
|
||||
var action: oldVKMessageAction? = null
|
||||
|
||||
var fromUser: oldVKUser? = null
|
||||
|
||||
var fromGroup: oldVKGroup? = null
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
date = o.optInt("date")
|
||||
peerId = o.optInt("peer_id", -1)
|
||||
fromId = o.optInt("from_id", -1)
|
||||
editTime = o.optInt("edit_time", -1)
|
||||
isOut = o.optInt("out") == 1
|
||||
|
||||
text = oldVKUtil.prepareMessageText(o.optString("text"))
|
||||
|
||||
randomId = o.optInt("random_id", -1)
|
||||
conversationMessageId = o.optInt("conversation_message_id", -1)
|
||||
isImportant = o.optBoolean("important")
|
||||
|
||||
o.optJSONArray("attachments")?.let {
|
||||
attachments = VKAttachments.parse(it)
|
||||
}
|
||||
|
||||
o.optJSONArray("fwd_messages")?.let {
|
||||
val fwdMessages = ArrayList<oldVKMessage>(it.length())
|
||||
for (i in 0 until it.length()) {
|
||||
fwdMessages.add(oldVKMessage(it.optJSONObject(i)))
|
||||
}
|
||||
this.fwdMessages = fwdMessages
|
||||
}
|
||||
|
||||
o.optJSONObject("reply_message")?.let {
|
||||
replyMessage = oldVKMessage(it)
|
||||
}
|
||||
|
||||
o.optJSONObject("action")?.let {
|
||||
action = oldVKMessageAction(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun getForwardedMessages() = ArrayList<oldVKMessage>().apply {
|
||||
for (model in fwdMessages) add(model)
|
||||
}
|
||||
|
||||
fun isFromUser() = fromId > 0
|
||||
|
||||
fun isFromGroup() = fromId < 0
|
||||
|
||||
fun isOutbox() = isOut
|
||||
|
||||
fun isInbox() = !isOutbox()
|
||||
|
||||
override fun toString(): String {
|
||||
return if (text.isNotEmpty()) {
|
||||
text
|
||||
} else {
|
||||
super.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKMessageAction() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
var type: Type = Type.NONE
|
||||
var memberId = 0
|
||||
var message: oldVKMessage? = null
|
||||
var conversationMessageId: Int = 0
|
||||
var text: String = ""
|
||||
var oldText: String = ""
|
||||
|
||||
//TODO: add photo
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
type = Type.fromString(o.optString("type"))
|
||||
memberId = o.optInt("member_id", -1)
|
||||
text = o.optString("text")
|
||||
}
|
||||
|
||||
enum class Type(val value: String) {
|
||||
NONE("none"),
|
||||
CHAT_CREATE("chat_create"),
|
||||
PHOTO_UPDATE("chat_photo_update"),
|
||||
PHOTO_REMOVE("chat_photo_remove"),
|
||||
TITLE_UPDATE("chat_title_update"),
|
||||
PIN_MESSAGE("chat_pin_message"),
|
||||
UNPIN_MESSAGE("chat_unpin_message"),
|
||||
INVITE_USER("chat_invite_user"),
|
||||
INVITE_USER_BY_LINK("chat_invite_user_by_link"),
|
||||
KICK_USER("chat_kick_user"),
|
||||
SCREENSHOT("chat_screenshot"),
|
||||
INVITE_USER_BY_CALL("chat_invite_user_by_call"),
|
||||
INVITE_USER_BY_CALL_LINK("chat_invite_user_by_call_link");
|
||||
|
||||
companion object {
|
||||
fun fromString(value: String) = values().first { it.value == value }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
class oldVKPhoto() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.PHOTO
|
||||
|
||||
var id: Int = 0
|
||||
var albumId: Int = 0
|
||||
var ownerId: Int = 0
|
||||
var text: String = ""
|
||||
var date: Int = 0
|
||||
var width: Int = 0
|
||||
var height: Int = 0
|
||||
var sizes: ArrayList<oldVKPhotoSize>? = null
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
id = o.optInt("id", -1)
|
||||
albumId = o.optInt("album_id", -1)
|
||||
ownerId = o.optInt("owner_id", -1)
|
||||
text = o.optString("text")
|
||||
date = o.optInt("date")
|
||||
width = o.optInt("width")
|
||||
height = o.optInt("height")
|
||||
|
||||
o.optJSONArray("sizes")?.let {
|
||||
val sizes = ArrayList<oldVKPhotoSize>()
|
||||
for (i in 0 until it.length()) {
|
||||
sizes.add(oldVKPhotoSize(it.optJSONObject(i)))
|
||||
}
|
||||
this.sizes = sizes
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKPhotoSize(o: JSONObject) : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
var type: String = o.optString("type")
|
||||
var url: String = o.optString("url")
|
||||
var height: Int = o.optInt("height")
|
||||
var width: Int = o.optInt("width")
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKPoll() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.POLL
|
||||
|
||||
constructor(o: JSONObject): this() {}
|
||||
|
||||
// var id = o.optInt("id", -1)
|
||||
// var ownerId = o.optInt("owner_id", -1)
|
||||
// var created = o.optInt("created")
|
||||
// var question: String = o.optString("question")
|
||||
// var votes = o.optInt("votes")
|
||||
// var answers = ArrayList<Answer>()
|
||||
// var isAnonymous = o.optBoolean("anonymous")
|
||||
// var isMultiple = o.optBoolean("multiple")
|
||||
// var answerIds = ArrayList<Int>()
|
||||
// var endDate = o.optInt("end_date")
|
||||
// var isClosed = o.optBoolean("closed")
|
||||
// var isBoard = o.optBoolean("is_board")
|
||||
// var isCanEdit = o.optBoolean("can_edit")
|
||||
// var isCanVote = false
|
||||
// var isCanReport = false
|
||||
// var isCanShare = false
|
||||
// var authorId = 0
|
||||
// var background = Color.WHITE
|
||||
|
||||
//TODO: private ArrayList friends
|
||||
|
||||
// init {
|
||||
// o.optJSONArray("answers")?.let {
|
||||
// val answers = ArrayList<Answer>()
|
||||
// for (i in 0 until it.length()) {
|
||||
// answers.add(Answer(it.optJSONObject(i)))
|
||||
// }
|
||||
// this.answers = answers
|
||||
// }
|
||||
|
||||
// //setAnswerIds();
|
||||
|
||||
// // ...
|
||||
// }
|
||||
|
||||
// class Answer(o: JSONObject) : Serializable {
|
||||
|
||||
// var id = o.optInt("id", -1)
|
||||
// var text: String = o.optString("text")
|
||||
// var votes = o.optInt("votes")
|
||||
// var rate = o.optInt("rate")
|
||||
|
||||
// }
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
class oldVKSticker() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.STICKER
|
||||
|
||||
var productId: Int = 0
|
||||
var stickerId: Int = 0
|
||||
var images: ArrayList<Image>? = null
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
productId = o.optInt("product_id", -1)
|
||||
stickerId = o.optInt("sticker_id", -1)
|
||||
|
||||
o.optJSONArray("images")?.let {
|
||||
val images = ArrayList<Image>()
|
||||
for (i in 0 until it.length()) {
|
||||
images.add(Image(it.optJSONObject(i)))
|
||||
}
|
||||
this.images = images
|
||||
}
|
||||
}
|
||||
|
||||
class Image(o: JSONObject) : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
var url: String = o.optString("url")
|
||||
var width = o.optInt("width")
|
||||
var height = o.optInt("height")
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
open class oldVKUser() : VKModel() {
|
||||
|
||||
override val attachmentType = VKAttachments.Type.NONE
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
|
||||
var friendsCount: Int = 0
|
||||
|
||||
fun parse(array: JSONArray): ArrayList<oldVKUser> {
|
||||
val users = ArrayList<oldVKUser>()
|
||||
|
||||
for (i in 0 until array.length()) {
|
||||
users.add(oldVKUser(array.optJSONObject(i)))
|
||||
}
|
||||
|
||||
return users
|
||||
}
|
||||
}
|
||||
|
||||
var sortId: Int = 0
|
||||
|
||||
var userId: Int = 0
|
||||
var firstName: String = ""
|
||||
var lastName: String = ""
|
||||
var deactivated: String = ""
|
||||
var isClosed: Boolean = false
|
||||
var isCanAccessClosed: Boolean = true
|
||||
var sex: Int = 0
|
||||
var screenName: String = ""
|
||||
var photo50: String = ""
|
||||
var photo100: String = ""
|
||||
var photo200: String = ""
|
||||
var isOnline: Boolean = false
|
||||
var isOnlineMobile: Boolean = false
|
||||
var status: String = ""
|
||||
|
||||
var lastSeen: Int = 0
|
||||
var lastSeenPlatform: Int = 0
|
||||
|
||||
var isVerified: Boolean = false
|
||||
|
||||
constructor(o: JSONObject) : this() {
|
||||
sortId = 0
|
||||
userId = o.optInt("id", -1)
|
||||
firstName = o.optString("first_name")
|
||||
lastName = o.optString("last_name")
|
||||
deactivated = o.optString("deactivated", "")
|
||||
isClosed = o.optBoolean("is_closed")
|
||||
isCanAccessClosed = o.optBoolean("can_access_closed")
|
||||
sex = o.optInt("sex")
|
||||
screenName = o.optString("screen_name")
|
||||
photo50 = o.optString("photo_50")
|
||||
photo100 = o.optString("photo_100")
|
||||
photo200 = o.optString("photo_200")
|
||||
isOnline = o.optInt("online") == 1
|
||||
isOnlineMobile = isOnline && o.optInt("online_mobile") == 1
|
||||
status = o.optString("status")
|
||||
lastSeen = 0
|
||||
lastSeenPlatform = 0
|
||||
isVerified = o.optInt("verified") == 1
|
||||
|
||||
o.optJSONObject("last_seen")?.let {
|
||||
lastSeen = it.optInt("time")
|
||||
lastSeenPlatform = it.optInt("platform")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun isDeactivated() = deactivated.isNotEmpty()
|
||||
|
||||
override fun toString(): String {
|
||||
return "$firstName $lastName"
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import com.meloda.fast.api.model.old.VKAttachments
|
||||
import com.meloda.fast.api.model.old.VKModel
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKVideo() : VKModel() {
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.VIDEO
|
||||
|
||||
// var id = o.optInt("id", -1)
|
||||
// var ownerId = o.optInt("owner_id", -1)
|
||||
// var title: String = o.optString("title")
|
||||
// var description: String = o.optString("description")
|
||||
// var duration = o.optInt("duration", -1)
|
||||
// var photo130: String = o.optString("photo_130")
|
||||
// var photo320: String = o.optString("photo_320")
|
||||
// var photo640: String = o.optString("photo_640")
|
||||
// var photo800: String = o.optString("photo_800")
|
||||
// var photo1280: String = o.optString("photo_1280")
|
||||
// var firstFrame130: String = o.optString("first_frame_130")
|
||||
// var firstFrame320: String = o.optString("first_frame_320")
|
||||
// var firstFrame640: String = o.optString("first_frame_640")
|
||||
// var firstFrame800: String = o.optString("first_frame_800")
|
||||
// var firstFrame1280: String = o.optString("first_frame_1280")
|
||||
// var date = o.optInt("date")
|
||||
// var views = o.optInt("views")
|
||||
// var comments = o.optInt("comments")
|
||||
// var player: String = o.optString("player")
|
||||
// var isCanEdit = o.optInt("can_edit", 0) == 1
|
||||
// var isCanAdd = o.optInt("can_add") == 1
|
||||
// var isPrivate = o.optInt("is_private", 0) == 1
|
||||
// var accessKey: String = o.optString("access_key")
|
||||
// var isProcessing = o.optInt("processing", 0) == 1
|
||||
// var isLive = o.optInt("live", 0) == 1
|
||||
// var isUpcoming = o.optInt("upcoming", 0) == 1
|
||||
// var isFavorite = o.optBoolean("favorite")
|
||||
|
||||
constructor(o: JSONObject) : this() {}
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.meloda.fast.api.model.old
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
class oldVKWall() : VKModel() { //https://vk.com/dev/objects/post
|
||||
|
||||
companion object {
|
||||
const val serialVersionUID: Long = 1L
|
||||
}
|
||||
|
||||
override val attachmentType = VKAttachments.Type.WALL_POST
|
||||
|
||||
constructor(o: JSONObject) : this() {}
|
||||
|
||||
}
|
||||
@@ -22,5 +22,5 @@ data class ConversationsGetResponse(
|
||||
data class ConversationsResponseItems(
|
||||
val conversation: BaseVkConversation,
|
||||
@SerializedName("last_message")
|
||||
val lastMessage: BaseVkMessage
|
||||
val lastMessage: BaseVkMessage?
|
||||
) : Parcelable
|
||||
@@ -1,379 +0,0 @@
|
||||
package com.meloda.fast.api
|
||||
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.api.model.*
|
||||
import com.meloda.fast.api.model.old.*
|
||||
import com.meloda.fast.api.network.VKErrors
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
// TODO: 8/31/2021 review
|
||||
object oldVKUtil {
|
||||
|
||||
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 sortMessagesByDate(
|
||||
values: ArrayList<oldVKMessage>,
|
||||
firstOnTop: Boolean
|
||||
): ArrayList<oldVKMessage> {
|
||||
values.sortWith { m1, m2 ->
|
||||
val d1 = m1.date
|
||||
val d2 = m2.date
|
||||
|
||||
if (firstOnTop) {
|
||||
d2 - d1
|
||||
} else {
|
||||
d1 - d2
|
||||
}
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
fun sortConversationsByDate(
|
||||
values: ArrayList<oldVKConversation>,
|
||||
firstOnTop: Boolean
|
||||
): ArrayList<oldVKConversation> {
|
||||
values.sortWith { c1, c2 ->
|
||||
val d1 = c1.lastMessage.date
|
||||
val d2 = c2.lastMessage.date
|
||||
|
||||
return@sortWith if (firstOnTop) {
|
||||
d2 - d1
|
||||
} else {
|
||||
d1 - d2
|
||||
}
|
||||
}
|
||||
|
||||
return values
|
||||
}
|
||||
|
||||
fun prepareMessageText(message: String): String {
|
||||
if (message.isEmpty()) return message
|
||||
|
||||
var newText = message
|
||||
|
||||
val mentions = hashMapOf<String, String>()
|
||||
|
||||
var startFrom = 0
|
||||
|
||||
while (true) {
|
||||
val leftBracketIndex = newText.indexOf('[', startFrom)
|
||||
val verticalLineIndex = newText.indexOf('|', startFrom)
|
||||
val rightBracketIndex = newText.indexOf(']', startFrom)
|
||||
|
||||
if (leftBracketIndex == -1 ||
|
||||
verticalLineIndex == -1 ||
|
||||
rightBracketIndex == -1
|
||||
) {
|
||||
break
|
||||
}
|
||||
|
||||
val id = newText.substring(leftBracketIndex + 1, verticalLineIndex)
|
||||
|
||||
if (!id.matches(Regex("^id(\\d+)\$")) || rightBracketIndex - verticalLineIndex < 2) {
|
||||
break
|
||||
}
|
||||
|
||||
val text = newText.substring(verticalLineIndex + 1, rightBracketIndex)
|
||||
|
||||
val str = "[$id|$text]"
|
||||
|
||||
mentions[str] = text
|
||||
startFrom = rightBracketIndex + 1
|
||||
}
|
||||
|
||||
mentions.forEach {
|
||||
newText = newText.replace(it.key, it.value)
|
||||
}
|
||||
|
||||
return newText
|
||||
}
|
||||
|
||||
// fun removeTime(date: Date): Long {
|
||||
// return Calendar.getInstance().apply {
|
||||
// time = date
|
||||
// this[Calendar.HOUR_OF_DAY] = 0
|
||||
// this[Calendar.MINUTE] = 0
|
||||
// this[Calendar.SECOND] = 0
|
||||
// this[Calendar.MILLISECOND] = 0
|
||||
// }.timeInMillis
|
||||
// }
|
||||
|
||||
|
||||
//TODO: нормальное время
|
||||
fun getLastSeenTime(date: Long): String {
|
||||
return SimpleDateFormat("HH:mm", Locale.getDefault()).format(date)
|
||||
}
|
||||
|
||||
|
||||
fun getTitle(
|
||||
conversation: oldVKConversation,
|
||||
peerUser: oldVKUser?,
|
||||
peerGroup: oldVKGroup?
|
||||
): String {
|
||||
return when {
|
||||
conversation.isUser() -> peerUser?.let { return it.toString() } ?: ""
|
||||
|
||||
|
||||
conversation.isGroup() -> peerGroup?.let { return it.name } ?: ""
|
||||
|
||||
|
||||
conversation.isChat() -> conversation.title ?: ""
|
||||
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun getMessageTitle(
|
||||
message: oldVKMessage,
|
||||
fromUser: oldVKUser?,
|
||||
fromGroup: oldVKGroup?
|
||||
): String {
|
||||
return when {
|
||||
message.isFromUser() -> {
|
||||
fromUser?.let { return it.toString() } ?: ""
|
||||
}
|
||||
|
||||
message.isFromGroup() -> {
|
||||
fromGroup?.let { return it.name } ?: ""
|
||||
}
|
||||
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun getAvatar(
|
||||
conversation: oldVKConversation,
|
||||
peerUser: oldVKUser?,
|
||||
peerGroup: oldVKGroup?
|
||||
): String {
|
||||
return when {
|
||||
conversation.isUser() -> {
|
||||
peerUser?.let { return it.photo200 } ?: ""
|
||||
}
|
||||
|
||||
conversation.isGroup() -> {
|
||||
peerGroup?.let { return it.photo200 } ?: ""
|
||||
}
|
||||
|
||||
conversation.isChat() -> {
|
||||
conversation.photo200
|
||||
}
|
||||
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun getUserAvatar(
|
||||
message: oldVKMessage,
|
||||
fromUser: oldVKUser?,
|
||||
fromGroup: oldVKGroup?
|
||||
): String {
|
||||
return when {
|
||||
message.isFromUser() -> {
|
||||
fromUser?.let { return it.photo100 } ?: ""
|
||||
}
|
||||
|
||||
message.isFromGroup() -> {
|
||||
fromGroup?.let { return it.photo100 } ?: ""
|
||||
}
|
||||
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun getUserPhoto(user: oldVKUser): String {
|
||||
if (user.photo200.isEmpty()) {
|
||||
if (user.photo100.isEmpty()) {
|
||||
if (user.photo50.isEmpty()) {
|
||||
return ""
|
||||
}
|
||||
} else {
|
||||
return user.photo100
|
||||
}
|
||||
} else {
|
||||
return user.photo200
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
fun getGroupPhoto(group: oldVKGroup): String {
|
||||
if (group.photo200.isEmpty()) {
|
||||
if (group.photo100.isEmpty()) {
|
||||
if (group.photo50.isEmpty()) {
|
||||
return ""
|
||||
}
|
||||
} else {
|
||||
return group.photo100
|
||||
}
|
||||
} else {
|
||||
return group.photo200
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
fun parseConversations(array: JSONArray): ArrayList<oldVKConversation> {
|
||||
val conversations = arrayListOf<oldVKConversation>()
|
||||
for (i in 0 until array.length()) {
|
||||
conversations.add(oldVKConversation(array.optJSONObject(i)))
|
||||
}
|
||||
|
||||
return conversations
|
||||
}
|
||||
|
||||
fun parseMessages(array: JSONArray): ArrayList<oldVKMessage> {
|
||||
val messages = arrayListOf<oldVKMessage>()
|
||||
for (i in 0 until array.length()) {
|
||||
messages.add(oldVKMessage(array.optJSONObject(i)))
|
||||
}
|
||||
|
||||
return messages
|
||||
}
|
||||
|
||||
fun isMessageHasFlag(mask: Int, flagName: String): Boolean {
|
||||
val o: Any? = oldVKMessage.flags[flagName]
|
||||
return if (o != null) { //has flag
|
||||
val flag = o as Int
|
||||
flag and mask > 0
|
||||
} else false
|
||||
}
|
||||
|
||||
//TODO: rewrite parsing
|
||||
//fromUser and fromGroup are null
|
||||
@Deprecated("need to rewrite")
|
||||
@WorkerThread
|
||||
fun parseLongPollMessage(array: JSONArray): oldVKMessage {
|
||||
val message = oldVKMessage()
|
||||
|
||||
val id = array.optInt(1)
|
||||
val flags = array.optInt(2)
|
||||
val peerId = array.optInt(3)
|
||||
val date = array.optInt(4)
|
||||
val text = array.optString(5)
|
||||
|
||||
message.id = id
|
||||
message.peerId = peerId
|
||||
message.date = date
|
||||
message.text = text
|
||||
|
||||
// val fromId =
|
||||
// if (isMessageHasFlag(flags, "outbox")) com.meloda.fast.api.UserConfig.userId
|
||||
// else peerId
|
||||
|
||||
message.fromId = peerId
|
||||
|
||||
array.optJSONObject(6)?.let {
|
||||
if (it.has("emoji")) message.hasEmoji = true
|
||||
|
||||
if (it.has("from")) {
|
||||
message.fromId = it.optInt("from", -1)
|
||||
}
|
||||
|
||||
if (it.has("source_act")) {
|
||||
message.action = oldVKMessageAction().also { action ->
|
||||
action.type =
|
||||
oldVKMessageAction.Type.fromString(it.optString("source_act"))
|
||||
|
||||
when (action.type) {
|
||||
oldVKMessageAction.Type.CHAT_CREATE -> {
|
||||
action.text = it.optString("source_text")
|
||||
}
|
||||
oldVKMessageAction.Type.TITLE_UPDATE -> {
|
||||
action.oldText = it.optString("source_old_text")
|
||||
action.text = it.optString("source_text")
|
||||
}
|
||||
oldVKMessageAction.Type.PIN_MESSAGE -> {
|
||||
action.memberId = it.optInt("source_mid")
|
||||
action.conversationMessageId = it.optInt("source_chat_local_id")
|
||||
|
||||
it.optJSONObject("source_message")?.let { message ->
|
||||
action.message = oldVKMessage(message)
|
||||
}
|
||||
}
|
||||
oldVKMessageAction.Type.UNPIN_MESSAGE -> {
|
||||
action.memberId = it.optInt("source_mid")
|
||||
action.conversationMessageId = it.optInt("source_chat_local_id")
|
||||
}
|
||||
oldVKMessageAction.Type.INVITE_USER,
|
||||
oldVKMessageAction.Type.KICK_USER,
|
||||
oldVKMessageAction.Type.SCREENSHOT,
|
||||
oldVKMessageAction.Type.INVITE_USER_BY_CALL -> {
|
||||
action.memberId = it.optInt("source_mid")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
array.optJSONObject(7)?.let {
|
||||
/**
|
||||
*
|
||||
* fwd? reply? attachments_count? attachments?
|
||||
*
|
||||
*/
|
||||
}
|
||||
|
||||
val randomId = array.optInt(8)
|
||||
message.randomId = randomId
|
||||
|
||||
val conversationMessageId = array.optInt(9)
|
||||
message.conversationMessageId = conversationMessageId
|
||||
|
||||
val editTime = array.optInt(10)
|
||||
message.editTime = editTime
|
||||
|
||||
// val out = fromId == com.meloda.fast.api.UserConfig.userId
|
||||
// message.isOut = out
|
||||
//
|
||||
// if (message.isFromUser()) {
|
||||
// message.fromUser = MemoryCache.getUserById(fromId)
|
||||
// } else {
|
||||
// message.fromGroup = MemoryCache.getGroupById(abs(fromId))
|
||||
// }
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
fun parseJsonPhotos(jsonPhotos: JSONObject): List<String> {
|
||||
val photos = arrayListOf<String>()
|
||||
|
||||
for (key in jsonPhotos.keys()) {
|
||||
photos.add(jsonPhotos.getString(key))
|
||||
}
|
||||
|
||||
return photos
|
||||
}
|
||||
|
||||
fun putPhotosToJson(photo50: String, photo100: String, photo200: String): JSONObject {
|
||||
val json = JSONObject()
|
||||
|
||||
json.put("photo_50", photo50)
|
||||
json.put("photo_100", photo100)
|
||||
json.put("photo_200", photo200)
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
fun isGroupId(id: Int) = id < 0
|
||||
|
||||
fun isUserId(id: Int) = id in 1..1999999999
|
||||
|
||||
fun isChatId(id: Int) = id > 2_000_000_000
|
||||
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.meloda.fast.base
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.meloda.fast.R
|
||||
|
||||
abstract class BaseFullscreenDialog : DialogFragment() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setStyle(STYLE_NORMAL, R.style.AppTheme_FullScreenDialog)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
dialog?.let { dialog ->
|
||||
val width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
val height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
|
||||
dialog.window?.let {
|
||||
it.setLayout(width, height)
|
||||
it.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
|
||||
it.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
|
||||
it.setWindowAnimations(R.style.AppTheme_Slide)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,22 @@
|
||||
package com.meloda.fast.common
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.net.ConnectivityManager
|
||||
import android.os.Handler
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.core.content.pm.PackageInfoCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.room.Room
|
||||
import com.meloda.fast.BuildConfig
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.database.AppDatabase
|
||||
import com.meloda.fast.database.old.DatabaseHelper
|
||||
import com.meloda.fast.util.AndroidUtils
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import org.acra.ACRA
|
||||
import org.acra.ReportingInteractionMode
|
||||
import org.acra.annotation.ReportsCrashes
|
||||
import java.util.*
|
||||
|
||||
@SuppressLint("NonConstantResourceId")
|
||||
@ReportsCrashes(
|
||||
mailTo = "lischenkodev@gmail.com",
|
||||
mode = ReportingInteractionMode.DIALOG,
|
||||
resDialogTitle = R.string.app_has_been_crashed,
|
||||
resDialogText = R.string.empty,
|
||||
resDialogTheme = R.style.AppTheme_Dialog,
|
||||
resDialogPositiveButtonText = R.string.send_crash_report,
|
||||
resDialogNegativeButtonText = R.string.ok
|
||||
)
|
||||
@HiltAndroidApp
|
||||
class AppGlobal : Application() {
|
||||
|
||||
@@ -45,17 +27,12 @@ class AppGlobal : Application() {
|
||||
lateinit var clipboardManager: ClipboardManager
|
||||
|
||||
lateinit var preferences: SharedPreferences
|
||||
lateinit var locale: Locale
|
||||
lateinit var handler: Handler
|
||||
lateinit var resources: Resources
|
||||
lateinit var packageName: String
|
||||
lateinit var instance: AppGlobal
|
||||
|
||||
lateinit var appDatabase: AppDatabase
|
||||
|
||||
lateinit var dbHelper: DatabaseHelper
|
||||
lateinit var oldDatabase: SQLiteDatabase
|
||||
|
||||
lateinit var packageManager: PackageManager
|
||||
|
||||
var versionName = ""
|
||||
@@ -63,10 +40,6 @@ class AppGlobal : Application() {
|
||||
|
||||
var screenWidth = 0
|
||||
var screenHeight = 0
|
||||
|
||||
fun post(runnable: Runnable) {
|
||||
handler.post(runnable)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
@@ -84,11 +57,6 @@ class AppGlobal : Application() {
|
||||
.build()
|
||||
|
||||
preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
handler = Handler(mainLooper)
|
||||
locale = Locale.getDefault()
|
||||
|
||||
dbHelper = DatabaseHelper(this)
|
||||
oldDatabase = dbHelper.writableDatabase
|
||||
|
||||
val info = packageManager.getPackageInfo(this.packageName, PackageManager.GET_ACTIVITIES)
|
||||
versionName = info.versionName
|
||||
|
||||
@@ -18,7 +18,7 @@ import com.meloda.fast.database.dao.UsersDao
|
||||
VkUser::class,
|
||||
VkGroup::class
|
||||
],
|
||||
version = 8,
|
||||
version = 11,
|
||||
exportSchema = false
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
package com.meloda.fast.database.old
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
import com.meloda.fast.common.AppGlobal.Companion.oldDatabase
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_CHATS
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_FRIENDS
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_MESSAGES
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_USERS
|
||||
import com.meloda.fast.database.old.storage.ChatsStorage
|
||||
import com.meloda.fast.database.old.storage.GroupsStorage
|
||||
import com.meloda.fast.database.old.storage.MessagesStorage
|
||||
import com.meloda.fast.database.old.storage.UsersStorage
|
||||
import com.meloda.fast.api.model.old.oldVKConversation
|
||||
import com.meloda.fast.api.model.old.oldVKMessage
|
||||
import com.meloda.fast.api.model.old.oldVKUser
|
||||
import java.util.*
|
||||
|
||||
object CacheStorage {
|
||||
|
||||
val usersStorage = UsersStorage()
|
||||
val messagesStorage = MessagesStorage()
|
||||
val chatsStorage = ChatsStorage()
|
||||
val groupsStorage = GroupsStorage()
|
||||
|
||||
fun selectCursor(tableName: String): Cursor {
|
||||
return QueryBuilder.query()
|
||||
.select("*").from(tableName)
|
||||
.asCursor(oldDatabase)
|
||||
}
|
||||
|
||||
fun selectCursor(tableName: String, where: String): Cursor {
|
||||
return QueryBuilder.query()
|
||||
.select("*").from(tableName)
|
||||
.where(where)
|
||||
.asCursor(oldDatabase)
|
||||
}
|
||||
|
||||
fun selectCursor(tableName: String, columnName: String, value: Any): Cursor {
|
||||
return QueryBuilder.query()
|
||||
.select("*").from(tableName)
|
||||
.where("$columnName=$value")
|
||||
.asCursor(oldDatabase)
|
||||
}
|
||||
|
||||
fun selectCursor(tableName: String, columnName: String, ids: IntArray): Cursor {
|
||||
val where = StringBuilder(5 * ids.size)
|
||||
|
||||
where.append("$columnName=${ids[0]}")
|
||||
|
||||
for (i in 1 until ids.size) {
|
||||
where.append(" OR ")
|
||||
where.append("$columnName=${ids[i]}")
|
||||
}
|
||||
|
||||
return selectCursor(tableName, where.toString())
|
||||
}
|
||||
|
||||
fun getInt(cursor: Cursor, columnName: String) =
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(columnName))
|
||||
|
||||
fun getString(cursor: Cursor, columnName: String) =
|
||||
cursor.getString(cursor.getColumnIndexOrThrow(columnName))
|
||||
|
||||
fun getBlob(cursor: Cursor, columnName: String) =
|
||||
cursor.getBlob(cursor.getColumnIndexOrThrow(columnName))
|
||||
|
||||
fun <T> insert(tableName: String, values: ArrayList<T>) {
|
||||
oldDatabase.beginTransaction()
|
||||
|
||||
val contentValues = ContentValues()
|
||||
|
||||
for (value in values) {
|
||||
when (tableName) {
|
||||
TABLE_USERS -> {
|
||||
usersStorage.cacheValue(contentValues, value as oldVKUser)
|
||||
break
|
||||
}
|
||||
TABLE_FRIENDS -> {
|
||||
usersStorage.cacheValue(
|
||||
contentValues,
|
||||
value as oldVKUser,
|
||||
Bundle().apply { putBoolean("toFriends", true) })
|
||||
break
|
||||
}
|
||||
TABLE_MESSAGES -> {
|
||||
messagesStorage.cacheValue(contentValues, value as oldVKMessage)
|
||||
break
|
||||
}
|
||||
TABLE_CHATS -> {
|
||||
chatsStorage.cacheValue(contentValues, value as oldVKConversation)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
oldDatabase.insert(tableName, null, contentValues)
|
||||
contentValues.clear()
|
||||
}
|
||||
|
||||
oldDatabase.setTransactionSuccessful()
|
||||
oldDatabase.endTransaction()
|
||||
}
|
||||
|
||||
fun delete(tableName: String, whereClause: String, vararg whereArgs: String) {
|
||||
oldDatabase.delete(tableName, whereClause, whereArgs)
|
||||
}
|
||||
|
||||
fun delete(tableName: String) {
|
||||
oldDatabase.delete(tableName, null, null)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
package com.meloda.fast.database.old
|
||||
|
||||
import android.content.Context
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
|
||||
class DatabaseHelper constructor(context: Context) : SQLiteOpenHelper(
|
||||
context,
|
||||
DB_NAME,
|
||||
null,
|
||||
DB_VERSION
|
||||
) {
|
||||
companion object {
|
||||
private const val DB_NAME = "cache.db"
|
||||
private const val DB_VERSION = 1
|
||||
}
|
||||
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
db.execSQL(DatabaseUtils.createUsersTable())
|
||||
db.execSQL(DatabaseUtils.createGroupsTable())
|
||||
db.execSQL(DatabaseUtils.createFriendsTable())
|
||||
db.execSQL(DatabaseUtils.createMessagesTable())
|
||||
db.execSQL(DatabaseUtils.createChatsTable())
|
||||
}
|
||||
|
||||
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package com.meloda.fast.database.old
|
||||
|
||||
object DatabaseKeys {
|
||||
|
||||
const val ID = "_id"
|
||||
|
||||
const val SORT_ID = "_sort_id"
|
||||
|
||||
const val USER_ID = "_user_id"
|
||||
|
||||
const val FIRST_NAME = "_first_name"
|
||||
|
||||
const val LAST_NAME = "_last_name"
|
||||
|
||||
const val DEACTIVATED = "_deactivated"
|
||||
|
||||
const val GENDER = "_gender"
|
||||
|
||||
const val SCREEN_NAME = "_screen_name"
|
||||
|
||||
const val PHOTOS = "_photos"
|
||||
|
||||
const val IS_ONLINE = "_is_online"
|
||||
|
||||
const val IS_ONLINE_MOBILE = "_is_online_mobile"
|
||||
|
||||
const val STATUS = "_status"
|
||||
|
||||
const val LAST_SEEN = "_last_seen"
|
||||
|
||||
const val MESSAGE_ID = "_message_id"
|
||||
|
||||
const val DATE = "_date"
|
||||
|
||||
const val PEER_ID = "_peer_id"
|
||||
|
||||
const val FROM_ID = "_from_id"
|
||||
|
||||
const val EDIT_TIME = "_edit_time"
|
||||
|
||||
const val IS_OUT = "_is_out"
|
||||
|
||||
const val TEXT = "_text"
|
||||
|
||||
const val RANDOM_ID = "_random_id"
|
||||
|
||||
const val CONVERSATION_MESSAGE_ID = "_conversation_message_id"
|
||||
|
||||
const val ATTACHMENTS = "_attachments"
|
||||
|
||||
const val FWD_MESSAGES = "_fwd_messages"
|
||||
|
||||
const val REPLY_MESSAGE_ID = "_reply_message_id"
|
||||
|
||||
const val ACTION = "_action"
|
||||
|
||||
const val IS_ALLOWED = "_is_allowed"
|
||||
|
||||
const val NOT_ALLOWED_REASON = "_not_allowed_reason"
|
||||
|
||||
const val IN_READ_MESSAGE_ID = "_in_read_message_id"
|
||||
|
||||
const val OUT_READ_MESSAGE_ID = "_out_read_message_id"
|
||||
|
||||
const val LAST_MESSAGE_ID = "_last_message_id"
|
||||
|
||||
const val UNREAD_COUNT = "_unread_count"
|
||||
|
||||
const val CONVERSATION_ID = "_conversation_id"
|
||||
|
||||
const val TYPE = "_type"
|
||||
|
||||
const val LOCAL_ID = "_local_id"
|
||||
|
||||
const val IS_NOTIFICATIONS_DISABLED = "_is_notifications_disabled"
|
||||
|
||||
const val MEMBERS_COUNT = "_members_count"
|
||||
|
||||
const val TITLE = "_title"
|
||||
|
||||
const val PINNED_MESSAGE_ID = "_pinned_message_id"
|
||||
|
||||
const val CHAT_STATE = "_chat_state"
|
||||
|
||||
const val IS_GROUP_CHANNEL = "_is_group_channel"
|
||||
|
||||
const val FRIEND_ID = "_friend_id"
|
||||
|
||||
const val GROUP_ID = "_group_id"
|
||||
|
||||
const val NAME = "_name"
|
||||
|
||||
const val IS_CLOSED = "_is_closed"
|
||||
|
||||
}
|
||||
@@ -1,153 +0,0 @@
|
||||
package com.meloda.fast.database.old
|
||||
|
||||
import com.meloda.fast.database.old.DatabaseKeys.ACTION
|
||||
import com.meloda.fast.database.old.DatabaseKeys.ATTACHMENTS
|
||||
import com.meloda.fast.database.old.DatabaseKeys.CHAT_STATE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.CONVERSATION_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.CONVERSATION_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.DATE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.DEACTIVATED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.EDIT_TIME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.FIRST_NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.FRIEND_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.FROM_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.FWD_MESSAGES
|
||||
import com.meloda.fast.database.old.DatabaseKeys.GENDER
|
||||
import com.meloda.fast.database.old.DatabaseKeys.GROUP_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IN_READ_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_ALLOWED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_CLOSED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_GROUP_CHANNEL
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_NOTIFICATIONS_DISABLED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_ONLINE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_ONLINE_MOBILE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_OUT
|
||||
import com.meloda.fast.database.old.DatabaseKeys.LAST_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.LAST_NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.LAST_SEEN
|
||||
import com.meloda.fast.database.old.DatabaseKeys.LOCAL_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.MEMBERS_COUNT
|
||||
import com.meloda.fast.database.old.DatabaseKeys.MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.NOT_ALLOWED_REASON
|
||||
import com.meloda.fast.database.old.DatabaseKeys.OUT_READ_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.PEER_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.PHOTOS
|
||||
import com.meloda.fast.database.old.DatabaseKeys.PINNED_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.RANDOM_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.REPLY_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.SCREEN_NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.SORT_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.STATUS
|
||||
import com.meloda.fast.database.old.DatabaseKeys.TEXT
|
||||
import com.meloda.fast.database.old.DatabaseKeys.TITLE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.TYPE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.UNREAD_COUNT
|
||||
import com.meloda.fast.database.old.DatabaseKeys.USER_ID
|
||||
|
||||
object DatabaseUtils {
|
||||
|
||||
const val TABLE_USERS = "users"
|
||||
const val TABLE_MESSAGES = "messages"
|
||||
const val TABLE_CHATS = "chats"
|
||||
const val TABLE_FRIENDS = "friends"
|
||||
const val TABLE_GROUPS = "groups"
|
||||
|
||||
private val usersTableMap = HashMap<String, String>().apply {
|
||||
this[USER_ID] = "integer primary key on conflict replace"
|
||||
this[FIRST_NAME] = "varchar(255)"
|
||||
this[LAST_NAME] = "varchar(255)"
|
||||
this[DEACTIVATED] = "varchar(255)"
|
||||
this[GENDER] = "integer default 0"
|
||||
this[SCREEN_NAME] = "varchar(255)"
|
||||
this[PHOTOS] = "text"
|
||||
this[IS_ONLINE] = "integer default 0"
|
||||
this[IS_ONLINE_MOBILE] = "integer default 0"
|
||||
this[STATUS] = "varchar(255)"
|
||||
this[LAST_SEEN] = "integer"
|
||||
}
|
||||
|
||||
private val groupsTableMap = HashMap<String, String>().apply {
|
||||
this[GROUP_ID] = "integer primary key on conflict replace"
|
||||
this[NAME] = "varchar(255)"
|
||||
this[SCREEN_NAME] = "varchar(255)"
|
||||
this[IS_CLOSED] = "integer default 0"
|
||||
this[DEACTIVATED] = "varchar(255)"
|
||||
this[TYPE] = "varchar(255)"
|
||||
this[PHOTOS] = "text"
|
||||
}
|
||||
|
||||
private val messagesTableMap = HashMap<String, String>().apply {
|
||||
this[MESSAGE_ID] = "integer primary key on conflict replace"
|
||||
this[DATE] = "integer"
|
||||
this[PEER_ID] = "integer"
|
||||
this[FROM_ID] = "integer"
|
||||
this[EDIT_TIME] = "integer"
|
||||
this[IS_OUT] = "integer default 0"
|
||||
this[TEXT] = "text"
|
||||
this[RANDOM_ID] = "integer"
|
||||
this[CONVERSATION_MESSAGE_ID] = "integer"
|
||||
this[ATTACHMENTS] = "blob"
|
||||
this[REPLY_MESSAGE_ID] = "integer"
|
||||
this[ACTION] = "blob"
|
||||
|
||||
//2,3,4,5 - message_ids
|
||||
this[FWD_MESSAGES] = "text"
|
||||
}
|
||||
|
||||
private val chatsTableMap = HashMap<String, String>().apply {
|
||||
this[CONVERSATION_ID] = "integer primary key on conflict replace"
|
||||
this[IS_ALLOWED] = "integer default 1"
|
||||
this[NOT_ALLOWED_REASON] = "integer"
|
||||
this[IN_READ_MESSAGE_ID] = "integer"
|
||||
this[OUT_READ_MESSAGE_ID] = "integer"
|
||||
this[LAST_MESSAGE_ID] = "integer"
|
||||
this[UNREAD_COUNT] = "integer"
|
||||
this[LOCAL_ID] = "integer"
|
||||
this[IS_NOTIFICATIONS_DISABLED] = "integer default 0"
|
||||
this[MEMBERS_COUNT] = "integer"
|
||||
this[TITLE] = "varchar(255)"
|
||||
this[IS_GROUP_CHANNEL] = "integer default 0"
|
||||
this[TYPE] = "integer"
|
||||
this[CHAT_STATE] = "integer"
|
||||
this[PHOTOS] = "text"
|
||||
|
||||
this[PINNED_MESSAGE_ID] = "integer"
|
||||
}
|
||||
|
||||
private val friendsTableMap = HashMap<String, String>().apply {
|
||||
this[FRIEND_ID] = "integer primary key on conflict replace"
|
||||
this[SORT_ID] = "integer"
|
||||
|
||||
//id which user friend
|
||||
this[USER_ID] = "integer"
|
||||
}
|
||||
|
||||
fun createUsersTable() = createTableQuery(TABLE_USERS, usersTableMap)
|
||||
fun createGroupsTable() = createTableQuery(TABLE_GROUPS, groupsTableMap)
|
||||
fun createMessagesTable() = createTableQuery(TABLE_MESSAGES, messagesTableMap)
|
||||
fun createChatsTable() = createTableQuery(TABLE_CHATS, chatsTableMap)
|
||||
fun createFriendsTable() = createTableQuery(TABLE_FRIENDS, friendsTableMap)
|
||||
|
||||
private fun createTableQuery(tableName: String, tableData: HashMap<String, String>): String {
|
||||
val builder = StringBuilder("create table $tableName (")
|
||||
|
||||
val entry: Map.Entry<String, String> = tableData.entries.first()
|
||||
builder.append(entry.key)
|
||||
builder.append(" ")
|
||||
builder.append(entry.value)
|
||||
|
||||
tableData.forEach {
|
||||
if (it == entry) return@forEach
|
||||
builder.append(", ")
|
||||
builder.append(it.key)
|
||||
builder.append(" ")
|
||||
builder.append(it.value)
|
||||
}
|
||||
|
||||
builder.append(");")
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package com.meloda.fast.database.old
|
||||
|
||||
import android.database.Cursor
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
|
||||
|
||||
class QueryBuilder private constructor() {
|
||||
|
||||
companion object {
|
||||
fun query(): QueryBuilder {
|
||||
return QueryBuilder()
|
||||
}
|
||||
}
|
||||
|
||||
private val builder: StringBuilder = StringBuilder()
|
||||
|
||||
fun select(column: String): QueryBuilder {
|
||||
builder.append("SELECT ")
|
||||
.append(column)
|
||||
.append(" ")
|
||||
return this
|
||||
}
|
||||
|
||||
fun from(table: String): QueryBuilder {
|
||||
builder.append("FROM ")
|
||||
.append(table)
|
||||
.append(" ")
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
fun where(clause: String): QueryBuilder {
|
||||
builder.append("WHERE ")
|
||||
.append(clause)
|
||||
.append(" ")
|
||||
return this
|
||||
}
|
||||
|
||||
fun leftJoin(table: String): QueryBuilder {
|
||||
builder.append("LEFT JOIN ")
|
||||
.append(table)
|
||||
.append(" ")
|
||||
return this
|
||||
}
|
||||
|
||||
fun on(where: String): QueryBuilder {
|
||||
builder.append("ON ")
|
||||
.append(where)
|
||||
.append(" ")
|
||||
return this
|
||||
}
|
||||
|
||||
fun and(): QueryBuilder {
|
||||
builder.append("AND ")
|
||||
return this
|
||||
}
|
||||
|
||||
fun or(): QueryBuilder {
|
||||
builder.append("OR ")
|
||||
return this
|
||||
}
|
||||
|
||||
fun asCursor(db: SQLiteDatabase): Cursor {
|
||||
return db.rawQuery(toString(), null)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return builder.toString().trim()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.meloda.fast.database.old.base
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.common.AppGlobal
|
||||
|
||||
abstract class Storage<T> {
|
||||
|
||||
abstract val tag: String
|
||||
|
||||
protected var database = AppGlobal.oldDatabase
|
||||
|
||||
@WorkerThread
|
||||
abstract fun getAllValues(): ArrayList<T>
|
||||
|
||||
@WorkerThread
|
||||
abstract fun insertValues(values: ArrayList<T>, params: Bundle? = null)
|
||||
|
||||
@WorkerThread
|
||||
fun insertValue(value: T, params: Bundle? = null) {
|
||||
insertValues(arrayListOf(value), params)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
abstract fun cacheValue(values: ContentValues, value: T, params: Bundle? = null)
|
||||
|
||||
@WorkerThread
|
||||
abstract fun parseValue(cursor: Cursor): T
|
||||
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package com.meloda.fast.database.old.storage
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.database.old.CacheStorage
|
||||
import com.meloda.fast.database.old.CacheStorage.messagesStorage
|
||||
import com.meloda.fast.database.old.DatabaseKeys.CHAT_STATE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.CONVERSATION_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IN_READ_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_ALLOWED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_GROUP_CHANNEL
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_NOTIFICATIONS_DISABLED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.LAST_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.LOCAL_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.MEMBERS_COUNT
|
||||
import com.meloda.fast.database.old.DatabaseKeys.NOT_ALLOWED_REASON
|
||||
import com.meloda.fast.database.old.DatabaseKeys.OUT_READ_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.PHOTOS
|
||||
import com.meloda.fast.database.old.DatabaseKeys.PINNED_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.TITLE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.TYPE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.UNREAD_COUNT
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_CHATS
|
||||
import com.meloda.fast.database.old.base.Storage
|
||||
import com.meloda.fast.api.model.old.oldVKConversation
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import org.json.JSONObject
|
||||
|
||||
@WorkerThread
|
||||
class ChatsStorage : Storage<oldVKConversation>() {
|
||||
|
||||
override val tag = "ChatsStorage"
|
||||
|
||||
override fun getAllValues(): ArrayList<oldVKConversation> {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_CHATS)
|
||||
val conversations = ArrayList<oldVKConversation>()
|
||||
|
||||
while (cursor.moveToNext()) conversations.add(parseValue(cursor))
|
||||
|
||||
cursor.close()
|
||||
|
||||
return conversations
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun insertValues(values: ArrayList<oldVKConversation>, params: Bundle?) {
|
||||
if (values.isEmpty()) return
|
||||
|
||||
database.beginTransaction()
|
||||
|
||||
val contentValues = ContentValues()
|
||||
|
||||
for (value in values) {
|
||||
cacheValue(contentValues, value, params)
|
||||
|
||||
database.insert(TABLE_CHATS, null, contentValues)
|
||||
|
||||
contentValues.clear()
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful()
|
||||
database.endTransaction()
|
||||
|
||||
Log.d(tag, "Successful cached chats")
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun cacheValue(values: ContentValues, value: oldVKConversation, params: Bundle?) {
|
||||
values.put(CONVERSATION_ID, value.id)
|
||||
values.put(IS_ALLOWED, value.isAllowed)
|
||||
values.put(NOT_ALLOWED_REASON, value.notAllowedReason.value)
|
||||
values.put(IN_READ_MESSAGE_ID, value.inReadMessageId)
|
||||
values.put(OUT_READ_MESSAGE_ID, value.outReadMessageId)
|
||||
values.put(LAST_MESSAGE_ID, value.lastMessageId)
|
||||
values.put(UNREAD_COUNT, value.unreadCount)
|
||||
values.put(LOCAL_ID, value.localId)
|
||||
values.put(IS_NOTIFICATIONS_DISABLED, value.notificationsEnabled)
|
||||
values.put(MEMBERS_COUNT, value.membersCount)
|
||||
values.put(TITLE, value.title)
|
||||
values.put(IS_GROUP_CHANNEL, value.isGroupChannel)
|
||||
values.put(TYPE, value.intType)
|
||||
values.put(CHAT_STATE, value.intState)
|
||||
|
||||
values.put(
|
||||
PHOTOS,
|
||||
oldVKUtil.putPhotosToJson(
|
||||
value.photo50,
|
||||
value.photo100,
|
||||
value.photo200
|
||||
).toString()
|
||||
)
|
||||
|
||||
value.pinnedMessage?.let {
|
||||
values.put(PINNED_MESSAGE_ID, it.id)
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun parseValue(cursor: Cursor): oldVKConversation {
|
||||
val conversation = oldVKConversation()
|
||||
|
||||
conversation.id = CacheStorage.getInt(cursor, CONVERSATION_ID)
|
||||
conversation.isAllowed = CacheStorage.getInt(cursor, IS_ALLOWED) == 1
|
||||
conversation.notAllowedReason = oldVKConversation.Reason.fromInt(
|
||||
CacheStorage.getInt(cursor, NOT_ALLOWED_REASON)
|
||||
)
|
||||
conversation.inReadMessageId = CacheStorage.getInt(cursor, IN_READ_MESSAGE_ID)
|
||||
conversation.outReadMessageId = CacheStorage.getInt(cursor, OUT_READ_MESSAGE_ID)
|
||||
conversation.unreadCount = CacheStorage.getInt(cursor, UNREAD_COUNT)
|
||||
conversation.localId = CacheStorage.getInt(cursor, LOCAL_ID)
|
||||
conversation.notificationsEnabled =
|
||||
CacheStorage.getInt(cursor, IS_NOTIFICATIONS_DISABLED) == 1
|
||||
conversation.membersCount = CacheStorage.getInt(cursor, MEMBERS_COUNT)
|
||||
conversation.title = CacheStorage.getString(cursor, TITLE)
|
||||
conversation.isGroupChannel = CacheStorage.getInt(cursor, IS_GROUP_CHANNEL) == 1
|
||||
|
||||
val pinnedMessageId = CacheStorage.getInt(cursor, PINNED_MESSAGE_ID)
|
||||
if (pinnedMessageId != -1) {
|
||||
val pinnedMessage = messagesStorage.getMessageById(pinnedMessageId)
|
||||
if (pinnedMessage != null) conversation.pinnedMessage = pinnedMessage
|
||||
}
|
||||
|
||||
conversation.intType = CacheStorage.getInt(cursor, TYPE)
|
||||
conversation.intState = CacheStorage.getInt(cursor, CHAT_STATE)
|
||||
|
||||
conversation.lastMessageId = CacheStorage.getInt(cursor, LAST_MESSAGE_ID)
|
||||
val lastMessage = messagesStorage.getMessageById(conversation.lastMessageId)
|
||||
if (lastMessage != null) conversation.lastMessage = lastMessage
|
||||
|
||||
val photos = oldVKUtil.parseJsonPhotos(JSONObject(CacheStorage.getString(cursor, PHOTOS)))
|
||||
conversation.photo50 = photos[0]
|
||||
conversation.photo100 = photos[1]
|
||||
conversation.photo200 = photos[2]
|
||||
|
||||
return conversation
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package com.meloda.fast.database.old.storage
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.database.old.CacheStorage
|
||||
import com.meloda.fast.database.old.CacheStorage.getInt
|
||||
import com.meloda.fast.database.old.CacheStorage.getString
|
||||
import com.meloda.fast.database.old.DatabaseKeys.DEACTIVATED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.GROUP_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_CLOSED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.PHOTOS
|
||||
import com.meloda.fast.database.old.DatabaseKeys.SCREEN_NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.TYPE
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_GROUPS
|
||||
import com.meloda.fast.database.old.base.Storage
|
||||
import com.meloda.fast.api.model.old.oldVKGroup
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import org.json.JSONObject
|
||||
|
||||
class GroupsStorage : Storage<oldVKGroup>() {
|
||||
|
||||
override val tag = "GroupsStorage"
|
||||
|
||||
@WorkerThread
|
||||
fun getGroups(ids: IntArray): ArrayList<oldVKGroup> {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_GROUPS, GROUP_ID, ids)
|
||||
|
||||
val groups = ArrayList<oldVKGroup>(cursor.count)
|
||||
while (cursor.moveToNext()) groups.add(parseValue(cursor))
|
||||
|
||||
cursor.close()
|
||||
return groups
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun getGroup(userId: Int): oldVKGroup? {
|
||||
val group = getGroups(intArrayOf(userId))
|
||||
|
||||
return if (group.isNotEmpty()) group[0] else null
|
||||
}
|
||||
|
||||
override fun getAllValues(): ArrayList<oldVKGroup> {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_GROUPS)
|
||||
val groups = ArrayList<oldVKGroup>()
|
||||
|
||||
while (cursor.moveToNext()) groups.add(parseValue(cursor))
|
||||
|
||||
cursor.close()
|
||||
|
||||
return groups
|
||||
}
|
||||
|
||||
override fun insertValues(values: ArrayList<oldVKGroup>, params: Bundle?) {
|
||||
if (values.isEmpty()) return
|
||||
|
||||
database.beginTransaction()
|
||||
|
||||
val contentValues = ContentValues()
|
||||
|
||||
for (value in values) {
|
||||
cacheValue(contentValues, value, params)
|
||||
|
||||
database.insert(TABLE_GROUPS, null, contentValues)
|
||||
|
||||
contentValues.clear()
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful()
|
||||
database.endTransaction()
|
||||
|
||||
Log.d(tag, "Successful cached groups")
|
||||
}
|
||||
|
||||
override fun cacheValue(values: ContentValues, value: oldVKGroup, params: Bundle?) {
|
||||
values.put(GROUP_ID, value.id)
|
||||
values.put(NAME, value.name)
|
||||
values.put(SCREEN_NAME, value.screenName)
|
||||
values.put(IS_CLOSED, value.isClosed)
|
||||
values.put(DEACTIVATED, value.deactivated)
|
||||
values.put(TYPE, value.type.value)
|
||||
|
||||
val photos =
|
||||
oldVKUtil.putPhotosToJson(value.photo50, value.photo100, value.photo200).toString()
|
||||
|
||||
values.put(PHOTOS, photos)
|
||||
}
|
||||
|
||||
override fun parseValue(cursor: Cursor): oldVKGroup {
|
||||
val group = oldVKGroup()
|
||||
|
||||
group.id = getInt(cursor, GROUP_ID)
|
||||
group.name = getString(cursor, NAME)
|
||||
group.screenName = getString(cursor, SCREEN_NAME)
|
||||
group.isClosed = getInt(cursor, IS_CLOSED) == 1
|
||||
group.deactivated = getString(cursor, DEACTIVATED)
|
||||
group.type = oldVKGroup.Type.fromString(getString(cursor, TYPE))
|
||||
|
||||
val photos = oldVKUtil.parseJsonPhotos(JSONObject(getString(cursor, PHOTOS)))
|
||||
|
||||
group.photo50 = photos[0]
|
||||
group.photo100 = photos[1]
|
||||
group.photo200 = photos[2]
|
||||
|
||||
return group
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package com.meloda.fast.database.old.storage
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.database.old.CacheStorage
|
||||
import com.meloda.fast.database.old.CacheStorage.selectCursor
|
||||
import com.meloda.fast.database.old.DatabaseKeys.ACTION
|
||||
import com.meloda.fast.database.old.DatabaseKeys.ATTACHMENTS
|
||||
import com.meloda.fast.database.old.DatabaseKeys.CONVERSATION_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.DATE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.EDIT_TIME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.FROM_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.FWD_MESSAGES
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_OUT
|
||||
import com.meloda.fast.database.old.DatabaseKeys.MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.PEER_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.RANDOM_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.REPLY_MESSAGE_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.TEXT
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_MESSAGES
|
||||
import com.meloda.fast.database.old.base.Storage
|
||||
import com.meloda.fast.util.Utils
|
||||
import com.meloda.fast.api.model.old.oldVKMessage
|
||||
import com.meloda.fast.api.model.old.oldVKMessageAction
|
||||
import com.meloda.fast.api.model.old.VKModel
|
||||
import java.util.stream.Collectors
|
||||
|
||||
@WorkerThread
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class MessagesStorage : Storage<oldVKMessage>() {
|
||||
|
||||
override val tag = "MessagesStorage"
|
||||
|
||||
@WorkerThread
|
||||
fun getMessagesHistory(peerId: Int): ArrayList<oldVKMessage> {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_MESSAGES, PEER_ID, peerId)
|
||||
|
||||
val messages = ArrayList<oldVKMessage>(cursor.count)
|
||||
while (cursor.moveToNext()) messages.add(parseValue(cursor))
|
||||
|
||||
cursor.close()
|
||||
|
||||
return messages
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun getMessageById(messageId: Int): oldVKMessage? {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_MESSAGES, MESSAGE_ID, messageId)
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
val message = parseValue(cursor)
|
||||
cursor.close()
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getAllValues(): ArrayList<oldVKMessage> {
|
||||
val cursor = selectCursor(TABLE_MESSAGES)
|
||||
val messages = ArrayList<oldVKMessage>()
|
||||
|
||||
while (cursor.moveToNext()) messages.add(parseValue(cursor))
|
||||
|
||||
cursor.close()
|
||||
|
||||
return messages
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun insertValues(values: ArrayList<oldVKMessage>, params: Bundle?) {
|
||||
if (values.isEmpty()) return
|
||||
|
||||
database.beginTransaction()
|
||||
|
||||
val contentValues = ContentValues()
|
||||
|
||||
for (value in values) {
|
||||
cacheValue(contentValues, value)
|
||||
|
||||
database.insert(TABLE_MESSAGES, null, contentValues)
|
||||
|
||||
contentValues.clear()
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful()
|
||||
database.endTransaction()
|
||||
|
||||
Log.d(tag, "Successful cached messages")
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun cacheValue(values: ContentValues, value: oldVKMessage, params: Bundle?) {
|
||||
values.put(MESSAGE_ID, value.id)
|
||||
values.put(DATE, value.date)
|
||||
values.put(PEER_ID, value.peerId)
|
||||
values.put(FROM_ID, value.fromId)
|
||||
values.put(EDIT_TIME, value.editTime)
|
||||
values.put(TEXT, value.text)
|
||||
values.put(RANDOM_ID, value.randomId)
|
||||
values.put(CONVERSATION_MESSAGE_ID, value.conversationMessageId)
|
||||
|
||||
value.replyMessage?.let {
|
||||
values.put(REPLY_MESSAGE_ID, it.id)
|
||||
}
|
||||
|
||||
value.action?.let {
|
||||
values.put(ACTION, Utils.serialize(it))
|
||||
}
|
||||
|
||||
value.attachments.let {
|
||||
if (it.isNotEmpty()) {
|
||||
values.put(ATTACHMENTS, Utils.serialize(it))
|
||||
}
|
||||
}
|
||||
|
||||
value.fwdMessages.let {
|
||||
if (it.isNotEmpty()) {
|
||||
val ids = arrayListOf<String>()
|
||||
it.forEach { message -> ids.add(message.id.toString()) }
|
||||
|
||||
ids.stream().collect(Collectors.joining(",")).let { str ->
|
||||
values.put(FWD_MESSAGES, str)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun parseValue(cursor: Cursor): oldVKMessage {
|
||||
val message = oldVKMessage()
|
||||
|
||||
message.id = CacheStorage.getInt(cursor, MESSAGE_ID)
|
||||
message.date = CacheStorage.getInt(cursor, DATE)
|
||||
message.peerId = CacheStorage.getInt(cursor, PEER_ID)
|
||||
message.fromId = CacheStorage.getInt(cursor, FROM_ID)
|
||||
message.editTime = CacheStorage.getInt(cursor, EDIT_TIME)
|
||||
message.isOut = CacheStorage.getInt(cursor, IS_OUT) == 1
|
||||
message.text = CacheStorage.getString(cursor, TEXT)
|
||||
message.randomId = CacheStorage.getInt(cursor, RANDOM_ID)
|
||||
message.conversationMessageId = CacheStorage.getInt(cursor, CONVERSATION_MESSAGE_ID)
|
||||
|
||||
val blobAttachments = Utils.deserialize(CacheStorage.getBlob(cursor, ATTACHMENTS))
|
||||
if (blobAttachments != null) message.attachments = blobAttachments as ArrayList<VKModel>
|
||||
else message.attachments = arrayListOf()
|
||||
|
||||
val replyMessageId = CacheStorage.getInt(cursor, REPLY_MESSAGE_ID)
|
||||
val replyMessage = getMessageById(replyMessageId)
|
||||
if (replyMessage != null) message.replyMessage = replyMessage
|
||||
|
||||
val blobAction = Utils.deserialize(CacheStorage.getBlob(cursor, ACTION))
|
||||
if (blobAction != null) message.action = blobAction as oldVKMessageAction
|
||||
|
||||
val stringFwdMessages = CacheStorage.getString(cursor, FWD_MESSAGES)
|
||||
if (stringFwdMessages != null) {
|
||||
val split = stringFwdMessages.split(',')
|
||||
|
||||
val ids = arrayListOf<Int>()
|
||||
for (s in split) ids.add(s.toInt())
|
||||
|
||||
val fwdMessages = arrayListOf<oldVKMessage>()
|
||||
|
||||
ids.forEach {
|
||||
val fwdMessage = getMessageById(it)
|
||||
if (fwdMessage != null) fwdMessages.add(fwdMessage)
|
||||
}
|
||||
|
||||
message.fwdMessages = fwdMessages
|
||||
} else message.fwdMessages = arrayListOf()
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
package com.meloda.fast.database.old.storage
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.api.UserConfig
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import com.meloda.fast.api.model.old.oldVKUser
|
||||
import com.meloda.fast.database.old.CacheStorage
|
||||
import com.meloda.fast.database.old.DatabaseKeys.DEACTIVATED
|
||||
import com.meloda.fast.database.old.DatabaseKeys.FIRST_NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.FRIEND_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.GENDER
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_ONLINE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.IS_ONLINE_MOBILE
|
||||
import com.meloda.fast.database.old.DatabaseKeys.LAST_NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.LAST_SEEN
|
||||
import com.meloda.fast.database.old.DatabaseKeys.PHOTOS
|
||||
import com.meloda.fast.database.old.DatabaseKeys.SCREEN_NAME
|
||||
import com.meloda.fast.database.old.DatabaseKeys.SORT_ID
|
||||
import com.meloda.fast.database.old.DatabaseKeys.STATUS
|
||||
import com.meloda.fast.database.old.DatabaseKeys.USER_ID
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_FRIENDS
|
||||
import com.meloda.fast.database.old.DatabaseUtils.TABLE_USERS
|
||||
import com.meloda.fast.database.old.QueryBuilder
|
||||
import com.meloda.fast.database.old.base.Storage
|
||||
import org.json.JSONObject
|
||||
|
||||
@WorkerThread
|
||||
class UsersStorage : Storage<oldVKUser>() {
|
||||
|
||||
override val tag = "UsersStorage"
|
||||
|
||||
@WorkerThread
|
||||
fun getUsers(ids: IntArray): ArrayList<oldVKUser> {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_USERS, USER_ID, ids)
|
||||
|
||||
val users = ArrayList<oldVKUser>(cursor.count)
|
||||
while (cursor.moveToNext()) users.add(parseValue(cursor))
|
||||
|
||||
cursor.close()
|
||||
return users
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun getUser(userId: Int): oldVKUser? {
|
||||
val user = getUsers(intArrayOf(userId))
|
||||
|
||||
return if (user.isNotEmpty()) user[0] else null
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
fun getFriends(userId: Int, onlyOnline: Boolean = false): ArrayList<oldVKUser> {
|
||||
val cursor = QueryBuilder.query()
|
||||
.select("*")
|
||||
.from(TABLE_FRIENDS)
|
||||
.leftJoin(TABLE_USERS)
|
||||
.on("friends.${FRIEND_ID} = users.$USER_ID")
|
||||
.where("friends.${USER_ID} = $userId")
|
||||
.asCursor(database)
|
||||
|
||||
val users = ArrayList<oldVKUser>(cursor.count)
|
||||
|
||||
while (cursor.moveToNext()) {
|
||||
val userOnline = CacheStorage.getInt(cursor, IS_ONLINE) == 1
|
||||
if (onlyOnline && !userOnline) continue
|
||||
|
||||
val user = parseValue(cursor)
|
||||
users.add(user)
|
||||
}
|
||||
|
||||
cursor.close()
|
||||
|
||||
return users
|
||||
}
|
||||
|
||||
override fun getAllValues(): ArrayList<oldVKUser> {
|
||||
val cursor = CacheStorage.selectCursor(TABLE_USERS)
|
||||
val users = ArrayList<oldVKUser>()
|
||||
|
||||
while (cursor.moveToNext()) users.add(parseValue(cursor))
|
||||
|
||||
cursor.close()
|
||||
|
||||
return users
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun insertValues(values: ArrayList<oldVKUser>, params: Bundle?) {
|
||||
if (values.isEmpty()) return
|
||||
|
||||
val toFriends = params?.getBoolean("toFriends") ?: false
|
||||
|
||||
database.beginTransaction()
|
||||
|
||||
val contentValues = ContentValues()
|
||||
|
||||
for (user in values) {
|
||||
cacheValue(contentValues, user, params)
|
||||
|
||||
database.insert(if (toFriends) TABLE_FRIENDS else TABLE_USERS, null, contentValues)
|
||||
|
||||
contentValues.clear()
|
||||
}
|
||||
|
||||
database.setTransactionSuccessful()
|
||||
database.endTransaction()
|
||||
|
||||
Log.d(tag, "Successful cached users. toFriends: $toFriends")
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun cacheValue(values: ContentValues, value: oldVKUser, params: Bundle?) {
|
||||
val toFriends = params?.getBoolean("toFriends") ?: false
|
||||
|
||||
if (toFriends) {
|
||||
values.put(USER_ID, UserConfig.userId)
|
||||
values.put(FRIEND_ID, value.userId)
|
||||
values.put(SORT_ID, value.sortId)
|
||||
return
|
||||
}
|
||||
|
||||
values.put(USER_ID, value.userId)
|
||||
values.put(FIRST_NAME, value.firstName)
|
||||
values.put(LAST_NAME, value.lastName)
|
||||
values.put(DEACTIVATED, value.deactivated)
|
||||
values.put(GENDER, value.sex)
|
||||
values.put(SCREEN_NAME, value.screenName)
|
||||
values.put(IS_ONLINE, value.isOnline)
|
||||
values.put(IS_ONLINE_MOBILE, value.isOnlineMobile)
|
||||
values.put(STATUS, value.status)
|
||||
values.put(LAST_SEEN, value.lastSeen)
|
||||
|
||||
values.put(
|
||||
PHOTOS,
|
||||
oldVKUtil.putPhotosToJson(
|
||||
value.photo50,
|
||||
value.photo100,
|
||||
value.photo200
|
||||
).toString()
|
||||
)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
override fun parseValue(cursor: Cursor): oldVKUser {
|
||||
val user = oldVKUser()
|
||||
|
||||
user.userId = CacheStorage.getInt(cursor, USER_ID)
|
||||
user.firstName = CacheStorage.getString(cursor, FIRST_NAME)
|
||||
user.lastName = CacheStorage.getString(cursor, LAST_NAME)
|
||||
user.deactivated = CacheStorage.getString(cursor, DEACTIVATED)
|
||||
user.sex = CacheStorage.getInt(cursor, GENDER)
|
||||
user.screenName = CacheStorage.getString(cursor, SCREEN_NAME)
|
||||
user.isOnline = CacheStorage.getInt(cursor, IS_ONLINE) == 1
|
||||
user.isOnlineMobile = CacheStorage.getInt(cursor, IS_ONLINE_MOBILE) == 1
|
||||
user.status = CacheStorage.getString(cursor, STATUS)
|
||||
user.lastSeen = CacheStorage.getInt(cursor, LAST_SEEN)
|
||||
|
||||
val photos =
|
||||
oldVKUtil.parseJsonPhotos(JSONObject(CacheStorage.getString(cursor, PHOTOS)))
|
||||
|
||||
user.photo50 = photos[0]
|
||||
user.photo100 = photos[1]
|
||||
user.photo200 = photos[2]
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1,73 @@
|
||||
package com.meloda.fast.extensions
|
||||
package com.meloda.fast.extensions
|
||||
|
||||
import android.graphics.*
|
||||
import kotlin.math.min
|
||||
|
||||
fun Bitmap.borderedCircularBitmap(
|
||||
borderColor: Int = 0,
|
||||
borderWidth: Int = 0
|
||||
): Bitmap? {
|
||||
val bitmap = Bitmap.createBitmap(
|
||||
width, // width in pixels
|
||||
height, // height in pixels
|
||||
Bitmap.Config.ARGB_8888
|
||||
)
|
||||
|
||||
// canvas to draw circular bitmap
|
||||
val canvas = Canvas(bitmap)
|
||||
|
||||
// get the maximum radius
|
||||
val radius = min(width / 2f, height / 2f)
|
||||
|
||||
// create a path to draw circular bitmap border
|
||||
val borderPath = Path().apply {
|
||||
addCircle(
|
||||
width / 2f,
|
||||
height / 2f,
|
||||
radius,
|
||||
Path.Direction.CCW
|
||||
)
|
||||
}
|
||||
|
||||
// draw border on circular bitmap
|
||||
canvas.clipPath(borderPath)
|
||||
canvas.drawColor(borderColor)
|
||||
|
||||
|
||||
// create a path for circular bitmap
|
||||
val bitmapPath = Path().apply {
|
||||
addCircle(
|
||||
width / 2f,
|
||||
height / 2f,
|
||||
radius - borderWidth,
|
||||
Path.Direction.CCW
|
||||
)
|
||||
}
|
||||
|
||||
canvas.clipPath(bitmapPath)
|
||||
val paint = Paint().apply {
|
||||
xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
|
||||
isAntiAlias = true
|
||||
}
|
||||
|
||||
// clear the circular bitmap drawing area
|
||||
// it will keep bitmap transparency
|
||||
canvas.drawBitmap(this, 0f, 0f, paint)
|
||||
|
||||
// now draw the circular bitmap
|
||||
canvas.drawBitmap(this, 0f, 0f, null)
|
||||
|
||||
|
||||
val diameter = (radius * 2).toInt()
|
||||
val x = (width - diameter) / 2
|
||||
val y = (height - diameter) / 2
|
||||
|
||||
// return cropped circular bitmap with border
|
||||
return Bitmap.createBitmap(
|
||||
bitmap, // source bitmap
|
||||
x, // x coordinate of the first pixel in source
|
||||
y, // y coordinate of the first pixel in source
|
||||
diameter, // width
|
||||
diameter // height
|
||||
)
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.meloda.fast.screens.friends
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.viewbinding.library.fragment.viewBinding
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.base.BaseFragment
|
||||
import com.meloda.fast.databinding.FragmentFriendsBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class FriendsFragment : BaseFragment(R.layout.fragment_friends) {
|
||||
|
||||
private val binding: FragmentFriendsBinding by viewBinding()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.meloda.fast.screens.important
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.viewbinding.library.fragment.viewBinding
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.base.BaseFragment
|
||||
import com.meloda.fast.databinding.FragmentImportantBinding
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ImportantFragment : BaseFragment(R.layout.fragment_important) {
|
||||
|
||||
private val binding: FragmentImportantBinding by viewBinding()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,7 +26,6 @@ import com.meloda.fast.base.viewmodel.VKEvent
|
||||
import com.meloda.fast.databinding.DialogCaptchaBinding
|
||||
import com.meloda.fast.databinding.DialogValidationBinding
|
||||
import com.meloda.fast.databinding.FragmentLoginBinding
|
||||
import com.meloda.fast.screens.main.MainFragment
|
||||
import com.meloda.fast.util.KeyboardUtils
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -52,8 +51,6 @@ class LoginFragment : BaseViewModelFragment<LoginViewModel>(R.layout.fragment_lo
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
(parentFragment?.parentFragment as? MainFragment)?.bottomBar?.isVisible = false
|
||||
|
||||
prepareViews()
|
||||
|
||||
binding.loginInput.clearFocus()
|
||||
|
||||
@@ -5,7 +5,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.meloda.fast.api.UserConfig
|
||||
import com.meloda.fast.api.VKConstants
|
||||
import com.meloda.fast.api.VKException
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import com.meloda.fast.api.VkUtils
|
||||
import com.meloda.fast.api.datasource.AuthDataSource
|
||||
import com.meloda.fast.api.network.request.RequestAuthDirect
|
||||
import com.meloda.fast.base.viewmodel.BaseViewModel
|
||||
@@ -61,13 +61,13 @@ class LoginViewModel @Inject constructor(
|
||||
|
||||
twoFaCode?.let { sendEvent(CodeSent) }
|
||||
|
||||
if (oldVKUtil.isValidationRequired(it)) {
|
||||
if (VkUtils.isValidationRequired(it)) {
|
||||
it.validationSid?.let { sid ->
|
||||
sendEvent(ValidationRequired(validationSid = sid))
|
||||
|
||||
sendSms(sid)
|
||||
}
|
||||
} else if (oldVKUtil.isCaptchaRequired(it)) {
|
||||
} else if (VkUtils.isCaptchaRequired(it)) {
|
||||
it.captcha?.let { captcha ->
|
||||
sendEvent(CaptchaRequired(captcha.first to captcha.second))
|
||||
}
|
||||
|
||||
@@ -29,8 +29,6 @@ class MainFragment : BaseViewModelFragment<MainViewModel>(R.layout.fragment_main
|
||||
private fun setupBottomBar() {
|
||||
val navGraphIds = listOf(
|
||||
R.navigation.messages,
|
||||
R.navigation.friends,
|
||||
R.navigation.important,
|
||||
R.navigation.login
|
||||
)
|
||||
|
||||
@@ -45,7 +43,5 @@ class MainFragment : BaseViewModelFragment<MainViewModel>(R.layout.fragment_main
|
||||
}
|
||||
}
|
||||
|
||||
val bottomBar get() = binding.bottomBar
|
||||
|
||||
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.meloda.fast.screens.messages
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.text.SpannableString
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.view.ViewGroup
|
||||
@@ -36,12 +34,30 @@ class ConversationsAdapter constructor(
|
||||
inner class ItemHolder(binding: ItemConversationBinding) :
|
||||
BindingHolder<ItemConversationBinding>(binding) {
|
||||
|
||||
private val dateColor = ContextCompat.getColor(context, R.color.date)
|
||||
private val dateColor = ContextCompat.getColor(context, R.color.n2_500)
|
||||
private val youPrefix = context.getString(R.string.you_message_prefix)
|
||||
|
||||
override fun bind(position: Int) {
|
||||
val conversation = getItem(position)
|
||||
val message = conversation.lastMessage ?: return
|
||||
|
||||
binding.service.isVisible = conversation.isPhantom || conversation.callInProgress
|
||||
binding.callIcon.isVisible = conversation.callInProgress
|
||||
binding.phantomIcon.isVisible = conversation.isPhantom
|
||||
|
||||
val message = if (conversation.lastMessage != null) conversation.lastMessage!!
|
||||
else {
|
||||
binding.title.text = conversation.title
|
||||
val text = context.getString(
|
||||
if (conversation.isPhantom) R.string.messages_self_destructed
|
||||
else R.string.no_messages
|
||||
)
|
||||
|
||||
val span = SpannableString(text)
|
||||
span.setSpan(ForegroundColorSpan(dateColor), 0, text.length, 0)
|
||||
|
||||
binding.message.text = span
|
||||
return
|
||||
}
|
||||
|
||||
val chatUser: VkUser? = if (conversation.isUser()) {
|
||||
profiles[conversation.id]
|
||||
@@ -70,8 +86,11 @@ class ConversationsAdapter constructor(
|
||||
else -> null
|
||||
}
|
||||
|
||||
binding.avatar.isVisible = avatar != null
|
||||
binding.avatarPlaceholder.isVisible = avatar == null
|
||||
|
||||
if (avatar == null) {
|
||||
binding.avatar.setImageDrawable(ColorDrawable(Color.RED))
|
||||
binding.avatar.setImageDrawable(null)
|
||||
} else {
|
||||
binding.avatar.load(avatar) { crossfade(200) }
|
||||
}
|
||||
@@ -87,23 +106,38 @@ class ConversationsAdapter constructor(
|
||||
messageGroup = messageGroup
|
||||
)
|
||||
|
||||
val attachmentsMessage = VkUtils.getAttachmentConversationText(
|
||||
context = context,
|
||||
message = message
|
||||
)
|
||||
val attachmentIcon =
|
||||
if (message.text == null) null
|
||||
else if (!message.forwards.isNullOrEmpty()) ContextCompat.getDrawable(
|
||||
context,
|
||||
if (message.forwards?.size == 1) R.drawable.ic_attachment_forwarded_message
|
||||
else R.drawable.ic_attachment_forwarded_messages
|
||||
)
|
||||
else VkUtils.getAttachmentConversationIcon(
|
||||
context = context,
|
||||
message = message
|
||||
)
|
||||
|
||||
val forwardsMessage = VkUtils.getForwardsConversationText(
|
||||
binding.textAttachment.isVisible = attachmentIcon != null
|
||||
binding.textAttachment.setImageDrawable(attachmentIcon)
|
||||
|
||||
val attachmentText = if (attachmentIcon == null) VkUtils.getAttachmentConversationText(
|
||||
context = context,
|
||||
message = message
|
||||
)
|
||||
) else null
|
||||
|
||||
val forwardsMessage = if (message.text == null) VkUtils.getForwardsConversationText(
|
||||
context = context,
|
||||
message = message
|
||||
) else null
|
||||
|
||||
val messageText = if (actionMessage != null ||
|
||||
attachmentsMessage != null ||
|
||||
forwardsMessage != null
|
||||
forwardsMessage != null ||
|
||||
attachmentText != null
|
||||
) ""
|
||||
else message.text ?: "no_message"
|
||||
else message.text ?: "[no_message]"
|
||||
|
||||
val coloredMessage = actionMessage ?: attachmentsMessage ?: forwardsMessage ?: ""
|
||||
val coloredMessage = actionMessage ?: attachmentText ?: forwardsMessage ?: ""
|
||||
|
||||
var prefix = when {
|
||||
actionMessage != null -> ""
|
||||
@@ -114,11 +148,11 @@ class ConversationsAdapter constructor(
|
||||
else -> ""
|
||||
}
|
||||
|
||||
if (!conversation.isChat() && !message.isOut || conversation.id == UserConfig.userId) prefix =
|
||||
""
|
||||
if (!conversation.isChat() && !message.isOut || conversation.id == UserConfig.userId)
|
||||
prefix = ""
|
||||
|
||||
// if (conversation.isChat() || message.isOut) {
|
||||
val spanText = "$prefix$coloredMessage $messageText".trim()
|
||||
val spanText = "$prefix$coloredMessage$messageText"
|
||||
|
||||
val spanMessage = SpannableString(spanText)
|
||||
spanMessage.setSpan(
|
||||
@@ -135,6 +169,22 @@ class ConversationsAdapter constructor(
|
||||
getItem(position).title ?: chatUser?.toString() ?: chatGroup?.name ?: "..."
|
||||
|
||||
binding.date.text = SimpleDateFormat("HH:mm").format(message.date * 1000)
|
||||
|
||||
binding.container.background = if (conversation.isUnread()) ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.ic_message_unread
|
||||
) else null
|
||||
|
||||
|
||||
binding.counter.isVisible = conversation.isInUnread()
|
||||
if (conversation.isInUnread()) {
|
||||
conversation.unreadCount?.let {
|
||||
val count = if (it > 999) "${it / 1000}K" else it.toString()
|
||||
binding.counter.text = count
|
||||
}
|
||||
} else {
|
||||
binding.counter.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ import android.view.View
|
||||
import android.viewbinding.library.fragment.viewBinding
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.viewModels
|
||||
import coil.load
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.api.UserConfig
|
||||
import com.meloda.fast.api.model.VkConversation
|
||||
import com.meloda.fast.base.BaseViewModelFragment
|
||||
import com.meloda.fast.base.viewmodel.StartProgressEvent
|
||||
@@ -40,6 +43,16 @@ class ConversationsFragment :
|
||||
binding.recyclerView.adapter = adapter
|
||||
|
||||
viewModel.loadConversations()
|
||||
|
||||
binding.createChat.setOnClickListener {
|
||||
Snackbar.make(it, "Test Snackbar with action", Snackbar.LENGTH_LONG)
|
||||
.setAction("Action") {}.show()
|
||||
|
||||
}
|
||||
|
||||
UserConfig.vkUser.observe(viewLifecycleOwner) {
|
||||
it?.let { user -> binding.avatar.load(user.photo200) { crossfade(100) } }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEvent(event: VKEvent) {
|
||||
|
||||
@@ -58,7 +58,7 @@ class ConversationsViewModel @Inject constructor(
|
||||
unreadCount = response.unreadCount ?: 0,
|
||||
conversations = response.items.map { items ->
|
||||
items.conversation.asVkConversation(
|
||||
items.lastMessage.asVkMessage()
|
||||
items.lastMessage?.asVkMessage()
|
||||
)
|
||||
},
|
||||
profiles = profiles,
|
||||
@@ -88,7 +88,7 @@ class ConversationsViewModel @Inject constructor(
|
||||
val users = r.map { u -> u.asVkUser() }
|
||||
usersDataSource.storeUsers(users)
|
||||
|
||||
UserConfig.vkUser = users[0]
|
||||
UserConfig.vkUser.value = users[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -100,4 +100,4 @@ data class ConversationsLoaded(
|
||||
val conversations: List<VkConversation>,
|
||||
val profiles: HashMap<Int, VkUser>,
|
||||
val groups: HashMap<Int, VkGroup>
|
||||
) : VKEvent()
|
||||
) : VKEvent()
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
package com.meloda.fast.service
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import androidx.annotation.WorkerThread
|
||||
import com.meloda.fast.api.UserConfig
|
||||
import com.meloda.fast.api.model.old.VKLongPollServer
|
||||
import com.meloda.fast.util.AndroidUtils
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
// TODO: 8/31/2021 rewrite, use job
|
||||
@Deprecated("Absolutely obsolete")
|
||||
class LongPollService : Service() {
|
||||
private var thread: Thread? = null
|
||||
private var running = false
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
running = false
|
||||
|
||||
// thread = LowThread(Updater())
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
if (flags and START_FLAG_RETRY == 0) {
|
||||
Log.w(TAG, "Retry launch!")
|
||||
} else {
|
||||
Log.d(TAG, "Simple launch")
|
||||
}
|
||||
if (running) return START_STICKY
|
||||
running = true
|
||||
|
||||
try {
|
||||
thread?.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
|
||||
running = false
|
||||
|
||||
thread?.interrupt()
|
||||
}
|
||||
|
||||
private inner class Updater : Runnable {
|
||||
override fun run() {
|
||||
|
||||
var server: VKLongPollServer? = null
|
||||
|
||||
while (running && UserConfig.isLoggedIn()) {
|
||||
if (!AndroidUtils.hasConnection()) {
|
||||
try {
|
||||
Thread.sleep(5000)
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
continue
|
||||
}
|
||||
try {
|
||||
if (server == null) {
|
||||
server = null
|
||||
// server = VKApi.messages().getLongPollServer()
|
||||
// .execute(VKLongPollServer::class.java)!![0]
|
||||
}
|
||||
|
||||
val response = getResponse(server)
|
||||
if (response.has("failed")) {
|
||||
Log.w(TAG, "Failed get response")
|
||||
Thread.sleep(1000)
|
||||
server = null
|
||||
continue
|
||||
}
|
||||
|
||||
val tsResponse = response.optLong("ts")
|
||||
val updates = response.getJSONArray("updates")
|
||||
|
||||
Log.i(TAG, "updates: $updates")
|
||||
|
||||
server?.ts = tsResponse
|
||||
|
||||
if (updates.length() != 0) {
|
||||
process(updates)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
try {
|
||||
Thread.sleep(5000)
|
||||
server = null
|
||||
} catch (e1: InterruptedException) {
|
||||
e1.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun getResponse(server: VKLongPollServer?): JSONObject {
|
||||
return JSONObject("")
|
||||
// val params = arrayMapOf<String, String>()
|
||||
// params["act"] = "a_check"
|
||||
// params["key"] = server.key
|
||||
// params["ts"] = server.ts.toString()
|
||||
// params["wait"] = "10"
|
||||
// params["mode"] = "490"
|
||||
// params["version"] = "9"
|
||||
//
|
||||
// val buffer = HttpRequest["https://" + server.server, params].asString()
|
||||
//
|
||||
// return JSONObject(buffer)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private fun process(updates: JSONArray) {
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "LongPollService"
|
||||
}
|
||||
}
|
||||
@@ -1,296 +0,0 @@
|
||||
package com.meloda.fast.util
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.api.oldVKUtil
|
||||
import com.meloda.fast.api.model.old.*
|
||||
import com.meloda.fast.common.AppGlobal
|
||||
import com.meloda.fast.extensions.ContextExtensions.color
|
||||
import com.meloda.fast.extensions.ContextExtensions.drawable
|
||||
import com.meloda.fast.extensions.DrawableExtensions.tint
|
||||
import com.meloda.fast.extensions.StringExtensions.lowerCase
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import kotlin.math.abs
|
||||
|
||||
object VKUtils {
|
||||
|
||||
fun getUserOnline(user: oldVKUser): String {
|
||||
val r = AppGlobal.resources
|
||||
return if (user.isOnline) {
|
||||
if (user.isOnlineMobile) {
|
||||
r.getString(R.string.user_online_mobile)
|
||||
} else {
|
||||
r.getString(R.string.user_online)
|
||||
}
|
||||
} else {
|
||||
if (user.lastSeen == 0) {
|
||||
r.getString(R.string.user_last_seen_recently)
|
||||
} else {
|
||||
r.getString(
|
||||
R.string.user_last_seen_at,
|
||||
oldVKUtil.getLastSeenTime(user.lastSeen * 1000L)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getUserOnlineIcon(
|
||||
context: Context,
|
||||
conversation: oldVKConversation?,
|
||||
peerUser: oldVKUser?
|
||||
): Drawable? {
|
||||
return if (conversation != null) {
|
||||
if (conversation.isUser() && peerUser != null) {
|
||||
if (!peerUser.isOnline) {
|
||||
null
|
||||
} else {
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
if (peerUser.isOnlineMobile) R.drawable.ic_online_mobile else R.drawable.ic_online_pc
|
||||
)
|
||||
}
|
||||
} else null
|
||||
} else {
|
||||
if (peerUser!!.isOnline) {
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
if (peerUser.isOnlineMobile) R.drawable.ic_online_mobile else R.drawable.ic_online_pc
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getUserOnlineIcon(context: Context, user: oldVKUser): Drawable? {
|
||||
return getUserOnlineIcon(context, null, user)
|
||||
}
|
||||
|
||||
// fun getAvatarPlaceholder(context: Context, dialogTitle: String): TextDrawable {
|
||||
// return TextDrawable.builder().buildRound(
|
||||
// if (dialogTitle.isEmpty()) "" else {
|
||||
// TextUtils.getFirstLetterFromString(dialogTitle)
|
||||
// },
|
||||
// context.color(R.color.accent)
|
||||
// )
|
||||
// }
|
||||
|
||||
|
||||
fun getAttachmentText(context: Context, attachments: List<VKModel>): String {
|
||||
val resId: Int
|
||||
|
||||
if (attachments.isNotEmpty()) {
|
||||
if (attachments.size > 1) {
|
||||
var oneType = true
|
||||
|
||||
val firstType = attachments[0].attachmentType
|
||||
|
||||
// val className = attachments[0].javaClass.simpleName
|
||||
|
||||
for (model in attachments) {
|
||||
// if (model.javaClass.simpleName != className) {
|
||||
if (model.attachmentType != firstType) {
|
||||
oneType = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return if (oneType) {
|
||||
// val objectClass: Class<VKModel> = attachments[0].javaClass
|
||||
|
||||
resId = when (firstType) {
|
||||
VKAttachments.Type.PHOTO -> {
|
||||
R.string.message_attachment_photos
|
||||
}
|
||||
VKAttachments.Type.VIDEO -> {
|
||||
R.string.message_attachment_videos
|
||||
}
|
||||
VKAttachments.Type.AUDIO -> {
|
||||
R.string.message_attachment_audios
|
||||
}
|
||||
VKAttachments.Type.DOCUMENT -> {
|
||||
R.string.message_attachment_docs
|
||||
}
|
||||
else -> -1
|
||||
|
||||
}
|
||||
if (resId == -1) "Unknown attachments" else context.getString(
|
||||
resId,
|
||||
attachments.size
|
||||
).lowerCase()
|
||||
} else {
|
||||
context.getString(R.string.message_attachments_many)
|
||||
}
|
||||
} else {
|
||||
// val objectClass: Class<VKModel> = attachments[0].javaClass
|
||||
val firstType = attachments[0].attachmentType
|
||||
|
||||
resId = when (firstType) {
|
||||
VKAttachments.Type.PHOTO -> R.string.message_attachment_photo
|
||||
VKAttachments.Type.AUDIO -> R.string.message_attachment_audio
|
||||
VKAttachments.Type.VIDEO -> R.string.message_attachment_video
|
||||
VKAttachments.Type.DOCUMENT -> R.string.message_attachment_doc
|
||||
VKAttachments.Type.GRAFFITI -> R.string.message_attachment_graffiti
|
||||
VKAttachments.Type.VOICE_MESSAGE -> R.string.message_attachment_voice
|
||||
VKAttachments.Type.STICKER -> R.string.message_attachment_sticker
|
||||
VKAttachments.Type.GIFT -> R.string.message_attachment_gift
|
||||
VKAttachments.Type.LINK -> R.string.message_attachment_link
|
||||
VKAttachments.Type.POLL -> R.string.message_attachment_poll
|
||||
VKAttachments.Type.CALL -> R.string.message_attachment_call
|
||||
VKAttachments.Type.WALL_POST -> R.string.message_attachment_wall_post
|
||||
VKAttachments.Type.WALL_REPLY -> R.string.message_attachment_wall_reply
|
||||
else -> return "Unknown"
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
return context.getString(resId)
|
||||
}
|
||||
|
||||
fun getAttachmentDrawable(context: Context, attachments: List<VKModel>): Drawable? {
|
||||
if (attachments.isEmpty() || attachments.size > 1) return null
|
||||
|
||||
val resId = when (attachments[0].attachmentType) {
|
||||
VKAttachments.Type.PHOTO -> R.drawable.ic_message_attachment_camera
|
||||
VKAttachments.Type.AUDIO -> R.drawable.ic_message_attachment_audio
|
||||
VKAttachments.Type.VIDEO -> R.drawable.ic_message_attachment_video
|
||||
VKAttachments.Type.DOCUMENT -> R.drawable.ic_message_attachment_doc
|
||||
VKAttachments.Type.GRAFFITI -> R.drawable.ic_message_attachment_graffiti
|
||||
VKAttachments.Type.VOICE_MESSAGE -> R.drawable.ic_message_attachment_audio_message
|
||||
VKAttachments.Type.STICKER -> R.drawable.ic_message_attachment_sticker
|
||||
VKAttachments.Type.GIFT -> R.drawable.ic_message_attachment_gift
|
||||
VKAttachments.Type.LINK -> R.drawable.ic_message_attachment_link
|
||||
VKAttachments.Type.POLL -> R.drawable.ic_message_attachment_poll
|
||||
VKAttachments.Type.CALL -> R.drawable.ic_message_attachment_call
|
||||
|
||||
else -> null
|
||||
}
|
||||
|
||||
resId?.let { return context.drawable(it).tint(context.color(R.color.accent)) }
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun getFwdText(context: Context, forwardedMessages: List<oldVKMessage>): String {
|
||||
return if (forwardedMessages.isNotEmpty()) {
|
||||
if (forwardedMessages.size > 1) {
|
||||
context.getString(R.string.message_fwd_many, forwardedMessages.size).lowerCase()
|
||||
} else {
|
||||
context.getString(R.string.message_fwd_one)
|
||||
}
|
||||
} else ""
|
||||
}
|
||||
|
||||
@Deprecated("need to rewrite")
|
||||
fun getActionText(
|
||||
context: Context,
|
||||
lastMessage: oldVKMessage
|
||||
) {
|
||||
|
||||
lastMessage.action?.let {
|
||||
var result = ""
|
||||
|
||||
when (it.type) {
|
||||
oldVKMessageAction.Type.CHAT_CREATE -> result = context.getString(
|
||||
R.string.message_action_created_chat,
|
||||
""
|
||||
)
|
||||
oldVKMessageAction.Type.INVITE_USER -> result =
|
||||
if (lastMessage.fromId == lastMessage.action!!.memberId) {
|
||||
context.getString(R.string.message_action_returned_to_chat, "")
|
||||
} else {
|
||||
""
|
||||
// val invited = MemoryCache.getUserById(lastMessage.action!!.memberId)
|
||||
// context.getString(R.string.message_action_invited_user, invited)
|
||||
}
|
||||
oldVKMessageAction.Type.INVITE_USER_BY_LINK -> result = context.getString(
|
||||
R.string.message_action_invited_by_link,
|
||||
""
|
||||
)
|
||||
oldVKMessageAction.Type.KICK_USER -> result =
|
||||
if (lastMessage.fromId == lastMessage.action!!.memberId) {
|
||||
context.getString(R.string.message_action_left_from_chat, "")
|
||||
} else {
|
||||
""
|
||||
// val kicked = MemoryCache.getUserById(lastMessage.action!!.memberId)
|
||||
// context.getString(R.string.message_action_kicked_user, kicked)
|
||||
}
|
||||
oldVKMessageAction.Type.PHOTO_REMOVE -> result = context.getString(
|
||||
R.string.message_action_removed_photo,
|
||||
""
|
||||
)
|
||||
oldVKMessageAction.Type.PHOTO_UPDATE -> result = context.getString(
|
||||
R.string.message_action_updated_photo,
|
||||
""
|
||||
)
|
||||
oldVKMessageAction.Type.PIN_MESSAGE -> result = context.getString(
|
||||
R.string.message_action_pinned_message,
|
||||
""
|
||||
)
|
||||
oldVKMessageAction.Type.UNPIN_MESSAGE -> result = context.getString(
|
||||
R.string.message_action_unpinned_message,
|
||||
""
|
||||
)
|
||||
oldVKMessageAction.Type.TITLE_UPDATE -> result = context.getString(
|
||||
R.string.message_action_updated_title,
|
||||
""
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun getTime(context: Context, lastMessage: oldVKMessage): String {
|
||||
val then = lastMessage.date * 1000L
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
val change = abs(now - then)
|
||||
|
||||
val seconds = change / 1000
|
||||
|
||||
if (seconds == 0L) {
|
||||
return context.getString(R.string.time_format_now)
|
||||
}
|
||||
|
||||
val minutes = seconds / 60
|
||||
|
||||
if (minutes == 0L) {
|
||||
return context.getString(R.string.time_format_second, seconds)
|
||||
}
|
||||
|
||||
val hours = minutes / 60
|
||||
|
||||
if (hours == 0L) {
|
||||
return context.getString(R.string.time_format_minute, minutes)
|
||||
}
|
||||
|
||||
val days = hours / 24
|
||||
|
||||
if (days == 0L) {
|
||||
return context.getString(R.string.time_format_hour, hours)
|
||||
}
|
||||
|
||||
val months = days / 30
|
||||
|
||||
if (months == 0L) {
|
||||
return context.getString(R.string.time_format_day, days)
|
||||
}
|
||||
|
||||
val years = months / 12
|
||||
|
||||
if (years == 0L) {
|
||||
return context.getString(R.string.time_format_month, months)
|
||||
} else if (years > 0L) {
|
||||
return context.getString(R.string.time_format_year, years)
|
||||
}
|
||||
|
||||
return SimpleDateFormat("HH:mm", Locale.getDefault()).format(then)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package com.meloda.fast.util
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.text.TextUtils
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.meloda.fast.extensions.ContextExtensions.color
|
||||
import com.meloda.fast.R
|
||||
import com.meloda.fast.widget.CircleImageView
|
||||
import com.meloda.fast.api.model.old.oldVKUser
|
||||
|
||||
|
||||
object ViewUtils {
|
||||
|
||||
fun showErrorSnackbar(view: View, t: Throwable) {
|
||||
Snackbar.make(
|
||||
view,
|
||||
Utils.getLocalizedThrowable(view.context, t),
|
||||
Snackbar.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
|
||||
fun showErrorToast(context: Context, t: Throwable) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
Utils.getLocalizedThrowable(context, t),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
|
||||
fun prepareNavigationHeader(view: View, user: oldVKUser) {
|
||||
val profileName = view.findViewById<TextView>(R.id.headerName)
|
||||
|
||||
profileName.text = user.toString()
|
||||
|
||||
val profileStatus = view.findViewById<TextView>(R.id.headerStatus)
|
||||
|
||||
val statusText = if (TextUtils.isEmpty(user.status)) "@id${user.userId}" else user.status
|
||||
|
||||
profileStatus.text = statusText
|
||||
|
||||
val profileAvatar: CircleImageView = view.findViewById(R.id.headerAvatar)
|
||||
|
||||
if (AndroidUtils.hasConnection()) {
|
||||
// Picasso.get().load(VKUtil.getUserPhoto(user)).into(profileAvatar)
|
||||
} else {
|
||||
profileAvatar.setImageDrawable(ColorDrawable(view.context.color(R.color.accent)))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:duration="@android:integer/config_shortAnimTime"
|
||||
android:fromYDelta="0%p"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:toYDelta="100%p" />
|
||||
</set>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate
|
||||
android:duration="@android:integer/config_shortAnimTime"
|
||||
android:fromYDelta="100%"
|
||||
android:interpolator="@android:anim/accelerate_interpolator"
|
||||
android:toXDelta="0" />
|
||||
</set>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 MiB |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M7.07,18.28C7.5,17.38 10.12,16.5 12,16.5C13.88,16.5 16.5,17.38 16.93,18.28C15.57,19.36 13.86,20 12,20C10.14,20 8.43,19.36 7.07,18.28M18.36,16.83C16.93,15.09 13.46,14.5 12,14.5C10.54,14.5 7.07,15.09 5.64,16.83C4.62,15.5 4,13.82 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,13.82 19.38,15.5 18.36,16.83M12,6C10.06,6 8.5,7.56 8.5,9.5C8.5,11.44 10.06,13 12,13C13.94,13 15.5,11.44 15.5,9.5C15.5,7.56 13.94,6 12,6M12,11A1.5,1.5 0 0,1 10.5,9.5A1.5,1.5 0 0,1 12,8A1.5,1.5 0 0,1 13.5,9.5A1.5,1.5 0 0,1 12,11Z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM8,11c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zM8,13c-2.33,0 -7,1.17 -7,3.5L1,19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zM16,13c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45L17,19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z" />
|
||||
</vector>
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:width="24dp"
|
||||
android:height="24dp">
|
||||
<path
|
||||
android:pathData="M12.72 2.03C6.63 1.6 1.6 6.63 2.03 12.72 2.39 18.01 7.01 22 12.31 22L16 22c0.55 0 1 -0.45 1 -1l0 0c0 -0.55 -0.45 -1 -1 -1l-3.67 0C8.6 20 5.18 17.58 4.25 13.97 2.76 8.17 8.16 2.76 13.96 4.26 17.58 5.18 20 8.6 20 12.33l0 1.1C20 14.22 19.29 15 18.5 15 17.71 15 17 14.22 17 13.43l0 -1.25C17 9.67 15.22 7.41 12.74 7.06 9.34 6.57 6.47 9.51 7.08 12.93c0.34 1.91 1.83 3.49 3.72 3.94 1.84 0.43 3.59 -0.16 4.74 -1.33 0.89 1.22 2.67 1.86 4.3 1.21 1.34 -0.53 2.16 -1.9 2.16 -3.34 0 -0.33 0 -0.7 0 -1.09C22 7.01 18.01 2.39 12.72 2.03ZM12 15c-1.66 0 -3 -1.34 -3 -3 0 -1.66 1.34 -3 3 -3 1.66 0 3 1.34 3 3 0 1.66 -1.34 3 -3 3z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="0.9" />
|
||||
</vector>
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +0,0 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M19,9h-4V3H9v6H5l7,7 7,-7zM5,18v2h14v-2H5z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M9,4v3h5v12h3L17,7h5L22,4L9,4zM3,12h3v7h3v-7h3L12,9L3,9v3z" />
|
||||
</vector>
|
||||
@@ -1,5 +0,0 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1s3.1,1.39 3.1,3.1v2L8.9,8L8.9,6zM18,20L6,20L6,10h12v10z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M12,3v9.28c-0.47,-0.17 -0.97,-0.28 -1.5,-0.28C8.01,12 6,14.01 6,16.5S8.01,21 10.5,21c2.31,0 4.2,-1.75 4.45,-4H15V6h4V3h-7z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M6.62,10.79c1.44,2.83 3.76,5.14 6.59,6.59l2.2,-2.2c0.27,-0.27 0.67,-0.36 1.02,-0.24 1.12,0.37 2.33,0.57 3.57,0.57 0.55,0 1,0.45 1,1V20c0,0.55 -0.45,1 -1,1 -9.39,0 -17,-7.61 -17,-17 0,-0.55 0.45,-1 1,-1h3.5c0.55,0 1,0.45 1,1 0,1.25 0.2,2.45 0.57,3.57 0.11,0.35 0.03,0.74 -0.25,1.02l-2.2,2.2z" />
|
||||
</vector>
|
||||
@@ -1,12 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="14"
|
||||
android:viewportHeight="14">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M7,7m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0" />
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M11.667,2.334L9.818,2.334l-0.723,-0.787A1.161,1.161 0,0 0,8.237 1.167L5.767,1.167a1.184,1.184 0,0 0,-0.863 0.379l-0.717,0.787L2.334,2.333A1.17,1.17 0,0 0,1.167 3.5v7A1.17,1.17 0,0 0,2.334 11.667L11.667,11.667a1.17,1.17 0,0 0,1.167 -1.167v-7A1.17,1.17 0,0 0,11.667 2.334ZM7,9.917A2.917,2.917 0,1 1,9.917 7,2.918 2.918,0 0,1 7,9.917Z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M20,6h-2.18c0.11,-0.31 0.18,-0.65 0.18,-1 0,-1.66 -1.34,-3 -3,-3 -1.05,0 -1.96,0.54 -2.5,1.35l-0.5,0.67 -0.5,-0.68C10.96,2.54 10.05,2 9,2 7.34,2 6,3.34 6,5c0,0.35 0.07,0.69 0.18,1L4,6c-1.11,0 -1.99,0.89 -1.99,2L2,19c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2L22,8c0,-1.11 -0.89,-2 -2,-2zM15,4c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM9,4c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM20,19L4,19v-2h16v2zM20,14L4,14L4,8h5.08L7,10.83 8.62,12 11,8.76l1,-1.36 1,1.36L15.38,12 17,10.83 14.92,8L20,8v6z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4L11,7L7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1zM8,13h8v-2L8,11v2zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1s-1.39,3.1 -3.1,3.1h-4L13,17h4c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM9,17L7,17v-7h2v7zM13,17h-2L11,7h2v10zM17,17h-2v-4h2v4z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l4,4v-11l-4,4z" />
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M12,14c1.66,0 2.99,-1.34 2.99,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.3,11c0,3 -2.54,5.1 -5.3,5.1S6.7,14 6.7,11L5,11c0,3.41 2.72,6.23 6,6.72L11,21h2v-3.28c3.28,-0.48 6,-3.3 6,-6.72h-1.7z" />
|
||||
</vector>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,18 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="11.586dp"
|
||||
android:height="15.921dp"
|
||||
android:viewportWidth="11.586"
|
||||
android:viewportHeight="15.921">
|
||||
|
||||
<path
|
||||
android:fillColor="?android:windowBackground"
|
||||
android:pathData="M2,3h7v10h-7z" />
|
||||
<path
|
||||
android:fillColor="?colorAccent"
|
||||
android:pathData="M8.5026,14.9214L3.0838,14.9214C1.9348,14.9214 1,13.9866 1,12.8376L1,3.0838C1,1.9348 1.9348,1 3.0838,1L8.5036,1.0054C9.6516,1.0054 10.5863,1.9378 10.5863,3.0838L10.5863,12.8376C10.5863,13.9866 9.6516,14.9214 8.5026,14.9214ZM4.0838,10.7539L7.5026,10.7539L7.5026,5.1675L4.0838,5.1675L4.0838,10.7539Z"
|
||||
android:strokeColor="#00000000" />
|
||||
<path
|
||||
android:fillColor="?android:windowBackground"
|
||||
android:pathData="M3.0838,2C2.4877,2 2,2.4877 2,3.0838L2,12.8376C2,13.4337 2.4877,13.9214 3.0838,13.9214L8.5026,13.9214C9.0986,13.9214 9.5863,13.4337 9.5863,12.8376L9.5863,3.0838C9.5863,2.4877 9.0986,2.0054 8.5026,2.0054L3.0838,2M8.5026,11.7539L3.0838,11.7539L3.0838,4.1675L8.5026,4.1675L8.5026,11.7539M3.0838,0L3.0848,0L3.0858,0L8.5046,0.0054C10.203,0.0054 11.5863,1.3864 11.5863,3.0838L11.5863,12.8376C11.5863,14.538 10.203,15.9214 8.5026,15.9214L3.0838,15.9214C1.3834,15.9214 -0,14.538 -0,12.8376L-0,3.0838C-0,1.3834 1.3834,0 3.0838,0ZM6.5026,6.1675L5.0838,6.1675L5.0838,9.7539L6.5026,9.7539L6.5026,6.1675Z"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
@@ -1,18 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="11.586dp"
|
||||
android:height="15.921dp"
|
||||
android:viewportWidth="11.586"
|
||||
android:viewportHeight="15.921">
|
||||
|
||||
<path
|
||||
android:fillColor="?android:windowBackground"
|
||||
android:pathData="M2,3h7v10h-7z" />
|
||||
<path
|
||||
android:fillColor="?colorAccent"
|
||||
android:pathData="M8.5026,14.9214L3.0838,14.9214C1.9348,14.9214 1,13.9866 1,12.8376L1,3.0838C1,1.9348 1.9348,1 3.0838,1L8.5036,1.0054C9.6516,1.0054 10.5863,1.9378 10.5863,3.0838L10.5863,12.8376C10.5863,13.9866 9.6516,14.9214 8.5026,14.9214ZM4.0838,10.7539L7.5026,10.7539L7.5026,5.1675L4.0838,5.1675L4.0838,10.7539Z"
|
||||
android:strokeColor="#00000000" />
|
||||
<path
|
||||
android:fillColor="#fff"
|
||||
android:pathData="M3.0838,2C2.4877,2 2,2.4877 2,3.0838L2,12.8376C2,13.4337 2.4877,13.9214 3.0838,13.9214L8.5026,13.9214C9.0986,13.9214 9.5863,13.4337 9.5863,12.8376L9.5863,3.0838C9.5863,2.4877 9.0986,2.0054 8.5026,2.0054L3.0838,2M8.5026,11.7539L3.0838,11.7539L3.0838,4.1675L8.5026,4.1675L8.5026,11.7539M3.0838,0L3.0848,0L3.0858,0L8.5046,0.0054C10.203,0.0054 11.5863,1.3864 11.5863,3.0838L11.5863,12.8376C11.5863,14.538 10.203,15.9214 8.5026,15.9214L3.0838,15.9214C1.3834,15.9214 -0,14.538 -0,12.8376L-0,3.0838C-0,1.3834 1.3834,0 3.0838,0ZM6.5026,6.1675L5.0838,6.1675L5.0838,9.7539L6.5026,9.7539L6.5026,6.1675Z"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M18,4L18,3c0,-0.55 -0.45,-1 -1,-1L5,2c-0.55,0 -1,0.45 -1,1v4c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1L18,6h1v4L9,10v11c0,0.55 0.45,1 1,1h2c0.55,0 1,-0.45 1,-1v-9h8L21,4h-3zM16,6L6,6L6,4h10v2z"/>
|
||||
</vector>
|
||||
@@ -1,5 +0,0 @@
|
||||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M2.5 19.6L3.8 20.2V11.2L1.4 17C1 18.1 1.5 19.2 2.5 19.6M15.2 4.8L20.2 16.8L12.9 19.8L7.9 7.9V7.8L15.2 4.8M15.3 2.8C15 2.8 14.8 2.8 14.5 2.9L7.1 6C6.4 6.3 5.9 7 5.9 7.8C5.9 8 5.9 8.3 6 8.6L11 20.5C11.3 21.3 12 21.7 12.8 21.7C13.1 21.7 13.3 21.7 13.6 21.6L21 18.5C22 18.1 22.5 16.9 22.1 15.9L17.1 4C16.8 3.2 16 2.8 15.3 2.8M10.5 9.9C9.9 9.9 9.5 9.5 9.5 8.9S9.9 7.9 10.5 7.9C11.1 7.9 11.5 8.4 11.5 8.9S11.1 9.9 10.5 9.9M5.9 19.8C5.9 20.9 6.8 21.8 7.9 21.8H9.3L5.9 13.5V19.8Z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M16,1L8,1C6.34,1 5,2.34 5,4v16c0,1.66 1.34,3 3,3h8c1.66,0 3,-1.34 3,-3L19,4c0,-1.66 -1.34,-3 -3,-3zM14,21h-4v-1h4v1zM17.25,18L6.75,18L6.75,4h10.5v14z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z" />
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M19.1,12.9a2.8,2.8 0,0 0,0.1 -0.9,2.8 2.8,0 0,0 -0.1,-0.9l2.1,-1.6a0.7,0.7 0,0 0,0.1 -0.6L19.4,5.5a0.7,0.7 0,0 0,-0.6 -0.2l-2.4,1a6.5,6.5 0,0 0,-1.6 -0.9l-0.4,-2.6a0.5,0.5 0,0 0,-0.5 -0.4H10.1a0.5,0.5 0,0 0,-0.5 0.4L9.3,5.4a5.6,5.6 0,0 0,-1.7 0.9l-2.4,-1a0.4,0.4 0,0 0,-0.5 0.2l-2,3.4c-0.1,0.2 0,0.4 0.2,0.6l2,1.6a2.8,2.8 0,0 0,-0.1 0.9,2.8 2.8,0 0,0 0.1,0.9L2.8,14.5a0.7,0.7 0,0 0,-0.1 0.6l1.9,3.4a0.7,0.7 0,0 0,0.6 0.2l2.4,-1a6.5,6.5 0,0 0,1.6 0.9l0.4,2.6a0.5,0.5 0,0 0,0.5 0.4h3.8a0.5,0.5 0,0 0,0.5 -0.4l0.3,-2.6a5.6,5.6 0,0 0,1.7 -0.9l2.4,1a0.4,0.4 0,0 0,0.5 -0.2l2,-3.4c0.1,-0.2 0,-0.4 -0.2,-0.6ZM12,15.6A3.6,3.6 0,1 1,15.6 12,3.6 3.6,0 0,1 12,15.6Z"/>
|
||||
</vector>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M12,8A4,4 0 0,1 16,12A4,4 0 0,1 12,16A4,4 0 0,1 8,12A4,4 0 0,1 12,8M12,10A2,2 0 0,0 10,12A2,2 0 0,0 12,14A2,2 0 0,0 14,12A2,2 0 0,0 12,10M10,22C9.75,22 9.54,21.82 9.5,21.58L9.13,18.93C8.5,18.68 7.96,18.34 7.44,17.94L4.95,18.95C4.73,19.03 4.46,18.95 4.34,18.73L2.34,15.27C2.21,15.05 2.27,14.78 2.46,14.63L4.57,12.97L4.5,12L4.57,11L2.46,9.37C2.27,9.22 2.21,8.95 2.34,8.73L4.34,5.27C4.46,5.05 4.73,4.96 4.95,5.05L7.44,6.05C7.96,5.66 8.5,5.32 9.13,5.07L9.5,2.42C9.54,2.18 9.75,2 10,2H14C14.25,2 14.46,2.18 14.5,2.42L14.87,5.07C15.5,5.32 16.04,5.66 16.56,6.05L19.05,5.05C19.27,4.96 19.54,5.05 19.66,5.27L21.66,8.73C21.79,8.95 21.73,9.22 21.54,9.37L19.43,11L19.5,12L19.43,13L21.54,14.63C21.73,14.78 21.79,15.05 21.66,15.27L19.66,18.73C19.54,18.95 19.27,19.04 19.05,18.95L16.56,17.95C16.04,18.34 15.5,18.68 14.87,18.93L14.5,21.58C14.46,21.82 14.25,22 14,22H10M11.25,4L10.88,6.61C9.68,6.86 8.62,7.5 7.85,8.39L5.44,7.35L4.69,8.65L6.8,10.2C6.4,11.37 6.4,12.64 6.8,13.8L4.68,15.36L5.43,16.66L7.86,15.62C8.63,16.5 9.68,17.14 10.87,17.38L11.24,20H12.76L13.13,17.39C14.32,17.14 15.37,16.5 16.14,15.62L18.57,16.66L19.32,15.36L17.2,13.81C17.6,12.64 17.6,11.37 17.2,10.2L19.31,8.65L18.56,7.35L16.15,8.39C15.38,7.5 14.32,6.86 13.12,6.62L12.75,4H11.25Z" />
|
||||
</vector>
|
||||
@@ -1,17 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:name="vector"
|
||||
android:width="361dp"
|
||||
android:height="252dp"
|
||||
android:viewportWidth="361"
|
||||
android:viewportHeight="252">
|
||||
<path
|
||||
android:name="path"
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 361 252 L 0 252 L 0 29.935 C 6.2 28.612 12.523 27.525 18.781 26.705 L 22.07 26.705 C 31.053 25.393 40.12 24.735 49.199 24.736 C 61.536 24.763 73.844 25.921 85.969 28.197 C 97.971 30.462 109.779 33.657 121.286 37.753 C 121.632 38.014 122 38.245 122.386 38.443 C 122.772 38.641 123.14 38.872 123.486 39.133 C 137.726 44.494 151.312 52.099 166.241 63.069 C 196.546 84.093 234.209 95.205 275.157 95.205 C 283.269 95.199 291.374 94.765 299.44 93.905 C 321.029 91.159 337.259 87.605 352.062 82.398 C 355.095 81.329 358.105 80.212 361.008 79.078 L 361.008 252 Z"
|
||||
android:strokeWidth="1" />
|
||||
<path
|
||||
android:name="path_1"
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M 228.5 0 C 223.728 0 219.146 1.898 215.772 5.272 C 212.398 8.646 210.5 13.228 210.5 18 C 210.5 22.772 212.398 27.354 215.772 30.728 C 219.146 34.102 223.728 36 228.5 36 C 233.272 36 237.854 34.102 241.228 30.728 C 244.602 27.354 246.5 22.772 246.5 18 C 246.5 13.228 244.602 8.646 241.228 5.272 C 237.854 1.898 233.272 0 228.5 0 Z M 283.5 47 C 281.114 47 278.823 47.949 277.136 49.636 C 275.449 51.323 274.5 53.614 274.5 56 C 274.5 58.386 275.449 60.677 277.136 62.364 C 278.823 64.051 281.114 65 283.5 65 C 285.886 65 288.177 64.051 289.864 62.364 C 291.551 60.677 292.5 58.386 292.5 56 C 292.5 53.614 291.551 51.323 289.864 49.636 C 288.177 47.949 285.886 47 283.5 47 Z"
|
||||
android:strokeWidth="1" />
|
||||
</vector>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user