mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-04-14 19:56:32 +00:00
finalize first version of party seeking
This commit is contained in:
parent
8252969a26
commit
2a78e89624
21 changed files with 99 additions and 75 deletions
BIN
Habitica/res/drawable/party_seeking.png
Normal file
BIN
Habitica/res/drawable/party_seeking.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
5
Habitica/res/drawable/success_border.xml
Normal file
5
Habitica/res/drawable/success_border.xml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
|
||||
<corners android:radius="8dp" />
|
||||
<stroke android:color="@color/background_green" android:width="3dp" />
|
||||
</shape>
|
||||
|
|
@ -12,9 +12,7 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="?android:actionBarSize">
|
||||
|
||||
android:orientation="vertical">
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -57,7 +55,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/spacing_large">
|
||||
android:layout_margin="@dimen/spacing_sides">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
@ -86,15 +84,25 @@
|
|||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:layout_margin="@dimen/spacing_large">
|
||||
android:paddingHorizontal="@dimen/spacing_sides"
|
||||
android:paddingTop="@dimen/spacing_sides"
|
||||
android:paddingBottom="60dp"
|
||||
android:background="@color/window_background">
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/party_seeking"
|
||||
android:layout_marginBottom="@dimen/spacing_large"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Headline"
|
||||
android:textSize="16sp"
|
||||
android:text="@string/join_party_title"
|
||||
android:text="@string/seeking_party_title"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="@dimen/spacing_medium"/>
|
||||
<TextView
|
||||
|
|
@ -102,23 +110,51 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Body2"
|
||||
android:text="@string/join_party_description"
|
||||
android:text="@string/seeking_party_description"
|
||||
android:textColor="@color/text_quad"
|
||||
android:textColorLink="@color/text_brand_neon"
|
||||
android:gravity="center"
|
||||
android:layout_marginStart="@dimen/spacing_large"
|
||||
android:layout_marginEnd="@dimen/spacing_large"/>
|
||||
android:layout_marginEnd="@dimen/spacing_large"
|
||||
android:layout_marginBottom="@dimen/spacing_large"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/username_textview"
|
||||
android:id="@+id/seek_party_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/HabiticaButton.Gray"
|
||||
android:layout_marginTop="@dimen/spacing_large"
|
||||
android:layout_marginBottom="@dimen/spacing_large"/>
|
||||
style="@style/HabiticaButton.Primary"
|
||||
android:text="@string/look_for_party"/>
|
||||
<LinearLayout
|
||||
android:id="@+id/seeking_party_wrapper"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:text="@string/you_re_looking_for_party"
|
||||
android:textColor="@color/text_green"
|
||||
style="@style/Body1_Button"
|
||||
android:background="@drawable/success_border"/>
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/seeking_hint"
|
||||
android:textColor="@color/text_green"
|
||||
style="@style/Body1"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="6dp"/>
|
||||
<Button
|
||||
android:id="@+id/leave_seeking_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/HabiticaButton.Borderless"
|
||||
android:textColor="@color/text_maroon"
|
||||
android:text="@string/leave_party_finder"/>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
|
|
|||
|
|
@ -1370,6 +1370,12 @@
|
|||
<string name="invite_with_username_email">Invite with @username or email</string>
|
||||
<string name="habiticans_send_invite">Send an invite directly to Habiticans you know</string>
|
||||
<string name="username_or_email">Username or email address</string>
|
||||
<string name="seeking_party_description">Want to join a Party with others but don’t know any Habiticans? Join our Party Finder to let Party leaders know you’re looking for an invite!</string>
|
||||
<string name="seeking_party_title">Looking for a Party?</string>
|
||||
<string name="look_for_party">Look for a Party</string>
|
||||
<string name="you_re_looking_for_party">You’re looking for a Party!</string>
|
||||
<string name="seeking_hint">Keep an eye out for an invite or start your own Party at any time</string>
|
||||
<string name="leave_party_finder">Leave Party Finder</string>
|
||||
|
||||
<plurals name="you_x_others">
|
||||
<item quantity="zero">You</item>
|
||||
|
|
|
|||
|
|
@ -1015,7 +1015,7 @@
|
|||
|
||||
<style name="FlatCardView">
|
||||
<item name="android:background">@drawable/layout_rounded_bg_window</item>
|
||||
<item name="android:layout_margin">@dimen/spacing_medium</item>
|
||||
<item name="android:layout_margin">@dimen/spacing_sides</item>
|
||||
</style>
|
||||
|
||||
<style name="CountLabel">
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ interface ApiService {
|
|||
suspend fun getContent(@Query("language") language: String?): HabitResponse<ContentResult>
|
||||
|
||||
@PUT("user/")
|
||||
suspend fun updateUser(@Body updateDictionary: Map<String, Any>): HabitResponse<User>
|
||||
suspend fun updateUser(@Body updateDictionary: Map<String, Any?>): HabitResponse<User>
|
||||
|
||||
@PUT("user/")
|
||||
suspend fun registrationLanguage(@Header("Accept-Language") registrationLanguage: String): HabitResponse<User>
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ public class GSonFactoryCreator {
|
|||
.registerTypeAdapter(Notification.class, new NotificationDeserializer())
|
||||
.registerTypeAdapter(SocialAuthentication.class, new SocialAuthenticationDeserializer())
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||
.serializeNulls()
|
||||
.create();
|
||||
}
|
||||
public static GsonConverterFactory create() {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ interface ApiClient {
|
|||
var languageCode: String?
|
||||
suspend fun getContent(language: String? = null): ContentResult?
|
||||
|
||||
suspend fun updateUser(updateDictionary: Map<String, Any>): User?
|
||||
suspend fun updateUser(updateDictionary: Map<String, Any?>): User?
|
||||
|
||||
suspend fun registrationLanguage(registrationLanguage: String): User?
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ interface UserRepository : BaseRepository {
|
|||
fun getUser(): Flow<User?>
|
||||
fun getUser(userID: String): Flow<User?>
|
||||
|
||||
suspend fun updateUser(updateData: Map<String, Any>): User?
|
||||
suspend fun updateUser(key: String, value: Any): User?
|
||||
suspend fun updateUser(updateData: Map<String, Any?>): User?
|
||||
suspend fun updateUser(key : String, value : Any?): User?
|
||||
|
||||
suspend fun retrieveUser(withTasks: Boolean = false, forced: Boolean = false, overrideExisting: Boolean = false): User?
|
||||
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ class ApiClientImpl(
|
|||
return process { apiService.getContent(language ?: this.languageCode) }
|
||||
}
|
||||
|
||||
override suspend fun updateUser(updateDictionary: Map<String, Any>): User? {
|
||||
override suspend fun updateUser(updateDictionary: Map<String, Any?>): User? {
|
||||
return process { apiService.updateUser(updateDictionary) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,21 +46,21 @@ class UserRepositoryImpl(
|
|||
override fun getUser(): Flow<User?> = getUser(userID)
|
||||
override fun getUser(userID: String): Flow<User?> = localRepository.getUser(userID)
|
||||
|
||||
private suspend fun updateUser(userID: String, updateData: Map<String, Any>): User? {
|
||||
private suspend fun updateUser(userID: String, updateData: Map<String, Any?>): User? {
|
||||
val networkUser = apiClient.updateUser(updateData) ?: return null
|
||||
val oldUser = localRepository.getUser(userID).firstOrNull()
|
||||
return mergeUser(oldUser, networkUser)
|
||||
}
|
||||
|
||||
private suspend fun updateUser(userID: String, key: String, value: Any): User? {
|
||||
private suspend fun updateUser(userID : String, key : String, value : Any?): User? {
|
||||
return updateUser(userID, mapOf(key to value))
|
||||
}
|
||||
|
||||
override suspend fun updateUser(updateData: Map<String, Any>): User? {
|
||||
override suspend fun updateUser(updateData: Map<String, Any?>): User? {
|
||||
return updateUser(userID, updateData)
|
||||
}
|
||||
|
||||
override suspend fun updateUser(key: String, value: Any): User? {
|
||||
override suspend fun updateUser(key : String, value : Any?): User? {
|
||||
return updateUser(userID, key, value)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,14 @@ import com.habitrpg.android.habitica.models.BaseObject
|
|||
import com.habitrpg.android.habitica.models.inventory.Quest
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.RealmClass
|
||||
import java.util.Date
|
||||
|
||||
@RealmClass(embedded = true)
|
||||
open class UserParty : RealmObject(), BaseObject {
|
||||
@SerializedName("_id")
|
||||
var id: String = ""
|
||||
var quest: Quest? = null
|
||||
var seeking: Date? = null
|
||||
@SerializedName("order")
|
||||
var partyOrder: String? = null // Order to display ppl
|
||||
var orderAscending: String? = null // Order type
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.map
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.components.UserComponent
|
||||
import com.habitrpg.android.habitica.data.InventoryRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentComposeScrollingBinding
|
||||
import com.habitrpg.android.habitica.helpers.MainNavigationController
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
package com.habitrpg.android.habitica.ui.fragments.social.party
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Shader
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
|
@ -16,8 +12,8 @@ import android.view.ViewGroup
|
|||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.habitrpg.android.habitica.R
|
||||
import com.habitrpg.android.habitica.data.SocialRepository
|
||||
import com.habitrpg.android.habitica.databinding.FragmentNoPartyBinding
|
||||
|
|
@ -26,15 +22,14 @@ import com.habitrpg.android.habitica.helpers.MainNavigationController
|
|||
import com.habitrpg.android.habitica.ui.activities.GroupFormActivity
|
||||
import com.habitrpg.android.habitica.ui.fragments.BaseMainFragment
|
||||
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
|
||||
import com.habitrpg.android.habitica.ui.views.HabiticaSnackbar
|
||||
import com.habitrpg.common.habitica.extensions.DataBindingUtils
|
||||
import com.habitrpg.common.habitica.helpers.ExceptionHandler
|
||||
import com.habitrpg.common.habitica.helpers.launchCatching
|
||||
import com.habitrpg.common.habitica.helpers.setMarkdown
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.util.Date
|
||||
|
||||
@AndroidEntryPoint
|
||||
class NoPartyFragmentFragment : BaseMainFragment<FragmentNoPartyBinding>() {
|
||||
|
|
@ -97,15 +92,21 @@ class NoPartyFragmentFragment : BaseMainFragment<FragmentNoPartyBinding>() {
|
|||
} else {
|
||||
binding?.invitationWrapper?.visibility = View.GONE
|
||||
}
|
||||
|
||||
val isSeeking = user?.party?.seeking != null
|
||||
binding?.seekPartyButton?.isVisible = !isSeeking
|
||||
binding?.seekingPartyWrapper?.isVisible = isSeeking
|
||||
}
|
||||
|
||||
binding?.usernameTextview?.setOnClickListener {
|
||||
val clipboard = context?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
|
||||
val clip = ClipData.newPlainText(context?.getString(R.string.username), userViewModel.username)
|
||||
clipboard?.setPrimaryClip(clip)
|
||||
val activity = mainActivity
|
||||
if (activity != null && Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
||||
HabiticaSnackbar.showSnackbar(activity.snackbarContainer, getString(R.string.username_copied), HabiticaSnackbar.SnackbarDisplayType.NORMAL)
|
||||
binding?.seekPartyButton?.setOnClickListener {
|
||||
lifecycleScope.launchCatching {
|
||||
userRepository.updateUser("party.seeking", Date())
|
||||
}
|
||||
}
|
||||
|
||||
binding?.leaveSeekingButton?.setOnClickListener {
|
||||
lifecycleScope.launchCatching {
|
||||
userRepository.updateUser("party.seeking", null)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,16 +133,6 @@ class NoPartyFragmentFragment : BaseMainFragment<FragmentNoPartyBinding>() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (configManager.noPartyLinkPartyGuild()) {
|
||||
binding?.joinPartyDescriptionTextview?.setMarkdown(getString(R.string.join_party_description_guild, "[Party Wanted Guild](https://habitica.com/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601)"))
|
||||
binding?.joinPartyDescriptionTextview?.setOnClickListener {
|
||||
context?.let { FirebaseAnalytics.getInstance(it).logEvent("clicked_party_wanted", null) }
|
||||
MainNavigationController.navigate(R.id.guildFragment, bundleOf("groupID" to "f2db2a7f-13c5-454d-b3ee-ea1f5089e601"))
|
||||
}
|
||||
}
|
||||
|
||||
binding?.usernameTextview?.text = userViewModel.formattedUsername
|
||||
}
|
||||
|
||||
private val groupFormResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
|
|
@ -184,20 +175,7 @@ class NoPartyFragmentFragment : BaseMainFragment<FragmentNoPartyBinding>() {
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
userRepository.close()
|
||||
socialRepository.close()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): NoPartyFragmentFragment {
|
||||
val args = Bundle()
|
||||
|
||||
val fragment = NoPartyFragmentFragment()
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ class PartyFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
val inviteData = HashMap<String, Any>()
|
||||
inviteData["inviter"] = viewModel.user.value?.profile?.name ?: ""
|
||||
val emails = it.data?.getStringArrayExtra(GroupInviteActivity.EMAILS_KEY)
|
||||
if (emails != null && emails.isNotEmpty()) {
|
||||
if (!emails.isNullOrEmpty()) {
|
||||
val invites = ArrayList<HashMap<String, String>>()
|
||||
emails.forEach { email ->
|
||||
val invite = HashMap<String, String>()
|
||||
|
|
@ -171,7 +171,7 @@ class PartyFragment : BaseMainFragment<FragmentViewpagerBinding>() {
|
|||
inviteData["emails"] = invites
|
||||
}
|
||||
val userIDs = it.data?.getStringArrayExtra(GroupInviteActivity.USER_IDS_KEY)
|
||||
if (userIDs != null && userIDs.isNotEmpty()) {
|
||||
if (!userIDs.isNullOrEmpty()) {
|
||||
val invites = ArrayList<String>()
|
||||
userIDs.forEach { invites.add(it) }
|
||||
inviteData["usernames"] = invites
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class InboxViewModel @Inject constructor(
|
|||
.setEnablePlaceholders(false)
|
||||
.build()
|
||||
|
||||
val dataSourceFactory = MessagesDataSourceFactory(socialRepository, recipientID, ChatMessage())
|
||||
private val dataSourceFactory = MessagesDataSourceFactory(socialRepository, recipientID, ChatMessage())
|
||||
val messages: LiveData<PagedList<ChatMessage>> = dataSourceFactory.toLiveData(config)
|
||||
private val member = memberIDFlow
|
||||
.filterNotNull()
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ import androidx.compose.material.pullrefresh.pullRefresh
|
|||
import androidx.compose.material.pullrefresh.pullRefreshIndicatorTransform
|
||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
|
@ -47,9 +44,6 @@ fun HabiticaPullRefreshIndicator(
|
|||
}
|
||||
}
|
||||
if (!isInitial) {
|
||||
val showElevation by remember(isRefreshing, state) {
|
||||
derivedStateOf { isRefreshing || state.progress > 0.5f }
|
||||
}
|
||||
Surface(
|
||||
modifier = modifier
|
||||
.pullRefreshIndicatorTransform(state, scale),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ buildscript {
|
|||
kotest_version = '5.5.5'
|
||||
kotlin_version = '1.8.10'
|
||||
ktlint_version = '0.48.2'
|
||||
lifecycle_version = '2.5.1'
|
||||
lifecycle_version = '2.6.0'
|
||||
markwon_version = '4.6.2'
|
||||
mockk_version = '1.13.4'
|
||||
moshi_version = '1.14.0'
|
||||
|
|
@ -30,7 +30,7 @@ buildscript {
|
|||
preferences_version = '1.2.0'
|
||||
realm_version = '1.0.2'
|
||||
retrofit_version = '2.9.0'
|
||||
recyclerview_version = '1.2.1'
|
||||
recyclerview_version = '1.3.0'
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
|
@ -39,7 +39,7 @@ buildscript {
|
|||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.1'
|
||||
classpath 'com.android.tools.build:gradle:7.4.2'
|
||||
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
|
||||
classpath 'com.google.gms:google-services:4.3.15'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.4'
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
<color name="text_inverted">@color/gray_10</color>
|
||||
<color name="text_brand">@color/brand_600</color>
|
||||
<color name="text_brand_neon">@color/brand_500</color>
|
||||
<color name="text_maroon">@color/maroon_100</color>
|
||||
<color name="text_red">@color/red_100</color>
|
||||
<color name="text_orange">@color/orange_100</color>
|
||||
<color name="text_yellow">@color/yellow_100</color>
|
||||
|
|
|
|||
|
|
@ -151,6 +151,7 @@
|
|||
<color name="text_inverted">@color/gray_700</color>
|
||||
<color name="text_brand">@color/brand_300</color>
|
||||
<color name="text_brand_neon">@color/brand_400</color>
|
||||
<color name="text_maroon">@color/maroon_10</color>
|
||||
<color name="text_red">@color/maroon_100</color>
|
||||
<color name="text_orange">@color/orange_10</color>
|
||||
<color name="text_yellow">@color/yellow_10</color>
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@
|
|||
<dimen name="spacing_large">16dp</dimen>
|
||||
<dimen name="spacing_medium">8dp</dimen>
|
||||
<dimen name="spacing_xlarge">32dp</dimen>
|
||||
<dimen name="spacing_sides">25dp</dimen>
|
||||
|
||||
<dimen name="icon_size">18dp</dimen>
|
||||
|
||||
<dimen name="card_medium_text">18.0sp</dimen>
|
||||
<dimen name="card_small_text">14.0sp</dimen>
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in a new issue